xref: /petsc/src/dm/interface/dm.c (revision baf369e73c834e6d9bd6baf7b5d05002dc48c405)
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   }
345*baf369e7SPeter Brune   {
346*baf369e7SPeter Brune     DMGlobalToLocalHookLink link,next;
347*baf369e7SPeter Brune     for (link=(*dm)->gtolhook; link; link=next) {
348*baf369e7SPeter Brune       next = link->next;
349*baf369e7SPeter Brune       ierr = PetscFree(link);CHKERRQ(ierr);
350*baf369e7SPeter Brune     }
351*baf369e7SPeter Brune     (*dm)->gtolhook = PETSC_NULL;
352*baf369e7SPeter 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     MPI_Comm         comm;
54732c0f0efSBarry Smith     PetscMPIInt      rank;
54832c0f0efSBarry Smith     char             type[256];
54932c0f0efSBarry Smith 
55032c0f0efSBarry Smith     ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
55132c0f0efSBarry Smith     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
55232c0f0efSBarry Smith     if (!rank) {
55332c0f0efSBarry Smith       ierr = PetscViewerBinaryWrite(v,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
55432c0f0efSBarry Smith       ierr = PetscStrncpy(type,((PetscObject)dm)->type_name,256);CHKERRQ(ierr);
55532c0f0efSBarry Smith       ierr = PetscViewerBinaryWrite(v,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
55632c0f0efSBarry Smith     }
55732c0f0efSBarry Smith   }
5580c010503SBarry Smith   if (dm->ops->view) {
5590c010503SBarry Smith     ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr);
56047c6ae99SBarry Smith   }
56147c6ae99SBarry Smith   PetscFunctionReturn(0);
56247c6ae99SBarry Smith }
56347c6ae99SBarry Smith 
564ba654b55SMatthew G Knepley PETSC_EXTERN PetscErrorCode VecView_Complex_Local(Vec, PetscViewer);
565ba654b55SMatthew G Knepley PETSC_EXTERN PetscErrorCode VecView_Complex(Vec, PetscViewer);
566ba654b55SMatthew G Knepley 
56747c6ae99SBarry Smith #undef __FUNCT__
56847c6ae99SBarry Smith #define __FUNCT__ "DMCreateGlobalVector"
56947c6ae99SBarry Smith /*@
570aa219208SBarry Smith     DMCreateGlobalVector - Creates a global vector from a DMDA or DMComposite object
57147c6ae99SBarry Smith 
57247c6ae99SBarry Smith     Collective on DM
57347c6ae99SBarry Smith 
57447c6ae99SBarry Smith     Input Parameter:
57547c6ae99SBarry Smith .   dm - the DM object
57647c6ae99SBarry Smith 
57747c6ae99SBarry Smith     Output Parameter:
57847c6ae99SBarry Smith .   vec - the global vector
57947c6ae99SBarry Smith 
580073dac72SJed Brown     Level: beginner
58147c6ae99SBarry Smith 
582e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
58347c6ae99SBarry Smith 
58447c6ae99SBarry Smith @*/
5857087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector(DM dm,Vec *vec)
58647c6ae99SBarry Smith {
58747c6ae99SBarry Smith   PetscErrorCode ierr;
58847c6ae99SBarry Smith 
58947c6ae99SBarry Smith   PetscFunctionBegin;
590171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
59188ed4aceSMatthew G Knepley   if (dm->defaultSection) {
59288ed4aceSMatthew G Knepley     PetscSection gSection;
5931f588964SMatthew G Knepley     PetscInt     localSize, blockSize = -1, pStart, pEnd, p;
59488ed4aceSMatthew G Knepley 
59588ed4aceSMatthew G Knepley     ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr);
5961f588964SMatthew G Knepley     ierr = PetscSectionGetChart(dm->defaultSection, &pStart, &pEnd);CHKERRQ(ierr);
5971f588964SMatthew G Knepley     for(p = pStart; p < pEnd; ++p) {
5981f588964SMatthew G Knepley       PetscInt dof, cdof;
5991f588964SMatthew G Knepley 
6001f588964SMatthew G Knepley       ierr = PetscSectionGetDof(dm->defaultSection, p, &dof);CHKERRQ(ierr);
6011f588964SMatthew G Knepley       ierr = PetscSectionGetConstraintDof(dm->defaultSection, p, &cdof);CHKERRQ(ierr);
6021f588964SMatthew G Knepley       if ((blockSize < 0) && (dof > 0)) blockSize = dof-cdof;
6031f588964SMatthew G Knepley       if ((dof > 0) && (dof-cdof != blockSize)) {
6041f588964SMatthew G Knepley         blockSize = 1;
6051f588964SMatthew G Knepley         break;
6061f588964SMatthew G Knepley       }
6071f588964SMatthew G Knepley     }
60888ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstrainedStorageSize(dm->defaultGlobalSection, &localSize);CHKERRQ(ierr);
6091f588964SMatthew G Knepley     if (localSize%blockSize) SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_ARG_WRONG, "Mismatch between blocksize %d and local storage size %d", blockSize, localSize);
61088ed4aceSMatthew G Knepley     ierr = VecCreate(((PetscObject) dm)->comm, vec);CHKERRQ(ierr);
61188ed4aceSMatthew G Knepley     ierr = VecSetSizes(*vec, localSize, PETSC_DETERMINE);CHKERRQ(ierr);
6121f588964SMatthew G Knepley     ierr = VecSetBlockSize(*vec, blockSize);CHKERRQ(ierr);
61388ed4aceSMatthew G Knepley     /* ierr = VecSetType(*vec, dm->vectype);CHKERRQ(ierr); */
61488ed4aceSMatthew G Knepley     ierr = VecSetFromOptions(*vec);CHKERRQ(ierr);
615c688c046SMatthew G Knepley     ierr = VecSetDM(*vec, dm);CHKERRQ(ierr);
61688ed4aceSMatthew G Knepley     /* ierr = VecSetLocalToGlobalMapping(*vec, dm->ltogmap);CHKERRQ(ierr); */
61788ed4aceSMatthew G Knepley     /* ierr = VecSetLocalToGlobalMappingBlock(*vec, dm->ltogmapb);CHKERRQ(ierr); */
61888ed4aceSMatthew G Knepley     /* ierr = VecSetOperation(*vec, VECOP_DUPLICATE, (void(*)(void)) VecDuplicate_MPI_DM);CHKERRQ(ierr); */
619ba654b55SMatthew G Knepley     ierr = VecSetOperation(*vec, VECOP_VIEW, (void(*)(void)) VecView_Complex);CHKERRQ(ierr);
62088ed4aceSMatthew G Knepley   } else {
62147c6ae99SBarry Smith     ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr);
62288ed4aceSMatthew G Knepley   }
62347c6ae99SBarry Smith   PetscFunctionReturn(0);
62447c6ae99SBarry Smith }
62547c6ae99SBarry Smith 
62647c6ae99SBarry Smith #undef __FUNCT__
62747c6ae99SBarry Smith #define __FUNCT__ "DMCreateLocalVector"
62847c6ae99SBarry Smith /*@
629aa219208SBarry Smith     DMCreateLocalVector - Creates a local vector from a DMDA or DMComposite object
63047c6ae99SBarry Smith 
63147c6ae99SBarry Smith     Not Collective
63247c6ae99SBarry Smith 
63347c6ae99SBarry Smith     Input Parameter:
63447c6ae99SBarry Smith .   dm - the DM object
63547c6ae99SBarry Smith 
63647c6ae99SBarry Smith     Output Parameter:
63747c6ae99SBarry Smith .   vec - the local vector
63847c6ae99SBarry Smith 
639073dac72SJed Brown     Level: beginner
64047c6ae99SBarry Smith 
641e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
64247c6ae99SBarry Smith 
64347c6ae99SBarry Smith @*/
6447087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector(DM dm,Vec *vec)
64547c6ae99SBarry Smith {
64647c6ae99SBarry Smith   PetscErrorCode ierr;
64747c6ae99SBarry Smith 
64847c6ae99SBarry Smith   PetscFunctionBegin;
649171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
65088ed4aceSMatthew G Knepley   if (dm->defaultSection) {
6511f588964SMatthew G Knepley     PetscInt localSize, blockSize = -1, pStart, pEnd, p;
65288ed4aceSMatthew G Knepley 
6531f588964SMatthew G Knepley     ierr = PetscSectionGetChart(dm->defaultSection, &pStart, &pEnd);CHKERRQ(ierr);
6541f588964SMatthew G Knepley     for(p = pStart; p < pEnd; ++p) {
6551f588964SMatthew G Knepley       PetscInt dof;
6561f588964SMatthew G Knepley 
6571f588964SMatthew G Knepley       ierr = PetscSectionGetDof(dm->defaultSection, p, &dof);CHKERRQ(ierr);
6581f588964SMatthew G Knepley       if ((blockSize < 0) && (dof > 0)) blockSize = dof;
6591f588964SMatthew G Knepley       if ((dof > 0) && (dof != blockSize)) {
6601f588964SMatthew G Knepley         blockSize = 1;
6611f588964SMatthew G Knepley         break;
6621f588964SMatthew G Knepley       }
6631f588964SMatthew G Knepley     }
66488ed4aceSMatthew G Knepley     ierr = PetscSectionGetStorageSize(dm->defaultSection, &localSize);CHKERRQ(ierr);
66588ed4aceSMatthew G Knepley     ierr = VecCreate(PETSC_COMM_SELF, vec);CHKERRQ(ierr);
66688ed4aceSMatthew G Knepley     ierr = VecSetSizes(*vec, localSize, localSize);CHKERRQ(ierr);
6671f588964SMatthew G Knepley     ierr = VecSetBlockSize(*vec, blockSize);CHKERRQ(ierr);
66888ed4aceSMatthew G Knepley     ierr = VecSetFromOptions(*vec);CHKERRQ(ierr);
669c688c046SMatthew G Knepley     ierr = VecSetDM(*vec, dm);CHKERRQ(ierr);
670ba654b55SMatthew G Knepley     ierr = VecSetOperation(*vec, VECOP_VIEW, (void(*)(void)) VecView_Complex_Local);CHKERRQ(ierr);
67188ed4aceSMatthew G Knepley   } else {
67247c6ae99SBarry Smith     ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr);
67388ed4aceSMatthew G Knepley   }
67447c6ae99SBarry Smith   PetscFunctionReturn(0);
67547c6ae99SBarry Smith }
67647c6ae99SBarry Smith 
67747c6ae99SBarry Smith #undef __FUNCT__
6781411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMapping"
6791411c6eeSJed Brown /*@
6801411c6eeSJed Brown    DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM.
6811411c6eeSJed Brown 
6821411c6eeSJed Brown    Collective on DM
6831411c6eeSJed Brown 
6841411c6eeSJed Brown    Input Parameter:
6851411c6eeSJed Brown .  dm - the DM that provides the mapping
6861411c6eeSJed Brown 
6871411c6eeSJed Brown    Output Parameter:
6881411c6eeSJed Brown .  ltog - the mapping
6891411c6eeSJed Brown 
6901411c6eeSJed Brown    Level: intermediate
6911411c6eeSJed Brown 
6921411c6eeSJed Brown    Notes:
6931411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMapping() or
6941411c6eeSJed Brown    MatSetLocalToGlobalMapping().
6951411c6eeSJed Brown 
6961411c6eeSJed Brown .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMappingBlock()
6971411c6eeSJed Brown @*/
6987087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog)
6991411c6eeSJed Brown {
7001411c6eeSJed Brown   PetscErrorCode ierr;
7011411c6eeSJed Brown 
7021411c6eeSJed Brown   PetscFunctionBegin;
7031411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7041411c6eeSJed Brown   PetscValidPointer(ltog,2);
7051411c6eeSJed Brown   if (!dm->ltogmap) {
70637d0c07bSMatthew G Knepley     PetscSection section, sectionGlobal;
70737d0c07bSMatthew G Knepley 
70837d0c07bSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
70937d0c07bSMatthew G Knepley     if (section) {
71037d0c07bSMatthew G Knepley       PetscInt      *ltog;
71137d0c07bSMatthew G Knepley       PetscInt       pStart, pEnd, size, p, l;
71237d0c07bSMatthew G Knepley 
71337d0c07bSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
71437d0c07bSMatthew G Knepley       ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
71537d0c07bSMatthew G Knepley       ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr);
71637d0c07bSMatthew G Knepley       ierr = PetscMalloc(size * sizeof(PetscInt), &ltog);CHKERRQ(ierr); /* We want the local+overlap size */
71737d0c07bSMatthew G Knepley       for (p = pStart, l = 0; p < pEnd; ++p) {
71837d0c07bSMatthew G Knepley         PetscInt dof, off, c;
71937d0c07bSMatthew G Knepley 
72037d0c07bSMatthew G Knepley         /* Should probably use constrained dofs */
72137d0c07bSMatthew G Knepley         ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr);
72237d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr);
72337d0c07bSMatthew G Knepley         for (c = 0; c < dof; ++c, ++l) {
72437d0c07bSMatthew G Knepley           ltog[l] = off+c;
72537d0c07bSMatthew G Knepley         }
72637d0c07bSMatthew G Knepley       }
72737d0c07bSMatthew G Knepley       ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF, size, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr);
72837d0c07bSMatthew G Knepley       ierr = PetscLogObjectParent(dm, dm->ltogmap);CHKERRQ(ierr);
72937d0c07bSMatthew G Knepley     } else {
7301411c6eeSJed Brown       if (!dm->ops->createlocaltoglobalmapping) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMapping");
7311411c6eeSJed Brown       ierr = (*dm->ops->createlocaltoglobalmapping)(dm);CHKERRQ(ierr);
7321411c6eeSJed Brown     }
73337d0c07bSMatthew G Knepley   }
7341411c6eeSJed Brown   *ltog = dm->ltogmap;
7351411c6eeSJed Brown   PetscFunctionReturn(0);
7361411c6eeSJed Brown }
7371411c6eeSJed Brown 
7381411c6eeSJed Brown #undef __FUNCT__
7391411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMappingBlock"
7401411c6eeSJed Brown /*@
7411411c6eeSJed Brown    DMGetLocalToGlobalMappingBlock - Accesses the blocked local-to-global mapping in a DM.
7421411c6eeSJed Brown 
7431411c6eeSJed Brown    Collective on DM
7441411c6eeSJed Brown 
7451411c6eeSJed Brown    Input Parameter:
7461411c6eeSJed Brown .  da - the distributed array that provides the mapping
7471411c6eeSJed Brown 
7481411c6eeSJed Brown    Output Parameter:
7491411c6eeSJed Brown .  ltog - the block mapping
7501411c6eeSJed Brown 
7511411c6eeSJed Brown    Level: intermediate
7521411c6eeSJed Brown 
7531411c6eeSJed Brown    Notes:
7541411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMappingBlock() or
7551411c6eeSJed Brown    MatSetLocalToGlobalMappingBlock().
7561411c6eeSJed Brown 
7571411c6eeSJed Brown .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMapping(), DMGetBlockSize(), VecSetBlockSize(), MatSetBlockSize()
7581411c6eeSJed Brown @*/
7597087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMappingBlock(DM dm,ISLocalToGlobalMapping *ltog)
7601411c6eeSJed Brown {
7611411c6eeSJed Brown   PetscErrorCode ierr;
7621411c6eeSJed Brown 
7631411c6eeSJed Brown   PetscFunctionBegin;
7641411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7651411c6eeSJed Brown   PetscValidPointer(ltog,2);
7661411c6eeSJed Brown   if (!dm->ltogmapb) {
7671411c6eeSJed Brown     PetscInt bs;
7681411c6eeSJed Brown     ierr = DMGetBlockSize(dm,&bs);CHKERRQ(ierr);
7691411c6eeSJed Brown     if (bs > 1) {
7701411c6eeSJed Brown       if (!dm->ops->createlocaltoglobalmappingblock) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMappingBlock");
7711411c6eeSJed Brown       ierr = (*dm->ops->createlocaltoglobalmappingblock)(dm);CHKERRQ(ierr);
7721411c6eeSJed Brown     } else {
7731411c6eeSJed Brown       ierr = DMGetLocalToGlobalMapping(dm,&dm->ltogmapb);CHKERRQ(ierr);
7741411c6eeSJed Brown       ierr = PetscObjectReference((PetscObject)dm->ltogmapb);CHKERRQ(ierr);
7751411c6eeSJed Brown     }
7761411c6eeSJed Brown   }
7771411c6eeSJed Brown   *ltog = dm->ltogmapb;
7781411c6eeSJed Brown   PetscFunctionReturn(0);
7791411c6eeSJed Brown }
7801411c6eeSJed Brown 
7811411c6eeSJed Brown #undef __FUNCT__
7821411c6eeSJed Brown #define __FUNCT__ "DMGetBlockSize"
7831411c6eeSJed Brown /*@
7841411c6eeSJed Brown    DMGetBlockSize - Gets the inherent block size associated with a DM
7851411c6eeSJed Brown 
7861411c6eeSJed Brown    Not Collective
7871411c6eeSJed Brown 
7881411c6eeSJed Brown    Input Parameter:
7891411c6eeSJed Brown .  dm - the DM with block structure
7901411c6eeSJed Brown 
7911411c6eeSJed Brown    Output Parameter:
7921411c6eeSJed Brown .  bs - the block size, 1 implies no exploitable block structure
7931411c6eeSJed Brown 
7941411c6eeSJed Brown    Level: intermediate
7951411c6eeSJed Brown 
7961411c6eeSJed Brown .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMappingBlock()
7971411c6eeSJed Brown @*/
7987087cfbeSBarry Smith PetscErrorCode  DMGetBlockSize(DM dm,PetscInt *bs)
7991411c6eeSJed Brown {
8001411c6eeSJed Brown   PetscFunctionBegin;
8011411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8021411c6eeSJed Brown   PetscValidPointer(bs,2);
8031411c6eeSJed 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");
8041411c6eeSJed Brown   *bs = dm->bs;
8051411c6eeSJed Brown   PetscFunctionReturn(0);
8061411c6eeSJed Brown }
8071411c6eeSJed Brown 
8081411c6eeSJed Brown #undef __FUNCT__
809e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation"
81047c6ae99SBarry Smith /*@
811e727c939SJed Brown     DMCreateInterpolation - Gets interpolation matrix between two DMDA or DMComposite objects
81247c6ae99SBarry Smith 
81347c6ae99SBarry Smith     Collective on DM
81447c6ae99SBarry Smith 
81547c6ae99SBarry Smith     Input Parameter:
81647c6ae99SBarry Smith +   dm1 - the DM object
81747c6ae99SBarry Smith -   dm2 - the second, finer DM object
81847c6ae99SBarry Smith 
81947c6ae99SBarry Smith     Output Parameter:
82047c6ae99SBarry Smith +  mat - the interpolation
82147c6ae99SBarry Smith -  vec - the scaling (optional)
82247c6ae99SBarry Smith 
82347c6ae99SBarry Smith     Level: developer
82447c6ae99SBarry Smith 
82585afcc9aSBarry 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
82685afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
827d52bd9f3SBarry Smith 
8281f588964SMatthew G Knepley         For DMDA objects you can use this interpolation (more precisely the interpolation from the DMGetCoordinateDM()) to interpolate the mesh coordinate vectors
829d52bd9f3SBarry Smith         EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic.
83085afcc9aSBarry Smith 
83185afcc9aSBarry Smith 
832e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen()
83347c6ae99SBarry Smith 
83447c6ae99SBarry Smith @*/
835e727c939SJed Brown PetscErrorCode  DMCreateInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec)
83647c6ae99SBarry Smith {
83747c6ae99SBarry Smith   PetscErrorCode ierr;
83847c6ae99SBarry Smith 
83947c6ae99SBarry Smith   PetscFunctionBegin;
840171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
841171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
84225296bd5SBarry Smith   ierr = (*dm1->ops->createinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr);
84347c6ae99SBarry Smith   PetscFunctionReturn(0);
84447c6ae99SBarry Smith }
84547c6ae99SBarry Smith 
84647c6ae99SBarry Smith #undef __FUNCT__
847e727c939SJed Brown #define __FUNCT__ "DMCreateInjection"
84847c6ae99SBarry Smith /*@
849e727c939SJed Brown     DMCreateInjection - Gets injection matrix between two DMDA or DMComposite objects
85047c6ae99SBarry Smith 
85147c6ae99SBarry Smith     Collective on DM
85247c6ae99SBarry Smith 
85347c6ae99SBarry Smith     Input Parameter:
85447c6ae99SBarry Smith +   dm1 - the DM object
85547c6ae99SBarry Smith -   dm2 - the second, finer DM object
85647c6ae99SBarry Smith 
85747c6ae99SBarry Smith     Output Parameter:
85847c6ae99SBarry Smith .   ctx - the injection
85947c6ae99SBarry Smith 
86047c6ae99SBarry Smith     Level: developer
86147c6ae99SBarry Smith 
86285afcc9aSBarry 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
86385afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection.
86485afcc9aSBarry Smith 
865e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation()
86647c6ae99SBarry Smith 
86747c6ae99SBarry Smith @*/
868e727c939SJed Brown PetscErrorCode  DMCreateInjection(DM dm1,DM dm2,VecScatter *ctx)
86947c6ae99SBarry Smith {
87047c6ae99SBarry Smith   PetscErrorCode ierr;
87147c6ae99SBarry Smith 
87247c6ae99SBarry Smith   PetscFunctionBegin;
873171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
874171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
87547c6ae99SBarry Smith   ierr = (*dm1->ops->getinjection)(dm1,dm2,ctx);CHKERRQ(ierr);
87647c6ae99SBarry Smith   PetscFunctionReturn(0);
87747c6ae99SBarry Smith }
87847c6ae99SBarry Smith 
87947c6ae99SBarry Smith #undef __FUNCT__
880e727c939SJed Brown #define __FUNCT__ "DMCreateColoring"
881d1e2c406SBarry Smith /*@C
882e727c939SJed Brown     DMCreateColoring - Gets coloring for a DMDA or DMComposite
88347c6ae99SBarry Smith 
88447c6ae99SBarry Smith     Collective on DM
88547c6ae99SBarry Smith 
88647c6ae99SBarry Smith     Input Parameter:
88747c6ae99SBarry Smith +   dm - the DM object
88847c6ae99SBarry Smith .   ctype - IS_COLORING_GHOSTED or IS_COLORING_GLOBAL
88947c6ae99SBarry Smith -   matype - either MATAIJ or MATBAIJ
89047c6ae99SBarry Smith 
89147c6ae99SBarry Smith     Output Parameter:
89247c6ae99SBarry Smith .   coloring - the coloring
89347c6ae99SBarry Smith 
89447c6ae99SBarry Smith     Level: developer
89547c6ae99SBarry Smith 
896e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix()
89747c6ae99SBarry Smith 
898aab9d709SJed Brown @*/
89919fd82e9SBarry Smith PetscErrorCode  DMCreateColoring(DM dm,ISColoringType ctype,MatType mtype,ISColoring *coloring)
90047c6ae99SBarry Smith {
90147c6ae99SBarry Smith   PetscErrorCode ierr;
90247c6ae99SBarry Smith 
90347c6ae99SBarry Smith   PetscFunctionBegin;
904171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
90547c6ae99SBarry Smith   if (!dm->ops->getcoloring) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No coloring for this type of DM yet");
90647c6ae99SBarry Smith   ierr = (*dm->ops->getcoloring)(dm,ctype,mtype,coloring);CHKERRQ(ierr);
90747c6ae99SBarry Smith   PetscFunctionReturn(0);
90847c6ae99SBarry Smith }
90947c6ae99SBarry Smith 
91047c6ae99SBarry Smith #undef __FUNCT__
911950540a4SJed Brown #define __FUNCT__ "DMCreateMatrix"
91247c6ae99SBarry Smith /*@C
913950540a4SJed Brown     DMCreateMatrix - Gets empty Jacobian for a DMDA or DMComposite
91447c6ae99SBarry Smith 
91547c6ae99SBarry Smith     Collective on DM
91647c6ae99SBarry Smith 
91747c6ae99SBarry Smith     Input Parameter:
91847c6ae99SBarry Smith +   dm - the DM object
91947c6ae99SBarry Smith -   mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, or
92094013140SBarry Smith             any type which inherits from one of these (such as MATAIJ)
92147c6ae99SBarry Smith 
92247c6ae99SBarry Smith     Output Parameter:
92347c6ae99SBarry Smith .   mat - the empty Jacobian
92447c6ae99SBarry Smith 
925073dac72SJed Brown     Level: beginner
92647c6ae99SBarry Smith 
92794013140SBarry Smith     Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
92894013140SBarry Smith        do not need to do it yourself.
92994013140SBarry Smith 
93094013140SBarry Smith        By default it also sets the nonzero structure and puts in the zero entries. To prevent setting
931aa219208SBarry Smith        the nonzero pattern call DMDASetMatPreallocateOnly()
93294013140SBarry Smith 
93394013140SBarry 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
93494013140SBarry Smith        internally by PETSc.
93594013140SBarry Smith 
93694013140SBarry Smith        For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires
937aa219208SBarry Smith        the indices for the global numbering for DMDAs which is complicated.
93894013140SBarry Smith 
939e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
94047c6ae99SBarry Smith 
941aab9d709SJed Brown @*/
94219fd82e9SBarry Smith PetscErrorCode  DMCreateMatrix(DM dm,MatType mtype,Mat *mat)
94347c6ae99SBarry Smith {
94447c6ae99SBarry Smith   PetscErrorCode ierr;
94547c6ae99SBarry Smith 
94647c6ae99SBarry Smith   PetscFunctionBegin;
947171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
948235683edSBarry Smith #ifndef PETSC_USE_DYNAMIC_LIBRARIES
949235683edSBarry Smith   ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr);
950235683edSBarry Smith #endif
951c7b7c8a4SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
952c7b7c8a4SJed Brown   PetscValidPointer(mat,3);
953073dac72SJed Brown   if (dm->mattype) {
95425296bd5SBarry Smith     ierr = (*dm->ops->creatematrix)(dm,dm->mattype,mat);CHKERRQ(ierr);
955073dac72SJed Brown   } else {
95625296bd5SBarry Smith     ierr = (*dm->ops->creatematrix)(dm,mtype,mat);CHKERRQ(ierr);
957c7b7c8a4SJed Brown   }
95847c6ae99SBarry Smith   PetscFunctionReturn(0);
95947c6ae99SBarry Smith }
96047c6ae99SBarry Smith 
96147c6ae99SBarry Smith #undef __FUNCT__
962732e2eb9SMatthew G Knepley #define __FUNCT__ "DMSetMatrixPreallocateOnly"
963732e2eb9SMatthew G Knepley /*@
964950540a4SJed Brown   DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly
965732e2eb9SMatthew G Knepley     preallocated but the nonzero structure and zero values will not be set.
966732e2eb9SMatthew G Knepley 
967732e2eb9SMatthew G Knepley   Logically Collective on DMDA
968732e2eb9SMatthew G Knepley 
969732e2eb9SMatthew G Knepley   Input Parameter:
970732e2eb9SMatthew G Knepley + dm - the DM
971732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation
972732e2eb9SMatthew G Knepley 
973732e2eb9SMatthew G Knepley   Level: developer
974950540a4SJed Brown .seealso DMCreateMatrix()
975732e2eb9SMatthew G Knepley @*/
976732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only)
977732e2eb9SMatthew G Knepley {
978732e2eb9SMatthew G Knepley   PetscFunctionBegin;
979732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
980732e2eb9SMatthew G Knepley   dm->prealloc_only = only;
981732e2eb9SMatthew G Knepley   PetscFunctionReturn(0);
982732e2eb9SMatthew G Knepley }
983732e2eb9SMatthew G Knepley 
984732e2eb9SMatthew G Knepley #undef __FUNCT__
985a89ea682SMatthew G Knepley #define __FUNCT__ "DMGetWorkArray"
986a89ea682SMatthew G Knepley /*@C
987aa1993deSMatthew G Knepley   DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
988a89ea682SMatthew G Knepley 
989a89ea682SMatthew G Knepley   Not Collective
990a89ea682SMatthew G Knepley 
991a89ea682SMatthew G Knepley   Input Parameters:
992a89ea682SMatthew G Knepley + dm - the DM object
993aa1993deSMatthew G Knepley . count - The minium size
994aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT)
995a89ea682SMatthew G Knepley 
996a89ea682SMatthew G Knepley   Output Parameter:
997a89ea682SMatthew G Knepley . array - the work array
998a89ea682SMatthew G Knepley 
999a89ea682SMatthew G Knepley   Level: developer
1000a89ea682SMatthew G Knepley 
1001a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate()
1002a89ea682SMatthew G Knepley @*/
1003aa1993deSMatthew G Knepley PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem)
1004a89ea682SMatthew G Knepley {
1005a89ea682SMatthew G Knepley   PetscErrorCode ierr;
1006aa1993deSMatthew G Knepley   DMWorkLink link;
1007aa1993deSMatthew G Knepley   size_t size;
1008a89ea682SMatthew G Knepley 
1009a89ea682SMatthew G Knepley   PetscFunctionBegin;
1010a89ea682SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1011aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
1012aa1993deSMatthew G Knepley   if (dm->workin) {
1013aa1993deSMatthew G Knepley     link = dm->workin;
1014aa1993deSMatthew G Knepley     dm->workin = dm->workin->next;
1015aa1993deSMatthew G Knepley   } else {
1016aa1993deSMatthew G Knepley     ierr = PetscNewLog(dm,struct _DMWorkLink,&link);CHKERRQ(ierr);
1017a89ea682SMatthew G Knepley   }
1018aa1993deSMatthew G Knepley   ierr = PetscDataTypeGetSize(dtype,&size);CHKERRQ(ierr);
1019aa1993deSMatthew G Knepley   if (size*count > link->bytes) {
1020aa1993deSMatthew G Knepley     ierr = PetscFree(link->mem);CHKERRQ(ierr);
1021aa1993deSMatthew G Knepley     ierr = PetscMalloc(size*count,&link->mem);CHKERRQ(ierr);
1022aa1993deSMatthew G Knepley     link->bytes = size*count;
1023aa1993deSMatthew G Knepley   }
1024aa1993deSMatthew G Knepley   link->next = dm->workout;
1025aa1993deSMatthew G Knepley   dm->workout = link;
1026aa1993deSMatthew G Knepley   *(void**)mem = link->mem;
1027a89ea682SMatthew G Knepley   PetscFunctionReturn(0);
1028a89ea682SMatthew G Knepley }
1029a89ea682SMatthew G Knepley 
1030aa1993deSMatthew G Knepley #undef __FUNCT__
1031aa1993deSMatthew G Knepley #define __FUNCT__ "DMRestoreWorkArray"
1032aa1993deSMatthew G Knepley /*@C
1033aa1993deSMatthew G Knepley   DMRestoreWorkArray - Restores a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
1034aa1993deSMatthew G Knepley 
1035aa1993deSMatthew G Knepley   Not Collective
1036aa1993deSMatthew G Knepley 
1037aa1993deSMatthew G Knepley   Input Parameters:
1038aa1993deSMatthew G Knepley + dm - the DM object
1039aa1993deSMatthew G Knepley . count - The minium size
1040aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT)
1041aa1993deSMatthew G Knepley 
1042aa1993deSMatthew G Knepley   Output Parameter:
1043aa1993deSMatthew G Knepley . array - the work array
1044aa1993deSMatthew G Knepley 
1045aa1993deSMatthew G Knepley   Level: developer
1046aa1993deSMatthew G Knepley 
1047aa1993deSMatthew G Knepley .seealso DMDestroy(), DMCreate()
1048aa1993deSMatthew G Knepley @*/
1049aa1993deSMatthew G Knepley PetscErrorCode DMRestoreWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem)
1050aa1993deSMatthew G Knepley {
1051aa1993deSMatthew G Knepley   DMWorkLink *p,link;
1052aa1993deSMatthew G Knepley 
1053aa1993deSMatthew G Knepley   PetscFunctionBegin;
1054aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1055aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
1056aa1993deSMatthew G Knepley   for (p=&dm->workout; (link=*p); p=&link->next) {
1057aa1993deSMatthew G Knepley     if (link->mem == *(void**)mem) {
1058aa1993deSMatthew G Knepley       *p = link->next;
1059aa1993deSMatthew G Knepley       link->next = dm->workin;
1060aa1993deSMatthew G Knepley       dm->workin = link;
1061aa1993deSMatthew G Knepley       *(void**)mem = PETSC_NULL;
1062aa1993deSMatthew G Knepley       PetscFunctionReturn(0);
1063aa1993deSMatthew G Knepley     }
1064aa1993deSMatthew G Knepley   }
1065aa1993deSMatthew G Knepley   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out");
1066aa1993deSMatthew G Knepley   PetscFunctionReturn(0);
1067aa1993deSMatthew G Knepley }
1068e7c4fc90SDmitry Karpeev 
1069e7c4fc90SDmitry Karpeev #undef __FUNCT__
1070435a35e8SMatthew G Knepley #define __FUNCT__ "DMSetNullSpaceConstructor"
1071435a35e8SMatthew G Knepley PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace))
1072435a35e8SMatthew G Knepley {
1073435a35e8SMatthew G Knepley   PetscFunctionBegin;
1074435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1075435a35e8SMatthew G Knepley   if (field >= 10) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field);
1076435a35e8SMatthew G Knepley   dm->nullspaceConstructors[field] = nullsp;
1077435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1078435a35e8SMatthew G Knepley }
1079435a35e8SMatthew G Knepley 
1080435a35e8SMatthew G Knepley #undef __FUNCT__
10814d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS"
10824f3b5142SJed Brown /*@C
10834d343eeaSMatthew G Knepley   DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field
10844d343eeaSMatthew G Knepley 
10854d343eeaSMatthew G Knepley   Not collective
10864d343eeaSMatthew G Knepley 
10874d343eeaSMatthew G Knepley   Input Parameter:
10884d343eeaSMatthew G Knepley . dm - the DM object
10894d343eeaSMatthew G Knepley 
10904d343eeaSMatthew G Knepley   Output Parameters:
109121c9b008SJed Brown + numFields  - The number of fields (or PETSC_NULL if not requested)
109237d0c07bSMatthew G Knepley . fieldNames - The name for each field (or PETSC_NULL if not requested)
109321c9b008SJed Brown - fields     - The global indices for each field (or PETSC_NULL if not requested)
10944d343eeaSMatthew G Knepley 
10954d343eeaSMatthew G Knepley   Level: intermediate
10964d343eeaSMatthew G Knepley 
109721c9b008SJed Brown   Notes:
109821c9b008SJed Brown   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
109921c9b008SJed Brown   PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with
110021c9b008SJed Brown   PetscFree().
110121c9b008SJed Brown 
11024d343eeaSMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
11034d343eeaSMatthew G Knepley @*/
110437d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields)
11054d343eeaSMatthew G Knepley {
110637d0c07bSMatthew G Knepley   PetscSection   section, sectionGlobal;
11074d343eeaSMatthew G Knepley   PetscErrorCode ierr;
11084d343eeaSMatthew G Knepley 
11094d343eeaSMatthew G Knepley   PetscFunctionBegin;
11104d343eeaSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
111169ca1f37SDmitry Karpeev   if (numFields) {
111269ca1f37SDmitry Karpeev     PetscValidPointer(numFields,2);
111369ca1f37SDmitry Karpeev     *numFields = 0;
111469ca1f37SDmitry Karpeev   }
111537d0c07bSMatthew G Knepley   if (fieldNames) {
111637d0c07bSMatthew G Knepley     PetscValidPointer(fieldNames,3);
111737d0c07bSMatthew G Knepley     *fieldNames = PETSC_NULL;
111869ca1f37SDmitry Karpeev   }
111969ca1f37SDmitry Karpeev   if (fields) {
112069ca1f37SDmitry Karpeev     PetscValidPointer(fields,4);
112169ca1f37SDmitry Karpeev     *fields = PETSC_NULL;
112269ca1f37SDmitry Karpeev   }
112337d0c07bSMatthew G Knepley   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
112437d0c07bSMatthew G Knepley   if (section) {
112537d0c07bSMatthew G Knepley     PetscInt *fieldSizes, **fieldIndices;
112637d0c07bSMatthew G Knepley     PetscInt  nF, f, pStart, pEnd, p;
112737d0c07bSMatthew G Knepley 
112837d0c07bSMatthew G Knepley     ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
112937d0c07bSMatthew G Knepley     ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr);
113037d0c07bSMatthew G Knepley     ierr = PetscMalloc2(nF,PetscInt,&fieldSizes,nF,PetscInt *,&fieldIndices);CHKERRQ(ierr);
113137d0c07bSMatthew G Knepley     ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr);
113237d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
113337d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
113437d0c07bSMatthew G Knepley     }
113537d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
113637d0c07bSMatthew G Knepley       PetscInt gdof;
113737d0c07bSMatthew G Knepley 
113837d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
113937d0c07bSMatthew G Knepley       if (gdof > 0) {
114037d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
114137d0c07bSMatthew G Knepley           PetscInt fdof, fcdof;
114237d0c07bSMatthew G Knepley 
114337d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
114437d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
114537d0c07bSMatthew G Knepley           fieldSizes[f] += fdof-fcdof;
114637d0c07bSMatthew G Knepley         }
114737d0c07bSMatthew G Knepley       }
114837d0c07bSMatthew G Knepley     }
114937d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
115037d0c07bSMatthew G Knepley       ierr = PetscMalloc(fieldSizes[f] * sizeof(PetscInt), &fieldIndices[f]);CHKERRQ(ierr);
115137d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
115237d0c07bSMatthew G Knepley     }
115337d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
115437d0c07bSMatthew G Knepley       PetscInt gdof, goff;
115537d0c07bSMatthew G Knepley 
115637d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
115737d0c07bSMatthew G Knepley       if (gdof > 0) {
115837d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr);
115937d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
116037d0c07bSMatthew G Knepley           PetscInt fdof, fcdof, fc;
116137d0c07bSMatthew G Knepley 
116237d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
116337d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
116437d0c07bSMatthew G Knepley           for (fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) {
116537d0c07bSMatthew G Knepley             fieldIndices[f][fieldSizes[f]] = goff++;
116637d0c07bSMatthew G Knepley           }
116737d0c07bSMatthew G Knepley         }
116837d0c07bSMatthew G Knepley       }
116937d0c07bSMatthew G Knepley     }
117037d0c07bSMatthew G Knepley     if (numFields) {*numFields = nF;}
117137d0c07bSMatthew G Knepley     if (fieldNames) {
117237d0c07bSMatthew G Knepley       ierr = PetscMalloc(nF * sizeof(char *), fieldNames);CHKERRQ(ierr);
117337d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
117437d0c07bSMatthew G Knepley         const char *fieldName;
117537d0c07bSMatthew G Knepley 
117637d0c07bSMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
117737d0c07bSMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char **) &(*fieldNames)[f]);CHKERRQ(ierr);
117837d0c07bSMatthew G Knepley       }
117937d0c07bSMatthew G Knepley     }
118037d0c07bSMatthew G Knepley     if (fields) {
118137d0c07bSMatthew G Knepley       ierr = PetscMalloc(nF * sizeof(IS), fields);CHKERRQ(ierr);
118237d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
118337d0c07bSMatthew G Knepley         ierr = ISCreateGeneral(((PetscObject) dm)->comm, fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr);
118437d0c07bSMatthew G Knepley       }
118537d0c07bSMatthew G Knepley     }
118637d0c07bSMatthew G Knepley     ierr = PetscFree2(fieldSizes,fieldIndices);CHKERRQ(ierr);
118737d0c07bSMatthew G Knepley   } else {
118837d0c07bSMatthew G Knepley     if (dm->ops->createfieldis) {ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr);}
118969ca1f37SDmitry Karpeev   }
11904d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
11914d343eeaSMatthew G Knepley }
11924d343eeaSMatthew G Knepley 
1193a89ea682SMatthew G Knepley #undef __FUNCT__
119416621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecompositionDM"
1195e7c4fc90SDmitry Karpeev /*@C
119616621825SDmitry Karpeev   DMCreateFieldDecompositionDM - creates a DM that encapsulates a decomposition of the original DM into fields.
119716621825SDmitry Karpeev 
119816621825SDmitry Karpeev   Not Collective
119916621825SDmitry Karpeev 
120016621825SDmitry Karpeev   Input Parameters:
120116621825SDmitry Karpeev + dm   - the DM object
120216621825SDmitry Karpeev - name - the name of the field decomposition
120316621825SDmitry Karpeev 
120416621825SDmitry Karpeev   Output Parameter:
120516621825SDmitry Karpeev . ddm  - the field decomposition DM (PETSC_NULL, if no such decomposition is known)
120616621825SDmitry Karpeev 
120716621825SDmitry Karpeev   Level: advanced
120816621825SDmitry Karpeev 
120916621825SDmitry Karpeev .seealso DMDestroy(), DMCreate(), DMCreateFieldDecomposition(), DMCreateDomainDecompositionDM()
121016621825SDmitry Karpeev @*/
121116621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecompositionDM(DM dm, const char* name, DM *ddm)
121216621825SDmitry Karpeev {
121316621825SDmitry Karpeev   PetscErrorCode ierr;
121416621825SDmitry Karpeev 
121516621825SDmitry Karpeev   PetscFunctionBegin;
121616621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
121716621825SDmitry Karpeev   PetscValidCharPointer(name,2);
121816621825SDmitry Karpeev   PetscValidPointer(ddm,3);
121916621825SDmitry Karpeev   *ddm = PETSC_NULL;
1220731c8d9eSDmitry Karpeev   if (dm->ops->createfielddecompositiondm) {
122116621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecompositiondm)(dm,name,ddm); CHKERRQ(ierr);
122216621825SDmitry Karpeev   }
122316621825SDmitry Karpeev   PetscFunctionReturn(0);
122416621825SDmitry Karpeev }
122516621825SDmitry Karpeev 
122616621825SDmitry Karpeev #undef __FUNCT__
122716621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecomposition"
122816621825SDmitry Karpeev /*@C
122916621825SDmitry Karpeev   DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems
123016621825SDmitry Karpeev                           corresponding to different fields: each IS contains the global indices of the dofs of the
123116621825SDmitry Karpeev                           corresponding field. The optional list of DMs define the DM for each subproblem.
1232e7c4fc90SDmitry Karpeev                           Generalizes DMCreateFieldIS().
1233e7c4fc90SDmitry Karpeev 
1234e7c4fc90SDmitry Karpeev   Not collective
1235e7c4fc90SDmitry Karpeev 
1236e7c4fc90SDmitry Karpeev   Input Parameter:
1237e7c4fc90SDmitry Karpeev . dm - the DM object
1238e7c4fc90SDmitry Karpeev 
1239e7c4fc90SDmitry Karpeev   Output Parameters:
124016621825SDmitry Karpeev + len       - The number of subproblems in the field decomposition (or PETSC_NULL if not requested)
124116621825SDmitry Karpeev . namelist  - The name for each field (or PETSC_NULL if not requested)
124216621825SDmitry Karpeev . islist    - The global indices for each field (or PETSC_NULL if not requested)
124316621825SDmitry Karpeev - dmlist    - The DMs for each field subproblem (or PETSC_NULL, if not requested; if PETSC_NULL is returned, no DMs are defined)
1244e7c4fc90SDmitry Karpeev 
1245e7c4fc90SDmitry Karpeev   Level: intermediate
1246e7c4fc90SDmitry Karpeev 
1247e7c4fc90SDmitry Karpeev   Notes:
1248e7c4fc90SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
1249e7c4fc90SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
1250e7c4fc90SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
1251e7c4fc90SDmitry Karpeev 
1252e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1253e7c4fc90SDmitry Karpeev @*/
125416621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
1255e7c4fc90SDmitry Karpeev {
1256e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
1257e7c4fc90SDmitry Karpeev 
1258e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
1259e7c4fc90SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1260731c8d9eSDmitry Karpeev   if (len)      {PetscValidPointer(len,2);      *len      = 0;}
1261731c8d9eSDmitry Karpeev   if (namelist) {PetscValidPointer(namelist,3); *namelist = 0;}
1262731c8d9eSDmitry Karpeev   if (islist)   {PetscValidPointer(islist,4);   *islist   = 0;}
1263731c8d9eSDmitry Karpeev   if (dmlist)   {PetscValidPointer(dmlist,5);   *dmlist   = 0;}
126416621825SDmitry Karpeev   if (!dm->ops->createfielddecomposition) {
1265435a35e8SMatthew G Knepley     PetscSection section;
1266435a35e8SMatthew G Knepley     PetscInt     numFields, f;
1267435a35e8SMatthew G Knepley 
1268435a35e8SMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
1269435a35e8SMatthew G Knepley     if (section) {ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr);}
1270435a35e8SMatthew G Knepley     if (section && numFields && dm->ops->createsubdm) {
1271435a35e8SMatthew G Knepley       *len = numFields;
1272435a35e8SMatthew G Knepley       ierr = PetscMalloc3(numFields,char*,namelist,numFields,IS,islist,numFields,DM,dmlist);CHKERRQ(ierr);
1273435a35e8SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
1274435a35e8SMatthew G Knepley         const char *fieldName;
1275435a35e8SMatthew G Knepley 
1276435a35e8SMatthew G Knepley         ierr = DMCreateSubDM(dm, 1, &f, &(*islist)[f], &(*dmlist)[f]);CHKERRQ(ierr);
1277435a35e8SMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
1278435a35e8SMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char **) &(*namelist)[f]);CHKERRQ(ierr);
1279435a35e8SMatthew G Knepley       }
1280435a35e8SMatthew G Knepley     } else {
128169ca1f37SDmitry Karpeev       ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr);
1282e7c4fc90SDmitry Karpeev       /* By default there are no DMs associated with subproblems. */
1283e7c4fc90SDmitry Karpeev       if (dmlist) *dmlist = PETSC_NULL;
1284e7c4fc90SDmitry Karpeev     }
1285435a35e8SMatthew G Knepley   }
1286e7c4fc90SDmitry Karpeev   else {
128716621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist); CHKERRQ(ierr);
128816621825SDmitry Karpeev   }
128916621825SDmitry Karpeev   PetscFunctionReturn(0);
129016621825SDmitry Karpeev }
129116621825SDmitry Karpeev 
129216621825SDmitry Karpeev #undef __FUNCT__
1293435a35e8SMatthew G Knepley #define __FUNCT__ "DMCreateSubDM"
1294435a35e8SMatthew G Knepley /*@C
1295435a35e8SMatthew G Knepley   DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in.
1296435a35e8SMatthew G Knepley                   The fields are defined by DMCreateFieldIS().
1297435a35e8SMatthew G Knepley 
1298435a35e8SMatthew G Knepley   Not collective
1299435a35e8SMatthew G Knepley 
1300435a35e8SMatthew G Knepley   Input Parameters:
1301435a35e8SMatthew G Knepley + dm - the DM object
1302435a35e8SMatthew G Knepley . numFields - number of fields in this subproblem
1303435a35e8SMatthew G Knepley - len       - The number of subproblems in the decomposition (or PETSC_NULL if not requested)
1304435a35e8SMatthew G Knepley 
1305435a35e8SMatthew G Knepley   Output Parameters:
1306435a35e8SMatthew G Knepley . is - The global indices for the subproblem
1307435a35e8SMatthew G Knepley - dm - The DM for the subproblem
1308435a35e8SMatthew G Knepley 
1309435a35e8SMatthew G Knepley   Level: intermediate
1310435a35e8SMatthew G Knepley 
1311435a35e8SMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1312435a35e8SMatthew G Knepley @*/
1313435a35e8SMatthew G Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm)
1314435a35e8SMatthew G Knepley {
1315435a35e8SMatthew G Knepley   PetscErrorCode ierr;
1316435a35e8SMatthew G Knepley 
1317435a35e8SMatthew G Knepley   PetscFunctionBegin;
1318435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1319435a35e8SMatthew G Knepley   PetscValidPointer(fields,3);
1320435a35e8SMatthew G Knepley   if (is) {PetscValidPointer(is,4);}
1321435a35e8SMatthew G Knepley   if (subdm) {PetscValidPointer(subdm,5);}
1322435a35e8SMatthew G Knepley   if (dm->ops->createsubdm) {
1323435a35e8SMatthew G Knepley     ierr = (*dm->ops->createsubdm)(dm, numFields, fields, is, subdm); CHKERRQ(ierr);
1324435a35e8SMatthew G Knepley   } else SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "This type has no DMCreateSubDM implementation defined");
1325435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1326435a35e8SMatthew G Knepley }
1327435a35e8SMatthew G Knepley 
1328435a35e8SMatthew G Knepley #undef __FUNCT__
132916621825SDmitry Karpeev #define __FUNCT__ "DMCreateDomainDecompositionDM"
133016621825SDmitry Karpeev /*@C
133116621825SDmitry Karpeev   DMCreateDomainDecompositionDM - creates a DM that encapsulates a decomposition of the original DM into subdomains.
133216621825SDmitry Karpeev 
133316621825SDmitry Karpeev   Not Collective
133416621825SDmitry Karpeev 
133516621825SDmitry Karpeev   Input Parameters:
133616621825SDmitry Karpeev + dm   - the DM object
133716621825SDmitry Karpeev - name - the name of the subdomain decomposition
133816621825SDmitry Karpeev 
133916621825SDmitry Karpeev   Output Parameter:
134016621825SDmitry Karpeev . ddm  - the subdomain decomposition DM (PETSC_NULL, if no such decomposition is known)
134116621825SDmitry Karpeev 
134216621825SDmitry Karpeev   Level: advanced
134316621825SDmitry Karpeev 
134416621825SDmitry Karpeev .seealso DMDestroy(), DMCreate(), DMCreateFieldDecomposition(), DMCreateDomainDecompositionDM()
134516621825SDmitry Karpeev @*/
134616621825SDmitry Karpeev PetscErrorCode DMCreateDomainDecompositionDM(DM dm, const char* name, DM *ddm)
134716621825SDmitry Karpeev {
134816621825SDmitry Karpeev   PetscErrorCode ierr;
134916621825SDmitry Karpeev 
135016621825SDmitry Karpeev   PetscFunctionBegin;
135116621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
135216621825SDmitry Karpeev   PetscValidCharPointer(name,2);
135316621825SDmitry Karpeev   PetscValidPointer(ddm,3);
135416621825SDmitry Karpeev   *ddm = PETSC_NULL;
1355731c8d9eSDmitry Karpeev   if (dm->ops->createdomaindecompositiondm) {
135616621825SDmitry Karpeev     ierr = (*dm->ops->createdomaindecompositiondm)(dm,name,ddm); CHKERRQ(ierr);
135716621825SDmitry Karpeev   }
135816621825SDmitry Karpeev   PetscFunctionReturn(0);
135916621825SDmitry Karpeev }
136016621825SDmitry Karpeev 
136116621825SDmitry Karpeev #undef __FUNCT__
136216621825SDmitry Karpeev #define __FUNCT__ "DMCreateDomainDecomposition"
136316621825SDmitry Karpeev /*@C
13648d4ac253SDmitry Karpeev   DMCreateDomainDecomposition - Returns lists of IS objects defining a decomposition of a problem into subproblems
13658d4ac253SDmitry Karpeev                           corresponding to restrictions to pairs nested subdomains: each IS contains the global
13668d4ac253SDmitry Karpeev                           indices of the dofs of the corresponding subdomains.  The inner subdomains conceptually
13678d4ac253SDmitry Karpeev                           define a nonoverlapping covering, while outer subdomains can overlap.
13688d4ac253SDmitry Karpeev                           The optional list of DMs define the DM for each subproblem.
136916621825SDmitry Karpeev 
137016621825SDmitry Karpeev   Not collective
137116621825SDmitry Karpeev 
137216621825SDmitry Karpeev   Input Parameter:
137316621825SDmitry Karpeev . dm - the DM object
137416621825SDmitry Karpeev 
137516621825SDmitry Karpeev   Output Parameters:
137616621825SDmitry Karpeev + len         - The number of subproblems in the domain decomposition (or PETSC_NULL if not requested)
137716621825SDmitry Karpeev . namelist    - The name for each subdomain (or PETSC_NULL if not requested)
13788d4ac253SDmitry Karpeev . innerislist - The global indices for each inner subdomain (or PETSC_NULL, if not requested)
13798d4ac253SDmitry Karpeev . outerislist - The global indices for each outer subdomain (or PETSC_NULL, if not requested)
138016621825SDmitry Karpeev - dmlist      - The DMs for each subdomain subproblem (or PETSC_NULL, if not requested; if PETSC_NULL is returned, no DMs are defined)
138116621825SDmitry Karpeev 
138216621825SDmitry Karpeev   Level: intermediate
138316621825SDmitry Karpeev 
138416621825SDmitry Karpeev   Notes:
138516621825SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
138616621825SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
138716621825SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
138816621825SDmitry Karpeev 
13898d4ac253SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateDomainDecompositionDM(), DMCreateFieldDecomposition()
139016621825SDmitry Karpeev @*/
13918d4ac253SDmitry Karpeev PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
139216621825SDmitry Karpeev {
139316621825SDmitry Karpeev   PetscErrorCode ierr;
1394be081cd6SPeter Brune   DMSubDomainHookLink link;
1395be081cd6SPeter Brune   PetscInt            i,l;
139616621825SDmitry Karpeev 
139716621825SDmitry Karpeev   PetscFunctionBegin;
139816621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1399731c8d9eSDmitry Karpeev   if (len)           {PetscValidPointer(len,2);            *len         = PETSC_NULL;}
140016621825SDmitry Karpeev   if (namelist)      {PetscValidPointer(namelist,3);       *namelist    = PETSC_NULL;}
14018d4ac253SDmitry Karpeev   if (innerislist)   {PetscValidPointer(innerislist,4);    *innerislist = PETSC_NULL;}
14028d4ac253SDmitry Karpeev   if (outerislist)   {PetscValidPointer(outerislist,5);    *outerislist = PETSC_NULL;}
14038d4ac253SDmitry Karpeev   if (dmlist)        {PetscValidPointer(dmlist,6);         *dmlist      = PETSC_NULL;}
140416621825SDmitry Karpeev   if (dm->ops->createdomaindecomposition) {
1405be081cd6SPeter Brune     ierr = (*dm->ops->createdomaindecomposition)(dm,&l,namelist,innerislist,outerislist,dmlist); CHKERRQ(ierr);
1406be081cd6SPeter Brune   }
1407be081cd6SPeter Brune   if (len) *len = l;
1408be081cd6SPeter Brune   for (i = 0; i < l; i++) {
1409be081cd6SPeter Brune     for (link=dm->subdomainhook; link; link=link->next) {
1410be081cd6SPeter Brune       if (link->ddhook) {ierr = (*link->ddhook)(dm,(*dmlist)[i],link->ctx);CHKERRQ(ierr);}
1411be081cd6SPeter Brune     }
1412e7c4fc90SDmitry Karpeev   }
1413e30e807fSPeter Brune   PetscFunctionReturn(0);
1414e30e807fSPeter Brune }
1415e30e807fSPeter Brune 
1416e30e807fSPeter Brune 
1417e30e807fSPeter Brune #undef __FUNCT__
1418e30e807fSPeter Brune #define __FUNCT__ "DMCreateDomainDecompositionScatters"
1419e30e807fSPeter Brune /*@C
1420e30e807fSPeter Brune   DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector
1421e30e807fSPeter Brune 
1422e30e807fSPeter Brune   Not collective
1423e30e807fSPeter Brune 
1424e30e807fSPeter Brune   Input Parameters:
1425e30e807fSPeter Brune + dm - the DM object
1426e30e807fSPeter Brune . n  - the number of subdomain scatters
1427e30e807fSPeter Brune - subdms - the local subdomains
1428e30e807fSPeter Brune 
1429e30e807fSPeter Brune   Output Parameters:
1430e30e807fSPeter Brune + n     - the number of scatters returned
1431e30e807fSPeter Brune . iscat - scatter from global vector to nonoverlapping global vector entries on subdomain
1432e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain
1433e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts)
1434e30e807fSPeter Brune 
1435e30e807fSPeter Brune   Notes: This is an alternative to the iis and ois arguments in DMCreateDomainDecomposition that allow for the solution
1436e30e807fSPeter Brune   of general nonlinear problems with overlapping subdomain methods.  While merely having index sets that enable subsets
1437e30e807fSPeter Brune   of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of
1438e30e807fSPeter Brune   solution and residual data.
1439e30e807fSPeter Brune 
1440e30e807fSPeter Brune   Level: developer
1441e30e807fSPeter Brune 
1442e30e807fSPeter Brune .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1443e30e807fSPeter Brune @*/
1444e30e807fSPeter Brune PetscErrorCode DMCreateDomainDecompositionScatters(DM dm,PetscInt n,DM *subdms,VecScatter **iscat,VecScatter **oscat,VecScatter **gscat)
1445e30e807fSPeter Brune {
1446e30e807fSPeter Brune   PetscErrorCode ierr;
1447e30e807fSPeter Brune 
1448e30e807fSPeter Brune   PetscFunctionBegin;
1449e30e807fSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1450e30e807fSPeter Brune   PetscValidPointer(subdms,3);
1451e30e807fSPeter Brune   PetscValidPointer(iscat,4);
1452e30e807fSPeter Brune   PetscValidPointer(oscat,5);
1453e30e807fSPeter Brune   PetscValidPointer(gscat,6);
1454e30e807fSPeter Brune   if (dm->ops->createddscatters) {
1455e30e807fSPeter Brune     ierr = (*dm->ops->createddscatters)(dm,n,subdms,iscat,oscat,gscat); CHKERRQ(ierr);
1456e30e807fSPeter Brune   } else SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "This type has no DMCreateDomainDecompositionLocalScatter implementation defined");
1457e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
1458e7c4fc90SDmitry Karpeev }
1459e7c4fc90SDmitry Karpeev 
1460731c8d9eSDmitry Karpeev #undef __FUNCT__
146147c6ae99SBarry Smith #define __FUNCT__ "DMRefine"
146247c6ae99SBarry Smith /*@
146347c6ae99SBarry Smith   DMRefine - Refines a DM object
146447c6ae99SBarry Smith 
146547c6ae99SBarry Smith   Collective on DM
146647c6ae99SBarry Smith 
146747c6ae99SBarry Smith   Input Parameter:
146847c6ae99SBarry Smith + dm   - the DM object
146991d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
147047c6ae99SBarry Smith 
147147c6ae99SBarry Smith   Output Parameter:
1472ae0a1c52SMatthew G Knepley . dmf - the refined DM, or PETSC_NULL
1473ae0a1c52SMatthew G Knepley 
1474ae0a1c52SMatthew G Knepley   Note: If no refinement was done, the return value is PETSC_NULL
147547c6ae99SBarry Smith 
147647c6ae99SBarry Smith   Level: developer
147747c6ae99SBarry Smith 
1478e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
147947c6ae99SBarry Smith @*/
14807087cfbeSBarry Smith PetscErrorCode  DMRefine(DM dm,MPI_Comm comm,DM *dmf)
148147c6ae99SBarry Smith {
148247c6ae99SBarry Smith   PetscErrorCode ierr;
1483c833c3b5SJed Brown   DMRefineHookLink link;
148447c6ae99SBarry Smith 
148547c6ae99SBarry Smith   PetscFunctionBegin;
1486732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
148747c6ae99SBarry Smith   ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr);
14884057135bSMatthew G Knepley   if (*dmf) {
148943842a1eSJed Brown     (*dmf)->ops->creatematrix = dm->ops->creatematrix;
14908cd211a4SJed Brown     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr);
1491644e2e5bSBarry Smith     (*dmf)->ctx       = dm->ctx;
14920598a293SJed Brown     (*dmf)->leveldown = dm->leveldown;
1493656b349aSBarry Smith     (*dmf)->levelup   = dm->levelup + 1;
1494e4b4b23bSJed Brown     ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr);
1495c833c3b5SJed Brown     for (link=dm->refinehook; link; link=link->next) {
1496c833c3b5SJed Brown       if (link->refinehook) {ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr);}
1497c833c3b5SJed Brown     }
1498c833c3b5SJed Brown   }
1499c833c3b5SJed Brown   PetscFunctionReturn(0);
1500c833c3b5SJed Brown }
1501c833c3b5SJed Brown 
1502c833c3b5SJed Brown #undef __FUNCT__
1503c833c3b5SJed Brown #define __FUNCT__ "DMRefineHookAdd"
1504c833c3b5SJed Brown /*@
1505c833c3b5SJed Brown    DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid
1506c833c3b5SJed Brown 
1507c833c3b5SJed Brown    Logically Collective
1508c833c3b5SJed Brown 
1509c833c3b5SJed Brown    Input Arguments:
1510c833c3b5SJed Brown +  coarse - nonlinear solver context on which to run a hook when restricting to a coarser level
1511c833c3b5SJed Brown .  refinehook - function to run when setting up a coarser level
1512c833c3b5SJed Brown .  interphook - function to run to update data on finer levels (once per SNESSolve())
1513c833c3b5SJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
1514c833c3b5SJed Brown 
1515c833c3b5SJed Brown    Calling sequence of refinehook:
1516c833c3b5SJed Brown $    refinehook(DM coarse,DM fine,void *ctx);
1517c833c3b5SJed Brown 
1518c833c3b5SJed Brown +  coarse - coarse level DM
1519c833c3b5SJed Brown .  fine - fine level DM to interpolate problem to
1520c833c3b5SJed Brown -  ctx - optional user-defined function context
1521c833c3b5SJed Brown 
1522c833c3b5SJed Brown    Calling sequence for interphook:
1523c833c3b5SJed Brown $    interphook(DM coarse,Mat interp,DM fine,void *ctx)
1524c833c3b5SJed Brown 
1525c833c3b5SJed Brown +  coarse - coarse level DM
1526c833c3b5SJed Brown .  interp - matrix interpolating a coarse-level solution to the finer grid
1527c833c3b5SJed Brown .  fine - fine level DM to update
1528c833c3b5SJed Brown -  ctx - optional user-defined function context
1529c833c3b5SJed Brown 
1530c833c3b5SJed Brown    Level: advanced
1531c833c3b5SJed Brown 
1532c833c3b5SJed Brown    Notes:
1533c833c3b5SJed Brown    This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing
1534c833c3b5SJed Brown 
1535c833c3b5SJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1536c833c3b5SJed Brown 
1537c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1538c833c3b5SJed Brown @*/
1539c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx)
1540c833c3b5SJed Brown {
1541c833c3b5SJed Brown   PetscErrorCode ierr;
1542c833c3b5SJed Brown   DMRefineHookLink link,*p;
1543c833c3b5SJed Brown 
1544c833c3b5SJed Brown   PetscFunctionBegin;
1545c833c3b5SJed Brown   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
1546c833c3b5SJed Brown   for (p=&coarse->refinehook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1547c833c3b5SJed Brown   ierr = PetscMalloc(sizeof(struct _DMRefineHookLink),&link);CHKERRQ(ierr);
1548c833c3b5SJed Brown   link->refinehook = refinehook;
1549c833c3b5SJed Brown   link->interphook = interphook;
1550c833c3b5SJed Brown   link->ctx = ctx;
1551c833c3b5SJed Brown   link->next = PETSC_NULL;
1552c833c3b5SJed Brown   *p = link;
1553c833c3b5SJed Brown   PetscFunctionReturn(0);
1554c833c3b5SJed Brown }
1555c833c3b5SJed Brown 
1556c833c3b5SJed Brown #undef __FUNCT__
1557c833c3b5SJed Brown #define __FUNCT__ "DMInterpolate"
1558c833c3b5SJed Brown /*@
1559c833c3b5SJed Brown    DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd()
1560c833c3b5SJed Brown 
1561c833c3b5SJed Brown    Collective if any hooks are
1562c833c3b5SJed Brown 
1563c833c3b5SJed Brown    Input Arguments:
1564c833c3b5SJed Brown +  coarse - coarser DM to use as a base
1565c833c3b5SJed Brown .  restrct - interpolation matrix, apply using MatInterpolate()
1566c833c3b5SJed Brown -  fine - finer DM to update
1567c833c3b5SJed Brown 
1568c833c3b5SJed Brown    Level: developer
1569c833c3b5SJed Brown 
1570c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate()
1571c833c3b5SJed Brown @*/
1572c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine)
1573c833c3b5SJed Brown {
1574c833c3b5SJed Brown   PetscErrorCode ierr;
1575c833c3b5SJed Brown   DMRefineHookLink link;
1576c833c3b5SJed Brown 
1577c833c3b5SJed Brown   PetscFunctionBegin;
1578c833c3b5SJed Brown   for (link=fine->refinehook; link; link=link->next) {
1579c833c3b5SJed Brown     if (link->interphook) {ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr);}
15804057135bSMatthew G Knepley   }
158147c6ae99SBarry Smith   PetscFunctionReturn(0);
158247c6ae99SBarry Smith }
158347c6ae99SBarry Smith 
158447c6ae99SBarry Smith #undef __FUNCT__
1585eb3f98d2SBarry Smith #define __FUNCT__ "DMGetRefineLevel"
1586eb3f98d2SBarry Smith /*@
1587eb3f98d2SBarry Smith     DMGetRefineLevel - Get's the number of refinements that have generated this DM.
1588eb3f98d2SBarry Smith 
1589eb3f98d2SBarry Smith     Not Collective
1590eb3f98d2SBarry Smith 
1591eb3f98d2SBarry Smith     Input Parameter:
1592eb3f98d2SBarry Smith .   dm - the DM object
1593eb3f98d2SBarry Smith 
1594eb3f98d2SBarry Smith     Output Parameter:
1595eb3f98d2SBarry Smith .   level - number of refinements
1596eb3f98d2SBarry Smith 
1597eb3f98d2SBarry Smith     Level: developer
1598eb3f98d2SBarry Smith 
15996a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
1600eb3f98d2SBarry Smith 
1601eb3f98d2SBarry Smith @*/
1602eb3f98d2SBarry Smith PetscErrorCode  DMGetRefineLevel(DM dm,PetscInt *level)
1603eb3f98d2SBarry Smith {
1604eb3f98d2SBarry Smith   PetscFunctionBegin;
1605eb3f98d2SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1606eb3f98d2SBarry Smith   *level = dm->levelup;
1607eb3f98d2SBarry Smith   PetscFunctionReturn(0);
1608eb3f98d2SBarry Smith }
1609eb3f98d2SBarry Smith 
1610eb3f98d2SBarry Smith #undef __FUNCT__
1611*baf369e7SPeter Brune #define __FUNCT__ "DMGlobalToLocalHookAdd"
1612*baf369e7SPeter Brune /*@
1613*baf369e7SPeter Brune    DMGlobalToLocalHookAdd - adds a callback to be run when global to local is called
1614*baf369e7SPeter Brune 
1615*baf369e7SPeter Brune    Logically Collective
1616*baf369e7SPeter Brune 
1617*baf369e7SPeter Brune    Input Arguments:
1618*baf369e7SPeter Brune +  dm - the DM
1619*baf369e7SPeter Brune .  beginhook - function to run at the beginning of DMGlobalToLocalBegin()
1620*baf369e7SPeter Brune .  endhook - function to run after DMGlobalToLocalEnd() has completed
1621*baf369e7SPeter Brune -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
1622*baf369e7SPeter Brune 
1623*baf369e7SPeter Brune    Calling sequence for beginhook:
1624*baf369e7SPeter Brune $    beginhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
1625*baf369e7SPeter Brune 
1626*baf369e7SPeter Brune +  dm - global DM
1627*baf369e7SPeter Brune .  g - global vector
1628*baf369e7SPeter Brune .  mode - mode
1629*baf369e7SPeter Brune .  l - local vector
1630*baf369e7SPeter Brune -  ctx - optional user-defined function context
1631*baf369e7SPeter Brune 
1632*baf369e7SPeter Brune 
1633*baf369e7SPeter Brune    Calling sequence for endhook:
1634*baf369e7SPeter Brune $    beginhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
1635*baf369e7SPeter Brune 
1636*baf369e7SPeter Brune +  global - global DM
1637*baf369e7SPeter Brune -  ctx - optional user-defined function context
1638*baf369e7SPeter Brune 
1639*baf369e7SPeter Brune    Level: advanced
1640*baf369e7SPeter Brune 
1641*baf369e7SPeter Brune    Notes:
1642*baf369e7SPeter Brune    This function is only needed if auxiliary data needs to be set up on coarse grids.
1643*baf369e7SPeter Brune 
1644*baf369e7SPeter Brune    If this function is called multiple times, the hooks will be run in the order they are added.
1645*baf369e7SPeter Brune 
1646*baf369e7SPeter Brune    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
1647*baf369e7SPeter Brune    extract the finest level information from its context (instead of from the SNES).
1648*baf369e7SPeter Brune 
1649*baf369e7SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1650*baf369e7SPeter Brune @*/
1651*baf369e7SPeter Brune PetscErrorCode DMGlobalToLocalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx)
1652*baf369e7SPeter Brune {
1653*baf369e7SPeter Brune   PetscErrorCode ierr;
1654*baf369e7SPeter Brune   DMGlobalToLocalHookLink link,*p;
1655*baf369e7SPeter Brune 
1656*baf369e7SPeter Brune   PetscFunctionBegin;
1657*baf369e7SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1658*baf369e7SPeter Brune   for (p=&dm->gtolhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1659*baf369e7SPeter Brune   ierr = PetscMalloc(sizeof(struct _DMGlobalToLocalHookLink),&link);CHKERRQ(ierr);
1660*baf369e7SPeter Brune   link->beginhook = beginhook;
1661*baf369e7SPeter Brune   link->endhook = endhook;
1662*baf369e7SPeter Brune   link->ctx = ctx;
1663*baf369e7SPeter Brune   link->next = PETSC_NULL;
1664*baf369e7SPeter Brune   *p = link;
1665*baf369e7SPeter Brune   PetscFunctionReturn(0);
1666*baf369e7SPeter Brune }
1667*baf369e7SPeter Brune 
1668*baf369e7SPeter Brune #undef __FUNCT__
166947c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin"
167047c6ae99SBarry Smith /*@
167147c6ae99SBarry Smith     DMGlobalToLocalBegin - Begins updating local vectors from global vector
167247c6ae99SBarry Smith 
167347c6ae99SBarry Smith     Neighbor-wise Collective on DM
167447c6ae99SBarry Smith 
167547c6ae99SBarry Smith     Input Parameters:
167647c6ae99SBarry Smith +   dm - the DM object
167747c6ae99SBarry Smith .   g - the global vector
167847c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
167947c6ae99SBarry Smith -   l - the local vector
168047c6ae99SBarry Smith 
168147c6ae99SBarry Smith 
168247c6ae99SBarry Smith     Level: beginner
168347c6ae99SBarry Smith 
1684e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
168547c6ae99SBarry Smith 
168647c6ae99SBarry Smith @*/
16877087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
168847c6ae99SBarry Smith {
16897128ae9fSMatthew G Knepley   PetscSF        sf;
169047c6ae99SBarry Smith   PetscErrorCode ierr;
1691*baf369e7SPeter Brune   DMGlobalToLocalHookLink link;
169247c6ae99SBarry Smith 
169347c6ae99SBarry Smith   PetscFunctionBegin;
1694171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1695*baf369e7SPeter Brune   for (link=dm->gtolhook; link; link=link->next) {
1696*baf369e7SPeter Brune     if (link->beginhook) {ierr = (*link->beginhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);}
1697*baf369e7SPeter Brune   }
16987128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
16997128ae9fSMatthew G Knepley   if (sf) {
17007128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
17017128ae9fSMatthew G Knepley 
17027128ae9fSMatthew G Knepley     if (mode == ADD_VALUES) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
17037128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
17047128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
17057128ae9fSMatthew G Knepley     ierr = PetscSFBcastBegin(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
17067128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
17077128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
17087128ae9fSMatthew G Knepley   } else {
1709843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
17107128ae9fSMatthew G Knepley   }
171147c6ae99SBarry Smith   PetscFunctionReturn(0);
171247c6ae99SBarry Smith }
171347c6ae99SBarry Smith 
171447c6ae99SBarry Smith #undef __FUNCT__
171547c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd"
171647c6ae99SBarry Smith /*@
171747c6ae99SBarry Smith     DMGlobalToLocalEnd - Ends updating local vectors from global vector
171847c6ae99SBarry Smith 
171947c6ae99SBarry Smith     Neighbor-wise Collective on DM
172047c6ae99SBarry Smith 
172147c6ae99SBarry Smith     Input Parameters:
172247c6ae99SBarry Smith +   dm - the DM object
172347c6ae99SBarry Smith .   g - the global vector
172447c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
172547c6ae99SBarry Smith -   l - the local vector
172647c6ae99SBarry Smith 
172747c6ae99SBarry Smith 
172847c6ae99SBarry Smith     Level: beginner
172947c6ae99SBarry Smith 
1730e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
173147c6ae99SBarry Smith 
173247c6ae99SBarry Smith @*/
17337087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
173447c6ae99SBarry Smith {
17357128ae9fSMatthew G Knepley   PetscSF        sf;
173647c6ae99SBarry Smith   PetscErrorCode ierr;
173761a3c1faSSatish Balay   PetscScalar    *lArray, *gArray;
1738*baf369e7SPeter Brune   DMGlobalToLocalHookLink link;
173947c6ae99SBarry Smith 
174047c6ae99SBarry Smith   PetscFunctionBegin;
1741171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
17427128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
17437128ae9fSMatthew G Knepley   if (sf) {
17447128ae9fSMatthew G Knepley   if (mode == ADD_VALUES) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
17457128ae9fSMatthew G Knepley 
17467128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
17477128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
17487128ae9fSMatthew G Knepley     ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
17497128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
17507128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
17517128ae9fSMatthew G Knepley   } else {
1752843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
17537128ae9fSMatthew G Knepley   }
1754*baf369e7SPeter Brune   for (link=dm->gtolhook; link; link=link->next) {
1755*baf369e7SPeter Brune     if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);}
1756*baf369e7SPeter Brune   }
175747c6ae99SBarry Smith   PetscFunctionReturn(0);
175847c6ae99SBarry Smith }
175947c6ae99SBarry Smith 
176047c6ae99SBarry Smith #undef __FUNCT__
17619a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalBegin"
176247c6ae99SBarry Smith /*@
17639a42bb27SBarry Smith     DMLocalToGlobalBegin - updates global vectors from local vectors
17649a42bb27SBarry Smith 
17659a42bb27SBarry Smith     Neighbor-wise Collective on DM
17669a42bb27SBarry Smith 
17679a42bb27SBarry Smith     Input Parameters:
17689a42bb27SBarry Smith +   dm - the DM object
1769f6813fd5SJed Brown .   l - the local vector
17709a42bb27SBarry 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
17719a42bb27SBarry Smith            base point.
1772f6813fd5SJed Brown - - the global vector
17739a42bb27SBarry Smith 
17749a42bb27SBarry 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
17759a42bb27SBarry 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
17769a42bb27SBarry Smith            global array to the final global array with VecAXPY().
17779a42bb27SBarry Smith 
17789a42bb27SBarry Smith     Level: beginner
17799a42bb27SBarry Smith 
1780e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
17819a42bb27SBarry Smith 
17829a42bb27SBarry Smith @*/
17837087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g)
17849a42bb27SBarry Smith {
17857128ae9fSMatthew G Knepley   PetscSF        sf;
17869a42bb27SBarry Smith   PetscErrorCode ierr;
17879a42bb27SBarry Smith 
17889a42bb27SBarry Smith   PetscFunctionBegin;
1789171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
17907128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
17917128ae9fSMatthew G Knepley   if (sf) {
17927128ae9fSMatthew G Knepley     MPI_Op       op;
17937128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
17947128ae9fSMatthew G Knepley 
17957128ae9fSMatthew G Knepley     switch(mode) {
17967128ae9fSMatthew G Knepley     case INSERT_VALUES:
17977128ae9fSMatthew G Knepley     case INSERT_ALL_VALUES:
17987128ae9fSMatthew G Knepley #if defined(PETSC_HAVE_MPI_REPLACE)
17997128ae9fSMatthew G Knepley       op = MPI_REPLACE; break;
18007128ae9fSMatthew G Knepley #else
18017128ae9fSMatthew G Knepley       SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No support for INSERT_VALUES without an MPI-2 implementation");
18027128ae9fSMatthew G Knepley #endif
18037128ae9fSMatthew G Knepley     case ADD_VALUES:
18047128ae9fSMatthew G Knepley     case ADD_ALL_VALUES:
18057128ae9fSMatthew G Knepley       op = MPI_SUM; break;
18067128ae9fSMatthew G Knepley   default:
18077128ae9fSMatthew G Knepley     SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
18087128ae9fSMatthew G Knepley     }
18097128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
18107128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
18117128ae9fSMatthew G Knepley     ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr);
18127128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
18137128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
18147128ae9fSMatthew G Knepley   } else {
1815843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
18167128ae9fSMatthew G Knepley   }
18179a42bb27SBarry Smith   PetscFunctionReturn(0);
18189a42bb27SBarry Smith }
18199a42bb27SBarry Smith 
18209a42bb27SBarry Smith #undef __FUNCT__
18219a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalEnd"
18229a42bb27SBarry Smith /*@
18239a42bb27SBarry Smith     DMLocalToGlobalEnd - updates global vectors from local vectors
182447c6ae99SBarry Smith 
182547c6ae99SBarry Smith     Neighbor-wise Collective on DM
182647c6ae99SBarry Smith 
182747c6ae99SBarry Smith     Input Parameters:
182847c6ae99SBarry Smith +   dm - the DM object
1829f6813fd5SJed Brown .   l - the local vector
183047c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
1831f6813fd5SJed Brown -   g - the global vector
183247c6ae99SBarry Smith 
183347c6ae99SBarry Smith 
183447c6ae99SBarry Smith     Level: beginner
183547c6ae99SBarry Smith 
1836e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd()
183747c6ae99SBarry Smith 
183847c6ae99SBarry Smith @*/
18397087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g)
184047c6ae99SBarry Smith {
18417128ae9fSMatthew G Knepley   PetscSF        sf;
184247c6ae99SBarry Smith   PetscErrorCode ierr;
184347c6ae99SBarry Smith 
184447c6ae99SBarry Smith   PetscFunctionBegin;
1845171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
18467128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
18477128ae9fSMatthew G Knepley   if (sf) {
18487128ae9fSMatthew G Knepley     MPI_Op       op;
18497128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
18507128ae9fSMatthew G Knepley 
18517128ae9fSMatthew G Knepley     switch(mode) {
18527128ae9fSMatthew G Knepley     case INSERT_VALUES:
18537128ae9fSMatthew G Knepley     case INSERT_ALL_VALUES:
18547128ae9fSMatthew G Knepley #if defined(PETSC_HAVE_MPI_REPLACE)
18557128ae9fSMatthew G Knepley       op = MPI_REPLACE; break;
18567128ae9fSMatthew G Knepley #else
18577128ae9fSMatthew G Knepley       SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No support for INSERT_VALUES without an MPI-2 implementation");
18587128ae9fSMatthew G Knepley #endif
18597128ae9fSMatthew G Knepley     case ADD_VALUES:
18607128ae9fSMatthew G Knepley     case ADD_ALL_VALUES:
18617128ae9fSMatthew G Knepley       op = MPI_SUM; break;
18627128ae9fSMatthew G Knepley     default:
18637128ae9fSMatthew G Knepley       SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
18647128ae9fSMatthew G Knepley     }
18657128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
18667128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
18677128ae9fSMatthew G Knepley     ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr);
18687128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
18697128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
18707128ae9fSMatthew G Knepley   } else {
1871843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
18727128ae9fSMatthew G Knepley   }
187347c6ae99SBarry Smith   PetscFunctionReturn(0);
187447c6ae99SBarry Smith }
187547c6ae99SBarry Smith 
187647c6ae99SBarry Smith #undef __FUNCT__
187747c6ae99SBarry Smith #define __FUNCT__ "DMCoarsen"
187847c6ae99SBarry Smith /*@
187947c6ae99SBarry Smith     DMCoarsen - Coarsens a DM object
188047c6ae99SBarry Smith 
188147c6ae99SBarry Smith     Collective on DM
188247c6ae99SBarry Smith 
188347c6ae99SBarry Smith     Input Parameter:
188447c6ae99SBarry Smith +   dm - the DM object
188591d95f02SJed Brown -   comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
188647c6ae99SBarry Smith 
188747c6ae99SBarry Smith     Output Parameter:
188847c6ae99SBarry Smith .   dmc - the coarsened DM
188947c6ae99SBarry Smith 
189047c6ae99SBarry Smith     Level: developer
189147c6ae99SBarry Smith 
1892e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
189347c6ae99SBarry Smith 
189447c6ae99SBarry Smith @*/
18957087cfbeSBarry Smith PetscErrorCode  DMCoarsen(DM dm, MPI_Comm comm, DM *dmc)
189647c6ae99SBarry Smith {
189747c6ae99SBarry Smith   PetscErrorCode ierr;
1898b17ce1afSJed Brown   DMCoarsenHookLink link;
189947c6ae99SBarry Smith 
190047c6ae99SBarry Smith   PetscFunctionBegin;
1901171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
190247c6ae99SBarry Smith   ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr);
190343842a1eSJed Brown   (*dmc)->ops->creatematrix = dm->ops->creatematrix;
19048cd211a4SJed Brown   ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr);
1905644e2e5bSBarry Smith   (*dmc)->ctx       = dm->ctx;
19060598a293SJed Brown   (*dmc)->levelup   = dm->levelup;
1907656b349aSBarry Smith   (*dmc)->leveldown = dm->leveldown + 1;
1908e4b4b23bSJed Brown   ierr = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr);
1909b17ce1afSJed Brown   for (link=dm->coarsenhook; link; link=link->next) {
1910b17ce1afSJed Brown     if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);}
1911b17ce1afSJed Brown   }
1912b17ce1afSJed Brown   PetscFunctionReturn(0);
1913b17ce1afSJed Brown }
1914b17ce1afSJed Brown 
1915b17ce1afSJed Brown #undef __FUNCT__
1916b17ce1afSJed Brown #define __FUNCT__ "DMCoarsenHookAdd"
1917b17ce1afSJed Brown /*@
1918b17ce1afSJed Brown    DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid
1919b17ce1afSJed Brown 
1920b17ce1afSJed Brown    Logically Collective
1921b17ce1afSJed Brown 
1922b17ce1afSJed Brown    Input Arguments:
1923b17ce1afSJed Brown +  fine - nonlinear solver context on which to run a hook when restricting to a coarser level
1924b17ce1afSJed Brown .  coarsenhook - function to run when setting up a coarser level
1925b17ce1afSJed Brown .  restricthook - function to run to update data on coarser levels (once per SNESSolve())
1926b17ce1afSJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
1927b17ce1afSJed Brown 
1928b17ce1afSJed Brown    Calling sequence of coarsenhook:
1929b17ce1afSJed Brown $    coarsenhook(DM fine,DM coarse,void *ctx);
1930b17ce1afSJed Brown 
1931b17ce1afSJed Brown +  fine - fine level DM
1932b17ce1afSJed Brown .  coarse - coarse level DM to restrict problem to
1933b17ce1afSJed Brown -  ctx - optional user-defined function context
1934b17ce1afSJed Brown 
1935b17ce1afSJed Brown    Calling sequence for restricthook:
1936c833c3b5SJed Brown $    restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx)
1937b17ce1afSJed Brown 
1938b17ce1afSJed Brown +  fine - fine level DM
1939b17ce1afSJed Brown .  mrestrict - matrix restricting a fine-level solution to the coarse grid
1940c833c3b5SJed Brown .  rscale - scaling vector for restriction
1941c833c3b5SJed Brown .  inject - matrix restricting by injection
1942b17ce1afSJed Brown .  coarse - coarse level DM to update
1943b17ce1afSJed Brown -  ctx - optional user-defined function context
1944b17ce1afSJed Brown 
1945b17ce1afSJed Brown    Level: advanced
1946b17ce1afSJed Brown 
1947b17ce1afSJed Brown    Notes:
1948b17ce1afSJed Brown    This function is only needed if auxiliary data needs to be set up on coarse grids.
1949b17ce1afSJed Brown 
1950b17ce1afSJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1951b17ce1afSJed Brown 
1952b17ce1afSJed Brown    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
1953b17ce1afSJed Brown    extract the finest level information from its context (instead of from the SNES).
1954b17ce1afSJed Brown 
1955c833c3b5SJed Brown .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1956b17ce1afSJed Brown @*/
1957b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx)
1958b17ce1afSJed Brown {
1959b17ce1afSJed Brown   PetscErrorCode ierr;
1960b17ce1afSJed Brown   DMCoarsenHookLink link,*p;
1961b17ce1afSJed Brown 
1962b17ce1afSJed Brown   PetscFunctionBegin;
1963b17ce1afSJed Brown   PetscValidHeaderSpecific(fine,DM_CLASSID,1);
19646bfea28cSJed Brown   for (p=&fine->coarsenhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1965b17ce1afSJed Brown   ierr = PetscMalloc(sizeof(struct _DMCoarsenHookLink),&link);CHKERRQ(ierr);
1966b17ce1afSJed Brown   link->coarsenhook = coarsenhook;
1967b17ce1afSJed Brown   link->restricthook = restricthook;
1968b17ce1afSJed Brown   link->ctx = ctx;
19696cab3a1bSJed Brown   link->next = PETSC_NULL;
1970b17ce1afSJed Brown   *p = link;
1971b17ce1afSJed Brown   PetscFunctionReturn(0);
1972b17ce1afSJed Brown }
1973b17ce1afSJed Brown 
1974b17ce1afSJed Brown #undef __FUNCT__
1975b17ce1afSJed Brown #define __FUNCT__ "DMRestrict"
1976b17ce1afSJed Brown /*@
1977b17ce1afSJed Brown    DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd()
1978b17ce1afSJed Brown 
1979b17ce1afSJed Brown    Collective if any hooks are
1980b17ce1afSJed Brown 
1981b17ce1afSJed Brown    Input Arguments:
1982b17ce1afSJed Brown +  fine - finer DM to use as a base
1983b17ce1afSJed Brown .  restrct - restriction matrix, apply using MatRestrict()
1984b17ce1afSJed Brown .  inject - injection matrix, also use MatRestrict()
1985b17ce1afSJed Brown -  coarse - coarer DM to update
1986b17ce1afSJed Brown 
1987b17ce1afSJed Brown    Level: developer
1988b17ce1afSJed Brown 
1989b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict()
1990b17ce1afSJed Brown @*/
1991b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse)
1992b17ce1afSJed Brown {
1993b17ce1afSJed Brown   PetscErrorCode ierr;
1994b17ce1afSJed Brown   DMCoarsenHookLink link;
1995b17ce1afSJed Brown 
1996b17ce1afSJed Brown   PetscFunctionBegin;
1997b17ce1afSJed Brown   for (link=fine->coarsenhook; link; link=link->next) {
1998b17ce1afSJed Brown     if (link->restricthook) {ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr);}
1999b17ce1afSJed Brown   }
200047c6ae99SBarry Smith   PetscFunctionReturn(0);
200147c6ae99SBarry Smith }
200247c6ae99SBarry Smith 
200347c6ae99SBarry Smith #undef __FUNCT__
2004be081cd6SPeter Brune #define __FUNCT__ "DMSubDomainHookAdd"
20055dbd56e3SPeter Brune /*@
2006be081cd6SPeter Brune    DMSubDomainHookAdd - adds a callback to be run when restricting a problem to the coarse grid
20075dbd56e3SPeter Brune 
20085dbd56e3SPeter Brune    Logically Collective
20095dbd56e3SPeter Brune 
20105dbd56e3SPeter Brune    Input Arguments:
20115dbd56e3SPeter Brune +  global - global DM
2012be081cd6SPeter Brune .
20135dbd56e3SPeter Brune .  restricthook - function to run to update data on block solve (at the beginning of the block solve)
20145dbd56e3SPeter Brune -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
20155dbd56e3SPeter Brune 
20165dbd56e3SPeter Brune    Calling sequence for restricthook:
20175dbd56e3SPeter Brune $    restricthook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
20185dbd56e3SPeter Brune 
20195dbd56e3SPeter Brune +  global - global DM
20205dbd56e3SPeter Brune .  out    - scatter to the outer (with ghost and overlap points) block vector
20215dbd56e3SPeter Brune .  in     - scatter to block vector values only owned locally
20225dbd56e3SPeter Brune .  block  - block DM (may just be a shell if the global DM is passed in correctly)
20235dbd56e3SPeter Brune -  ctx - optional user-defined function context
20245dbd56e3SPeter Brune 
20255dbd56e3SPeter Brune    Level: advanced
20265dbd56e3SPeter Brune 
20275dbd56e3SPeter Brune    Notes:
20285dbd56e3SPeter Brune    This function is only needed if auxiliary data needs to be set up on coarse grids.
20295dbd56e3SPeter Brune 
20305dbd56e3SPeter Brune    If this function is called multiple times, the hooks will be run in the order they are added.
20315dbd56e3SPeter Brune 
20325dbd56e3SPeter Brune    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
20335dbd56e3SPeter Brune    extract the finest level information from its context (instead of from the SNES).
20345dbd56e3SPeter Brune 
20355dbd56e3SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
20365dbd56e3SPeter Brune @*/
2037be081cd6SPeter Brune PetscErrorCode DMSubDomainHookAdd(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx)
20385dbd56e3SPeter Brune {
20395dbd56e3SPeter Brune   PetscErrorCode ierr;
2040be081cd6SPeter Brune   DMSubDomainHookLink link,*p;
20415dbd56e3SPeter Brune 
20425dbd56e3SPeter Brune   PetscFunctionBegin;
20435dbd56e3SPeter Brune   PetscValidHeaderSpecific(global,DM_CLASSID,1);
2044be081cd6SPeter Brune   for (p=&global->subdomainhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
2045be081cd6SPeter Brune   ierr = PetscMalloc(sizeof(struct _DMSubDomainHookLink),&link);CHKERRQ(ierr);
20465dbd56e3SPeter Brune   link->restricthook = restricthook;
2047be081cd6SPeter Brune   link->ddhook = ddhook;
20485dbd56e3SPeter Brune   link->ctx = ctx;
20495dbd56e3SPeter Brune   link->next = PETSC_NULL;
20505dbd56e3SPeter Brune   *p = link;
20515dbd56e3SPeter Brune   PetscFunctionReturn(0);
20525dbd56e3SPeter Brune }
20535dbd56e3SPeter Brune 
20545dbd56e3SPeter Brune #undef __FUNCT__
2055be081cd6SPeter Brune #define __FUNCT__ "DMSubDomainRestrict"
20565dbd56e3SPeter Brune /*@
2057be081cd6SPeter Brune    DMSubDomainRestrict - restricts user-defined problem data to a block DM by running hooks registered by DMSubDomainHookAdd()
20585dbd56e3SPeter Brune 
20595dbd56e3SPeter Brune    Collective if any hooks are
20605dbd56e3SPeter Brune 
20615dbd56e3SPeter Brune    Input Arguments:
20625dbd56e3SPeter Brune +  fine - finer DM to use as a base
2063be081cd6SPeter Brune .  oscatter - scatter from domain global vector filling subdomain global vector with overlap
2064be081cd6SPeter Brune .  gscatter - scatter from domain global vector filling subdomain local vector with ghosts
20655dbd56e3SPeter Brune -  coarse - coarer DM to update
20665dbd56e3SPeter Brune 
20675dbd56e3SPeter Brune    Level: developer
20685dbd56e3SPeter Brune 
20695dbd56e3SPeter Brune .seealso: DMCoarsenHookAdd(), MatRestrict()
20705dbd56e3SPeter Brune @*/
2071be081cd6SPeter Brune PetscErrorCode DMSubDomainRestrict(DM global,VecScatter oscatter,VecScatter gscatter,DM subdm)
20725dbd56e3SPeter Brune {
20735dbd56e3SPeter Brune   PetscErrorCode ierr;
2074be081cd6SPeter Brune   DMSubDomainHookLink link;
20755dbd56e3SPeter Brune 
20765dbd56e3SPeter Brune   PetscFunctionBegin;
2077be081cd6SPeter Brune   for (link=global->subdomainhook; link; link=link->next) {
2078be081cd6SPeter Brune     if (link->restricthook) {ierr = (*link->restricthook)(global,oscatter,gscatter,subdm,link->ctx);CHKERRQ(ierr);}
20795dbd56e3SPeter Brune   }
20805dbd56e3SPeter Brune   PetscFunctionReturn(0);
20815dbd56e3SPeter Brune }
20825dbd56e3SPeter Brune 
20835dbd56e3SPeter Brune #undef __FUNCT__
20845fe1f584SPeter Brune #define __FUNCT__ "DMGetCoarsenLevel"
20855fe1f584SPeter Brune /*@
20866a7d9d85SPeter Brune     DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM.
20875fe1f584SPeter Brune 
20885fe1f584SPeter Brune     Not Collective
20895fe1f584SPeter Brune 
20905fe1f584SPeter Brune     Input Parameter:
20915fe1f584SPeter Brune .   dm - the DM object
20925fe1f584SPeter Brune 
20935fe1f584SPeter Brune     Output Parameter:
20946a7d9d85SPeter Brune .   level - number of coarsenings
20955fe1f584SPeter Brune 
20965fe1f584SPeter Brune     Level: developer
20975fe1f584SPeter Brune 
20986a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
20995fe1f584SPeter Brune 
21005fe1f584SPeter Brune @*/
21015fe1f584SPeter Brune PetscErrorCode  DMGetCoarsenLevel(DM dm,PetscInt *level)
21025fe1f584SPeter Brune {
21035fe1f584SPeter Brune   PetscFunctionBegin;
21045fe1f584SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
21055fe1f584SPeter Brune   *level = dm->leveldown;
21065fe1f584SPeter Brune   PetscFunctionReturn(0);
21075fe1f584SPeter Brune }
21085fe1f584SPeter Brune 
21095fe1f584SPeter Brune 
21105fe1f584SPeter Brune 
21115fe1f584SPeter Brune #undef __FUNCT__
211247c6ae99SBarry Smith #define __FUNCT__ "DMRefineHierarchy"
211347c6ae99SBarry Smith /*@C
211447c6ae99SBarry Smith     DMRefineHierarchy - Refines a DM object, all levels at once
211547c6ae99SBarry Smith 
211647c6ae99SBarry Smith     Collective on DM
211747c6ae99SBarry Smith 
211847c6ae99SBarry Smith     Input Parameter:
211947c6ae99SBarry Smith +   dm - the DM object
212047c6ae99SBarry Smith -   nlevels - the number of levels of refinement
212147c6ae99SBarry Smith 
212247c6ae99SBarry Smith     Output Parameter:
212347c6ae99SBarry Smith .   dmf - the refined DM hierarchy
212447c6ae99SBarry Smith 
212547c6ae99SBarry Smith     Level: developer
212647c6ae99SBarry Smith 
2127e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
212847c6ae99SBarry Smith 
212947c6ae99SBarry Smith @*/
21307087cfbeSBarry Smith PetscErrorCode  DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[])
213147c6ae99SBarry Smith {
213247c6ae99SBarry Smith   PetscErrorCode ierr;
213347c6ae99SBarry Smith 
213447c6ae99SBarry Smith   PetscFunctionBegin;
2135171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
213647c6ae99SBarry Smith   if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
213747c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
213847c6ae99SBarry Smith   if (dm->ops->refinehierarchy) {
213947c6ae99SBarry Smith     ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr);
214047c6ae99SBarry Smith   } else if (dm->ops->refine) {
214147c6ae99SBarry Smith     PetscInt i;
214247c6ae99SBarry Smith 
214347c6ae99SBarry Smith     ierr = DMRefine(dm,((PetscObject)dm)->comm,&dmf[0]);CHKERRQ(ierr);
214447c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
214547c6ae99SBarry Smith       ierr = DMRefine(dmf[i-1],((PetscObject)dm)->comm,&dmf[i]);CHKERRQ(ierr);
214647c6ae99SBarry Smith     }
214747c6ae99SBarry Smith   } else {
214847c6ae99SBarry Smith     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No RefineHierarchy for this DM yet");
214947c6ae99SBarry Smith   }
215047c6ae99SBarry Smith   PetscFunctionReturn(0);
215147c6ae99SBarry Smith }
215247c6ae99SBarry Smith 
215347c6ae99SBarry Smith #undef __FUNCT__
215447c6ae99SBarry Smith #define __FUNCT__ "DMCoarsenHierarchy"
215547c6ae99SBarry Smith /*@C
215647c6ae99SBarry Smith     DMCoarsenHierarchy - Coarsens a DM object, all levels at once
215747c6ae99SBarry Smith 
215847c6ae99SBarry Smith     Collective on DM
215947c6ae99SBarry Smith 
216047c6ae99SBarry Smith     Input Parameter:
216147c6ae99SBarry Smith +   dm - the DM object
216247c6ae99SBarry Smith -   nlevels - the number of levels of coarsening
216347c6ae99SBarry Smith 
216447c6ae99SBarry Smith     Output Parameter:
216547c6ae99SBarry Smith .   dmc - the coarsened DM hierarchy
216647c6ae99SBarry Smith 
216747c6ae99SBarry Smith     Level: developer
216847c6ae99SBarry Smith 
2169e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
217047c6ae99SBarry Smith 
217147c6ae99SBarry Smith @*/
21727087cfbeSBarry Smith PetscErrorCode  DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[])
217347c6ae99SBarry Smith {
217447c6ae99SBarry Smith   PetscErrorCode ierr;
217547c6ae99SBarry Smith 
217647c6ae99SBarry Smith   PetscFunctionBegin;
2177171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
217847c6ae99SBarry Smith   if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
217947c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
218047c6ae99SBarry Smith   PetscValidPointer(dmc,3);
218147c6ae99SBarry Smith   if (dm->ops->coarsenhierarchy) {
218247c6ae99SBarry Smith     ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr);
218347c6ae99SBarry Smith   } else if (dm->ops->coarsen) {
218447c6ae99SBarry Smith     PetscInt i;
218547c6ae99SBarry Smith 
218647c6ae99SBarry Smith     ierr = DMCoarsen(dm,((PetscObject)dm)->comm,&dmc[0]);CHKERRQ(ierr);
218747c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
218847c6ae99SBarry Smith       ierr = DMCoarsen(dmc[i-1],((PetscObject)dm)->comm,&dmc[i]);CHKERRQ(ierr);
218947c6ae99SBarry Smith     }
219047c6ae99SBarry Smith   } else {
219147c6ae99SBarry Smith     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet");
219247c6ae99SBarry Smith   }
219347c6ae99SBarry Smith   PetscFunctionReturn(0);
219447c6ae99SBarry Smith }
219547c6ae99SBarry Smith 
219647c6ae99SBarry Smith #undef __FUNCT__
2197e727c939SJed Brown #define __FUNCT__ "DMCreateAggregates"
219847c6ae99SBarry Smith /*@
2199e727c939SJed Brown    DMCreateAggregates - Gets the aggregates that map between
220047c6ae99SBarry Smith    grids associated with two DMs.
220147c6ae99SBarry Smith 
220247c6ae99SBarry Smith    Collective on DM
220347c6ae99SBarry Smith 
220447c6ae99SBarry Smith    Input Parameters:
220547c6ae99SBarry Smith +  dmc - the coarse grid DM
220647c6ae99SBarry Smith -  dmf - the fine grid DM
220747c6ae99SBarry Smith 
220847c6ae99SBarry Smith    Output Parameters:
220947c6ae99SBarry Smith .  rest - the restriction matrix (transpose of the projection matrix)
221047c6ae99SBarry Smith 
221147c6ae99SBarry Smith    Level: intermediate
221247c6ae99SBarry Smith 
221347c6ae99SBarry Smith .keywords: interpolation, restriction, multigrid
221447c6ae99SBarry Smith 
2215e727c939SJed Brown .seealso: DMRefine(), DMCreateInjection(), DMCreateInterpolation()
221647c6ae99SBarry Smith @*/
2217e727c939SJed Brown PetscErrorCode  DMCreateAggregates(DM dmc, DM dmf, Mat *rest)
221847c6ae99SBarry Smith {
221947c6ae99SBarry Smith   PetscErrorCode ierr;
222047c6ae99SBarry Smith 
222147c6ae99SBarry Smith   PetscFunctionBegin;
2222171400e9SBarry Smith   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
2223171400e9SBarry Smith   PetscValidHeaderSpecific(dmf,DM_CLASSID,2);
222447c6ae99SBarry Smith   ierr = (*dmc->ops->getaggregates)(dmc, dmf, rest);CHKERRQ(ierr);
222547c6ae99SBarry Smith   PetscFunctionReturn(0);
222647c6ae99SBarry Smith }
222747c6ae99SBarry Smith 
222847c6ae99SBarry Smith #undef __FUNCT__
22291a266240SBarry Smith #define __FUNCT__ "DMSetApplicationContextDestroy"
22301a266240SBarry Smith /*@C
22311a266240SBarry Smith     DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed
22321a266240SBarry Smith 
22331a266240SBarry Smith     Not Collective
22341a266240SBarry Smith 
22351a266240SBarry Smith     Input Parameters:
22361a266240SBarry Smith +   dm - the DM object
22371a266240SBarry Smith -   destroy - the destroy function
22381a266240SBarry Smith 
22391a266240SBarry Smith     Level: intermediate
22401a266240SBarry Smith 
2241e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
22421a266240SBarry Smith 
2243f07f9ceaSJed Brown @*/
22441a266240SBarry Smith PetscErrorCode  DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**))
22451a266240SBarry Smith {
22461a266240SBarry Smith   PetscFunctionBegin;
2247171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
22481a266240SBarry Smith   dm->ctxdestroy = destroy;
22491a266240SBarry Smith   PetscFunctionReturn(0);
22501a266240SBarry Smith }
22511a266240SBarry Smith 
22521a266240SBarry Smith #undef __FUNCT__
22531b2093e4SBarry Smith #define __FUNCT__ "DMSetApplicationContext"
2254b07ff414SBarry Smith /*@
22551b2093e4SBarry Smith     DMSetApplicationContext - Set a user context into a DM object
225647c6ae99SBarry Smith 
225747c6ae99SBarry Smith     Not Collective
225847c6ae99SBarry Smith 
225947c6ae99SBarry Smith     Input Parameters:
226047c6ae99SBarry Smith +   dm - the DM object
226147c6ae99SBarry Smith -   ctx - the user context
226247c6ae99SBarry Smith 
226347c6ae99SBarry Smith     Level: intermediate
226447c6ae99SBarry Smith 
2265e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
226647c6ae99SBarry Smith 
226747c6ae99SBarry Smith @*/
22681b2093e4SBarry Smith PetscErrorCode  DMSetApplicationContext(DM dm,void *ctx)
226947c6ae99SBarry Smith {
227047c6ae99SBarry Smith   PetscFunctionBegin;
2271171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
227247c6ae99SBarry Smith   dm->ctx = ctx;
227347c6ae99SBarry Smith   PetscFunctionReturn(0);
227447c6ae99SBarry Smith }
227547c6ae99SBarry Smith 
227647c6ae99SBarry Smith #undef __FUNCT__
22771b2093e4SBarry Smith #define __FUNCT__ "DMGetApplicationContext"
227847c6ae99SBarry Smith /*@
22791b2093e4SBarry Smith     DMGetApplicationContext - Gets a user context from a DM object
228047c6ae99SBarry Smith 
228147c6ae99SBarry Smith     Not Collective
228247c6ae99SBarry Smith 
228347c6ae99SBarry Smith     Input Parameter:
228447c6ae99SBarry Smith .   dm - the DM object
228547c6ae99SBarry Smith 
228647c6ae99SBarry Smith     Output Parameter:
228747c6ae99SBarry Smith .   ctx - the user context
228847c6ae99SBarry Smith 
228947c6ae99SBarry Smith     Level: intermediate
229047c6ae99SBarry Smith 
2291e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
229247c6ae99SBarry Smith 
229347c6ae99SBarry Smith @*/
22941b2093e4SBarry Smith PetscErrorCode  DMGetApplicationContext(DM dm,void *ctx)
229547c6ae99SBarry Smith {
229647c6ae99SBarry Smith   PetscFunctionBegin;
2297171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
22981b2093e4SBarry Smith   *(void**)ctx = dm->ctx;
229947c6ae99SBarry Smith   PetscFunctionReturn(0);
230047c6ae99SBarry Smith }
230147c6ae99SBarry Smith 
230247c6ae99SBarry Smith #undef __FUNCT__
230308da532bSDmitry Karpeev #define __FUNCT__ "DMSetVariableBounds"
230408da532bSDmitry Karpeev /*@C
230508da532bSDmitry Karpeev     DMSetVariableBounds - sets a function to compute the the lower and upper bound vectors for SNESVI.
230608da532bSDmitry Karpeev 
230708da532bSDmitry Karpeev     Logically Collective on DM
230808da532bSDmitry Karpeev 
230908da532bSDmitry Karpeev     Input Parameter:
231008da532bSDmitry Karpeev +   dm - the DM object
231108da532bSDmitry Karpeev -   f - the function that computes variable bounds used by SNESVI (use PETSC_NULL to cancel a previous function that was set)
231208da532bSDmitry Karpeev 
231308da532bSDmitry Karpeev     Level: intermediate
231408da532bSDmitry Karpeev 
2315835c3ec7SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(),
231608da532bSDmitry Karpeev          DMSetJacobian()
231708da532bSDmitry Karpeev 
231808da532bSDmitry Karpeev @*/
231908da532bSDmitry Karpeev PetscErrorCode  DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
232008da532bSDmitry Karpeev {
232108da532bSDmitry Karpeev   PetscFunctionBegin;
232208da532bSDmitry Karpeev   dm->ops->computevariablebounds = f;
232308da532bSDmitry Karpeev   PetscFunctionReturn(0);
232408da532bSDmitry Karpeev }
232508da532bSDmitry Karpeev 
232608da532bSDmitry Karpeev #undef __FUNCT__
232708da532bSDmitry Karpeev #define __FUNCT__ "DMHasVariableBounds"
232808da532bSDmitry Karpeev /*@
232908da532bSDmitry Karpeev     DMHasVariableBounds - does the DM object have a variable bounds function?
233008da532bSDmitry Karpeev 
233108da532bSDmitry Karpeev     Not Collective
233208da532bSDmitry Karpeev 
233308da532bSDmitry Karpeev     Input Parameter:
233408da532bSDmitry Karpeev .   dm - the DM object to destroy
233508da532bSDmitry Karpeev 
233608da532bSDmitry Karpeev     Output Parameter:
233708da532bSDmitry Karpeev .   flg - PETSC_TRUE if the variable bounds function exists
233808da532bSDmitry Karpeev 
233908da532bSDmitry Karpeev     Level: developer
234008da532bSDmitry Karpeev 
234174e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
234208da532bSDmitry Karpeev 
234308da532bSDmitry Karpeev @*/
234408da532bSDmitry Karpeev PetscErrorCode  DMHasVariableBounds(DM dm,PetscBool  *flg)
234508da532bSDmitry Karpeev {
234608da532bSDmitry Karpeev   PetscFunctionBegin;
234708da532bSDmitry Karpeev   *flg =  (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE;
234808da532bSDmitry Karpeev   PetscFunctionReturn(0);
234908da532bSDmitry Karpeev }
235008da532bSDmitry Karpeev 
235108da532bSDmitry Karpeev #undef __FUNCT__
235208da532bSDmitry Karpeev #define __FUNCT__ "DMComputeVariableBounds"
235308da532bSDmitry Karpeev /*@C
235408da532bSDmitry Karpeev     DMComputeVariableBounds - compute variable bounds used by SNESVI.
235508da532bSDmitry Karpeev 
235608da532bSDmitry Karpeev     Logically Collective on DM
235708da532bSDmitry Karpeev 
235808da532bSDmitry Karpeev     Input Parameters:
235908da532bSDmitry Karpeev +   dm - the DM object to destroy
236008da532bSDmitry Karpeev -   x  - current solution at which the bounds are computed
236108da532bSDmitry Karpeev 
236208da532bSDmitry Karpeev     Output parameters:
236308da532bSDmitry Karpeev +   xl - lower bound
236408da532bSDmitry Karpeev -   xu - upper bound
236508da532bSDmitry Karpeev 
236608da532bSDmitry Karpeev     Level: intermediate
236708da532bSDmitry Karpeev 
236874e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
236908da532bSDmitry Karpeev 
237008da532bSDmitry Karpeev @*/
237108da532bSDmitry Karpeev PetscErrorCode  DMComputeVariableBounds(DM dm, Vec xl, Vec xu)
237208da532bSDmitry Karpeev {
237308da532bSDmitry Karpeev   PetscErrorCode ierr;
237408da532bSDmitry Karpeev   PetscFunctionBegin;
237508da532bSDmitry Karpeev   PetscValidHeaderSpecific(xl,VEC_CLASSID,2);
237608da532bSDmitry Karpeev   PetscValidHeaderSpecific(xu,VEC_CLASSID,2);
237708da532bSDmitry Karpeev   if (dm->ops->computevariablebounds) {
237808da532bSDmitry Karpeev     ierr = (*dm->ops->computevariablebounds)(dm, xl,xu); CHKERRQ(ierr);
237908da532bSDmitry Karpeev   }
2380a201590fSDmitry Karpeev   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "This DM is incapable of computing variable bounds.");
238108da532bSDmitry Karpeev   PetscFunctionReturn(0);
238208da532bSDmitry Karpeev }
238308da532bSDmitry Karpeev 
238408da532bSDmitry Karpeev #undef __FUNCT__
2385b0ae01b7SPeter Brune #define __FUNCT__ "DMHasColoring"
2386b0ae01b7SPeter Brune /*@
2387b0ae01b7SPeter Brune     DMHasColoring - does the DM object have a method of providing a coloring?
2388b0ae01b7SPeter Brune 
2389b0ae01b7SPeter Brune     Not Collective
2390b0ae01b7SPeter Brune 
2391b0ae01b7SPeter Brune     Input Parameter:
2392b0ae01b7SPeter Brune .   dm - the DM object
2393b0ae01b7SPeter Brune 
2394b0ae01b7SPeter Brune     Output Parameter:
2395b0ae01b7SPeter Brune .   flg - PETSC_TRUE if the DM has facilities for DMCreateColoring().
2396b0ae01b7SPeter Brune 
2397b0ae01b7SPeter Brune     Level: developer
2398b0ae01b7SPeter Brune 
2399b0ae01b7SPeter Brune .seealso DMHasFunction(), DMCreateColoring()
2400b0ae01b7SPeter Brune 
2401b0ae01b7SPeter Brune @*/
2402b0ae01b7SPeter Brune PetscErrorCode  DMHasColoring(DM dm,PetscBool  *flg)
2403b0ae01b7SPeter Brune {
2404b0ae01b7SPeter Brune   PetscFunctionBegin;
2405b0ae01b7SPeter Brune   *flg =  (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE;
2406b0ae01b7SPeter Brune   PetscFunctionReturn(0);
2407b0ae01b7SPeter Brune }
2408b0ae01b7SPeter Brune 
2409b0ae01b7SPeter Brune #undef  __FUNCT__
241008da532bSDmitry Karpeev #define __FUNCT__ "DMSetVec"
2411748fac09SDmitry Karpeev /*@C
241208da532bSDmitry Karpeev     DMSetVec - set the vector at which to compute residual, Jacobian and VI bounds, if the problem is nonlinear.
241308da532bSDmitry Karpeev 
241408da532bSDmitry Karpeev     Collective on DM
241508da532bSDmitry Karpeev 
241608da532bSDmitry Karpeev     Input Parameter:
241708da532bSDmitry Karpeev +   dm - the DM object
2418e88d7f4bSDmitry Karpeev -   x - location to compute residual and Jacobian, if PETSC_NULL is passed to those routines; will be PETSC_NULL for linear problems.
241908da532bSDmitry Karpeev 
242008da532bSDmitry Karpeev     Level: developer
242108da532bSDmitry Karpeev 
242274e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
242308da532bSDmitry Karpeev 
242408da532bSDmitry Karpeev @*/
242508da532bSDmitry Karpeev PetscErrorCode  DMSetVec(DM dm,Vec x)
242608da532bSDmitry Karpeev {
242708da532bSDmitry Karpeev   PetscErrorCode ierr;
242808da532bSDmitry Karpeev   PetscFunctionBegin;
242908da532bSDmitry Karpeev   if (x) {
243008da532bSDmitry Karpeev     if (!dm->x) {
243108da532bSDmitry Karpeev       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
243208da532bSDmitry Karpeev     }
243308da532bSDmitry Karpeev     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
243408da532bSDmitry Karpeev   }
243508da532bSDmitry Karpeev   else if (dm->x) {
243608da532bSDmitry Karpeev     ierr = VecDestroy(&dm->x);  CHKERRQ(ierr);
243708da532bSDmitry Karpeev   }
243808da532bSDmitry Karpeev   PetscFunctionReturn(0);
243908da532bSDmitry Karpeev }
244008da532bSDmitry Karpeev 
2441264ace61SBarry Smith PetscFList DMList                       = PETSC_NULL;
2442264ace61SBarry Smith PetscBool  DMRegisterAllCalled          = PETSC_FALSE;
2443264ace61SBarry Smith 
2444264ace61SBarry Smith #undef __FUNCT__
2445264ace61SBarry Smith #define __FUNCT__ "DMSetType"
2446264ace61SBarry Smith /*@C
2447264ace61SBarry Smith   DMSetType - Builds a DM, for a particular DM implementation.
2448264ace61SBarry Smith 
2449264ace61SBarry Smith   Collective on DM
2450264ace61SBarry Smith 
2451264ace61SBarry Smith   Input Parameters:
2452264ace61SBarry Smith + dm     - The DM object
2453264ace61SBarry Smith - method - The name of the DM type
2454264ace61SBarry Smith 
2455264ace61SBarry Smith   Options Database Key:
2456264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types
2457264ace61SBarry Smith 
2458264ace61SBarry Smith   Notes:
2459e1589f56SBarry Smith   See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D).
2460264ace61SBarry Smith 
2461264ace61SBarry Smith   Level: intermediate
2462264ace61SBarry Smith 
2463264ace61SBarry Smith .keywords: DM, set, type
2464264ace61SBarry Smith .seealso: DMGetType(), DMCreate()
2465264ace61SBarry Smith @*/
246619fd82e9SBarry Smith PetscErrorCode  DMSetType(DM dm, DMType method)
2467264ace61SBarry Smith {
2468264ace61SBarry Smith   PetscErrorCode (*r)(DM);
2469264ace61SBarry Smith   PetscBool      match;
2470264ace61SBarry Smith   PetscErrorCode ierr;
2471264ace61SBarry Smith 
2472264ace61SBarry Smith   PetscFunctionBegin;
2473264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2474251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr);
2475264ace61SBarry Smith   if (match) PetscFunctionReturn(0);
2476264ace61SBarry Smith 
2477264ace61SBarry Smith   if (!DMRegisterAllCalled) {ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
24784b91b6eaSBarry Smith   ierr = PetscFListFind(DMList, ((PetscObject)dm)->comm, method,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
247932c0f0efSBarry Smith   if (!r) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method);
2480264ace61SBarry Smith 
2481264ace61SBarry Smith   if (dm->ops->destroy) {
2482264ace61SBarry Smith     ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr);
2483b5c23020SJed Brown     dm->ops->destroy = PETSC_NULL;
2484264ace61SBarry Smith   }
2485264ace61SBarry Smith   ierr = (*r)(dm);CHKERRQ(ierr);
2486264ace61SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr);
2487264ace61SBarry Smith   PetscFunctionReturn(0);
2488264ace61SBarry Smith }
2489264ace61SBarry Smith 
2490264ace61SBarry Smith #undef __FUNCT__
2491264ace61SBarry Smith #define __FUNCT__ "DMGetType"
2492264ace61SBarry Smith /*@C
2493264ace61SBarry Smith   DMGetType - Gets the DM type name (as a string) from the DM.
2494264ace61SBarry Smith 
2495264ace61SBarry Smith   Not Collective
2496264ace61SBarry Smith 
2497264ace61SBarry Smith   Input Parameter:
2498264ace61SBarry Smith . dm  - The DM
2499264ace61SBarry Smith 
2500264ace61SBarry Smith   Output Parameter:
2501264ace61SBarry Smith . type - The DM type name
2502264ace61SBarry Smith 
2503264ace61SBarry Smith   Level: intermediate
2504264ace61SBarry Smith 
2505264ace61SBarry Smith .keywords: DM, get, type, name
2506264ace61SBarry Smith .seealso: DMSetType(), DMCreate()
2507264ace61SBarry Smith @*/
250819fd82e9SBarry Smith PetscErrorCode  DMGetType(DM dm, DMType *type)
2509264ace61SBarry Smith {
2510264ace61SBarry Smith   PetscErrorCode ierr;
2511264ace61SBarry Smith 
2512264ace61SBarry Smith   PetscFunctionBegin;
2513264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2514264ace61SBarry Smith   PetscValidCharPointer(type,2);
2515264ace61SBarry Smith   if (!DMRegisterAllCalled) {
2516264ace61SBarry Smith     ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);
2517264ace61SBarry Smith   }
2518264ace61SBarry Smith   *type = ((PetscObject)dm)->type_name;
2519264ace61SBarry Smith   PetscFunctionReturn(0);
2520264ace61SBarry Smith }
2521264ace61SBarry Smith 
252267a56275SMatthew G Knepley #undef __FUNCT__
252367a56275SMatthew G Knepley #define __FUNCT__ "DMConvert"
252467a56275SMatthew G Knepley /*@C
252567a56275SMatthew G Knepley   DMConvert - Converts a DM to another DM, either of the same or different type.
252667a56275SMatthew G Knepley 
252767a56275SMatthew G Knepley   Collective on DM
252867a56275SMatthew G Knepley 
252967a56275SMatthew G Knepley   Input Parameters:
253067a56275SMatthew G Knepley + dm - the DM
253167a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type)
253267a56275SMatthew G Knepley 
253367a56275SMatthew G Knepley   Output Parameter:
253467a56275SMatthew G Knepley . M - pointer to new DM
253567a56275SMatthew G Knepley 
253667a56275SMatthew G Knepley   Notes:
253767a56275SMatthew G Knepley   Cannot be used to convert a sequential DM to parallel or parallel to sequential,
253867a56275SMatthew G Knepley   the MPI communicator of the generated DM is always the same as the communicator
253967a56275SMatthew G Knepley   of the input DM.
254067a56275SMatthew G Knepley 
254167a56275SMatthew G Knepley   Level: intermediate
254267a56275SMatthew G Knepley 
254367a56275SMatthew G Knepley .seealso: DMCreate()
254467a56275SMatthew G Knepley @*/
254519fd82e9SBarry Smith PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M)
254667a56275SMatthew G Knepley {
254767a56275SMatthew G Knepley   DM             B;
254867a56275SMatthew G Knepley   char           convname[256];
254967a56275SMatthew G Knepley   PetscBool      sametype, issame;
255067a56275SMatthew G Knepley   PetscErrorCode ierr;
255167a56275SMatthew G Knepley 
255267a56275SMatthew G Knepley   PetscFunctionBegin;
255367a56275SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
255467a56275SMatthew G Knepley   PetscValidType(dm,1);
255567a56275SMatthew G Knepley   PetscValidPointer(M,3);
2556251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr);
255767a56275SMatthew G Knepley   ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr);
255867a56275SMatthew G Knepley   {
255919fd82e9SBarry Smith     PetscErrorCode (*conv)(DM, DMType, DM *) = PETSC_NULL;
256067a56275SMatthew G Knepley 
256167a56275SMatthew G Knepley     /*
256267a56275SMatthew G Knepley        Order of precedence:
256367a56275SMatthew G Knepley        1) See if a specialized converter is known to the current DM.
256467a56275SMatthew G Knepley        2) See if a specialized converter is known to the desired DM class.
256567a56275SMatthew G Knepley        3) See if a good general converter is registered for the desired class
256667a56275SMatthew G Knepley        4) See if a good general converter is known for the current matrix.
256767a56275SMatthew G Knepley        5) Use a really basic converter.
256867a56275SMatthew G Knepley     */
256967a56275SMatthew G Knepley 
257067a56275SMatthew G Knepley     /* 1) See if a specialized converter is known to the current DM and the desired class */
257167a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
257267a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
257367a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
257467a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
257567a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
257667a56275SMatthew G Knepley     ierr = PetscObjectQueryFunction((PetscObject)dm,convname,(void (**)(void))&conv);CHKERRQ(ierr);
257767a56275SMatthew G Knepley     if (conv) goto foundconv;
257867a56275SMatthew G Knepley 
257967a56275SMatthew G Knepley     /* 2)  See if a specialized converter is known to the desired DM class. */
258067a56275SMatthew G Knepley     ierr = DMCreate(((PetscObject) dm)->comm, &B);CHKERRQ(ierr);
258167a56275SMatthew G Knepley     ierr = DMSetType(B, newtype);CHKERRQ(ierr);
258267a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
258367a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
258467a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
258567a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
258667a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
258767a56275SMatthew G Knepley     ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
258867a56275SMatthew G Knepley     if (conv) {
2589fcfd50ebSBarry Smith       ierr = DMDestroy(&B);CHKERRQ(ierr);
259067a56275SMatthew G Knepley       goto foundconv;
259167a56275SMatthew G Knepley     }
259267a56275SMatthew G Knepley 
259367a56275SMatthew G Knepley #if 0
259467a56275SMatthew G Knepley     /* 3) See if a good general converter is registered for the desired class */
259567a56275SMatthew G Knepley     conv = B->ops->convertfrom;
2596fcfd50ebSBarry Smith     ierr = DMDestroy(&B);CHKERRQ(ierr);
259767a56275SMatthew G Knepley     if (conv) goto foundconv;
259867a56275SMatthew G Knepley 
259967a56275SMatthew G Knepley     /* 4) See if a good general converter is known for the current matrix */
260067a56275SMatthew G Knepley     if (dm->ops->convert) {
260167a56275SMatthew G Knepley       conv = dm->ops->convert;
260267a56275SMatthew G Knepley     }
260367a56275SMatthew G Knepley     if (conv) goto foundconv;
260467a56275SMatthew G Knepley #endif
260567a56275SMatthew G Knepley 
260667a56275SMatthew G Knepley     /* 5) Use a really basic converter. */
260767a56275SMatthew G Knepley     SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype);
260867a56275SMatthew G Knepley 
260967a56275SMatthew G Knepley     foundconv:
261067a56275SMatthew G Knepley     ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
261167a56275SMatthew G Knepley     ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr);
261267a56275SMatthew G Knepley     ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
261367a56275SMatthew G Knepley   }
261467a56275SMatthew G Knepley   ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr);
261567a56275SMatthew G Knepley   PetscFunctionReturn(0);
261667a56275SMatthew G Knepley }
2617264ace61SBarry Smith 
2618264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
2619264ace61SBarry Smith 
2620264ace61SBarry Smith #undef __FUNCT__
2621264ace61SBarry Smith #define __FUNCT__ "DMRegister"
2622264ace61SBarry Smith /*@C
2623264ace61SBarry Smith   DMRegister - See DMRegisterDynamic()
2624264ace61SBarry Smith 
2625264ace61SBarry Smith   Level: advanced
2626264ace61SBarry Smith @*/
26277087cfbeSBarry Smith PetscErrorCode  DMRegister(const char sname[], const char path[], const char name[], PetscErrorCode (*function)(DM))
2628264ace61SBarry Smith {
2629264ace61SBarry Smith   char fullname[PETSC_MAX_PATH_LEN];
2630264ace61SBarry Smith   PetscErrorCode ierr;
2631264ace61SBarry Smith 
2632264ace61SBarry Smith   PetscFunctionBegin;
2633264ace61SBarry Smith   ierr = PetscStrcpy(fullname, path);CHKERRQ(ierr);
2634264ace61SBarry Smith   ierr = PetscStrcat(fullname, ":");CHKERRQ(ierr);
2635264ace61SBarry Smith   ierr = PetscStrcat(fullname, name);CHKERRQ(ierr);
2636264ace61SBarry Smith   ierr = PetscFListAdd(&DMList, sname, fullname, (void (*)(void)) function);CHKERRQ(ierr);
2637264ace61SBarry Smith   PetscFunctionReturn(0);
2638264ace61SBarry Smith }
2639264ace61SBarry Smith 
2640264ace61SBarry Smith 
2641264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
2642264ace61SBarry Smith #undef __FUNCT__
2643264ace61SBarry Smith #define __FUNCT__ "DMRegisterDestroy"
2644264ace61SBarry Smith /*@C
2645264ace61SBarry Smith    DMRegisterDestroy - Frees the list of DM methods that were registered by DMRegister()/DMRegisterDynamic().
2646264ace61SBarry Smith 
2647264ace61SBarry Smith    Not Collective
2648264ace61SBarry Smith 
2649264ace61SBarry Smith    Level: advanced
2650264ace61SBarry Smith 
2651264ace61SBarry Smith .keywords: DM, register, destroy
2652264ace61SBarry Smith .seealso: DMRegister(), DMRegisterAll(), DMRegisterDynamic()
2653264ace61SBarry Smith @*/
26547087cfbeSBarry Smith PetscErrorCode  DMRegisterDestroy(void)
2655264ace61SBarry Smith {
2656264ace61SBarry Smith   PetscErrorCode ierr;
2657264ace61SBarry Smith 
2658264ace61SBarry Smith   PetscFunctionBegin;
2659264ace61SBarry Smith   ierr = PetscFListDestroy(&DMList);CHKERRQ(ierr);
2660264ace61SBarry Smith   DMRegisterAllCalled = PETSC_FALSE;
2661264ace61SBarry Smith   PetscFunctionReturn(0);
2662264ace61SBarry Smith }
266323f975d1SBarry Smith 
2664b859378eSBarry Smith #undef __FUNCT__
2665b859378eSBarry Smith #define __FUNCT__ "DMLoad"
2666b859378eSBarry Smith /*@C
266755849f57SBarry Smith   DMLoad - Loads a DM that has been stored in binary  with DMView().
2668b859378eSBarry Smith 
2669b859378eSBarry Smith   Collective on PetscViewer
2670b859378eSBarry Smith 
2671b859378eSBarry Smith   Input Parameters:
2672b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or
2673b859378eSBarry Smith            some related function before a call to DMLoad().
2674b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
2675b859378eSBarry Smith            HDF5 file viewer, obtained from PetscViewerHDF5Open()
2676b859378eSBarry Smith 
2677b859378eSBarry Smith    Level: intermediate
2678b859378eSBarry Smith 
2679b859378eSBarry Smith   Notes:
268055849f57SBarry Smith    The type is determined by the data in the file, any type set into the DM before this call is ignored.
2681b859378eSBarry Smith 
2682b859378eSBarry Smith   Notes for advanced users:
2683b859378eSBarry Smith   Most users should not need to know the details of the binary storage
2684b859378eSBarry Smith   format, since DMLoad() and DMView() completely hide these details.
2685b859378eSBarry Smith   But for anyone who's interested, the standard binary matrix storage
2686b859378eSBarry Smith   format is
2687b859378eSBarry Smith .vb
2688b859378eSBarry Smith      has not yet been determined
2689b859378eSBarry Smith .ve
2690b859378eSBarry Smith 
2691b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad()
2692b859378eSBarry Smith @*/
2693b859378eSBarry Smith PetscErrorCode  DMLoad(DM newdm, PetscViewer viewer)
2694b859378eSBarry Smith {
2695b859378eSBarry Smith   PetscErrorCode ierr;
269632c0f0efSBarry Smith   PetscBool      isbinary;
269755849f57SBarry Smith   PetscInt       classid;
269832c0f0efSBarry Smith   char           type[256];
2699b859378eSBarry Smith 
2700b859378eSBarry Smith   PetscFunctionBegin;
2701b859378eSBarry Smith   PetscValidHeaderSpecific(newdm,DM_CLASSID,1);
2702b859378eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
270332c0f0efSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
270432c0f0efSBarry Smith   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
2705b859378eSBarry Smith 
270632c0f0efSBarry Smith   ierr = PetscViewerBinaryRead(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr);
270732c0f0efSBarry Smith   if (classid != DM_FILE_CLASSID) SETERRQ(((PetscObject)newdm)->comm,PETSC_ERR_ARG_WRONG,"Not DM next in file");
270832c0f0efSBarry Smith   ierr = PetscViewerBinaryRead(viewer,type,256,PETSC_CHAR);CHKERRQ(ierr);
270932c0f0efSBarry Smith   ierr = DMSetType(newdm, type);CHKERRQ(ierr);
2710b859378eSBarry Smith   ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);
2711b859378eSBarry Smith   PetscFunctionReturn(0);
2712b859378eSBarry Smith }
2713b859378eSBarry Smith 
27147da65231SMatthew G Knepley /******************************** FEM Support **********************************/
27157da65231SMatthew G Knepley 
27167da65231SMatthew G Knepley #undef __FUNCT__
27177da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellVector"
27187da65231SMatthew G Knepley PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) {
27191d47ebbbSSatish Balay   PetscInt       f;
27201b30c384SMatthew G Knepley   PetscErrorCode ierr;
27211b30c384SMatthew G Knepley 
27227da65231SMatthew G Knepley   PetscFunctionBegin;
272374778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
27241d47ebbbSSatish Balay   for (f = 0; f < len; ++f) {
272574778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  | %G |\n", PetscRealPart(x[f]));CHKERRQ(ierr);
27267da65231SMatthew G Knepley   }
27277da65231SMatthew G Knepley   PetscFunctionReturn(0);
27287da65231SMatthew G Knepley }
27297da65231SMatthew G Knepley 
27307da65231SMatthew G Knepley #undef __FUNCT__
27317da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellMatrix"
27327da65231SMatthew G Knepley PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) {
27331b30c384SMatthew G Knepley   PetscInt       f, g;
27347da65231SMatthew G Knepley   PetscErrorCode ierr;
27357da65231SMatthew G Knepley 
27367da65231SMatthew G Knepley   PetscFunctionBegin;
273774778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
27381d47ebbbSSatish Balay   for (f = 0; f < rows; ++f) {
273974778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  |");CHKERRQ(ierr);
27401d47ebbbSSatish Balay     for (g = 0; g < cols; ++g) {
274174778d6cSJed Brown       ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5G", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr);
27427da65231SMatthew G Knepley     }
274374778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr);
27447da65231SMatthew G Knepley   }
27457da65231SMatthew G Knepley   PetscFunctionReturn(0);
27467da65231SMatthew G Knepley }
2747e7c4fc90SDmitry Karpeev 
2748970e74d5SMatthew G Knepley #undef __FUNCT__
274988ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSection"
275088ed4aceSMatthew G Knepley /*@
275188ed4aceSMatthew G Knepley   DMGetDefaultSection - Get the PetscSection encoding the local data layout for the DM.
275288ed4aceSMatthew G Knepley 
275388ed4aceSMatthew G Knepley   Input Parameter:
275488ed4aceSMatthew G Knepley . dm - The DM
275588ed4aceSMatthew G Knepley 
275688ed4aceSMatthew G Knepley   Output Parameter:
275788ed4aceSMatthew G Knepley . section - The PetscSection
275888ed4aceSMatthew G Knepley 
275988ed4aceSMatthew G Knepley   Level: intermediate
276088ed4aceSMatthew G Knepley 
276188ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
276288ed4aceSMatthew G Knepley 
276388ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
276488ed4aceSMatthew G Knepley @*/
276588ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultSection(DM dm, PetscSection *section) {
276688ed4aceSMatthew G Knepley   PetscFunctionBegin;
276788ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
276888ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
276988ed4aceSMatthew G Knepley   *section = dm->defaultSection;
277088ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
277188ed4aceSMatthew G Knepley }
277288ed4aceSMatthew G Knepley 
277388ed4aceSMatthew G Knepley #undef __FUNCT__
277488ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSection"
277588ed4aceSMatthew G Knepley /*@
277688ed4aceSMatthew G Knepley   DMSetDefaultSection - Set the PetscSection encoding the local data layout for the DM.
277788ed4aceSMatthew G Knepley 
277888ed4aceSMatthew G Knepley   Input Parameters:
277988ed4aceSMatthew G Knepley + dm - The DM
278088ed4aceSMatthew G Knepley - section - The PetscSection
278188ed4aceSMatthew G Knepley 
278288ed4aceSMatthew G Knepley   Level: intermediate
278388ed4aceSMatthew G Knepley 
278488ed4aceSMatthew G Knepley   Note: Any existing Section will be destroyed
278588ed4aceSMatthew G Knepley 
278688ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
278788ed4aceSMatthew G Knepley @*/
278888ed4aceSMatthew G Knepley PetscErrorCode DMSetDefaultSection(DM dm, PetscSection section) {
2789af122d2aSMatthew G Knepley   PetscInt       numFields;
2790af122d2aSMatthew G Knepley   PetscInt       f;
279188ed4aceSMatthew G Knepley   PetscErrorCode ierr;
279288ed4aceSMatthew G Knepley 
279388ed4aceSMatthew G Knepley   PetscFunctionBegin;
279488ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
279588ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultSection);CHKERRQ(ierr);
279688ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
279788ed4aceSMatthew G Knepley   dm->defaultSection = section;
2798af122d2aSMatthew G Knepley   ierr = PetscSectionGetNumFields(dm->defaultSection, &numFields);CHKERRQ(ierr);
2799af122d2aSMatthew G Knepley   if (numFields) {
2800af122d2aSMatthew G Knepley     ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr);
2801af122d2aSMatthew G Knepley     for (f = 0; f < numFields; ++f) {
2802af122d2aSMatthew G Knepley       const char *name;
2803af122d2aSMatthew G Knepley 
2804af122d2aSMatthew G Knepley       ierr = PetscSectionGetFieldName(dm->defaultSection, f, &name);CHKERRQ(ierr);
2805af122d2aSMatthew G Knepley       ierr = PetscObjectSetName(dm->fields[f], name);CHKERRQ(ierr);
2806af122d2aSMatthew G Knepley     }
2807af122d2aSMatthew G Knepley   }
280888ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
280988ed4aceSMatthew G Knepley }
281088ed4aceSMatthew G Knepley 
281188ed4aceSMatthew G Knepley #undef __FUNCT__
281288ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultGlobalSection"
281388ed4aceSMatthew G Knepley /*@
281488ed4aceSMatthew G Knepley   DMGetDefaultGlobalSection - Get the PetscSection encoding the global data layout for the DM.
281588ed4aceSMatthew G Knepley 
28168b1ab98fSJed Brown   Collective on DM
28178b1ab98fSJed Brown 
281888ed4aceSMatthew G Knepley   Input Parameter:
281988ed4aceSMatthew G Knepley . dm - The DM
282088ed4aceSMatthew G Knepley 
282188ed4aceSMatthew G Knepley   Output Parameter:
282288ed4aceSMatthew G Knepley . section - The PetscSection
282388ed4aceSMatthew G Knepley 
282488ed4aceSMatthew G Knepley   Level: intermediate
282588ed4aceSMatthew G Knepley 
282688ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
282788ed4aceSMatthew G Knepley 
282888ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultSection()
282988ed4aceSMatthew G Knepley @*/
283088ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultGlobalSection(DM dm, PetscSection *section) {
283188ed4aceSMatthew G Knepley   PetscErrorCode ierr;
283288ed4aceSMatthew G Knepley 
283388ed4aceSMatthew G Knepley   PetscFunctionBegin;
283488ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
283588ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
283688ed4aceSMatthew G Knepley   if (!dm->defaultGlobalSection) {
283740e8a239SMatthew 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");
2838b21d0597SMatthew G Knepley     ierr = PetscSectionCreateGlobalSection(dm->defaultSection, dm->sf, PETSC_FALSE, &dm->defaultGlobalSection);CHKERRQ(ierr);
28398b1ab98fSJed Brown     ierr = PetscSectionGetValueLayout(((PetscObject)dm)->comm,dm->defaultGlobalSection,&dm->map);CHKERRQ(ierr);
284088ed4aceSMatthew G Knepley   }
284188ed4aceSMatthew G Knepley   *section = dm->defaultGlobalSection;
284288ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
284388ed4aceSMatthew G Knepley }
284488ed4aceSMatthew G Knepley 
284588ed4aceSMatthew G Knepley #undef __FUNCT__
2846b21d0597SMatthew G Knepley #define __FUNCT__ "DMSetDefaultGlobalSection"
2847b21d0597SMatthew G Knepley /*@
2848b21d0597SMatthew G Knepley   DMSetDefaultGlobalSection - Set the PetscSection encoding the global data layout for the DM.
2849b21d0597SMatthew G Knepley 
2850b21d0597SMatthew G Knepley   Input Parameters:
2851b21d0597SMatthew G Knepley + dm - The DM
2852b21d0597SMatthew G Knepley - section - The PetscSection
2853b21d0597SMatthew G Knepley 
2854b21d0597SMatthew G Knepley   Level: intermediate
2855b21d0597SMatthew G Knepley 
2856b21d0597SMatthew G Knepley   Note: Any existing Section will be destroyed
2857b21d0597SMatthew G Knepley 
2858b21d0597SMatthew G Knepley .seealso: DMGetDefaultGlobalSection(), DMSetDefaultSection()
2859b21d0597SMatthew G Knepley @*/
2860b21d0597SMatthew G Knepley PetscErrorCode DMSetDefaultGlobalSection(DM dm, PetscSection section) {
2861b21d0597SMatthew G Knepley   PetscErrorCode ierr;
2862b21d0597SMatthew G Knepley 
2863b21d0597SMatthew G Knepley   PetscFunctionBegin;
2864b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2865b21d0597SMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
2866b21d0597SMatthew G Knepley   dm->defaultGlobalSection = section;
2867b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
2868b21d0597SMatthew G Knepley }
2869b21d0597SMatthew G Knepley 
2870b21d0597SMatthew G Knepley #undef __FUNCT__
287188ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSF"
287288ed4aceSMatthew G Knepley /*@
287388ed4aceSMatthew G Knepley   DMGetDefaultSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set,
287488ed4aceSMatthew G Knepley   it is created from the default PetscSection layouts in the DM.
287588ed4aceSMatthew G Knepley 
287688ed4aceSMatthew G Knepley   Input Parameter:
287788ed4aceSMatthew G Knepley . dm - The DM
287888ed4aceSMatthew G Knepley 
287988ed4aceSMatthew G Knepley   Output Parameter:
288088ed4aceSMatthew G Knepley . sf - The PetscSF
288188ed4aceSMatthew G Knepley 
288288ed4aceSMatthew G Knepley   Level: intermediate
288388ed4aceSMatthew G Knepley 
288488ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
288588ed4aceSMatthew G Knepley 
288688ed4aceSMatthew G Knepley .seealso: DMSetDefaultSF(), DMCreateDefaultSF()
288788ed4aceSMatthew G Knepley @*/
288888ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultSF(DM dm, PetscSF *sf) {
288988ed4aceSMatthew G Knepley   PetscInt       nroots;
289088ed4aceSMatthew G Knepley   PetscErrorCode ierr;
289188ed4aceSMatthew G Knepley 
289288ed4aceSMatthew G Knepley   PetscFunctionBegin;
289388ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
289488ed4aceSMatthew G Knepley   PetscValidPointer(sf, 2);
289588ed4aceSMatthew G Knepley   ierr = PetscSFGetGraph(dm->defaultSF, &nroots, PETSC_NULL, PETSC_NULL, PETSC_NULL);CHKERRQ(ierr);
289688ed4aceSMatthew G Knepley   if (nroots < 0) {
289788ed4aceSMatthew G Knepley     PetscSection section, gSection;
289888ed4aceSMatthew G Knepley 
289988ed4aceSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
290031ea6d37SMatthew G Knepley     if (section) {
290188ed4aceSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr);
290288ed4aceSMatthew G Knepley       ierr = DMCreateDefaultSF(dm, section, gSection);CHKERRQ(ierr);
290331ea6d37SMatthew G Knepley     } else {
290431ea6d37SMatthew G Knepley       *sf = PETSC_NULL;
290531ea6d37SMatthew G Knepley       PetscFunctionReturn(0);
290631ea6d37SMatthew G Knepley     }
290788ed4aceSMatthew G Knepley   }
290888ed4aceSMatthew G Knepley   *sf = dm->defaultSF;
290988ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
291088ed4aceSMatthew G Knepley }
291188ed4aceSMatthew G Knepley 
291288ed4aceSMatthew G Knepley #undef __FUNCT__
291388ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSF"
291488ed4aceSMatthew G Knepley /*@
291588ed4aceSMatthew G Knepley   DMSetDefaultSF - Set the PetscSF encoding the parallel dof overlap for the DM
291688ed4aceSMatthew G Knepley 
291788ed4aceSMatthew G Knepley   Input Parameters:
291888ed4aceSMatthew G Knepley + dm - The DM
291988ed4aceSMatthew G Knepley - sf - The PetscSF
292088ed4aceSMatthew G Knepley 
292188ed4aceSMatthew G Knepley   Level: intermediate
292288ed4aceSMatthew G Knepley 
292388ed4aceSMatthew G Knepley   Note: Any previous SF is destroyed
292488ed4aceSMatthew G Knepley 
292588ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMCreateDefaultSF()
292688ed4aceSMatthew G Knepley @*/
292788ed4aceSMatthew G Knepley PetscErrorCode DMSetDefaultSF(DM dm, PetscSF sf) {
292888ed4aceSMatthew G Knepley   PetscErrorCode ierr;
292988ed4aceSMatthew G Knepley 
293088ed4aceSMatthew G Knepley   PetscFunctionBegin;
293188ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
293288ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
293388ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&dm->defaultSF);CHKERRQ(ierr);
293488ed4aceSMatthew G Knepley   dm->defaultSF = sf;
293588ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
293688ed4aceSMatthew G Knepley }
293788ed4aceSMatthew G Knepley 
293888ed4aceSMatthew G Knepley #undef __FUNCT__
293988ed4aceSMatthew G Knepley #define __FUNCT__ "DMCreateDefaultSF"
294088ed4aceSMatthew G Knepley /*@C
294188ed4aceSMatthew G Knepley   DMCreateDefaultSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections
294288ed4aceSMatthew G Knepley   describing the data layout.
294388ed4aceSMatthew G Knepley 
294488ed4aceSMatthew G Knepley   Input Parameters:
294588ed4aceSMatthew G Knepley + dm - The DM
294688ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout
294788ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout
294888ed4aceSMatthew G Knepley 
294988ed4aceSMatthew G Knepley   Level: intermediate
295088ed4aceSMatthew G Knepley 
295188ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF()
295288ed4aceSMatthew G Knepley @*/
295388ed4aceSMatthew G Knepley PetscErrorCode DMCreateDefaultSF(DM dm, PetscSection localSection, PetscSection globalSection)
295488ed4aceSMatthew G Knepley {
295588ed4aceSMatthew G Knepley   MPI_Comm        comm = ((PetscObject) dm)->comm;
295688ed4aceSMatthew G Knepley   PetscLayout     layout;
295788ed4aceSMatthew G Knepley   const PetscInt *ranges;
295888ed4aceSMatthew G Knepley   PetscInt       *local;
295988ed4aceSMatthew G Knepley   PetscSFNode    *remote;
296088ed4aceSMatthew G Knepley   PetscInt        pStart, pEnd, p, nroots, nleaves, l;
296188ed4aceSMatthew G Knepley   PetscMPIInt     size, rank;
296288ed4aceSMatthew G Knepley   PetscErrorCode  ierr;
296388ed4aceSMatthew G Knepley 
296488ed4aceSMatthew G Knepley   PetscFunctionBegin;
296588ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
296688ed4aceSMatthew G Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
296788ed4aceSMatthew G Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
296888ed4aceSMatthew G Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
296988ed4aceSMatthew G Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
297088ed4aceSMatthew G Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
297188ed4aceSMatthew G Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
297288ed4aceSMatthew G Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
297388ed4aceSMatthew G Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
297488ed4aceSMatthew G Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
297588ed4aceSMatthew G Knepley   for (p = pStart, nleaves = 0; p < pEnd; ++p) {
29766636e97aSMatthew G Knepley     PetscInt gdof, gcdof;
297788ed4aceSMatthew G Knepley 
29786636e97aSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
29796636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
29806636e97aSMatthew G Knepley     nleaves += gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
298188ed4aceSMatthew G Knepley   }
298288ed4aceSMatthew G Knepley   ierr = PetscMalloc(nleaves * sizeof(PetscInt), &local);CHKERRQ(ierr);
298388ed4aceSMatthew G Knepley   ierr = PetscMalloc(nleaves * sizeof(PetscSFNode), &remote);CHKERRQ(ierr);
298488ed4aceSMatthew G Knepley   for (p = pStart, l = 0; p < pEnd; ++p) {
29851f588964SMatthew G Knepley     const PetscInt *cind;
29866636e97aSMatthew G Knepley     PetscInt        dof, cdof, off, gdof, gcdof, goff, gsize, d, c;
298788ed4aceSMatthew G Knepley 
298888ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
298988ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
299088ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
299188ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr);
299288ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
29936636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
299488ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
29956636e97aSMatthew G Knepley     if (!gdof) continue; /* Censored point */
29966636e97aSMatthew G Knepley     gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
29976636e97aSMatthew G Knepley     if (gsize != dof-cdof) {
2998057b4bcdSMatthew 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);
29996636e97aSMatthew G Knepley       cdof = 0; /* Ignore constraints */
30006636e97aSMatthew G Knepley     }
300188ed4aceSMatthew G Knepley     for (d = 0, c = 0; d < dof; ++d) {
300288ed4aceSMatthew G Knepley       if ((c < cdof) && (cind[c] == d)) {++c; continue;}
300388ed4aceSMatthew G Knepley       local[l+d-c] = off+d;
300488ed4aceSMatthew G Knepley     }
300588ed4aceSMatthew G Knepley     if (gdof < 0) {
30066636e97aSMatthew G Knepley       for(d = 0; d < gsize; ++d, ++l) {
300788ed4aceSMatthew G Knepley         PetscInt offset = -(goff+1) + d, r;
300888ed4aceSMatthew G Knepley 
300931d3f06eSJed Brown         ierr = PetscFindInt(offset,size,ranges,&r);CHKERRQ(ierr);
301031d3f06eSJed Brown         if (r < 0) r = -(r+2);
301188ed4aceSMatthew G Knepley         remote[l].rank  = r;
301288ed4aceSMatthew G Knepley         remote[l].index = offset - ranges[r];
301388ed4aceSMatthew G Knepley       }
301488ed4aceSMatthew G Knepley     } else {
30156636e97aSMatthew G Knepley       for(d = 0; d < gsize; ++d, ++l) {
301688ed4aceSMatthew G Knepley         remote[l].rank  = rank;
301788ed4aceSMatthew G Knepley         remote[l].index = goff+d - ranges[rank];
301888ed4aceSMatthew G Knepley       }
301988ed4aceSMatthew G Knepley     }
302088ed4aceSMatthew G Knepley   }
30216636e97aSMatthew G Knepley   if (l != nleaves) SETERRQ2(comm, PETSC_ERR_PLIB, "Iteration error, l %d != nleaves %d", l, nleaves);
302288ed4aceSMatthew G Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
302388ed4aceSMatthew G Knepley   ierr = PetscSFSetGraph(dm->defaultSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr);
302488ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
302588ed4aceSMatthew G Knepley }
3026af122d2aSMatthew G Knepley 
3027af122d2aSMatthew G Knepley #undef __FUNCT__
3028b21d0597SMatthew G Knepley #define __FUNCT__ "DMGetPointSF"
3029b21d0597SMatthew G Knepley /*@
3030b21d0597SMatthew G Knepley   DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM.
3031b21d0597SMatthew G Knepley 
3032b21d0597SMatthew G Knepley   Input Parameter:
3033b21d0597SMatthew G Knepley . dm - The DM
3034b21d0597SMatthew G Knepley 
3035b21d0597SMatthew G Knepley   Output Parameter:
3036b21d0597SMatthew G Knepley . sf - The PetscSF
3037b21d0597SMatthew G Knepley 
3038b21d0597SMatthew G Knepley   Level: intermediate
3039b21d0597SMatthew G Knepley 
3040b21d0597SMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
3041b21d0597SMatthew G Knepley 
3042057b4bcdSMatthew G Knepley .seealso: DMSetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
3043b21d0597SMatthew G Knepley @*/
3044b21d0597SMatthew G Knepley PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) {
3045b21d0597SMatthew G Knepley   PetscFunctionBegin;
3046b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3047b21d0597SMatthew G Knepley   PetscValidPointer(sf, 2);
3048b21d0597SMatthew G Knepley   *sf = dm->sf;
3049b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
3050b21d0597SMatthew G Knepley }
3051b21d0597SMatthew G Knepley 
3052b21d0597SMatthew G Knepley #undef __FUNCT__
3053057b4bcdSMatthew G Knepley #define __FUNCT__ "DMSetPointSF"
3054057b4bcdSMatthew G Knepley /*@
3055057b4bcdSMatthew G Knepley   DMSetPointSF - Set the PetscSF encoding the parallel section point overlap for the DM.
3056057b4bcdSMatthew G Knepley 
3057057b4bcdSMatthew G Knepley   Input Parameters:
3058057b4bcdSMatthew G Knepley + dm - The DM
3059057b4bcdSMatthew G Knepley - sf - The PetscSF
3060057b4bcdSMatthew G Knepley 
3061057b4bcdSMatthew G Knepley   Level: intermediate
3062057b4bcdSMatthew G Knepley 
3063057b4bcdSMatthew G Knepley .seealso: DMGetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
3064057b4bcdSMatthew G Knepley @*/
3065057b4bcdSMatthew G Knepley PetscErrorCode DMSetPointSF(DM dm, PetscSF sf) {
3066057b4bcdSMatthew G Knepley   PetscErrorCode ierr;
3067057b4bcdSMatthew G Knepley 
3068057b4bcdSMatthew G Knepley   PetscFunctionBegin;
3069057b4bcdSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3070057b4bcdSMatthew G Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 1);
3071057b4bcdSMatthew G Knepley   ierr = PetscSFDestroy(&dm->sf);CHKERRQ(ierr);
3072057b4bcdSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr);
3073057b4bcdSMatthew G Knepley   dm->sf = sf;
3074057b4bcdSMatthew G Knepley   PetscFunctionReturn(0);
3075057b4bcdSMatthew G Knepley }
3076057b4bcdSMatthew G Knepley 
3077057b4bcdSMatthew G Knepley #undef __FUNCT__
3078af122d2aSMatthew G Knepley #define __FUNCT__ "DMGetNumFields"
3079af122d2aSMatthew G Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields)
3080af122d2aSMatthew G Knepley {
3081af122d2aSMatthew G Knepley   PetscFunctionBegin;
3082af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3083af122d2aSMatthew G Knepley   PetscValidPointer(numFields, 2);
3084af122d2aSMatthew G Knepley   *numFields = dm->numFields;
3085af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3086af122d2aSMatthew G Knepley }
3087af122d2aSMatthew G Knepley 
3088af122d2aSMatthew G Knepley #undef __FUNCT__
3089af122d2aSMatthew G Knepley #define __FUNCT__ "DMSetNumFields"
3090af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields)
3091af122d2aSMatthew G Knepley {
3092af122d2aSMatthew G Knepley   PetscInt       f;
3093af122d2aSMatthew G Knepley   PetscErrorCode ierr;
3094af122d2aSMatthew G Knepley 
3095af122d2aSMatthew G Knepley   PetscFunctionBegin;
3096af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3097af122d2aSMatthew G Knepley   for (f = 0; f < dm->numFields; ++f) {
3098af122d2aSMatthew G Knepley     ierr = PetscObjectDestroy(&dm->fields[f]);CHKERRQ(ierr);
3099af122d2aSMatthew G Knepley   }
3100af122d2aSMatthew G Knepley   ierr = PetscFree(dm->fields);CHKERRQ(ierr);
3101af122d2aSMatthew G Knepley   dm->numFields = numFields;
3102af122d2aSMatthew G Knepley   ierr = PetscMalloc(dm->numFields * sizeof(PetscObject), &dm->fields);CHKERRQ(ierr);
3103af122d2aSMatthew G Knepley   for (f = 0; f < dm->numFields; ++f) {
3104af122d2aSMatthew G Knepley     ierr = PetscContainerCreate(((PetscObject) dm)->comm, (PetscContainer *) &dm->fields[f]);CHKERRQ(ierr);
3105af122d2aSMatthew G Knepley   }
3106af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3107af122d2aSMatthew G Knepley }
3108af122d2aSMatthew G Knepley 
3109af122d2aSMatthew G Knepley #undef __FUNCT__
3110af122d2aSMatthew G Knepley #define __FUNCT__ "DMGetField"
3111af122d2aSMatthew G Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, PetscObject *field)
3112af122d2aSMatthew G Knepley {
3113af122d2aSMatthew G Knepley   PetscFunctionBegin;
3114af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3115af122d2aSMatthew G Knepley   PetscValidPointer(field, 2);
3116af122d2aSMatthew G Knepley   if (!dm->fields) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Fields have not been setup in this DM. Call DMSetNumFields()");
3117af122d2aSMatthew 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);
3118af122d2aSMatthew G Knepley   *field = dm->fields[f];
3119af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3120af122d2aSMatthew G Knepley }
31216636e97aSMatthew G Knepley 
31226636e97aSMatthew G Knepley #undef __FUNCT__
31236636e97aSMatthew G Knepley #define __FUNCT__ "DMSetCoordinates"
31246636e97aSMatthew G Knepley /*@
31256636e97aSMatthew G Knepley   DMSetCoordinates - Sets into the DM a global vector that holds the coordinates
31266636e97aSMatthew G Knepley 
31276636e97aSMatthew G Knepley   Collective on DM
31286636e97aSMatthew G Knepley 
31296636e97aSMatthew G Knepley   Input Parameters:
31306636e97aSMatthew G Knepley + dm - the DM
31316636e97aSMatthew G Knepley - c - coordinate vector
31326636e97aSMatthew G Knepley 
31336636e97aSMatthew G Knepley   Note:
31346636e97aSMatthew G Knepley   The coordinates do include those for ghost points, which are in the local vector
31356636e97aSMatthew G Knepley 
31366636e97aSMatthew G Knepley   Level: intermediate
31376636e97aSMatthew G Knepley 
31386636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
31396636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLoca(), DMGetCoordinateDM()
31406636e97aSMatthew G Knepley @*/
31416636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c)
31426636e97aSMatthew G Knepley {
31436636e97aSMatthew G Knepley   PetscErrorCode ierr;
31446636e97aSMatthew G Knepley 
31456636e97aSMatthew G Knepley   PetscFunctionBegin;
31466636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
31476636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
31486636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
31496636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
31506636e97aSMatthew G Knepley   dm->coordinates = c;
31516636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
31526636e97aSMatthew G Knepley   PetscFunctionReturn(0);
31536636e97aSMatthew G Knepley }
31546636e97aSMatthew G Knepley 
31556636e97aSMatthew G Knepley #undef __FUNCT__
31566636e97aSMatthew G Knepley #define __FUNCT__ "DMSetCoordinatesLocal"
31576636e97aSMatthew G Knepley /*@
31586636e97aSMatthew G Knepley   DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates
31596636e97aSMatthew G Knepley 
31606636e97aSMatthew G Knepley   Collective on DM
31616636e97aSMatthew G Knepley 
31626636e97aSMatthew G Knepley    Input Parameters:
31636636e97aSMatthew G Knepley +  dm - the DM
31646636e97aSMatthew G Knepley -  c - coordinate vector
31656636e97aSMatthew G Knepley 
31666636e97aSMatthew G Knepley   Note:
31676636e97aSMatthew G Knepley   The coordinates of ghost points can be set using DMSetCoordinates()
31686636e97aSMatthew G Knepley   followed by DMGetCoordinatesLocal(). This is intended to enable the
31696636e97aSMatthew G Knepley   setting of ghost coordinates outside of the domain.
31706636e97aSMatthew G Knepley 
31716636e97aSMatthew G Knepley   Level: intermediate
31726636e97aSMatthew G Knepley 
31736636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
31746636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM()
31756636e97aSMatthew G Knepley @*/
31766636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c)
31776636e97aSMatthew G Knepley {
31786636e97aSMatthew G Knepley   PetscErrorCode ierr;
31796636e97aSMatthew G Knepley 
31806636e97aSMatthew G Knepley   PetscFunctionBegin;
31816636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
31826636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
31836636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
31846636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
31856636e97aSMatthew G Knepley   dm->coordinatesLocal = c;
31866636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
31876636e97aSMatthew G Knepley   PetscFunctionReturn(0);
31886636e97aSMatthew G Knepley }
31896636e97aSMatthew G Knepley 
31906636e97aSMatthew G Knepley #undef __FUNCT__
31916636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinates"
31926636e97aSMatthew G Knepley /*@
31936636e97aSMatthew G Knepley   DMGetCoordinates - Gets a global vector with the coordinates associated with the DM.
31946636e97aSMatthew G Knepley 
31956636e97aSMatthew G Knepley   Not Collective
31966636e97aSMatthew G Knepley 
31976636e97aSMatthew G Knepley   Input Parameter:
31986636e97aSMatthew G Knepley . dm - the DM
31996636e97aSMatthew G Knepley 
32006636e97aSMatthew G Knepley   Output Parameter:
32016636e97aSMatthew G Knepley . c - global coordinate vector
32026636e97aSMatthew G Knepley 
32036636e97aSMatthew G Knepley   Note:
32046636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
32056636e97aSMatthew G Knepley 
32066636e97aSMatthew G Knepley   Each process has only the local coordinates (does NOT have the ghost coordinates).
32076636e97aSMatthew G Knepley 
32086636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
32096636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
32106636e97aSMatthew G Knepley 
32116636e97aSMatthew G Knepley   Level: intermediate
32126636e97aSMatthew G Knepley 
32136636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
32146636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
32156636e97aSMatthew G Knepley @*/
32166636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c)
32176636e97aSMatthew G Knepley {
32186636e97aSMatthew G Knepley   PetscErrorCode ierr;
32196636e97aSMatthew G Knepley 
32206636e97aSMatthew G Knepley   PetscFunctionBegin;
32216636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
32226636e97aSMatthew G Knepley   PetscValidPointer(c,2);
32231f588964SMatthew G Knepley   if (!dm->coordinates && dm->coordinatesLocal) {
322487743a01SMatthew G Knepley     DM cdm = PETSC_NULL;
32256636e97aSMatthew G Knepley 
32266636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
32276636e97aSMatthew G Knepley     ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr);
32286636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr);
32296636e97aSMatthew G Knepley     ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
32306636e97aSMatthew G Knepley     ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
32316636e97aSMatthew G Knepley   }
32326636e97aSMatthew G Knepley   *c = dm->coordinates;
32336636e97aSMatthew G Knepley   PetscFunctionReturn(0);
32346636e97aSMatthew G Knepley }
32356636e97aSMatthew G Knepley 
32366636e97aSMatthew G Knepley #undef __FUNCT__
32376636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinatesLocal"
32386636e97aSMatthew G Knepley /*@
32396636e97aSMatthew G Knepley   DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM.
32406636e97aSMatthew G Knepley 
32416636e97aSMatthew G Knepley   Collective on DM
32426636e97aSMatthew G Knepley 
32436636e97aSMatthew G Knepley   Input Parameter:
32446636e97aSMatthew G Knepley . dm - the DM
32456636e97aSMatthew G Knepley 
32466636e97aSMatthew G Knepley   Output Parameter:
32476636e97aSMatthew G Knepley . c - coordinate vector
32486636e97aSMatthew G Knepley 
32496636e97aSMatthew G Knepley   Note:
32506636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
32516636e97aSMatthew G Knepley 
32526636e97aSMatthew G Knepley   Each process has the local and ghost coordinates
32536636e97aSMatthew G Knepley 
32546636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
32556636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
32566636e97aSMatthew G Knepley 
32576636e97aSMatthew G Knepley   Level: intermediate
32586636e97aSMatthew G Knepley 
32596636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
32606636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
32616636e97aSMatthew G Knepley @*/
32626636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c)
32636636e97aSMatthew G Knepley {
32646636e97aSMatthew G Knepley   PetscErrorCode ierr;
32656636e97aSMatthew G Knepley 
32666636e97aSMatthew G Knepley   PetscFunctionBegin;
32676636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
32686636e97aSMatthew G Knepley   PetscValidPointer(c,2);
32691f588964SMatthew G Knepley   if (!dm->coordinatesLocal && dm->coordinates) {
327087743a01SMatthew G Knepley     DM cdm = PETSC_NULL;
32716636e97aSMatthew G Knepley 
32726636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
32736636e97aSMatthew G Knepley     ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr);
32746636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr);
32756636e97aSMatthew G Knepley     ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
32766636e97aSMatthew G Knepley     ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
32776636e97aSMatthew G Knepley   }
32786636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
32796636e97aSMatthew G Knepley   PetscFunctionReturn(0);
32806636e97aSMatthew G Knepley }
32816636e97aSMatthew G Knepley 
32826636e97aSMatthew G Knepley #undef __FUNCT__
32836636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinateDM"
32846636e97aSMatthew G Knepley /*@
32856636e97aSMatthew G Knepley   DMGetCoordinateDM - Gets the DM that scatters between global and local coordinates
32866636e97aSMatthew G Knepley 
32876636e97aSMatthew G Knepley   Collective on DM
32886636e97aSMatthew G Knepley 
32896636e97aSMatthew G Knepley   Input Parameter:
32906636e97aSMatthew G Knepley . dm - the DM
32916636e97aSMatthew G Knepley 
32926636e97aSMatthew G Knepley   Output Parameter:
32936636e97aSMatthew G Knepley . cdm - coordinate DM
32946636e97aSMatthew G Knepley 
32956636e97aSMatthew G Knepley   Level: intermediate
32966636e97aSMatthew G Knepley 
32976636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
32986636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
32996636e97aSMatthew G Knepley @*/
33006636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm)
33016636e97aSMatthew G Knepley {
33026636e97aSMatthew G Knepley   PetscErrorCode ierr;
33036636e97aSMatthew G Knepley 
33046636e97aSMatthew G Knepley   PetscFunctionBegin;
33056636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
33066636e97aSMatthew G Knepley   PetscValidPointer(cdm,2);
33076636e97aSMatthew G Knepley   if (!dm->coordinateDM) {
33086636e97aSMatthew G Knepley     if (!dm->ops->createcoordinatedm) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Unable to create coordinates for this DM");
33096636e97aSMatthew G Knepley     ierr = (*dm->ops->createcoordinatedm)(dm, &dm->coordinateDM);CHKERRQ(ierr);
33106636e97aSMatthew G Knepley   }
33116636e97aSMatthew G Knepley   *cdm = dm->coordinateDM;
33126636e97aSMatthew G Knepley   PetscFunctionReturn(0);
33136636e97aSMatthew G Knepley }
3314