xref: /petsc/src/dm/interface/dm.c (revision c0f0dcc350ae2c2af87f5da198da299fa090912b)
1af0996ceSBarry Smith #include <petsc/private/dmimpl.h>           /*I      "petscdm.h"          I*/
2c58f1c22SToby Isaac #include <petsc/private/dmlabelimpl.h>      /*I      "petscdmlabel.h"     I*/
3e6f8dbb6SToby Isaac #include <petsc/private/petscdsimpl.h>      /*I      "petscds.h"     I*/
43e922f36SToby Isaac #include <petscdmplex.h>
5f19dbd58SToby Isaac #include <petscdmfield.h>
60c312b8eSJed Brown #include <petscsf.h>
72764a2aaSMatthew G. Knepley #include <petscds.h>
847c6ae99SBarry Smith 
9732e2eb9SMatthew G Knepley PetscClassId  DM_CLASSID;
10d67d17b1SMatthew G. Knepley PetscClassId  DMLABEL_CLASSID;
115a84ad33SLisandro Dalcin PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal, DM_LocalToLocal, DM_LocatePoints, DM_Coarsen, DM_Refine, DM_CreateInterpolation, DM_CreateRestriction, DM_CreateInjection, DM_CreateMatrix;
1267a56275SMatthew G Knepley 
13e249ee26SToby Isaac const char *const DMBoundaryTypes[] = {"NONE","GHOSTED","MIRROR","PERIODIC","TWIST","DMBoundaryType","DM_BOUNDARY_",0};
1440967b3bSMatthew G. Knepley const char *const DMBoundaryConditionTypes[] = {"INVALID","ESSENTIAL","NATURAL","INVALID","INVALID","ESSENTIAL_FIELD","NATURAL_FIELD","INVALID","INVALID","INVALID","NATURAL_RIEMANN","DMBoundaryConditionType","DM_BC_",0};
15bff4a2f0SMatthew G. Knepley 
16a4121054SBarry Smith /*@
17de043629SMatthew G Knepley   DMCreate - Creates an empty DM object. The type can then be set with DMSetType().
18a4121054SBarry Smith 
19a4121054SBarry Smith    If you never  call DMSetType()  it will generate an
20a4121054SBarry Smith    error when you try to use the vector.
21a4121054SBarry Smith 
22d083f849SBarry Smith   Collective
23a4121054SBarry Smith 
24a4121054SBarry Smith   Input Parameter:
25a4121054SBarry Smith . comm - The communicator for the DM object
26a4121054SBarry Smith 
27a4121054SBarry Smith   Output Parameter:
28a4121054SBarry Smith . dm - The DM object
29a4121054SBarry Smith 
30a4121054SBarry Smith   Level: beginner
31a4121054SBarry Smith 
328472ad0fSDave May .seealso: DMSetType(), DMDA, DMSLICED, DMCOMPOSITE, DMPLEX, DMMOAB, DMNETWORK
33a4121054SBarry Smith @*/
347087cfbeSBarry Smith PetscErrorCode  DMCreate(MPI_Comm comm,DM *dm)
35a4121054SBarry Smith {
36a4121054SBarry Smith   DM             v;
37e5e52638SMatthew G. Knepley   PetscDS        ds;
38a4121054SBarry Smith   PetscErrorCode ierr;
39a4121054SBarry Smith 
40a4121054SBarry Smith   PetscFunctionBegin;
411411c6eeSJed Brown   PetscValidPointer(dm,2);
420298fd71SBarry Smith   *dm = NULL;
43607a6623SBarry Smith   ierr = DMInitializePackage();CHKERRQ(ierr);
44a4121054SBarry Smith 
4573107ff1SLisandro Dalcin   ierr = PetscHeaderCreate(v, DM_CLASSID, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView);CHKERRQ(ierr);
46e7c4fc90SDmitry Karpeev 
4749be4549SMatthew G. Knepley   v->setupcalled              = PETSC_FALSE;
4849be4549SMatthew G. Knepley   v->setfromoptionscalled     = PETSC_FALSE;
490298fd71SBarry Smith   v->ltogmap                  = NULL;
501411c6eeSJed Brown   v->bs                       = 1;
51171400e9SBarry Smith   v->coloringtype             = IS_COLORING_GLOBAL;
5288ed4aceSMatthew G Knepley   ierr                        = PetscSFCreate(comm, &v->sf);CHKERRQ(ierr);
531bb6d2a8SBarry Smith   ierr                        = PetscSFCreate(comm, &v->sectionSF);CHKERRQ(ierr);
54c58f1c22SToby Isaac   v->labels                   = NULL;
5534aa8a36SMatthew G. Knepley   v->adjacency[0]             = PETSC_FALSE;
5634aa8a36SMatthew G. Knepley   v->adjacency[1]             = PETSC_TRUE;
57c58f1c22SToby Isaac   v->depthLabel               = NULL;
581bb6d2a8SBarry Smith   v->localSection             = NULL;
591bb6d2a8SBarry Smith   v->globalSection            = NULL;
60fba222abSToby Isaac   v->defaultConstraintSection = NULL;
61fba222abSToby Isaac   v->defaultConstraintMat     = NULL;
62c6b900c6SMatthew G. Knepley   v->L                        = NULL;
63c6b900c6SMatthew G. Knepley   v->maxCell                  = NULL;
645dc8c3f7SMatthew G. Knepley   v->bdtype                   = NULL;
659a9a41abSToby Isaac   v->dimEmbed                 = PETSC_DEFAULT;
6696173672SStefano Zampini   v->dim                      = PETSC_DETERMINE;
67435a35e8SMatthew G Knepley   {
68435a35e8SMatthew G Knepley     PetscInt i;
69435a35e8SMatthew G Knepley     for (i = 0; i < 10; ++i) {
700298fd71SBarry Smith       v->nullspaceConstructors[i] = NULL;
71f9d4088aSMatthew G. Knepley       v->nearnullspaceConstructors[i] = NULL;
72435a35e8SMatthew G Knepley     }
73435a35e8SMatthew G Knepley   }
74e5e52638SMatthew G. Knepley   ierr = PetscDSCreate(PetscObjectComm((PetscObject) v), &ds);CHKERRQ(ierr);
75b3cf3223SMatthew G. Knepley   ierr = DMSetRegionDS(v, NULL, NULL, ds);CHKERRQ(ierr);
76e5e52638SMatthew G. Knepley   ierr = PetscDSDestroy(&ds);CHKERRQ(ierr);
7714f150ffSMatthew G. Knepley   v->dmBC = NULL;
78a8fb8f29SToby Isaac   v->coarseMesh = NULL;
79f4d763aaSMatthew G. Knepley   v->outputSequenceNum = -1;
80cdb7a50dSMatthew G. Knepley   v->outputSequenceVal = 0.0;
81c0dedaeaSBarry Smith   ierr = DMSetVecType(v,VECSTANDARD);CHKERRQ(ierr);
82b412c318SBarry Smith   ierr = DMSetMatType(v,MATAIJ);CHKERRQ(ierr);
834a7a4c06SLawrence Mitchell 
841411c6eeSJed Brown   *dm = v;
85a4121054SBarry Smith   PetscFunctionReturn(0);
86a4121054SBarry Smith }
87a4121054SBarry Smith 
8838221697SMatthew G. Knepley /*@
8938221697SMatthew G. Knepley   DMClone - Creates a DM object with the same topology as the original.
9038221697SMatthew G. Knepley 
91d083f849SBarry Smith   Collective
9238221697SMatthew G. Knepley 
9338221697SMatthew G. Knepley   Input Parameter:
9438221697SMatthew G. Knepley . dm - The original DM object
9538221697SMatthew G. Knepley 
9638221697SMatthew G. Knepley   Output Parameter:
9738221697SMatthew G. Knepley . newdm  - The new DM object
9838221697SMatthew G. Knepley 
9938221697SMatthew G. Knepley   Level: beginner
10038221697SMatthew G. Knepley 
1011bb6d2a8SBarry Smith   Notes: For some DM this is a shallow clone, the result of which may share (referent counted) information with its parent. For example,
1021bb6d2a8SBarry Smith          DMClone() applied to a DMPLEX object will result in a new DMPLEX that shares the topology with the original DMPLEX. It does
1031bb6d2a8SBarry Smith          share the PetscSection of the original DM
1041bb6d2a8SBarry Smith 
1051bb6d2a8SBarry Smith .seealso: DMDestry(), DMCreate(), DMSetType(), DMSetLocalSection(), DMSetGlobalSection()
1061bb6d2a8SBarry Smith 
10738221697SMatthew G. Knepley @*/
10838221697SMatthew G. Knepley PetscErrorCode DMClone(DM dm, DM *newdm)
10938221697SMatthew G. Knepley {
11038221697SMatthew G. Knepley   PetscSF        sf;
11138221697SMatthew G. Knepley   Vec            coords;
11238221697SMatthew G. Knepley   void          *ctx;
113a3219837SMatthew G. Knepley   PetscInt       dim, cdim;
11438221697SMatthew G. Knepley   PetscErrorCode ierr;
11538221697SMatthew G. Knepley 
11638221697SMatthew G. Knepley   PetscFunctionBegin;
11738221697SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
11838221697SMatthew G. Knepley   PetscValidPointer(newdm,2);
11938221697SMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject) dm), newdm);CHKERRQ(ierr);
1205d80c0bfSVaclav Hapla   ierr = DMCopyLabels(dm, *newdm, PETSC_COPY_VALUES, PETSC_TRUE);CHKERRQ(ierr);
121ddf8437dSMatthew G. Knepley   (*newdm)->leveldown  = dm->leveldown;
122ddf8437dSMatthew G. Knepley   (*newdm)->levelup    = dm->levelup;
1231de53e9aSMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
1241de53e9aSMatthew G. Knepley   ierr = DMSetDimension(*newdm, dim);CHKERRQ(ierr);
12538221697SMatthew G. Knepley   if (dm->ops->clone) {
12638221697SMatthew G. Knepley     ierr = (*dm->ops->clone)(dm, newdm);CHKERRQ(ierr);
12738221697SMatthew G. Knepley   }
1283f22bcbcSToby Isaac   (*newdm)->setupcalled = dm->setupcalled;
12938221697SMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
13038221697SMatthew G. Knepley   ierr = DMSetPointSF(*newdm, sf);CHKERRQ(ierr);
13138221697SMatthew G. Knepley   ierr = DMGetApplicationContext(dm, &ctx);CHKERRQ(ierr);
13238221697SMatthew G. Knepley   ierr = DMSetApplicationContext(*newdm, ctx);CHKERRQ(ierr);
133be4c1c3eSMatthew G. Knepley   if (dm->coordinateDM) {
134be4c1c3eSMatthew G. Knepley     DM           ncdm;
135be4c1c3eSMatthew G. Knepley     PetscSection cs;
1365a0206caSToby Isaac     PetscInt     pEnd = -1, pEndMax = -1;
137be4c1c3eSMatthew G. Knepley 
13892fd8e1eSJed Brown     ierr = DMGetLocalSection(dm->coordinateDM, &cs);CHKERRQ(ierr);
139be4c1c3eSMatthew G. Knepley     if (cs) {ierr = PetscSectionGetChart(cs, NULL, &pEnd);CHKERRQ(ierr);}
1405a0206caSToby Isaac     ierr = MPI_Allreduce(&pEnd,&pEndMax,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
1415a0206caSToby Isaac     if (pEndMax >= 0) {
142be4c1c3eSMatthew G. Knepley       ierr = DMClone(dm->coordinateDM, &ncdm);CHKERRQ(ierr);
14383bfc06fSMatthew Knepley       ierr = DMCopyDisc(dm->coordinateDM, ncdm);CHKERRQ(ierr);
14492fd8e1eSJed Brown       ierr = DMSetLocalSection(ncdm, cs);CHKERRQ(ierr);
145a61e840bSMatthew G. Knepley       ierr = DMSetCoordinateDM(*newdm, ncdm);CHKERRQ(ierr);
146be4c1c3eSMatthew G. Knepley       ierr = DMDestroy(&ncdm);CHKERRQ(ierr);
147be4c1c3eSMatthew G. Knepley     }
148be4c1c3eSMatthew G. Knepley   }
149a3219837SMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
150a3219837SMatthew G. Knepley   ierr = DMSetCoordinateDim(*newdm, cdim);CHKERRQ(ierr);
15138221697SMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coords);CHKERRQ(ierr);
15238221697SMatthew G. Knepley   if (coords) {
15338221697SMatthew G. Knepley     ierr = DMSetCoordinatesLocal(*newdm, coords);CHKERRQ(ierr);
15438221697SMatthew G. Knepley   } else {
15538221697SMatthew G. Knepley     ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr);
15638221697SMatthew G. Knepley     if (coords) {ierr = DMSetCoordinates(*newdm, coords);CHKERRQ(ierr);}
15738221697SMatthew G. Knepley   }
15890b157c4SStefano Zampini   {
15990b157c4SStefano Zampini     PetscBool             isper;
160c6b900c6SMatthew G. Knepley     const PetscReal      *maxCell, *L;
1615dc8c3f7SMatthew G. Knepley     const DMBoundaryType *bd;
16290b157c4SStefano Zampini     ierr = DMGetPeriodicity(dm, &isper, &maxCell, &L, &bd);CHKERRQ(ierr);
16390b157c4SStefano Zampini     ierr = DMSetPeriodicity(*newdm, isper, maxCell,  L,  bd);CHKERRQ(ierr);
164c6b900c6SMatthew G. Knepley   }
16534aa8a36SMatthew G. Knepley   {
16634aa8a36SMatthew G. Knepley     PetscBool useCone, useClosure;
16734aa8a36SMatthew G. Knepley 
16834aa8a36SMatthew G. Knepley     ierr = DMGetAdjacency(dm, PETSC_DEFAULT, &useCone, &useClosure);CHKERRQ(ierr);
16934aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(*newdm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr);
17034aa8a36SMatthew G. Knepley   }
17138221697SMatthew G. Knepley   PetscFunctionReturn(0);
17238221697SMatthew G. Knepley }
17338221697SMatthew G. Knepley 
1749a42bb27SBarry Smith /*@C
175564755cdSBarry Smith        DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
1769a42bb27SBarry Smith 
177d083f849SBarry Smith    Logically Collective on da
1789a42bb27SBarry Smith 
1799a42bb27SBarry Smith    Input Parameter:
1809a42bb27SBarry Smith +  da - initial distributed array
181e9e886b6SKarl Rupp .  ctype - the vector type, currently either VECSTANDARD, VECCUDA, or VECVIENNACL
1829a42bb27SBarry Smith 
1839a42bb27SBarry Smith    Options Database:
184dd85299cSBarry Smith .   -dm_vec_type ctype
1859a42bb27SBarry Smith 
1869a42bb27SBarry Smith    Level: intermediate
1879a42bb27SBarry Smith 
188a2a9ebe5SBarry Smith .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType, DMGetVecType(), DMSetMatType(), DMGetMatType()
1899a42bb27SBarry Smith @*/
19019fd82e9SBarry Smith PetscErrorCode  DMSetVecType(DM da,VecType ctype)
1919a42bb27SBarry Smith {
1929a42bb27SBarry Smith   PetscErrorCode ierr;
1939a42bb27SBarry Smith 
1949a42bb27SBarry Smith   PetscFunctionBegin;
1959a42bb27SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
1969a42bb27SBarry Smith   ierr = PetscFree(da->vectype);CHKERRQ(ierr);
19719fd82e9SBarry Smith   ierr = PetscStrallocpy(ctype,(char**)&da->vectype);CHKERRQ(ierr);
1989a42bb27SBarry Smith   PetscFunctionReturn(0);
1999a42bb27SBarry Smith }
2009a42bb27SBarry Smith 
201c0dedaeaSBarry Smith /*@C
202c0dedaeaSBarry Smith        DMGetVecType - Gets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
203c0dedaeaSBarry Smith 
204d083f849SBarry Smith    Logically Collective on da
205c0dedaeaSBarry Smith 
206c0dedaeaSBarry Smith    Input Parameter:
207c0dedaeaSBarry Smith .  da - initial distributed array
208c0dedaeaSBarry Smith 
209c0dedaeaSBarry Smith    Output Parameter:
210c0dedaeaSBarry Smith .  ctype - the vector type
211c0dedaeaSBarry Smith 
212c0dedaeaSBarry Smith    Level: intermediate
213c0dedaeaSBarry Smith 
214a2a9ebe5SBarry Smith .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType, DMSetMatType(), DMGetMatType(), DMSetVecType()
215c0dedaeaSBarry Smith @*/
216c0dedaeaSBarry Smith PetscErrorCode  DMGetVecType(DM da,VecType *ctype)
217c0dedaeaSBarry Smith {
218c0dedaeaSBarry Smith   PetscFunctionBegin;
219c0dedaeaSBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
220c0dedaeaSBarry Smith   *ctype = da->vectype;
221c0dedaeaSBarry Smith   PetscFunctionReturn(0);
222c0dedaeaSBarry Smith }
223c0dedaeaSBarry Smith 
2245f1ad066SMatthew G Knepley /*@
22534f98d34SBarry Smith   VecGetDM - Gets the DM defining the data layout of the vector
2265f1ad066SMatthew G Knepley 
2275f1ad066SMatthew G Knepley   Not collective
2285f1ad066SMatthew G Knepley 
2295f1ad066SMatthew G Knepley   Input Parameter:
2305f1ad066SMatthew G Knepley . v - The Vec
2315f1ad066SMatthew G Knepley 
2325f1ad066SMatthew G Knepley   Output Parameter:
2335f1ad066SMatthew G Knepley . dm - The DM
2345f1ad066SMatthew G Knepley 
2355f1ad066SMatthew G Knepley   Level: intermediate
2365f1ad066SMatthew G Knepley 
2375f1ad066SMatthew G Knepley .seealso: VecSetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType()
2385f1ad066SMatthew G Knepley @*/
2395f1ad066SMatthew G Knepley PetscErrorCode VecGetDM(Vec v, DM *dm)
2405f1ad066SMatthew G Knepley {
2415f1ad066SMatthew G Knepley   PetscErrorCode ierr;
2425f1ad066SMatthew G Knepley 
2435f1ad066SMatthew G Knepley   PetscFunctionBegin;
2445f1ad066SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,1);
2455f1ad066SMatthew G Knepley   PetscValidPointer(dm,2);
2465f1ad066SMatthew G Knepley   ierr = PetscObjectQuery((PetscObject) v, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr);
2475f1ad066SMatthew G Knepley   PetscFunctionReturn(0);
2485f1ad066SMatthew G Knepley }
2495f1ad066SMatthew G Knepley 
2505f1ad066SMatthew G Knepley /*@
251d9805387SMatthew G. Knepley   VecSetDM - Sets the DM defining the data layout of the vector.
2525f1ad066SMatthew G Knepley 
2535f1ad066SMatthew G Knepley   Not collective
2545f1ad066SMatthew G Knepley 
2555f1ad066SMatthew G Knepley   Input Parameters:
2565f1ad066SMatthew G Knepley + v - The Vec
2575f1ad066SMatthew G Knepley - dm - The DM
2585f1ad066SMatthew G Knepley 
259d9805387SMatthew G. Knepley   Note: This is NOT the same as DMCreateGlobalVector() since it does not change the view methods or perform other customization, but merely sets the DM member.
260d9805387SMatthew G. Knepley 
2615f1ad066SMatthew G Knepley   Level: intermediate
2625f1ad066SMatthew G Knepley 
2635f1ad066SMatthew G Knepley .seealso: VecGetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType()
2645f1ad066SMatthew G Knepley @*/
2655f1ad066SMatthew G Knepley PetscErrorCode VecSetDM(Vec v, DM dm)
2665f1ad066SMatthew G Knepley {
2675f1ad066SMatthew G Knepley   PetscErrorCode ierr;
2685f1ad066SMatthew G Knepley 
2695f1ad066SMatthew G Knepley   PetscFunctionBegin;
2705f1ad066SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,1);
271d7f50e27SLisandro Dalcin   if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2);
2725f1ad066SMatthew G Knepley   ierr = PetscObjectCompose((PetscObject) v, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
2735f1ad066SMatthew G Knepley   PetscFunctionReturn(0);
2745f1ad066SMatthew G Knepley }
2755f1ad066SMatthew G Knepley 
276521d9a4cSLisandro Dalcin /*@C
2778f1509bcSBarry Smith        DMSetISColoringType - Sets the type of coloring, global or local, that is created by the DM
2788f1509bcSBarry Smith 
279d083f849SBarry Smith    Logically Collective on dm
2808f1509bcSBarry Smith 
2818f1509bcSBarry Smith    Input Parameters:
2828f1509bcSBarry Smith +  dm - the DM context
2838f1509bcSBarry Smith -  ctype - the matrix type
2848f1509bcSBarry Smith 
2858f1509bcSBarry Smith    Options Database:
2868f1509bcSBarry Smith .   -dm_is_coloring_type - global or local
2878f1509bcSBarry Smith 
2888f1509bcSBarry Smith    Level: intermediate
2898f1509bcSBarry Smith 
2908f1509bcSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(),
2918f1509bcSBarry Smith           DMGetISColoringType()
2928f1509bcSBarry Smith @*/
2938f1509bcSBarry Smith PetscErrorCode  DMSetISColoringType(DM dm,ISColoringType ctype)
2948f1509bcSBarry Smith {
2958f1509bcSBarry Smith   PetscFunctionBegin;
2968f1509bcSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2978f1509bcSBarry Smith   dm->coloringtype = ctype;
2988f1509bcSBarry Smith   PetscFunctionReturn(0);
2998f1509bcSBarry Smith }
3008f1509bcSBarry Smith 
3018f1509bcSBarry Smith /*@C
3028f1509bcSBarry Smith        DMGetISColoringType - Gets the type of coloring, global or local, that is created by the DM
303521d9a4cSLisandro Dalcin 
304d083f849SBarry Smith    Logically Collective on dm
305521d9a4cSLisandro Dalcin 
306521d9a4cSLisandro Dalcin    Input Parameter:
3078f1509bcSBarry Smith .  dm - the DM context
3088f1509bcSBarry Smith 
3098f1509bcSBarry Smith    Output Parameter:
3108f1509bcSBarry Smith .  ctype - the matrix type
3118f1509bcSBarry Smith 
3128f1509bcSBarry Smith    Options Database:
3138f1509bcSBarry Smith .   -dm_is_coloring_type - global or local
3148f1509bcSBarry Smith 
3158f1509bcSBarry Smith    Level: intermediate
3168f1509bcSBarry Smith 
3178f1509bcSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(),
3188f1509bcSBarry Smith           DMGetISColoringType()
3198f1509bcSBarry Smith @*/
3208f1509bcSBarry Smith PetscErrorCode  DMGetISColoringType(DM dm,ISColoringType *ctype)
3218f1509bcSBarry Smith {
3228f1509bcSBarry Smith   PetscFunctionBegin;
3238f1509bcSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3248f1509bcSBarry Smith   *ctype = dm->coloringtype;
3258f1509bcSBarry Smith   PetscFunctionReturn(0);
3268f1509bcSBarry Smith }
3278f1509bcSBarry Smith 
3288f1509bcSBarry Smith /*@C
3298f1509bcSBarry Smith        DMSetMatType - Sets the type of matrix created with DMCreateMatrix()
3308f1509bcSBarry Smith 
331d083f849SBarry Smith    Logically Collective on dm
3328f1509bcSBarry Smith 
3338f1509bcSBarry Smith    Input Parameters:
334521d9a4cSLisandro Dalcin +  dm - the DM context
335a2b5a043SBarry Smith -  ctype - the matrix type
336521d9a4cSLisandro Dalcin 
337521d9a4cSLisandro Dalcin    Options Database:
338521d9a4cSLisandro Dalcin .   -dm_mat_type ctype
339521d9a4cSLisandro Dalcin 
340521d9a4cSLisandro Dalcin    Level: intermediate
341521d9a4cSLisandro Dalcin 
342a2a9ebe5SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(), DMSetMatType(), DMGetMatType()
343521d9a4cSLisandro Dalcin @*/
34419fd82e9SBarry Smith PetscErrorCode  DMSetMatType(DM dm,MatType ctype)
345521d9a4cSLisandro Dalcin {
346521d9a4cSLisandro Dalcin   PetscErrorCode ierr;
34788f0584fSBarry Smith 
348521d9a4cSLisandro Dalcin   PetscFunctionBegin;
349521d9a4cSLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
350521d9a4cSLisandro Dalcin   ierr = PetscFree(dm->mattype);CHKERRQ(ierr);
35119fd82e9SBarry Smith   ierr = PetscStrallocpy(ctype,(char**)&dm->mattype);CHKERRQ(ierr);
352521d9a4cSLisandro Dalcin   PetscFunctionReturn(0);
353521d9a4cSLisandro Dalcin }
354521d9a4cSLisandro Dalcin 
355c0dedaeaSBarry Smith /*@C
356c0dedaeaSBarry Smith        DMGetMatType - Gets the type of matrix created with DMCreateMatrix()
357c0dedaeaSBarry Smith 
358d083f849SBarry Smith    Logically Collective on dm
359c0dedaeaSBarry Smith 
360c0dedaeaSBarry Smith    Input Parameter:
361c0dedaeaSBarry Smith .  dm - the DM context
362c0dedaeaSBarry Smith 
363c0dedaeaSBarry Smith    Output Parameter:
364c0dedaeaSBarry Smith .  ctype - the matrix type
365c0dedaeaSBarry Smith 
366c0dedaeaSBarry Smith    Options Database:
367c0dedaeaSBarry Smith .   -dm_mat_type ctype
368c0dedaeaSBarry Smith 
369c0dedaeaSBarry Smith    Level: intermediate
370c0dedaeaSBarry Smith 
371a2a9ebe5SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMSetMatType(), DMSetMatType(), DMGetMatType()
372c0dedaeaSBarry Smith @*/
373c0dedaeaSBarry Smith PetscErrorCode  DMGetMatType(DM dm,MatType *ctype)
374c0dedaeaSBarry Smith {
375c0dedaeaSBarry Smith   PetscFunctionBegin;
376c0dedaeaSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
377c0dedaeaSBarry Smith   *ctype = dm->mattype;
378c0dedaeaSBarry Smith   PetscFunctionReturn(0);
379c0dedaeaSBarry Smith }
380c0dedaeaSBarry Smith 
381c688c046SMatthew G Knepley /*@
38234f98d34SBarry Smith   MatGetDM - Gets the DM defining the data layout of the matrix
383c688c046SMatthew G Knepley 
384c688c046SMatthew G Knepley   Not collective
385c688c046SMatthew G Knepley 
386c688c046SMatthew G Knepley   Input Parameter:
387c688c046SMatthew G Knepley . A - The Mat
388c688c046SMatthew G Knepley 
389c688c046SMatthew G Knepley   Output Parameter:
390c688c046SMatthew G Knepley . dm - The DM
391c688c046SMatthew G Knepley 
392c688c046SMatthew G Knepley   Level: intermediate
393c688c046SMatthew G Knepley 
3948f1509bcSBarry Smith   Developer Note: Since the Mat class doesn't know about the DM class the DM object is associated with
3958f1509bcSBarry Smith                   the Mat through a PetscObjectCompose() operation
3968f1509bcSBarry Smith 
397c688c046SMatthew G Knepley .seealso: MatSetDM(), DMCreateMatrix(), DMSetMatType()
398c688c046SMatthew G Knepley @*/
399c688c046SMatthew G Knepley PetscErrorCode MatGetDM(Mat A, DM *dm)
400c688c046SMatthew G Knepley {
401c688c046SMatthew G Knepley   PetscErrorCode ierr;
402c688c046SMatthew G Knepley 
403c688c046SMatthew G Knepley   PetscFunctionBegin;
404c688c046SMatthew G Knepley   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
405c688c046SMatthew G Knepley   PetscValidPointer(dm,2);
406c688c046SMatthew G Knepley   ierr = PetscObjectQuery((PetscObject) A, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr);
407c688c046SMatthew G Knepley   PetscFunctionReturn(0);
408c688c046SMatthew G Knepley }
409c688c046SMatthew G Knepley 
410c688c046SMatthew G Knepley /*@
411c688c046SMatthew G Knepley   MatSetDM - Sets the DM defining the data layout of the matrix
412c688c046SMatthew G Knepley 
413c688c046SMatthew G Knepley   Not collective
414c688c046SMatthew G Knepley 
415c688c046SMatthew G Knepley   Input Parameters:
416c688c046SMatthew G Knepley + A - The Mat
417c688c046SMatthew G Knepley - dm - The DM
418c688c046SMatthew G Knepley 
419c688c046SMatthew G Knepley   Level: intermediate
420c688c046SMatthew G Knepley 
4218f1509bcSBarry Smith   Developer Note: Since the Mat class doesn't know about the DM class the DM object is associated with
4228f1509bcSBarry Smith                   the Mat through a PetscObjectCompose() operation
4238f1509bcSBarry Smith 
4248f1509bcSBarry Smith 
425c688c046SMatthew G Knepley .seealso: MatGetDM(), DMCreateMatrix(), DMSetMatType()
426c688c046SMatthew G Knepley @*/
427c688c046SMatthew G Knepley PetscErrorCode MatSetDM(Mat A, DM dm)
428c688c046SMatthew G Knepley {
429c688c046SMatthew G Knepley   PetscErrorCode ierr;
430c688c046SMatthew G Knepley 
431c688c046SMatthew G Knepley   PetscFunctionBegin;
432c688c046SMatthew G Knepley   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4338865f1eaSKarl Rupp   if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2);
434c688c046SMatthew G Knepley   ierr = PetscObjectCompose((PetscObject) A, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
435c688c046SMatthew G Knepley   PetscFunctionReturn(0);
436c688c046SMatthew G Knepley }
437c688c046SMatthew G Knepley 
4389a42bb27SBarry Smith /*@C
4399a42bb27SBarry Smith    DMSetOptionsPrefix - Sets the prefix used for searching for all
4406757b960SDave May    DM options in the database.
4419a42bb27SBarry Smith 
442d083f849SBarry Smith    Logically Collective on dm
4439a42bb27SBarry Smith 
4449a42bb27SBarry Smith    Input Parameter:
4458353ddbbSDave May +  da - the DM context
4469a42bb27SBarry Smith -  prefix - the prefix to prepend to all option names
4479a42bb27SBarry Smith 
4489a42bb27SBarry Smith    Notes:
4499a42bb27SBarry Smith    A hyphen (-) must NOT be given at the beginning of the prefix name.
4509a42bb27SBarry Smith    The first character of all runtime options is AUTOMATICALLY the hyphen.
4519a42bb27SBarry Smith 
4529a42bb27SBarry Smith    Level: advanced
4539a42bb27SBarry Smith 
4549a42bb27SBarry Smith .seealso: DMSetFromOptions()
4559a42bb27SBarry Smith @*/
4567087cfbeSBarry Smith PetscErrorCode  DMSetOptionsPrefix(DM dm,const char prefix[])
4579a42bb27SBarry Smith {
4589a42bb27SBarry Smith   PetscErrorCode ierr;
4599a42bb27SBarry Smith 
4609a42bb27SBarry Smith   PetscFunctionBegin;
4619a42bb27SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4629a42bb27SBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
463691be533SLawrence Mitchell   if (dm->sf) {
464691be533SLawrence Mitchell     ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->sf,prefix);CHKERRQ(ierr);
465691be533SLawrence Mitchell   }
4661bb6d2a8SBarry Smith   if (dm->sectionSF) {
4671bb6d2a8SBarry Smith     ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->sectionSF,prefix);CHKERRQ(ierr);
468691be533SLawrence Mitchell   }
4699a42bb27SBarry Smith   PetscFunctionReturn(0);
4709a42bb27SBarry Smith }
4719a42bb27SBarry Smith 
47231697293SDave May /*@C
47331697293SDave May    DMAppendOptionsPrefix - Appends to the prefix used for searching for all
47431697293SDave May    DM options in the database.
47531697293SDave May 
476d083f849SBarry Smith    Logically Collective on dm
47731697293SDave May 
47831697293SDave May    Input Parameters:
47931697293SDave May +  dm - the DM context
48031697293SDave May -  prefix - the prefix string to prepend to all DM option requests
48131697293SDave May 
48231697293SDave May    Notes:
48331697293SDave May    A hyphen (-) must NOT be given at the beginning of the prefix name.
48431697293SDave May    The first character of all runtime options is AUTOMATICALLY the hyphen.
48531697293SDave May 
48631697293SDave May    Level: advanced
48731697293SDave May 
48831697293SDave May .seealso: DMSetOptionsPrefix(), DMGetOptionsPrefix()
48931697293SDave May @*/
49031697293SDave May PetscErrorCode  DMAppendOptionsPrefix(DM dm,const char prefix[])
49131697293SDave May {
49231697293SDave May   PetscErrorCode ierr;
49331697293SDave May 
49431697293SDave May   PetscFunctionBegin;
49531697293SDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
49631697293SDave May   ierr = PetscObjectAppendOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
49731697293SDave May   PetscFunctionReturn(0);
49831697293SDave May }
49931697293SDave May 
50031697293SDave May /*@C
50131697293SDave May    DMGetOptionsPrefix - Gets the prefix used for searching for all
50231697293SDave May    DM options in the database.
50331697293SDave May 
50431697293SDave May    Not Collective
50531697293SDave May 
50631697293SDave May    Input Parameters:
50731697293SDave May .  dm - the DM context
50831697293SDave May 
50931697293SDave May    Output Parameters:
51031697293SDave May .  prefix - pointer to the prefix string used is returned
51131697293SDave May 
51295452b02SPatrick Sanan    Notes:
51395452b02SPatrick Sanan     On the fortran side, the user should pass in a string 'prefix' of
51431697293SDave May    sufficient length to hold the prefix.
51531697293SDave May 
51631697293SDave May    Level: advanced
51731697293SDave May 
51831697293SDave May .seealso: DMSetOptionsPrefix(), DMAppendOptionsPrefix()
51931697293SDave May @*/
52031697293SDave May PetscErrorCode  DMGetOptionsPrefix(DM dm,const char *prefix[])
52131697293SDave May {
52231697293SDave May   PetscErrorCode ierr;
52331697293SDave May 
52431697293SDave May   PetscFunctionBegin;
52531697293SDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
52631697293SDave May   ierr = PetscObjectGetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
52731697293SDave May   PetscFunctionReturn(0);
52831697293SDave May }
52931697293SDave May 
53088bdff64SToby Isaac static PetscErrorCode DMCountNonCyclicReferences(DM dm, PetscBool recurseCoarse, PetscBool recurseFine, PetscInt *ncrefct)
53188bdff64SToby Isaac {
53288bdff64SToby Isaac   PetscInt i, refct = ((PetscObject) dm)->refct;
53388bdff64SToby Isaac   DMNamedVecLink nlink;
53488bdff64SToby Isaac   PetscErrorCode ierr;
53588bdff64SToby Isaac 
53688bdff64SToby Isaac   PetscFunctionBegin;
537aab5bcd8SJed Brown   *ncrefct = 0;
53888bdff64SToby Isaac   /* count all the circular references of DM and its contained Vecs */
53988bdff64SToby Isaac   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
54088bdff64SToby Isaac     if (dm->localin[i])  refct--;
54188bdff64SToby Isaac     if (dm->globalin[i]) refct--;
54288bdff64SToby Isaac   }
54388bdff64SToby Isaac   for (nlink=dm->namedglobal; nlink; nlink=nlink->next) refct--;
54488bdff64SToby Isaac   for (nlink=dm->namedlocal; nlink; nlink=nlink->next) refct--;
54588bdff64SToby Isaac   if (dm->x) {
54688bdff64SToby Isaac     DM obj;
54788bdff64SToby Isaac     ierr = VecGetDM(dm->x, &obj);CHKERRQ(ierr);
54888bdff64SToby Isaac     if (obj == dm) refct--;
54988bdff64SToby Isaac   }
55088bdff64SToby Isaac   if (dm->coarseMesh && dm->coarseMesh->fineMesh == dm) {
55188bdff64SToby Isaac     refct--;
55288bdff64SToby Isaac     if (recurseCoarse) {
55388bdff64SToby Isaac       PetscInt coarseCount;
55488bdff64SToby Isaac 
55588bdff64SToby Isaac       ierr = DMCountNonCyclicReferences(dm->coarseMesh, PETSC_TRUE, PETSC_FALSE,&coarseCount);CHKERRQ(ierr);
55688bdff64SToby Isaac       refct += coarseCount;
55788bdff64SToby Isaac     }
55888bdff64SToby Isaac   }
55988bdff64SToby Isaac   if (dm->fineMesh && dm->fineMesh->coarseMesh == dm) {
56088bdff64SToby Isaac     refct--;
56188bdff64SToby Isaac     if (recurseFine) {
56288bdff64SToby Isaac       PetscInt fineCount;
56388bdff64SToby Isaac 
56488bdff64SToby Isaac       ierr = DMCountNonCyclicReferences(dm->fineMesh, PETSC_FALSE, PETSC_TRUE,&fineCount);CHKERRQ(ierr);
56588bdff64SToby Isaac       refct += fineCount;
56688bdff64SToby Isaac     }
56788bdff64SToby Isaac   }
56888bdff64SToby Isaac   *ncrefct = refct;
56988bdff64SToby Isaac   PetscFunctionReturn(0);
57088bdff64SToby Isaac }
57188bdff64SToby Isaac 
572f4cdcedcSVaclav Hapla PetscErrorCode DMDestroyLabelLinkList_Internal(DM dm)
573354557abSToby Isaac {
5745d80c0bfSVaclav Hapla   DMLabelLink    next = dm->labels;
575354557abSToby Isaac   PetscErrorCode ierr;
576354557abSToby Isaac 
577354557abSToby Isaac   PetscFunctionBegin;
578354557abSToby Isaac   /* destroy the labels */
579354557abSToby Isaac   while (next) {
580354557abSToby Isaac     DMLabelLink tmp = next->next;
581354557abSToby Isaac 
5825d80c0bfSVaclav Hapla     if (next->label == dm->depthLabel) dm->depthLabel = NULL;
583354557abSToby Isaac     ierr = DMLabelDestroy(&next->label);CHKERRQ(ierr);
584354557abSToby Isaac     ierr = PetscFree(next);CHKERRQ(ierr);
585354557abSToby Isaac     next = tmp;
586354557abSToby Isaac   }
5875d80c0bfSVaclav Hapla   dm->labels = NULL;
588354557abSToby Isaac   PetscFunctionReturn(0);
589354557abSToby Isaac }
590354557abSToby Isaac 
59147c6ae99SBarry Smith /*@
5928472ad0fSDave May     DMDestroy - Destroys a vector packer or DM.
59347c6ae99SBarry Smith 
594d083f849SBarry Smith     Collective on dm
59547c6ae99SBarry Smith 
59647c6ae99SBarry Smith     Input Parameter:
59747c6ae99SBarry Smith .   dm - the DM object to destroy
59847c6ae99SBarry Smith 
59947c6ae99SBarry Smith     Level: developer
60047c6ae99SBarry Smith 
601e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
60247c6ae99SBarry Smith 
60347c6ae99SBarry Smith @*/
604fcfd50ebSBarry Smith PetscErrorCode  DMDestroy(DM *dm)
60547c6ae99SBarry Smith {
60688bdff64SToby Isaac   PetscInt       i, cnt;
607dfe15315SJed Brown   DMNamedVecLink nlink,nnext;
60847c6ae99SBarry Smith   PetscErrorCode ierr;
60947c6ae99SBarry Smith 
61047c6ae99SBarry Smith   PetscFunctionBegin;
6116bf464f9SBarry Smith   if (!*dm) PetscFunctionReturn(0);
6126bf464f9SBarry Smith   PetscValidHeaderSpecific((*dm),DM_CLASSID,1);
61387e657c6SBarry Smith 
61488bdff64SToby Isaac   /* count all non-cyclic references in the doubly-linked list of coarse<->fine meshes */
61588bdff64SToby Isaac   ierr = DMCountNonCyclicReferences(*dm,PETSC_TRUE,PETSC_TRUE,&cnt);CHKERRQ(ierr);
61688bdff64SToby Isaac   --((PetscObject)(*dm))->refct;
61788bdff64SToby Isaac   if (--cnt > 0) {*dm = 0; PetscFunctionReturn(0);}
618732e2eb9SMatthew G Knepley   /*
619732e2eb9SMatthew G Knepley      Need this test because the dm references the vectors that
620732e2eb9SMatthew G Knepley      reference the dm, so destroying the dm calls destroy on the
621732e2eb9SMatthew G Knepley      vectors that cause another destroy on the dm
622732e2eb9SMatthew G Knepley   */
6236bf464f9SBarry Smith   if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0);
6246bf464f9SBarry Smith   ((PetscObject) (*dm))->refct = 0;
625732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
6266bf464f9SBarry Smith     if ((*dm)->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Destroying a DM that has a local vector obtained with DMGetLocalVector()");
6276bf464f9SBarry Smith     ierr = VecDestroy(&(*dm)->localin[i]);CHKERRQ(ierr);
628732e2eb9SMatthew G Knepley   }
629f490541aSPeter Brune   nnext=(*dm)->namedglobal;
6300298fd71SBarry Smith   (*dm)->namedglobal = NULL;
631f490541aSPeter Brune   for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named vectors */
6322348bcf4SPeter Brune     nnext = nlink->next;
6332348bcf4SPeter Brune     if (nlink->status != DMVEC_STATUS_IN) SETERRQ1(((PetscObject)*dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"DM still has Vec named '%s' checked out",nlink->name);
6342348bcf4SPeter Brune     ierr = PetscFree(nlink->name);CHKERRQ(ierr);
6352348bcf4SPeter Brune     ierr = VecDestroy(&nlink->X);CHKERRQ(ierr);
6362348bcf4SPeter Brune     ierr = PetscFree(nlink);CHKERRQ(ierr);
6372348bcf4SPeter Brune   }
638f490541aSPeter Brune   nnext=(*dm)->namedlocal;
6390298fd71SBarry Smith   (*dm)->namedlocal = NULL;
640f490541aSPeter Brune   for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named local vectors */
641f490541aSPeter Brune     nnext = nlink->next;
642f490541aSPeter Brune     if (nlink->status != DMVEC_STATUS_IN) SETERRQ1(((PetscObject)*dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"DM still has Vec named '%s' checked out",nlink->name);
643f490541aSPeter Brune     ierr = PetscFree(nlink->name);CHKERRQ(ierr);
644f490541aSPeter Brune     ierr = VecDestroy(&nlink->X);CHKERRQ(ierr);
645f490541aSPeter Brune     ierr = PetscFree(nlink);CHKERRQ(ierr);
646f490541aSPeter Brune   }
6472348bcf4SPeter Brune 
648b17ce1afSJed Brown   /* Destroy the list of hooks */
649c833c3b5SJed Brown   {
650c833c3b5SJed Brown     DMCoarsenHookLink link,next;
651b17ce1afSJed Brown     for (link=(*dm)->coarsenhook; link; link=next) {
652b17ce1afSJed Brown       next = link->next;
653b17ce1afSJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
654b17ce1afSJed Brown     }
6550298fd71SBarry Smith     (*dm)->coarsenhook = NULL;
656c833c3b5SJed Brown   }
657c833c3b5SJed Brown   {
658c833c3b5SJed Brown     DMRefineHookLink link,next;
659c833c3b5SJed Brown     for (link=(*dm)->refinehook; link; link=next) {
660c833c3b5SJed Brown       next = link->next;
661c833c3b5SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
662c833c3b5SJed Brown     }
6630298fd71SBarry Smith     (*dm)->refinehook = NULL;
664c833c3b5SJed Brown   }
665be081cd6SPeter Brune   {
666be081cd6SPeter Brune     DMSubDomainHookLink link,next;
667be081cd6SPeter Brune     for (link=(*dm)->subdomainhook; link; link=next) {
668be081cd6SPeter Brune       next = link->next;
669be081cd6SPeter Brune       ierr = PetscFree(link);CHKERRQ(ierr);
670be081cd6SPeter Brune     }
6710298fd71SBarry Smith     (*dm)->subdomainhook = NULL;
672be081cd6SPeter Brune   }
673baf369e7SPeter Brune   {
674baf369e7SPeter Brune     DMGlobalToLocalHookLink link,next;
675baf369e7SPeter Brune     for (link=(*dm)->gtolhook; link; link=next) {
676baf369e7SPeter Brune       next = link->next;
677baf369e7SPeter Brune       ierr = PetscFree(link);CHKERRQ(ierr);
678baf369e7SPeter Brune     }
6790298fd71SBarry Smith     (*dm)->gtolhook = NULL;
680baf369e7SPeter Brune   }
681d4d07f1eSToby Isaac   {
682d4d07f1eSToby Isaac     DMLocalToGlobalHookLink link,next;
683d4d07f1eSToby Isaac     for (link=(*dm)->ltoghook; link; link=next) {
684d4d07f1eSToby Isaac       next = link->next;
685d4d07f1eSToby Isaac       ierr = PetscFree(link);CHKERRQ(ierr);
686d4d07f1eSToby Isaac     }
687d4d07f1eSToby Isaac     (*dm)->ltoghook = NULL;
688d4d07f1eSToby Isaac   }
689aa1993deSMatthew G Knepley   /* Destroy the work arrays */
690aa1993deSMatthew G Knepley   {
691aa1993deSMatthew G Knepley     DMWorkLink link,next;
692aa1993deSMatthew G Knepley     if ((*dm)->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Work array still checked out");
693aa1993deSMatthew G Knepley     for (link=(*dm)->workin; link; link=next) {
694aa1993deSMatthew G Knepley       next = link->next;
695aa1993deSMatthew G Knepley       ierr = PetscFree(link->mem);CHKERRQ(ierr);
696aa1993deSMatthew G Knepley       ierr = PetscFree(link);CHKERRQ(ierr);
697aa1993deSMatthew G Knepley     }
6980298fd71SBarry Smith     (*dm)->workin = NULL;
699aa1993deSMatthew G Knepley   }
700c58f1c22SToby Isaac   /* destroy the labels */
701f4cdcedcSVaclav Hapla   ierr = DMDestroyLabelLinkList_Internal(*dm);CHKERRQ(ierr);
702f4cdcedcSVaclav Hapla   /* destroy the fields */
703e5e52638SMatthew G. Knepley   ierr = DMClearFields(*dm);CHKERRQ(ierr);
704f4cdcedcSVaclav Hapla   /* destroy the boundaries */
705e6f8dbb6SToby Isaac   {
706e6f8dbb6SToby Isaac     DMBoundary next = (*dm)->boundary;
707e6f8dbb6SToby Isaac     while (next) {
708e6f8dbb6SToby Isaac       DMBoundary b = next;
709e6f8dbb6SToby Isaac 
710e6f8dbb6SToby Isaac       next = b->next;
711e6f8dbb6SToby Isaac       ierr = PetscFree(b);CHKERRQ(ierr);
712e6f8dbb6SToby Isaac     }
713e6f8dbb6SToby Isaac   }
714b17ce1afSJed Brown 
71552536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmksp);CHKERRQ(ierr);
71652536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmsnes);CHKERRQ(ierr);
71752536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmts);CHKERRQ(ierr);
71852536dc3SBarry Smith 
7191a266240SBarry Smith   if ((*dm)->ctx && (*dm)->ctxdestroy) {
7201a266240SBarry Smith     ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr);
7211a266240SBarry Smith   }
72287e657c6SBarry Smith   ierr = VecDestroy(&(*dm)->x);CHKERRQ(ierr);
72371cd77b2SBarry Smith   ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr);
7244dcab191SBarry Smith   ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr);
7256bf464f9SBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr);
7266bf464f9SBarry Smith   ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr);
727073dac72SJed Brown   ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr);
72888ed4aceSMatthew G Knepley 
7291bb6d2a8SBarry Smith   ierr = PetscSectionDestroy(&(*dm)->localSection);CHKERRQ(ierr);
7301bb6d2a8SBarry Smith   ierr = PetscSectionDestroy(&(*dm)->globalSection);CHKERRQ(ierr);
7318b1ab98fSJed Brown   ierr = PetscLayoutDestroy(&(*dm)->map);CHKERRQ(ierr);
732fba222abSToby Isaac   ierr = PetscSectionDestroy(&(*dm)->defaultConstraintSection);CHKERRQ(ierr);
733fba222abSToby Isaac   ierr = MatDestroy(&(*dm)->defaultConstraintMat);CHKERRQ(ierr);
73488ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->sf);CHKERRQ(ierr);
7351bb6d2a8SBarry Smith   ierr = PetscSFDestroy(&(*dm)->sectionSF);CHKERRQ(ierr);
736736995cdSBlaise Bourdin   if ((*dm)->useNatural) {
737736995cdSBlaise Bourdin     if ((*dm)->sfNatural) {
7388e4ac7eaSMatthew G. Knepley       ierr = PetscSFDestroy(&(*dm)->sfNatural);CHKERRQ(ierr);
739736995cdSBlaise Bourdin     }
740736995cdSBlaise Bourdin     ierr = PetscObjectDereference((PetscObject) (*dm)->sfMigration);CHKERRQ(ierr);
741736995cdSBlaise Bourdin   }
74288bdff64SToby Isaac   if ((*dm)->coarseMesh && (*dm)->coarseMesh->fineMesh == *dm) {
74388bdff64SToby Isaac     ierr = DMSetFineDM((*dm)->coarseMesh,NULL);CHKERRQ(ierr);
74488bdff64SToby Isaac   }
745a8fb8f29SToby Isaac   ierr = DMDestroy(&(*dm)->coarseMesh);CHKERRQ(ierr);
74688bdff64SToby Isaac   if ((*dm)->fineMesh && (*dm)->fineMesh->coarseMesh == *dm) {
74788bdff64SToby Isaac     ierr = DMSetCoarseDM((*dm)->fineMesh,NULL);CHKERRQ(ierr);
74888bdff64SToby Isaac   }
74988bdff64SToby Isaac   ierr = DMDestroy(&(*dm)->fineMesh);CHKERRQ(ierr);
750f19dbd58SToby Isaac   ierr = DMFieldDestroy(&(*dm)->coordinateField);CHKERRQ(ierr);
7516636e97aSMatthew G Knepley   ierr = DMDestroy(&(*dm)->coordinateDM);CHKERRQ(ierr);
7526636e97aSMatthew G Knepley   ierr = VecDestroy(&(*dm)->coordinates);CHKERRQ(ierr);
7536636e97aSMatthew G Knepley   ierr = VecDestroy(&(*dm)->coordinatesLocal);CHKERRQ(ierr);
7545dc8c3f7SMatthew G. Knepley   ierr = PetscFree3((*dm)->L,(*dm)->maxCell,(*dm)->bdtype);CHKERRQ(ierr);
755ca3d3a14SMatthew G. Knepley   if ((*dm)->transformDestroy) {ierr = (*(*dm)->transformDestroy)(*dm, (*dm)->transformCtx);CHKERRQ(ierr);}
756ca3d3a14SMatthew G. Knepley   ierr = DMDestroy(&(*dm)->transformDM);CHKERRQ(ierr);
757ca3d3a14SMatthew G. Knepley   ierr = VecDestroy(&(*dm)->transform);CHKERRQ(ierr);
7586636e97aSMatthew G Knepley 
759e5e52638SMatthew G. Knepley   ierr = DMClearDS(*dm);CHKERRQ(ierr);
76014f150ffSMatthew G. Knepley   ierr = DMDestroy(&(*dm)->dmBC);CHKERRQ(ierr);
761e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
762e04113cfSBarry Smith   ierr = PetscObjectSAWsViewOff((PetscObject)*dm);CHKERRQ(ierr);
763732e2eb9SMatthew G Knepley 
764ed3c66a1SDave May   if ((*dm)->ops->destroy) {
7656bf464f9SBarry Smith     ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr);
766ed3c66a1SDave May   }
767*c0f0dcc3SMatthew G. Knepley   ierr = DMMonitorCancel(*dm);CHKERRQ(ierr);
768435a35e8SMatthew G Knepley   /* We do not destroy (*dm)->data here so that we can reference count backend objects */
769732e2eb9SMatthew G Knepley   ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr);
77047c6ae99SBarry Smith   PetscFunctionReturn(0);
77147c6ae99SBarry Smith }
77247c6ae99SBarry Smith 
773d7bf68aeSBarry Smith /*@
774d7bf68aeSBarry Smith     DMSetUp - sets up the data structures inside a DM object
775d7bf68aeSBarry Smith 
776d083f849SBarry Smith     Collective on dm
777d7bf68aeSBarry Smith 
778d7bf68aeSBarry Smith     Input Parameter:
779d7bf68aeSBarry Smith .   dm - the DM object to setup
780d7bf68aeSBarry Smith 
781d7bf68aeSBarry Smith     Level: developer
782d7bf68aeSBarry Smith 
783e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
784d7bf68aeSBarry Smith 
785d7bf68aeSBarry Smith @*/
7867087cfbeSBarry Smith PetscErrorCode  DMSetUp(DM dm)
787d7bf68aeSBarry Smith {
788d7bf68aeSBarry Smith   PetscErrorCode ierr;
789d7bf68aeSBarry Smith 
790d7bf68aeSBarry Smith   PetscFunctionBegin;
791171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7928387afaaSJed Brown   if (dm->setupcalled) PetscFunctionReturn(0);
793d7bf68aeSBarry Smith   if (dm->ops->setup) {
794d7bf68aeSBarry Smith     ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr);
795d7bf68aeSBarry Smith   }
7968387afaaSJed Brown   dm->setupcalled = PETSC_TRUE;
797d7bf68aeSBarry Smith   PetscFunctionReturn(0);
798d7bf68aeSBarry Smith }
799d7bf68aeSBarry Smith 
800d7bf68aeSBarry Smith /*@
801d7bf68aeSBarry Smith     DMSetFromOptions - sets parameters in a DM from the options database
802d7bf68aeSBarry Smith 
803d083f849SBarry Smith     Collective on dm
804d7bf68aeSBarry Smith 
805d7bf68aeSBarry Smith     Input Parameter:
806d7bf68aeSBarry Smith .   dm - the DM object to set options for
807d7bf68aeSBarry Smith 
808732e2eb9SMatthew G Knepley     Options Database:
8094164ae61SDominic Meiser +   -dm_preallocate_only - Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros
8104164ae61SDominic Meiser .   -dm_vec_type <type>  - type of vector to create inside DM
8114164ae61SDominic Meiser .   -dm_mat_type <type>  - type of matrix to create inside DM
8128f1509bcSBarry Smith -   -dm_is_coloring_type - <global or local>
813732e2eb9SMatthew G Knepley 
81495eb5ee5SVaclav Hapla     DMPLEX Specific Checks:
81595eb5ee5SVaclav Hapla     -dm_plex_check_symmetry        - Check that the adjacency information in the mesh is symmetric - DMPlexCheckSymmetry()
81695eb5ee5SVaclav Hapla     -dm_plex_check_skeleton        - Check that each cell has the correct number of vertices (only for homogeneous simplex or tensor meshes) - DMPlexCheckSkeleton()
81795eb5ee5SVaclav Hapla     -dm_plex_check_faces           - Check that the faces of each cell give a vertex order this is consistent with what we expect from the cell type - DMPlexCheckFaces()
81895eb5ee5SVaclav Hapla     -dm_plex_check_geometry        - Check that cells have positive volume - DMPlexCheckGeometry()
81995eb5ee5SVaclav Hapla     -dm_plex_check_pointsf         - Check some necessary conditions for PointSF - DMPlexCheckPointSF()
82095eb5ee5SVaclav Hapla     -dm_plex_check_interface_cones - Check points on inter-partition interfaces have conforming order of cone points - DMPlexCheckInterfaceCones()
821e902f1eaSVaclav Hapla     -dm_plex_check_all             - Perform all the checks above
822d7bf68aeSBarry Smith 
82395eb5ee5SVaclav Hapla     Level: intermediate
82495eb5ee5SVaclav Hapla 
82595eb5ee5SVaclav Hapla .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(),
82695eb5ee5SVaclav Hapla     DMPlexCheckSymmetry(), DMPlexCheckSkeleton(), DMPlexCheckFaces(), DMPlexCheckGeometry(), DMPlexCheckPointSF(), DMPlexCheckInterfaceCones()
827d7bf68aeSBarry Smith 
828d7bf68aeSBarry Smith @*/
8297087cfbeSBarry Smith PetscErrorCode DMSetFromOptions(DM dm)
830d7bf68aeSBarry Smith {
8317781c08eSBarry Smith   char           typeName[256];
832ca266f36SBarry Smith   PetscBool      flg;
833d7bf68aeSBarry Smith   PetscErrorCode ierr;
834d7bf68aeSBarry Smith 
835d7bf68aeSBarry Smith   PetscFunctionBegin;
836171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
83749be4549SMatthew G. Knepley   dm->setfromoptionscalled = PETSC_TRUE;
83849be4549SMatthew G. Knepley   if (dm->sf) {ierr = PetscSFSetFromOptions(dm->sf);CHKERRQ(ierr);}
8391bb6d2a8SBarry Smith   if (dm->sectionSF) {ierr = PetscSFSetFromOptions(dm->sectionSF);CHKERRQ(ierr);}
8403194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr);
8410298fd71SBarry Smith   ierr = PetscOptionsBool("-dm_preallocate_only","only preallocate matrix, but do not set column indices","DMSetMatrixPreallocateOnly",dm->prealloc_only,&dm->prealloc_only,NULL);CHKERRQ(ierr);
842a264d7a6SBarry Smith   ierr = PetscOptionsFList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr);
843f9ba7244SBarry Smith   if (flg) {
844f9ba7244SBarry Smith     ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr);
845f9ba7244SBarry Smith   }
846a264d7a6SBarry Smith   ierr = PetscOptionsFList("-dm_mat_type","Matrix type used for created matrices","DMSetMatType",MatList,dm->mattype ? dm->mattype : typeName,typeName,sizeof(typeName),&flg);CHKERRQ(ierr);
847073dac72SJed Brown   if (flg) {
848521d9a4cSLisandro Dalcin     ierr = DMSetMatType(dm,typeName);CHKERRQ(ierr);
849073dac72SJed Brown   }
8508f1509bcSBarry Smith   ierr = PetscOptionsEnum("-dm_is_coloring_type","Global or local coloring of Jacobian","DMSetISColoringType",ISColoringTypes,(PetscEnum)dm->coloringtype,(PetscEnum*)&dm->coloringtype,NULL);CHKERRQ(ierr);
851f9ba7244SBarry Smith   if (dm->ops->setfromoptions) {
852e55864a3SBarry Smith     ierr = (*dm->ops->setfromoptions)(PetscOptionsObject,dm);CHKERRQ(ierr);
853f9ba7244SBarry Smith   }
854f9ba7244SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
8550633abcbSJed Brown   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) dm);CHKERRQ(ierr);
85682fcb398SMatthew G Knepley   ierr = PetscOptionsEnd();CHKERRQ(ierr);
857d7bf68aeSBarry Smith   PetscFunctionReturn(0);
858d7bf68aeSBarry Smith }
859d7bf68aeSBarry Smith 
860fc9bc008SSatish Balay /*@C
861fe2efc57SMark    DMViewFromOptions - View from Options
862fe2efc57SMark 
863fe2efc57SMark    Collective on DM
864fe2efc57SMark 
865fe2efc57SMark    Input Parameters:
866fe2efc57SMark +  dm - the DM object
867736c3998SJose E. Roman .  obj - Optional object
868736c3998SJose E. Roman -  name - command line option
869fe2efc57SMark 
870fe2efc57SMark    Level: intermediate
871fe2efc57SMark .seealso:  DM, DMView, PetscObjectViewFromOptions(), DMCreate()
872fe2efc57SMark @*/
873fe2efc57SMark PetscErrorCode  DMViewFromOptions(DM dm,PetscObject obj,const char name[])
874fe2efc57SMark {
875fe2efc57SMark   PetscErrorCode ierr;
876fe2efc57SMark 
877fe2efc57SMark   PetscFunctionBegin;
878fe2efc57SMark   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
879fe2efc57SMark   ierr = PetscObjectViewFromOptions((PetscObject)dm,obj,name);CHKERRQ(ierr);
880fe2efc57SMark   PetscFunctionReturn(0);
881fe2efc57SMark }
882fe2efc57SMark 
883fe2efc57SMark /*@C
884224748a4SBarry Smith     DMView - Views a DM
88547c6ae99SBarry Smith 
886d083f849SBarry Smith     Collective on dm
88747c6ae99SBarry Smith 
88847c6ae99SBarry Smith     Input Parameter:
88947c6ae99SBarry Smith +   dm - the DM object to view
89047c6ae99SBarry Smith -   v - the viewer
89147c6ae99SBarry Smith 
892224748a4SBarry Smith     Level: beginner
89347c6ae99SBarry Smith 
894e727c939SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
89547c6ae99SBarry Smith 
89647c6ae99SBarry Smith @*/
8977087cfbeSBarry Smith PetscErrorCode  DMView(DM dm,PetscViewer v)
89847c6ae99SBarry Smith {
89947c6ae99SBarry Smith   PetscErrorCode    ierr;
90032c0f0efSBarry Smith   PetscBool         isbinary;
90176a8abe0SBarry Smith   PetscMPIInt       size;
90276a8abe0SBarry Smith   PetscViewerFormat format;
90347c6ae99SBarry Smith 
90447c6ae99SBarry Smith   PetscFunctionBegin;
905171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9063014e516SBarry Smith   if (!v) {
907ce94432eSBarry Smith     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)dm),&v);CHKERRQ(ierr);
9083014e516SBarry Smith   }
909b1b135c8SBarry Smith   PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,2);
91074903a4fSStefano Zampini   /* Ideally, we would like to have this test on.
91174903a4fSStefano Zampini      However, it currently breaks socket viz via GLVis.
91274903a4fSStefano Zampini      During DMView(parallel_mesh,glvis_viewer), each
91374903a4fSStefano Zampini      process opens a sequential ASCII socket to visualize
91474903a4fSStefano Zampini      the local mesh, and PetscObjectView(dm,local_socket)
91574903a4fSStefano Zampini      is internally called inside VecView_GLVis, incurring
91674903a4fSStefano Zampini      in an error here */
91774903a4fSStefano Zampini   /* PetscCheckSameComm(dm,1,v,2); */
9188bfd1ab9SVaclav Hapla   ierr = PetscViewerCheckWritable(v);CHKERRQ(ierr);
919b1b135c8SBarry Smith 
92076a8abe0SBarry Smith   ierr = PetscViewerGetFormat(v,&format);CHKERRQ(ierr);
92176a8abe0SBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&size);CHKERRQ(ierr);
92276a8abe0SBarry Smith   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
92398c3331eSBarry Smith   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)dm,v);CHKERRQ(ierr);
92432c0f0efSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
92532c0f0efSBarry Smith   if (isbinary) {
92655849f57SBarry Smith     PetscInt classid = DM_FILE_CLASSID;
92732c0f0efSBarry Smith     char     type[256];
92832c0f0efSBarry Smith 
92932c0f0efSBarry Smith     ierr = PetscViewerBinaryWrite(v,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
93032c0f0efSBarry Smith     ierr = PetscStrncpy(type,((PetscObject)dm)->type_name,256);CHKERRQ(ierr);
93132c0f0efSBarry Smith     ierr = PetscViewerBinaryWrite(v,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
93232c0f0efSBarry Smith   }
9330c010503SBarry Smith   if (dm->ops->view) {
9340c010503SBarry Smith     ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr);
93547c6ae99SBarry Smith   }
93647c6ae99SBarry Smith   PetscFunctionReturn(0);
93747c6ae99SBarry Smith }
93847c6ae99SBarry Smith 
93947c6ae99SBarry Smith /*@
9408472ad0fSDave May     DMCreateGlobalVector - Creates a global vector from a DM object
94147c6ae99SBarry Smith 
942d083f849SBarry Smith     Collective on dm
94347c6ae99SBarry Smith 
94447c6ae99SBarry Smith     Input Parameter:
94547c6ae99SBarry Smith .   dm - the DM object
94647c6ae99SBarry Smith 
94747c6ae99SBarry Smith     Output Parameter:
94847c6ae99SBarry Smith .   vec - the global vector
94947c6ae99SBarry Smith 
950073dac72SJed Brown     Level: beginner
95147c6ae99SBarry Smith 
952e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
95347c6ae99SBarry Smith 
95447c6ae99SBarry Smith @*/
9557087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector(DM dm,Vec *vec)
95647c6ae99SBarry Smith {
95747c6ae99SBarry Smith   PetscErrorCode ierr;
95847c6ae99SBarry Smith 
95947c6ae99SBarry Smith   PetscFunctionBegin;
960171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
961b9d85ea2SLisandro Dalcin   PetscValidPointer(vec,2);
962b9d85ea2SLisandro Dalcin   if (!dm->ops->createglobalvector) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateGlobalVector",((PetscObject)dm)->type_name);
96347c6ae99SBarry Smith   ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr);
96447c6ae99SBarry Smith   PetscFunctionReturn(0);
96547c6ae99SBarry Smith }
96647c6ae99SBarry Smith 
96747c6ae99SBarry Smith /*@
9688472ad0fSDave May     DMCreateLocalVector - Creates a local vector from a DM object
96947c6ae99SBarry Smith 
97047c6ae99SBarry Smith     Not Collective
97147c6ae99SBarry Smith 
97247c6ae99SBarry Smith     Input Parameter:
97347c6ae99SBarry Smith .   dm - the DM object
97447c6ae99SBarry Smith 
97547c6ae99SBarry Smith     Output Parameter:
97647c6ae99SBarry Smith .   vec - the local vector
97747c6ae99SBarry Smith 
978073dac72SJed Brown     Level: beginner
97947c6ae99SBarry Smith 
980e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
98147c6ae99SBarry Smith 
98247c6ae99SBarry Smith @*/
9837087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector(DM dm,Vec *vec)
98447c6ae99SBarry Smith {
98547c6ae99SBarry Smith   PetscErrorCode ierr;
98647c6ae99SBarry Smith 
98747c6ae99SBarry Smith   PetscFunctionBegin;
988171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
989b9d85ea2SLisandro Dalcin   PetscValidPointer(vec,2);
990b9d85ea2SLisandro Dalcin   if (!dm->ops->createlocalvector) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateLocalVector",((PetscObject)dm)->type_name);
99147c6ae99SBarry Smith   ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr);
99247c6ae99SBarry Smith   PetscFunctionReturn(0);
99347c6ae99SBarry Smith }
99447c6ae99SBarry Smith 
9951411c6eeSJed Brown /*@
9961411c6eeSJed Brown    DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM.
9971411c6eeSJed Brown 
998d083f849SBarry Smith    Collective on dm
9991411c6eeSJed Brown 
10001411c6eeSJed Brown    Input Parameter:
10011411c6eeSJed Brown .  dm - the DM that provides the mapping
10021411c6eeSJed Brown 
10031411c6eeSJed Brown    Output Parameter:
10041411c6eeSJed Brown .  ltog - the mapping
10051411c6eeSJed Brown 
10061411c6eeSJed Brown    Level: intermediate
10071411c6eeSJed Brown 
10081411c6eeSJed Brown    Notes:
10091411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMapping() or
10101411c6eeSJed Brown    MatSetLocalToGlobalMapping().
10111411c6eeSJed Brown 
1012fc31e74dSBarry Smith .seealso: DMCreateLocalVector()
10131411c6eeSJed Brown @*/
10147087cfbeSBarry Smith PetscErrorCode DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog)
10151411c6eeSJed Brown {
10160be3e97aSMatthew G. Knepley   PetscInt       bs = -1, bsLocal[2], bsMinMax[2];
10171411c6eeSJed Brown   PetscErrorCode ierr;
10181411c6eeSJed Brown 
10191411c6eeSJed Brown   PetscFunctionBegin;
10201411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10211411c6eeSJed Brown   PetscValidPointer(ltog,2);
10221411c6eeSJed Brown   if (!dm->ltogmap) {
102337d0c07bSMatthew G Knepley     PetscSection section, sectionGlobal;
102437d0c07bSMatthew G Knepley 
102592fd8e1eSJed Brown     ierr = DMGetLocalSection(dm, &section);CHKERRQ(ierr);
102637d0c07bSMatthew G Knepley     if (section) {
1027a974ec88SMatthew G. Knepley       const PetscInt *cdofs;
102837d0c07bSMatthew G Knepley       PetscInt       *ltog;
1029ccf3bd66SMatthew G. Knepley       PetscInt        pStart, pEnd, n, p, k, l;
103037d0c07bSMatthew G Knepley 
1031e87a4003SBarry Smith       ierr = DMGetGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
103237d0c07bSMatthew G Knepley       ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
1033ccf3bd66SMatthew G. Knepley       ierr = PetscSectionGetStorageSize(section, &n);CHKERRQ(ierr);
1034ccf3bd66SMatthew G. Knepley       ierr = PetscMalloc1(n, &ltog);CHKERRQ(ierr); /* We want the local+overlap size */
103537d0c07bSMatthew G Knepley       for (p = pStart, l = 0; p < pEnd; ++p) {
1036a974ec88SMatthew G. Knepley         PetscInt bdof, cdof, dof, off, c, cind = 0;
103737d0c07bSMatthew G Knepley 
103837d0c07bSMatthew G Knepley         /* Should probably use constrained dofs */
103937d0c07bSMatthew G Knepley         ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr);
1040a974ec88SMatthew G. Knepley         ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr);
1041a974ec88SMatthew G. Knepley         ierr = PetscSectionGetConstraintIndices(section, p, &cdofs);CHKERRQ(ierr);
104237d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr);
10431a7dc684SMatthew G. Knepley         /* If you have dofs, and constraints, and they are unequal, we set the blocksize to 1 */
10441a7dc684SMatthew G. Knepley         bdof = cdof && (dof-cdof) ? 1 : dof;
10451a7dc684SMatthew G. Knepley         if (dof) {
1046b190aa46SMatthew G. Knepley           if (bs < 0)          {bs = bdof;}
1047b190aa46SMatthew G. Knepley           else if (bs != bdof) {bs = 1;}
10481a7dc684SMatthew G. Knepley         }
104937d0c07bSMatthew G Knepley         for (c = 0; c < dof; ++c, ++l) {
1050a974ec88SMatthew G. Knepley           if ((cind < cdof) && (c == cdofs[cind])) ltog[l] = off < 0 ? off-c : off+c;
1051a974ec88SMatthew G. Knepley           else                                     ltog[l] = (off < 0 ? -(off+1) : off) + c;
105237d0c07bSMatthew G Knepley         }
105337d0c07bSMatthew G Knepley       }
1054bff27382SMatthew G. Knepley       /* Must have same blocksize on all procs (some might have no points) */
10550be3e97aSMatthew G. Knepley       bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs;
10560be3e97aSMatthew G. Knepley       ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr);
10570be3e97aSMatthew G. Knepley       if (bsMinMax[0] != bsMinMax[1]) {bs = 1;}
10580be3e97aSMatthew G. Knepley       else                            {bs = bsMinMax[0];}
10597591dbb2SMatthew G. Knepley       bs = bs < 0 ? 1 : bs;
10607591dbb2SMatthew G. Knepley       /* Must reduce indices by blocksize */
1061ccf3bd66SMatthew G. Knepley       if (bs > 1) {
1062ccf3bd66SMatthew G. Knepley         for (l = 0, k = 0; l < n; l += bs, ++k) ltog[k] = ltog[l]/bs;
1063ccf3bd66SMatthew G. Knepley         n /= bs;
1064ccf3bd66SMatthew G. Knepley       }
1065ccf3bd66SMatthew G. Knepley       ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, n, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr);
10663bb1ff40SBarry Smith       ierr = PetscLogObjectParent((PetscObject)dm, (PetscObject)dm->ltogmap);CHKERRQ(ierr);
106737d0c07bSMatthew G Knepley     } else {
1068b9d85ea2SLisandro Dalcin       if (!dm->ops->getlocaltoglobalmapping) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMGetLocalToGlobalMapping",((PetscObject)dm)->type_name);
1069184d77edSJed Brown       ierr = (*dm->ops->getlocaltoglobalmapping)(dm);CHKERRQ(ierr);
10701411c6eeSJed Brown     }
107137d0c07bSMatthew G Knepley   }
10721411c6eeSJed Brown   *ltog = dm->ltogmap;
10731411c6eeSJed Brown   PetscFunctionReturn(0);
10741411c6eeSJed Brown }
10751411c6eeSJed Brown 
10761411c6eeSJed Brown /*@
10771411c6eeSJed Brown    DMGetBlockSize - Gets the inherent block size associated with a DM
10781411c6eeSJed Brown 
10791411c6eeSJed Brown    Not Collective
10801411c6eeSJed Brown 
10811411c6eeSJed Brown    Input Parameter:
10821411c6eeSJed Brown .  dm - the DM with block structure
10831411c6eeSJed Brown 
10841411c6eeSJed Brown    Output Parameter:
10851411c6eeSJed Brown .  bs - the block size, 1 implies no exploitable block structure
10861411c6eeSJed Brown 
10871411c6eeSJed Brown    Level: intermediate
10881411c6eeSJed Brown 
1089fc31e74dSBarry Smith .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMapping()
10901411c6eeSJed Brown @*/
10917087cfbeSBarry Smith PetscErrorCode  DMGetBlockSize(DM dm,PetscInt *bs)
10921411c6eeSJed Brown {
10931411c6eeSJed Brown   PetscFunctionBegin;
10941411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1095534a8f05SLisandro Dalcin   PetscValidIntPointer(bs,2);
10961411c6eeSJed 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");
10971411c6eeSJed Brown   *bs = dm->bs;
10981411c6eeSJed Brown   PetscFunctionReturn(0);
10991411c6eeSJed Brown }
11001411c6eeSJed Brown 
110147c6ae99SBarry Smith /*@
11028472ad0fSDave May     DMCreateInterpolation - Gets interpolation matrix between two DM objects
110347c6ae99SBarry Smith 
1104d083f849SBarry Smith     Collective on dm1
110547c6ae99SBarry Smith 
110647c6ae99SBarry Smith     Input Parameter:
110747c6ae99SBarry Smith +   dm1 - the DM object
110847c6ae99SBarry Smith -   dm2 - the second, finer DM object
110947c6ae99SBarry Smith 
111047c6ae99SBarry Smith     Output Parameter:
111147c6ae99SBarry Smith +  mat - the interpolation
111247c6ae99SBarry Smith -  vec - the scaling (optional)
111347c6ae99SBarry Smith 
111447c6ae99SBarry Smith     Level: developer
111547c6ae99SBarry Smith 
111695452b02SPatrick Sanan     Notes:
111795452b02SPatrick Sanan     For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by
111885afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
1119d52bd9f3SBarry Smith 
11201f588964SMatthew G Knepley         For DMDA objects you can use this interpolation (more precisely the interpolation from the DMGetCoordinateDM()) to interpolate the mesh coordinate vectors
1121d52bd9f3SBarry Smith         EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic.
112285afcc9aSBarry Smith 
112385afcc9aSBarry Smith 
11243ad4599aSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateRestriction()
112547c6ae99SBarry Smith 
112647c6ae99SBarry Smith @*/
1127e727c939SJed Brown PetscErrorCode  DMCreateInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec)
112847c6ae99SBarry Smith {
112947c6ae99SBarry Smith   PetscErrorCode ierr;
113047c6ae99SBarry Smith 
113147c6ae99SBarry Smith   PetscFunctionBegin;
1132171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
1133171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
1134c7d20fa0SStefano Zampini   PetscValidPointer(mat,3);
1135b9d85ea2SLisandro Dalcin   if (!dm1->ops->createinterpolation) SETERRQ1(PetscObjectComm((PetscObject)dm1),PETSC_ERR_SUP,"DM type %s does not implement DMCreateInterpolation",((PetscObject)dm1)->type_name);
1136cea54e9dSPatrick Farrell   ierr = PetscLogEventBegin(DM_CreateInterpolation,dm1,dm2,0,0);CHKERRQ(ierr);
113725296bd5SBarry Smith   ierr = (*dm1->ops->createinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr);
1138cea54e9dSPatrick Farrell   ierr = PetscLogEventEnd(DM_CreateInterpolation,dm1,dm2,0,0);CHKERRQ(ierr);
113947c6ae99SBarry Smith   PetscFunctionReturn(0);
114047c6ae99SBarry Smith }
114147c6ae99SBarry Smith 
11423ad4599aSBarry Smith /*@
11433ad4599aSBarry Smith     DMCreateRestriction - Gets restriction matrix between two DM objects
11443ad4599aSBarry Smith 
1145d083f849SBarry Smith     Collective on dm1
11463ad4599aSBarry Smith 
11473ad4599aSBarry Smith     Input Parameter:
11483ad4599aSBarry Smith +   dm1 - the DM object
11493ad4599aSBarry Smith -   dm2 - the second, finer DM object
11503ad4599aSBarry Smith 
11513ad4599aSBarry Smith     Output Parameter:
11523ad4599aSBarry Smith .  mat - the restriction
11533ad4599aSBarry Smith 
11543ad4599aSBarry Smith 
11553ad4599aSBarry Smith     Level: developer
11563ad4599aSBarry Smith 
115795452b02SPatrick Sanan     Notes:
115895452b02SPatrick Sanan     For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by
11593ad4599aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
11603ad4599aSBarry Smith 
11613ad4599aSBarry Smith 
11623ad4599aSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateInterpolation()
11633ad4599aSBarry Smith 
11643ad4599aSBarry Smith @*/
11653ad4599aSBarry Smith PetscErrorCode  DMCreateRestriction(DM dm1,DM dm2,Mat *mat)
11663ad4599aSBarry Smith {
11673ad4599aSBarry Smith   PetscErrorCode ierr;
11683ad4599aSBarry Smith 
11693ad4599aSBarry Smith   PetscFunctionBegin;
11703ad4599aSBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
11713ad4599aSBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
11725a84ad33SLisandro Dalcin   PetscValidPointer(mat,3);
1173b9d85ea2SLisandro Dalcin   if (!dm1->ops->createrestriction) SETERRQ1(PetscObjectComm((PetscObject)dm1),PETSC_ERR_SUP,"DM type %s does not implement DMCreateRestriction",((PetscObject)dm1)->type_name);
11743ad4599aSBarry Smith   ierr = PetscLogEventBegin(DM_CreateRestriction,dm1,dm2,0,0);CHKERRQ(ierr);
11753ad4599aSBarry Smith   ierr = (*dm1->ops->createrestriction)(dm1,dm2,mat);CHKERRQ(ierr);
11763ad4599aSBarry Smith   ierr = PetscLogEventEnd(DM_CreateRestriction,dm1,dm2,0,0);CHKERRQ(ierr);
11773ad4599aSBarry Smith   PetscFunctionReturn(0);
11783ad4599aSBarry Smith }
11793ad4599aSBarry Smith 
118047c6ae99SBarry Smith /*@
11818472ad0fSDave May     DMCreateInjection - Gets injection matrix between two DM objects
118247c6ae99SBarry Smith 
1183d083f849SBarry Smith     Collective on dm1
118447c6ae99SBarry Smith 
118547c6ae99SBarry Smith     Input Parameter:
118647c6ae99SBarry Smith +   dm1 - the DM object
118747c6ae99SBarry Smith -   dm2 - the second, finer DM object
118847c6ae99SBarry Smith 
118947c6ae99SBarry Smith     Output Parameter:
11906dbf9973SLawrence Mitchell .   mat - the injection
119147c6ae99SBarry Smith 
119247c6ae99SBarry Smith     Level: developer
119347c6ae99SBarry Smith 
119495452b02SPatrick Sanan    Notes:
119595452b02SPatrick Sanan     For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by
119685afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection.
119785afcc9aSBarry Smith 
1198e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation()
119947c6ae99SBarry Smith 
120047c6ae99SBarry Smith @*/
12016dbf9973SLawrence Mitchell PetscErrorCode  DMCreateInjection(DM dm1,DM dm2,Mat *mat)
120247c6ae99SBarry Smith {
120347c6ae99SBarry Smith   PetscErrorCode ierr;
120447c6ae99SBarry Smith 
120547c6ae99SBarry Smith   PetscFunctionBegin;
1206171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
1207171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
12085a84ad33SLisandro Dalcin   PetscValidPointer(mat,3);
1209b9d85ea2SLisandro Dalcin   if (!dm1->ops->createinjection) SETERRQ1(PetscObjectComm((PetscObject)dm1),PETSC_ERR_SUP,"DM type %s does not implement DMCreateInjection",((PetscObject)dm1)->type_name);
12105a84ad33SLisandro Dalcin   ierr = PetscLogEventBegin(DM_CreateInjection,dm1,dm2,0,0);CHKERRQ(ierr);
12115a84ad33SLisandro Dalcin   ierr = (*dm1->ops->createinjection)(dm1,dm2,mat);CHKERRQ(ierr);
12125a84ad33SLisandro Dalcin   ierr = PetscLogEventEnd(DM_CreateInjection,dm1,dm2,0,0);CHKERRQ(ierr);
121347c6ae99SBarry Smith   PetscFunctionReturn(0);
121447c6ae99SBarry Smith }
121547c6ae99SBarry Smith 
1216b412c318SBarry Smith /*@
1217bd041c0cSMatthew G. Knepley   DMCreateMassMatrix - Gets mass matrix between two DM objects, M_ij = \int \phi_i \psi_j
1218bd041c0cSMatthew G. Knepley 
1219d083f849SBarry Smith   Collective on dm1
1220bd041c0cSMatthew G. Knepley 
1221bd041c0cSMatthew G. Knepley   Input Parameter:
1222bd041c0cSMatthew G. Knepley + dm1 - the DM object
1223bd041c0cSMatthew G. Knepley - dm2 - the second, finer DM object
1224bd041c0cSMatthew G. Knepley 
1225bd041c0cSMatthew G. Knepley   Output Parameter:
1226bd041c0cSMatthew G. Knepley . mat - the interpolation
1227bd041c0cSMatthew G. Knepley 
1228bd041c0cSMatthew G. Knepley   Level: developer
1229bd041c0cSMatthew G. Knepley 
1230bd041c0cSMatthew G. Knepley .seealso DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateRestriction(), DMCreateInterpolation(), DMCreateInjection()
1231bd041c0cSMatthew G. Knepley @*/
1232bd041c0cSMatthew G. Knepley PetscErrorCode DMCreateMassMatrix(DM dm1, DM dm2, Mat *mat)
1233bd041c0cSMatthew G. Knepley {
1234bd041c0cSMatthew G. Knepley   PetscErrorCode ierr;
1235bd041c0cSMatthew G. Knepley 
1236bd041c0cSMatthew G. Knepley   PetscFunctionBegin;
1237bd041c0cSMatthew G. Knepley   PetscValidHeaderSpecific(dm1, DM_CLASSID, 1);
1238bd041c0cSMatthew G. Knepley   PetscValidHeaderSpecific(dm2, DM_CLASSID, 2);
12395a84ad33SLisandro Dalcin   PetscValidPointer(mat,3);
1240b9d85ea2SLisandro Dalcin   if (!dm1->ops->createmassmatrix) SETERRQ1(PetscObjectComm((PetscObject)dm1),PETSC_ERR_SUP,"DM type %s does not implement DMCreateMassMatrix",((PetscObject)dm1)->type_name);
1241bd041c0cSMatthew G. Knepley   ierr = (*dm1->ops->createmassmatrix)(dm1, dm2, mat);CHKERRQ(ierr);
1242bd041c0cSMatthew G. Knepley   PetscFunctionReturn(0);
1243bd041c0cSMatthew G. Knepley }
1244bd041c0cSMatthew G. Knepley 
1245bd041c0cSMatthew G. Knepley /*@
1246b412c318SBarry Smith     DMCreateColoring - Gets coloring for a DM
124747c6ae99SBarry Smith 
1248d083f849SBarry Smith     Collective on dm
124947c6ae99SBarry Smith 
125047c6ae99SBarry Smith     Input Parameter:
125147c6ae99SBarry Smith +   dm - the DM object
12525bdb020cSBarry Smith -   ctype - IS_COLORING_LOCAL or IS_COLORING_GLOBAL
125347c6ae99SBarry Smith 
125447c6ae99SBarry Smith     Output Parameter:
125547c6ae99SBarry Smith .   coloring - the coloring
125647c6ae99SBarry Smith 
1257ec5066bdSBarry Smith     Notes:
1258ec5066bdSBarry Smith        Coloring of matrices can be computed directly from the sparse matrix nonzero structure via the MatColoring object or from the mesh from which the
1259ec5066bdSBarry Smith        matrix comes from. In general using the mesh produces a more optimal coloring (fewer colors).
1260ec5066bdSBarry Smith 
1261ec5066bdSBarry Smith        This produces a coloring with the distance of 2, see MatSetColoringDistance() which can be used for efficiently computing Jacobians with MatFDColoringCreate()
1262ec5066bdSBarry Smith 
126347c6ae99SBarry Smith     Level: developer
126447c6ae99SBarry Smith 
1265ec5066bdSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix(), DMSetMatType(), MatColoring, MatFDColoringCreate()
126647c6ae99SBarry Smith 
1267aab9d709SJed Brown @*/
1268b412c318SBarry Smith PetscErrorCode  DMCreateColoring(DM dm,ISColoringType ctype,ISColoring *coloring)
126947c6ae99SBarry Smith {
127047c6ae99SBarry Smith   PetscErrorCode ierr;
127147c6ae99SBarry Smith 
127247c6ae99SBarry Smith   PetscFunctionBegin;
1273171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
12745a84ad33SLisandro Dalcin   PetscValidPointer(coloring,3);
1275b9d85ea2SLisandro Dalcin   if (!dm->ops->getcoloring) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateColoring",((PetscObject)dm)->type_name);
1276b412c318SBarry Smith   ierr = (*dm->ops->getcoloring)(dm,ctype,coloring);CHKERRQ(ierr);
127747c6ae99SBarry Smith   PetscFunctionReturn(0);
127847c6ae99SBarry Smith }
127947c6ae99SBarry Smith 
1280b412c318SBarry Smith /*@
12818472ad0fSDave May     DMCreateMatrix - Gets empty Jacobian for a DM
128247c6ae99SBarry Smith 
1283d083f849SBarry Smith     Collective on dm
128447c6ae99SBarry Smith 
128547c6ae99SBarry Smith     Input Parameter:
1286b412c318SBarry Smith .   dm - the DM object
128747c6ae99SBarry Smith 
128847c6ae99SBarry Smith     Output Parameter:
128947c6ae99SBarry Smith .   mat - the empty Jacobian
129047c6ae99SBarry Smith 
1291073dac72SJed Brown     Level: beginner
129247c6ae99SBarry Smith 
129395452b02SPatrick Sanan     Notes:
129495452b02SPatrick Sanan     This properly preallocates the number of nonzeros in the sparse matrix so you
129594013140SBarry Smith        do not need to do it yourself.
129694013140SBarry Smith 
129794013140SBarry Smith        By default it also sets the nonzero structure and puts in the zero entries. To prevent setting
12987889ec69SBarry Smith        the nonzero pattern call DMSetMatrixPreallocateOnly()
129994013140SBarry Smith 
130094013140SBarry 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
130194013140SBarry Smith        internally by PETSc.
130294013140SBarry Smith 
130394013140SBarry Smith        For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires
1304aa219208SBarry Smith        the indices for the global numbering for DMDAs which is complicated.
130594013140SBarry Smith 
1306b412c318SBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMSetMatType()
130747c6ae99SBarry Smith 
1308aab9d709SJed Brown @*/
1309b412c318SBarry Smith PetscErrorCode  DMCreateMatrix(DM dm,Mat *mat)
131047c6ae99SBarry Smith {
131147c6ae99SBarry Smith   PetscErrorCode ierr;
131247c6ae99SBarry Smith 
131347c6ae99SBarry Smith   PetscFunctionBegin;
1314171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1315c7b7c8a4SJed Brown   PetscValidPointer(mat,3);
1316b9d85ea2SLisandro Dalcin   if (!dm->ops->creatematrix) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateMatrix",((PetscObject)dm)->type_name);
13175a84ad33SLisandro Dalcin   ierr = MatInitializePackage();CHKERRQ(ierr);
1318fdc842d1SBarry Smith   ierr = PetscLogEventBegin(DM_CreateMatrix,0,0,0,0);CHKERRQ(ierr);
1319b412c318SBarry Smith   ierr = (*dm->ops->creatematrix)(dm,mat);CHKERRQ(ierr);
1320e571a35bSMatthew G. Knepley   /* Handle nullspace and near nullspace */
1321e5e52638SMatthew G. Knepley   if (dm->Nf) {
1322e571a35bSMatthew G. Knepley     MatNullSpace nullSpace;
1323e571a35bSMatthew G. Knepley     PetscInt     Nf;
1324e571a35bSMatthew G. Knepley 
1325e5e52638SMatthew G. Knepley     ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
1326e571a35bSMatthew G. Knepley     if (Nf == 1) {
1327e571a35bSMatthew G. Knepley       if (dm->nullspaceConstructors[0]) {
1328e571a35bSMatthew G. Knepley         ierr = (*dm->nullspaceConstructors[0])(dm, 0, &nullSpace);CHKERRQ(ierr);
1329e571a35bSMatthew G. Knepley         ierr = MatSetNullSpace(*mat, nullSpace);CHKERRQ(ierr);
1330e571a35bSMatthew G. Knepley         ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr);
1331e571a35bSMatthew G. Knepley       }
1332e571a35bSMatthew G. Knepley       if (dm->nearnullspaceConstructors[0]) {
1333e571a35bSMatthew G. Knepley         ierr = (*dm->nearnullspaceConstructors[0])(dm, 0, &nullSpace);CHKERRQ(ierr);
1334e571a35bSMatthew G. Knepley         ierr = MatSetNearNullSpace(*mat, nullSpace);CHKERRQ(ierr);
1335e571a35bSMatthew G. Knepley         ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr);
1336e571a35bSMatthew G. Knepley       }
1337e571a35bSMatthew G. Knepley     }
1338e571a35bSMatthew G. Knepley   }
1339fdc842d1SBarry Smith   ierr = PetscLogEventEnd(DM_CreateMatrix,0,0,0,0);CHKERRQ(ierr);
134047c6ae99SBarry Smith   PetscFunctionReturn(0);
134147c6ae99SBarry Smith }
134247c6ae99SBarry Smith 
1343732e2eb9SMatthew G Knepley /*@
1344950540a4SJed Brown   DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly
1345732e2eb9SMatthew G Knepley     preallocated but the nonzero structure and zero values will not be set.
1346732e2eb9SMatthew G Knepley 
1347d083f849SBarry Smith   Logically Collective on dm
1348732e2eb9SMatthew G Knepley 
1349732e2eb9SMatthew G Knepley   Input Parameter:
1350732e2eb9SMatthew G Knepley + dm - the DM
1351732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation
1352732e2eb9SMatthew G Knepley 
1353732e2eb9SMatthew G Knepley   Level: developer
1354b06ff27eSHong Zhang .seealso DMCreateMatrix(), DMSetMatrixStructureOnly()
1355732e2eb9SMatthew G Knepley @*/
1356732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only)
1357732e2eb9SMatthew G Knepley {
1358732e2eb9SMatthew G Knepley   PetscFunctionBegin;
1359732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1360732e2eb9SMatthew G Knepley   dm->prealloc_only = only;
1361732e2eb9SMatthew G Knepley   PetscFunctionReturn(0);
1362732e2eb9SMatthew G Knepley }
1363732e2eb9SMatthew G Knepley 
1364b06ff27eSHong Zhang /*@
1365b06ff27eSHong Zhang   DMSetMatrixStructureOnly - When DMCreateMatrix() is called, the matrix structure will be created
1366b06ff27eSHong Zhang     but the array for values will not be allocated.
1367b06ff27eSHong Zhang 
1368d083f849SBarry Smith   Logically Collective on dm
1369b06ff27eSHong Zhang 
1370b06ff27eSHong Zhang   Input Parameter:
1371b06ff27eSHong Zhang + dm - the DM
1372b06ff27eSHong Zhang - only - PETSC_TRUE if only want matrix stucture
1373b06ff27eSHong Zhang 
1374b06ff27eSHong Zhang   Level: developer
1375b06ff27eSHong Zhang .seealso DMCreateMatrix(), DMSetMatrixPreallocateOnly()
1376b06ff27eSHong Zhang @*/
1377b06ff27eSHong Zhang PetscErrorCode DMSetMatrixStructureOnly(DM dm, PetscBool only)
1378b06ff27eSHong Zhang {
1379b06ff27eSHong Zhang   PetscFunctionBegin;
1380b06ff27eSHong Zhang   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1381b06ff27eSHong Zhang   dm->structure_only = only;
1382b06ff27eSHong Zhang   PetscFunctionReturn(0);
1383b06ff27eSHong Zhang }
1384b06ff27eSHong Zhang 
1385a89ea682SMatthew G Knepley /*@C
1386aa1993deSMatthew G Knepley   DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
1387a89ea682SMatthew G Knepley 
1388a89ea682SMatthew G Knepley   Not Collective
1389a89ea682SMatthew G Knepley 
1390a89ea682SMatthew G Knepley   Input Parameters:
1391a89ea682SMatthew G Knepley + dm - the DM object
1392aa1993deSMatthew G Knepley . count - The minium size
139369291d52SBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, MPIU_INT)
1394a89ea682SMatthew G Knepley 
1395a89ea682SMatthew G Knepley   Output Parameter:
1396a89ea682SMatthew G Knepley . array - the work array
1397a89ea682SMatthew G Knepley 
1398a89ea682SMatthew G Knepley   Level: developer
1399a89ea682SMatthew G Knepley 
1400a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate()
1401a89ea682SMatthew G Knepley @*/
140269291d52SBarry Smith PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,MPI_Datatype dtype,void *mem)
1403a89ea682SMatthew G Knepley {
1404a89ea682SMatthew G Knepley   PetscErrorCode ierr;
1405aa1993deSMatthew G Knepley   DMWorkLink     link;
140669291d52SBarry Smith   PetscMPIInt    dsize;
1407a89ea682SMatthew G Knepley 
1408a89ea682SMatthew G Knepley   PetscFunctionBegin;
1409a89ea682SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1410aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
1411aa1993deSMatthew G Knepley   if (dm->workin) {
1412aa1993deSMatthew G Knepley     link       = dm->workin;
1413aa1993deSMatthew G Knepley     dm->workin = dm->workin->next;
1414aa1993deSMatthew G Knepley   } else {
1415b00a9115SJed Brown     ierr = PetscNewLog(dm,&link);CHKERRQ(ierr);
1416a89ea682SMatthew G Knepley   }
141769291d52SBarry Smith   ierr = MPI_Type_size(dtype,&dsize);CHKERRQ(ierr);
14185056fcd2SBarry Smith   if (((size_t)dsize*count) > link->bytes) {
1419aa1993deSMatthew G Knepley     ierr        = PetscFree(link->mem);CHKERRQ(ierr);
1420854ce69bSBarry Smith     ierr        = PetscMalloc(dsize*count,&link->mem);CHKERRQ(ierr);
1421854ce69bSBarry Smith     link->bytes = dsize*count;
1422aa1993deSMatthew G Knepley   }
1423aa1993deSMatthew G Knepley   link->next   = dm->workout;
1424aa1993deSMatthew G Knepley   dm->workout  = link;
1425aa1993deSMatthew G Knepley   *(void**)mem = link->mem;
1426a89ea682SMatthew G Knepley   PetscFunctionReturn(0);
1427a89ea682SMatthew G Knepley }
1428a89ea682SMatthew G Knepley 
1429aa1993deSMatthew G Knepley /*@C
1430aa1993deSMatthew G Knepley   DMRestoreWorkArray - Restores a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
1431aa1993deSMatthew G Knepley 
1432aa1993deSMatthew G Knepley   Not Collective
1433aa1993deSMatthew G Knepley 
1434aa1993deSMatthew G Knepley   Input Parameters:
1435aa1993deSMatthew G Knepley + dm - the DM object
1436aa1993deSMatthew G Knepley . count - The minium size
143769291d52SBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, MPIU_INT
1438aa1993deSMatthew G Knepley 
1439aa1993deSMatthew G Knepley   Output Parameter:
1440aa1993deSMatthew G Knepley . array - the work array
1441aa1993deSMatthew G Knepley 
1442aa1993deSMatthew G Knepley   Level: developer
1443aa1993deSMatthew G Knepley 
144495452b02SPatrick Sanan   Developer Notes:
144595452b02SPatrick Sanan     count and dtype are ignored, they are only needed for DMGetWorkArray()
1446aa1993deSMatthew G Knepley .seealso DMDestroy(), DMCreate()
1447aa1993deSMatthew G Knepley @*/
144869291d52SBarry Smith PetscErrorCode DMRestoreWorkArray(DM dm,PetscInt count,MPI_Datatype dtype,void *mem)
1449aa1993deSMatthew G Knepley {
1450aa1993deSMatthew G Knepley   DMWorkLink *p,link;
1451aa1993deSMatthew G Knepley 
1452aa1993deSMatthew G Knepley   PetscFunctionBegin;
1453aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1454aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
1455aa1993deSMatthew G Knepley   for (p=&dm->workout; (link=*p); p=&link->next) {
1456aa1993deSMatthew G Knepley     if (link->mem == *(void**)mem) {
1457aa1993deSMatthew G Knepley       *p           = link->next;
1458aa1993deSMatthew G Knepley       link->next   = dm->workin;
1459aa1993deSMatthew G Knepley       dm->workin   = link;
14600298fd71SBarry Smith       *(void**)mem = NULL;
1461aa1993deSMatthew G Knepley       PetscFunctionReturn(0);
1462aa1993deSMatthew G Knepley     }
1463aa1993deSMatthew G Knepley   }
1464aa1993deSMatthew G Knepley   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out");
1465aa1993deSMatthew G Knepley }
1466e7c4fc90SDmitry Karpeev 
1467435a35e8SMatthew G Knepley PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace))
1468435a35e8SMatthew G Knepley {
1469435a35e8SMatthew G Knepley   PetscFunctionBegin;
1470435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
147182f516ccSBarry Smith   if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field);
1472435a35e8SMatthew G Knepley   dm->nullspaceConstructors[field] = nullsp;
1473435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1474435a35e8SMatthew G Knepley }
1475435a35e8SMatthew G Knepley 
14760a50eb56SMatthew G. Knepley PetscErrorCode DMGetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace))
14770a50eb56SMatthew G. Knepley {
14780a50eb56SMatthew G. Knepley   PetscFunctionBegin;
14790a50eb56SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1480f9d4088aSMatthew G. Knepley   PetscValidPointer(nullsp, 3);
14810a50eb56SMatthew G. Knepley   if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field);
14820a50eb56SMatthew G. Knepley   *nullsp = dm->nullspaceConstructors[field];
14830a50eb56SMatthew G. Knepley   PetscFunctionReturn(0);
14840a50eb56SMatthew G. Knepley }
14850a50eb56SMatthew G. Knepley 
1486f9d4088aSMatthew G. Knepley PetscErrorCode DMSetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace))
1487f9d4088aSMatthew G. Knepley {
1488f9d4088aSMatthew G. Knepley   PetscFunctionBegin;
1489f9d4088aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1490f9d4088aSMatthew G. Knepley   if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field);
1491f9d4088aSMatthew G. Knepley   dm->nearnullspaceConstructors[field] = nullsp;
1492f9d4088aSMatthew G. Knepley   PetscFunctionReturn(0);
1493f9d4088aSMatthew G. Knepley }
1494f9d4088aSMatthew G. Knepley 
1495f9d4088aSMatthew G. Knepley PetscErrorCode DMGetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace))
1496f9d4088aSMatthew G. Knepley {
1497f9d4088aSMatthew G. Knepley   PetscFunctionBegin;
1498f9d4088aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1499f9d4088aSMatthew G. Knepley   PetscValidPointer(nullsp, 3);
1500f9d4088aSMatthew G. Knepley   if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field);
1501f9d4088aSMatthew G. Knepley   *nullsp = dm->nearnullspaceConstructors[field];
1502f9d4088aSMatthew G. Knepley   PetscFunctionReturn(0);
1503f9d4088aSMatthew G. Knepley }
1504f9d4088aSMatthew G. Knepley 
15054f3b5142SJed Brown /*@C
15064d343eeaSMatthew G Knepley   DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field
15074d343eeaSMatthew G Knepley 
15084d343eeaSMatthew G Knepley   Not collective
15094d343eeaSMatthew G Knepley 
15104d343eeaSMatthew G Knepley   Input Parameter:
15114d343eeaSMatthew G Knepley . dm - the DM object
15124d343eeaSMatthew G Knepley 
15134d343eeaSMatthew G Knepley   Output Parameters:
15140298fd71SBarry Smith + numFields  - The number of fields (or NULL if not requested)
15150298fd71SBarry Smith . fieldNames - The name for each field (or NULL if not requested)
15160298fd71SBarry Smith - fields     - The global indices for each field (or NULL if not requested)
15174d343eeaSMatthew G Knepley 
15184d343eeaSMatthew G Knepley   Level: intermediate
15194d343eeaSMatthew G Knepley 
152021c9b008SJed Brown   Notes:
152121c9b008SJed Brown   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
152221c9b008SJed Brown   PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with
152321c9b008SJed Brown   PetscFree().
152421c9b008SJed Brown 
15254d343eeaSMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
15264d343eeaSMatthew G Knepley @*/
152737d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields)
15284d343eeaSMatthew G Knepley {
152937d0c07bSMatthew G Knepley   PetscSection   section, sectionGlobal;
15304d343eeaSMatthew G Knepley   PetscErrorCode ierr;
15314d343eeaSMatthew G Knepley 
15324d343eeaSMatthew G Knepley   PetscFunctionBegin;
15334d343eeaSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
153469ca1f37SDmitry Karpeev   if (numFields) {
1535534a8f05SLisandro Dalcin     PetscValidIntPointer(numFields,2);
153669ca1f37SDmitry Karpeev     *numFields = 0;
153769ca1f37SDmitry Karpeev   }
153837d0c07bSMatthew G Knepley   if (fieldNames) {
153937d0c07bSMatthew G Knepley     PetscValidPointer(fieldNames,3);
15400298fd71SBarry Smith     *fieldNames = NULL;
154169ca1f37SDmitry Karpeev   }
154269ca1f37SDmitry Karpeev   if (fields) {
154369ca1f37SDmitry Karpeev     PetscValidPointer(fields,4);
15440298fd71SBarry Smith     *fields = NULL;
154569ca1f37SDmitry Karpeev   }
154692fd8e1eSJed Brown   ierr = DMGetLocalSection(dm, &section);CHKERRQ(ierr);
154737d0c07bSMatthew G Knepley   if (section) {
15483a544194SStefano Zampini     PetscInt *fieldSizes, *fieldNc, **fieldIndices;
154937d0c07bSMatthew G Knepley     PetscInt nF, f, pStart, pEnd, p;
155037d0c07bSMatthew G Knepley 
1551e87a4003SBarry Smith     ierr = DMGetGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
155237d0c07bSMatthew G Knepley     ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr);
15533a544194SStefano Zampini     ierr = PetscMalloc3(nF,&fieldSizes,nF,&fieldNc,nF,&fieldIndices);CHKERRQ(ierr);
155437d0c07bSMatthew G Knepley     ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr);
155537d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
155637d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
15573a544194SStefano Zampini       ierr          = PetscSectionGetFieldComponents(section, f, &fieldNc[f]);CHKERRQ(ierr);
155837d0c07bSMatthew G Knepley     }
155937d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
156037d0c07bSMatthew G Knepley       PetscInt gdof;
156137d0c07bSMatthew G Knepley 
156237d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
156337d0c07bSMatthew G Knepley       if (gdof > 0) {
156437d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
15653a544194SStefano Zampini           PetscInt fdof, fcdof, fpdof;
156637d0c07bSMatthew G Knepley 
156737d0c07bSMatthew G Knepley           ierr  = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
156837d0c07bSMatthew G Knepley           ierr  = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
15693a544194SStefano Zampini           fpdof = fdof-fcdof;
15703a544194SStefano Zampini           if (fpdof && fpdof != fieldNc[f]) {
15713a544194SStefano Zampini             /* Layout does not admit a pointwise block size */
15723a544194SStefano Zampini             fieldNc[f] = 1;
15733a544194SStefano Zampini           }
15743a544194SStefano Zampini           fieldSizes[f] += fpdof;
157537d0c07bSMatthew G Knepley         }
157637d0c07bSMatthew G Knepley       }
157737d0c07bSMatthew G Knepley     }
157837d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
1579785e854fSJed Brown       ierr          = PetscMalloc1(fieldSizes[f], &fieldIndices[f]);CHKERRQ(ierr);
158037d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
158137d0c07bSMatthew G Knepley     }
158237d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
158337d0c07bSMatthew G Knepley       PetscInt gdof, goff;
158437d0c07bSMatthew G Knepley 
158537d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
158637d0c07bSMatthew G Knepley       if (gdof > 0) {
158737d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr);
158837d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
158937d0c07bSMatthew G Knepley           PetscInt fdof, fcdof, fc;
159037d0c07bSMatthew G Knepley 
159137d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
159237d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
159337d0c07bSMatthew G Knepley           for (fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) {
159437d0c07bSMatthew G Knepley             fieldIndices[f][fieldSizes[f]] = goff++;
159537d0c07bSMatthew G Knepley           }
159637d0c07bSMatthew G Knepley         }
159737d0c07bSMatthew G Knepley       }
159837d0c07bSMatthew G Knepley     }
15998865f1eaSKarl Rupp     if (numFields) *numFields = nF;
160037d0c07bSMatthew G Knepley     if (fieldNames) {
1601785e854fSJed Brown       ierr = PetscMalloc1(nF, fieldNames);CHKERRQ(ierr);
160237d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
160337d0c07bSMatthew G Knepley         const char *fieldName;
160437d0c07bSMatthew G Knepley 
160537d0c07bSMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
160637d0c07bSMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char**) &(*fieldNames)[f]);CHKERRQ(ierr);
160737d0c07bSMatthew G Knepley       }
160837d0c07bSMatthew G Knepley     }
160937d0c07bSMatthew G Knepley     if (fields) {
1610785e854fSJed Brown       ierr = PetscMalloc1(nF, fields);CHKERRQ(ierr);
161137d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
16123a544194SStefano Zampini         PetscInt bs, in[2], out[2];
16133a544194SStefano Zampini 
161482f516ccSBarry Smith         ierr  = ISCreateGeneral(PetscObjectComm((PetscObject)dm), fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr);
16153a544194SStefano Zampini         in[0] = -fieldNc[f];
16163a544194SStefano Zampini         in[1] = fieldNc[f];
16173a544194SStefano Zampini         ierr  = MPIU_Allreduce(in, out, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
16183a544194SStefano Zampini         bs    = (-out[0] == out[1]) ? out[1] : 1;
16193a544194SStefano Zampini         ierr  = ISSetBlockSize((*fields)[f], bs);CHKERRQ(ierr);
162037d0c07bSMatthew G Knepley       }
162137d0c07bSMatthew G Knepley     }
16223a544194SStefano Zampini     ierr = PetscFree3(fieldSizes,fieldNc,fieldIndices);CHKERRQ(ierr);
16238865f1eaSKarl Rupp   } else if (dm->ops->createfieldis) {
16248865f1eaSKarl Rupp     ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr);
162569ca1f37SDmitry Karpeev   }
16264d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
16274d343eeaSMatthew G Knepley }
16284d343eeaSMatthew G Knepley 
162916621825SDmitry Karpeev 
163016621825SDmitry Karpeev /*@C
163116621825SDmitry Karpeev   DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems
163216621825SDmitry Karpeev                           corresponding to different fields: each IS contains the global indices of the dofs of the
163316621825SDmitry Karpeev                           corresponding field. The optional list of DMs define the DM for each subproblem.
1634e7c4fc90SDmitry Karpeev                           Generalizes DMCreateFieldIS().
1635e7c4fc90SDmitry Karpeev 
1636e7c4fc90SDmitry Karpeev   Not collective
1637e7c4fc90SDmitry Karpeev 
1638e7c4fc90SDmitry Karpeev   Input Parameter:
1639e7c4fc90SDmitry Karpeev . dm - the DM object
1640e7c4fc90SDmitry Karpeev 
1641e7c4fc90SDmitry Karpeev   Output Parameters:
16420298fd71SBarry Smith + len       - The number of subproblems in the field decomposition (or NULL if not requested)
16430298fd71SBarry Smith . namelist  - The name for each field (or NULL if not requested)
16440298fd71SBarry Smith . islist    - The global indices for each field (or NULL if not requested)
16450298fd71SBarry Smith - dmlist    - The DMs for each field subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined)
1646e7c4fc90SDmitry Karpeev 
1647e7c4fc90SDmitry Karpeev   Level: intermediate
1648e7c4fc90SDmitry Karpeev 
1649e7c4fc90SDmitry Karpeev   Notes:
1650e7c4fc90SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
1651e7c4fc90SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
1652e7c4fc90SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
1653e7c4fc90SDmitry Karpeev 
1654e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1655e7c4fc90SDmitry Karpeev @*/
165616621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
1657e7c4fc90SDmitry Karpeev {
1658e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
1659e7c4fc90SDmitry Karpeev 
1660e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
1661e7c4fc90SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
16628865f1eaSKarl Rupp   if (len) {
1663534a8f05SLisandro Dalcin     PetscValidIntPointer(len,2);
16648865f1eaSKarl Rupp     *len = 0;
16658865f1eaSKarl Rupp   }
16668865f1eaSKarl Rupp   if (namelist) {
16678865f1eaSKarl Rupp     PetscValidPointer(namelist,3);
16688865f1eaSKarl Rupp     *namelist = 0;
16698865f1eaSKarl Rupp   }
16708865f1eaSKarl Rupp   if (islist) {
16718865f1eaSKarl Rupp     PetscValidPointer(islist,4);
16728865f1eaSKarl Rupp     *islist = 0;
16738865f1eaSKarl Rupp   }
16748865f1eaSKarl Rupp   if (dmlist) {
16758865f1eaSKarl Rupp     PetscValidPointer(dmlist,5);
16768865f1eaSKarl Rupp     *dmlist = 0;
16778865f1eaSKarl Rupp   }
1678f3f0edfdSDmitry Karpeev   /*
1679f3f0edfdSDmitry Karpeev    Is it a good idea to apply the following check across all impls?
1680f3f0edfdSDmitry Karpeev    Perhaps some impls can have a well-defined decomposition before DMSetUp?
1681f3f0edfdSDmitry Karpeev    This, however, follows the general principle that accessors are not well-behaved until the object is set up.
1682f3f0edfdSDmitry Karpeev    */
1683ce94432eSBarry Smith   if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp");
168416621825SDmitry Karpeev   if (!dm->ops->createfielddecomposition) {
1685435a35e8SMatthew G Knepley     PetscSection section;
1686435a35e8SMatthew G Knepley     PetscInt     numFields, f;
1687435a35e8SMatthew G Knepley 
168892fd8e1eSJed Brown     ierr = DMGetLocalSection(dm, &section);CHKERRQ(ierr);
1689435a35e8SMatthew G Knepley     if (section) {ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr);}
1690435a35e8SMatthew G Knepley     if (section && numFields && dm->ops->createsubdm) {
1691f25d98f1SMatthew G. Knepley       if (len) *len = numFields;
169203dc3394SMatthew G. Knepley       if (namelist) {ierr = PetscMalloc1(numFields,namelist);CHKERRQ(ierr);}
169303dc3394SMatthew G. Knepley       if (islist)   {ierr = PetscMalloc1(numFields,islist);CHKERRQ(ierr);}
169403dc3394SMatthew G. Knepley       if (dmlist)   {ierr = PetscMalloc1(numFields,dmlist);CHKERRQ(ierr);}
1695435a35e8SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
1696435a35e8SMatthew G Knepley         const char *fieldName;
1697435a35e8SMatthew G Knepley 
169803dc3394SMatthew G. Knepley         ierr = DMCreateSubDM(dm, 1, &f, islist ? &(*islist)[f] : NULL, dmlist ? &(*dmlist)[f] : NULL);CHKERRQ(ierr);
169903dc3394SMatthew G. Knepley         if (namelist) {
1700435a35e8SMatthew G Knepley           ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
1701435a35e8SMatthew G Knepley           ierr = PetscStrallocpy(fieldName, (char**) &(*namelist)[f]);CHKERRQ(ierr);
1702435a35e8SMatthew G Knepley         }
170303dc3394SMatthew G. Knepley       }
1704435a35e8SMatthew G Knepley     } else {
170569ca1f37SDmitry Karpeev       ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr);
1706e7c4fc90SDmitry Karpeev       /* By default there are no DMs associated with subproblems. */
17070298fd71SBarry Smith       if (dmlist) *dmlist = NULL;
1708e7c4fc90SDmitry Karpeev     }
17098865f1eaSKarl Rupp   } else {
171016621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist);CHKERRQ(ierr);
171116621825SDmitry Karpeev   }
171216621825SDmitry Karpeev   PetscFunctionReturn(0);
171316621825SDmitry Karpeev }
171416621825SDmitry Karpeev 
1715564cec59SMatthew G. Knepley /*@
1716435a35e8SMatthew G Knepley   DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in.
1717435a35e8SMatthew G Knepley                   The fields are defined by DMCreateFieldIS().
1718435a35e8SMatthew G Knepley 
1719435a35e8SMatthew G Knepley   Not collective
1720435a35e8SMatthew G Knepley 
1721435a35e8SMatthew G Knepley   Input Parameters:
17222adcc780SMatthew G. Knepley + dm        - The DM object
17232adcc780SMatthew G. Knepley . numFields - The number of fields in this subproblem
17242adcc780SMatthew G. Knepley - fields    - The field numbers of the selected fields
1725435a35e8SMatthew G Knepley 
1726435a35e8SMatthew G Knepley   Output Parameters:
17272adcc780SMatthew G. Knepley + is - The global indices for the subproblem
17282adcc780SMatthew G. Knepley - subdm - The DM for the subproblem
1729435a35e8SMatthew G Knepley 
17305d3b26e6SMatthew G. Knepley   Note: You need to call DMPlexSetMigrationSF() on the original DM if you want the Global-To-Natural map to be automatically constructed
17315d3b26e6SMatthew G. Knepley 
1732435a35e8SMatthew G Knepley   Level: intermediate
1733435a35e8SMatthew G Knepley 
17345d3b26e6SMatthew G. Knepley .seealso DMPlexSetMigrationSF(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1735435a35e8SMatthew G Knepley @*/
173637bc7515SMatthew G. Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
1737435a35e8SMatthew G Knepley {
1738435a35e8SMatthew G Knepley   PetscErrorCode ierr;
1739435a35e8SMatthew G Knepley 
1740435a35e8SMatthew G Knepley   PetscFunctionBegin;
1741435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1742435a35e8SMatthew G Knepley   PetscValidPointer(fields,3);
17438865f1eaSKarl Rupp   if (is) PetscValidPointer(is,4);
17448865f1eaSKarl Rupp   if (subdm) PetscValidPointer(subdm,5);
1745b9d85ea2SLisandro Dalcin   if (!dm->ops->createsubdm) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateSubDM",((PetscObject)dm)->type_name);
1746435a35e8SMatthew G Knepley   ierr = (*dm->ops->createsubdm)(dm, numFields, fields, is, subdm);CHKERRQ(ierr);
1747435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1748435a35e8SMatthew G Knepley }
1749435a35e8SMatthew G Knepley 
17502adcc780SMatthew G. Knepley /*@C
17512adcc780SMatthew G. Knepley   DMCreateSuperDM - Returns an arrays of ISes and DM encapsulating a superproblem defined by the DMs passed in.
17522adcc780SMatthew G. Knepley 
17532adcc780SMatthew G. Knepley   Not collective
17542adcc780SMatthew G. Knepley 
17552adcc780SMatthew G. Knepley   Input Parameter:
17562adcc780SMatthew G. Knepley + dms - The DM objects
17572adcc780SMatthew G. Knepley - len - The number of DMs
17582adcc780SMatthew G. Knepley 
17592adcc780SMatthew G. Knepley   Output Parameters:
1760a42bd24dSMatthew G. Knepley + is - The global indices for the subproblem, or NULL
17612adcc780SMatthew G. Knepley - superdm - The DM for the superproblem
17622adcc780SMatthew G. Knepley 
17635d3b26e6SMatthew G. Knepley   Note: You need to call DMPlexSetMigrationSF() on the original DM if you want the Global-To-Natural map to be automatically constructed
17645d3b26e6SMatthew G. Knepley 
17652adcc780SMatthew G. Knepley   Level: intermediate
17662adcc780SMatthew G. Knepley 
17675d3b26e6SMatthew G. Knepley .seealso DMPlexSetMigrationSF(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
17682adcc780SMatthew G. Knepley @*/
17692adcc780SMatthew G. Knepley PetscErrorCode DMCreateSuperDM(DM dms[], PetscInt len, IS **is, DM *superdm)
17702adcc780SMatthew G. Knepley {
17712adcc780SMatthew G. Knepley   PetscInt       i;
17722adcc780SMatthew G. Knepley   PetscErrorCode ierr;
17732adcc780SMatthew G. Knepley 
17742adcc780SMatthew G. Knepley   PetscFunctionBegin;
17752adcc780SMatthew G. Knepley   PetscValidPointer(dms,1);
17762adcc780SMatthew G. Knepley   for (i = 0; i < len; ++i) {PetscValidHeaderSpecific(dms[i],DM_CLASSID,1);}
17772adcc780SMatthew G. Knepley   if (is) PetscValidPointer(is,3);
1778a42bd24dSMatthew G. Knepley   PetscValidPointer(superdm,4);
17792adcc780SMatthew G. Knepley   if (len < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of DMs must be nonnegative: %D", len);
17802adcc780SMatthew G. Knepley   if (len) {
1781b9d85ea2SLisandro Dalcin     DM dm = dms[0];
1782b9d85ea2SLisandro Dalcin     if (!dm->ops->createsuperdm) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateSuperDM",((PetscObject)dm)->type_name);
1783b9d85ea2SLisandro Dalcin     ierr = (*dm->ops->createsuperdm)(dms, len, is, superdm);CHKERRQ(ierr);
17842adcc780SMatthew G. Knepley   }
17852adcc780SMatthew G. Knepley   PetscFunctionReturn(0);
17862adcc780SMatthew G. Knepley }
17872adcc780SMatthew G. Knepley 
178816621825SDmitry Karpeev 
178916621825SDmitry Karpeev /*@C
17908d4ac253SDmitry Karpeev   DMCreateDomainDecomposition - Returns lists of IS objects defining a decomposition of a problem into subproblems
17918d4ac253SDmitry Karpeev                           corresponding to restrictions to pairs nested subdomains: each IS contains the global
17928d4ac253SDmitry Karpeev                           indices of the dofs of the corresponding subdomains.  The inner subdomains conceptually
17938d4ac253SDmitry Karpeev                           define a nonoverlapping covering, while outer subdomains can overlap.
17948d4ac253SDmitry Karpeev                           The optional list of DMs define the DM for each subproblem.
179516621825SDmitry Karpeev 
179616621825SDmitry Karpeev   Not collective
179716621825SDmitry Karpeev 
179816621825SDmitry Karpeev   Input Parameter:
179916621825SDmitry Karpeev . dm - the DM object
180016621825SDmitry Karpeev 
180116621825SDmitry Karpeev   Output Parameters:
18020298fd71SBarry Smith + len         - The number of subproblems in the domain decomposition (or NULL if not requested)
18030298fd71SBarry Smith . namelist    - The name for each subdomain (or NULL if not requested)
18040298fd71SBarry Smith . innerislist - The global indices for each inner subdomain (or NULL, if not requested)
18050298fd71SBarry Smith . outerislist - The global indices for each outer subdomain (or NULL, if not requested)
18060298fd71SBarry Smith - dmlist      - The DMs for each subdomain subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined)
180716621825SDmitry Karpeev 
180816621825SDmitry Karpeev   Level: intermediate
180916621825SDmitry Karpeev 
181016621825SDmitry Karpeev   Notes:
181116621825SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
181216621825SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
181316621825SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
181416621825SDmitry Karpeev 
18158d4ac253SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateDomainDecompositionDM(), DMCreateFieldDecomposition()
181616621825SDmitry Karpeev @*/
18178d4ac253SDmitry Karpeev PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
181816621825SDmitry Karpeev {
181916621825SDmitry Karpeev   PetscErrorCode      ierr;
1820be081cd6SPeter Brune   DMSubDomainHookLink link;
1821be081cd6SPeter Brune   PetscInt            i,l;
182216621825SDmitry Karpeev 
182316621825SDmitry Karpeev   PetscFunctionBegin;
182416621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
182514a18fd3SPeter Brune   if (len)           {PetscValidPointer(len,2);            *len         = 0;}
18260298fd71SBarry Smith   if (namelist)      {PetscValidPointer(namelist,3);       *namelist    = NULL;}
18270298fd71SBarry Smith   if (innerislist)   {PetscValidPointer(innerislist,4);    *innerislist = NULL;}
18280298fd71SBarry Smith   if (outerislist)   {PetscValidPointer(outerislist,5);    *outerislist = NULL;}
18290298fd71SBarry Smith   if (dmlist)        {PetscValidPointer(dmlist,6);         *dmlist      = NULL;}
1830f3f0edfdSDmitry Karpeev   /*
1831f3f0edfdSDmitry Karpeev    Is it a good idea to apply the following check across all impls?
1832f3f0edfdSDmitry Karpeev    Perhaps some impls can have a well-defined decomposition before DMSetUp?
1833f3f0edfdSDmitry Karpeev    This, however, follows the general principle that accessors are not well-behaved until the object is set up.
1834f3f0edfdSDmitry Karpeev    */
1835ce94432eSBarry Smith   if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp");
183616621825SDmitry Karpeev   if (dm->ops->createdomaindecomposition) {
1837be081cd6SPeter Brune     ierr = (*dm->ops->createdomaindecomposition)(dm,&l,namelist,innerislist,outerislist,dmlist);CHKERRQ(ierr);
183814a18fd3SPeter Brune     /* copy subdomain hooks and context over to the subdomain DMs */
1839f891f5b9SPatrick Sanan     if (dmlist && *dmlist) {
1840be081cd6SPeter Brune       for (i = 0; i < l; i++) {
1841be081cd6SPeter Brune         for (link=dm->subdomainhook; link; link=link->next) {
1842be081cd6SPeter Brune           if (link->ddhook) {ierr = (*link->ddhook)(dm,(*dmlist)[i],link->ctx);CHKERRQ(ierr);}
1843be081cd6SPeter Brune         }
1844648262bbSPatrick Sanan         if (dm->ctx) (*dmlist)[i]->ctx = dm->ctx;
1845e7c4fc90SDmitry Karpeev       }
184614a18fd3SPeter Brune     }
184714a18fd3SPeter Brune     if (len) *len = l;
184814a18fd3SPeter Brune   }
1849e30e807fSPeter Brune   PetscFunctionReturn(0);
1850e30e807fSPeter Brune }
1851e30e807fSPeter Brune 
1852e30e807fSPeter Brune 
1853e30e807fSPeter Brune /*@C
1854e30e807fSPeter Brune   DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector
1855e30e807fSPeter Brune 
1856e30e807fSPeter Brune   Not collective
1857e30e807fSPeter Brune 
1858e30e807fSPeter Brune   Input Parameters:
1859e30e807fSPeter Brune + dm - the DM object
1860e30e807fSPeter Brune . n  - the number of subdomain scatters
1861e30e807fSPeter Brune - subdms - the local subdomains
1862e30e807fSPeter Brune 
1863e30e807fSPeter Brune   Output Parameters:
1864e30e807fSPeter Brune + n     - the number of scatters returned
1865e30e807fSPeter Brune . iscat - scatter from global vector to nonoverlapping global vector entries on subdomain
1866e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain
1867e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts)
1868e30e807fSPeter Brune 
186995452b02SPatrick Sanan   Notes:
187095452b02SPatrick Sanan     This is an alternative to the iis and ois arguments in DMCreateDomainDecomposition that allow for the solution
1871e30e807fSPeter Brune   of general nonlinear problems with overlapping subdomain methods.  While merely having index sets that enable subsets
1872e30e807fSPeter Brune   of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of
1873e30e807fSPeter Brune   solution and residual data.
1874e30e807fSPeter Brune 
1875e30e807fSPeter Brune   Level: developer
1876e30e807fSPeter Brune 
1877e30e807fSPeter Brune .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1878e30e807fSPeter Brune @*/
1879e30e807fSPeter Brune PetscErrorCode DMCreateDomainDecompositionScatters(DM dm,PetscInt n,DM *subdms,VecScatter **iscat,VecScatter **oscat,VecScatter **gscat)
1880e30e807fSPeter Brune {
1881e30e807fSPeter Brune   PetscErrorCode ierr;
1882e30e807fSPeter Brune 
1883e30e807fSPeter Brune   PetscFunctionBegin;
1884e30e807fSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1885e30e807fSPeter Brune   PetscValidPointer(subdms,3);
1886b9d85ea2SLisandro Dalcin   if (!dm->ops->createddscatters) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateDomainDecompositionScatters",((PetscObject)dm)->type_name);
1887e30e807fSPeter Brune   ierr = (*dm->ops->createddscatters)(dm,n,subdms,iscat,oscat,gscat);CHKERRQ(ierr);
1888e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
1889e7c4fc90SDmitry Karpeev }
1890e7c4fc90SDmitry Karpeev 
189147c6ae99SBarry Smith /*@
189247c6ae99SBarry Smith   DMRefine - Refines a DM object
189347c6ae99SBarry Smith 
1894d083f849SBarry Smith   Collective on dm
189547c6ae99SBarry Smith 
189647c6ae99SBarry Smith   Input Parameter:
189747c6ae99SBarry Smith + dm   - the DM object
189891d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
189947c6ae99SBarry Smith 
190047c6ae99SBarry Smith   Output Parameter:
19010298fd71SBarry Smith . dmf - the refined DM, or NULL
1902ae0a1c52SMatthew G Knepley 
19030298fd71SBarry Smith   Note: If no refinement was done, the return value is NULL
190447c6ae99SBarry Smith 
190547c6ae99SBarry Smith   Level: developer
190647c6ae99SBarry Smith 
1907e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
190847c6ae99SBarry Smith @*/
19097087cfbeSBarry Smith PetscErrorCode  DMRefine(DM dm,MPI_Comm comm,DM *dmf)
191047c6ae99SBarry Smith {
191147c6ae99SBarry Smith   PetscErrorCode   ierr;
1912c833c3b5SJed Brown   DMRefineHookLink link;
191347c6ae99SBarry Smith 
191447c6ae99SBarry Smith   PetscFunctionBegin;
1915732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1916b9d85ea2SLisandro Dalcin   if (!dm->ops->refine) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMRefine",((PetscObject)dm)->type_name);
19171ac00216SMatthew G. Knepley   ierr = PetscLogEventBegin(DM_Refine,dm,0,0,0);CHKERRQ(ierr);
191847c6ae99SBarry Smith   ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr);
19194057135bSMatthew G Knepley   if (*dmf) {
192043842a1eSJed Brown     (*dmf)->ops->creatematrix = dm->ops->creatematrix;
19218865f1eaSKarl Rupp 
19228cd211a4SJed Brown     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr);
19238865f1eaSKarl Rupp 
1924644e2e5bSBarry Smith     (*dmf)->ctx       = dm->ctx;
19250598a293SJed Brown     (*dmf)->leveldown = dm->leveldown;
1926656b349aSBarry Smith     (*dmf)->levelup   = dm->levelup + 1;
19278865f1eaSKarl Rupp 
1928e4b4b23bSJed Brown     ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr);
1929c833c3b5SJed Brown     for (link=dm->refinehook; link; link=link->next) {
19308865f1eaSKarl Rupp       if (link->refinehook) {
19318865f1eaSKarl Rupp         ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr);
19328865f1eaSKarl Rupp       }
1933c833c3b5SJed Brown     }
1934c833c3b5SJed Brown   }
19351ac00216SMatthew G. Knepley   ierr = PetscLogEventEnd(DM_Refine,dm,0,0,0);CHKERRQ(ierr);
1936c833c3b5SJed Brown   PetscFunctionReturn(0);
1937c833c3b5SJed Brown }
1938c833c3b5SJed Brown 
1939bb9467b5SJed Brown /*@C
1940c833c3b5SJed Brown    DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid
1941c833c3b5SJed Brown 
1942c833c3b5SJed Brown    Logically Collective
1943c833c3b5SJed Brown 
1944c833c3b5SJed Brown    Input Arguments:
1945c833c3b5SJed Brown +  coarse - nonlinear solver context on which to run a hook when restricting to a coarser level
1946c833c3b5SJed Brown .  refinehook - function to run when setting up a coarser level
1947c833c3b5SJed Brown .  interphook - function to run to update data on finer levels (once per SNESSolve())
19480298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
1949c833c3b5SJed Brown 
1950c833c3b5SJed Brown    Calling sequence of refinehook:
1951c833c3b5SJed Brown $    refinehook(DM coarse,DM fine,void *ctx);
1952c833c3b5SJed Brown 
1953c833c3b5SJed Brown +  coarse - coarse level DM
1954c833c3b5SJed Brown .  fine - fine level DM to interpolate problem to
1955c833c3b5SJed Brown -  ctx - optional user-defined function context
1956c833c3b5SJed Brown 
1957c833c3b5SJed Brown    Calling sequence for interphook:
1958c833c3b5SJed Brown $    interphook(DM coarse,Mat interp,DM fine,void *ctx)
1959c833c3b5SJed Brown 
1960c833c3b5SJed Brown +  coarse - coarse level DM
1961c833c3b5SJed Brown .  interp - matrix interpolating a coarse-level solution to the finer grid
1962c833c3b5SJed Brown .  fine - fine level DM to update
1963c833c3b5SJed Brown -  ctx - optional user-defined function context
1964c833c3b5SJed Brown 
1965c833c3b5SJed Brown    Level: advanced
1966c833c3b5SJed Brown 
1967c833c3b5SJed Brown    Notes:
1968c833c3b5SJed Brown    This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing
1969c833c3b5SJed Brown 
1970c833c3b5SJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1971c833c3b5SJed Brown 
1972bb9467b5SJed Brown    This function is currently not available from Fortran.
1973bb9467b5SJed Brown 
1974c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1975c833c3b5SJed Brown @*/
1976c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx)
1977c833c3b5SJed Brown {
1978c833c3b5SJed Brown   PetscErrorCode   ierr;
1979c833c3b5SJed Brown   DMRefineHookLink link,*p;
1980c833c3b5SJed Brown 
1981c833c3b5SJed Brown   PetscFunctionBegin;
1982c833c3b5SJed Brown   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
19833d8e3701SJed Brown   for (p=&coarse->refinehook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */
19843d8e3701SJed Brown     if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) PetscFunctionReturn(0);
19853d8e3701SJed Brown   }
198695dccacaSBarry Smith   ierr             = PetscNew(&link);CHKERRQ(ierr);
1987c833c3b5SJed Brown   link->refinehook = refinehook;
1988c833c3b5SJed Brown   link->interphook = interphook;
1989c833c3b5SJed Brown   link->ctx        = ctx;
19900298fd71SBarry Smith   link->next       = NULL;
1991c833c3b5SJed Brown   *p               = link;
1992c833c3b5SJed Brown   PetscFunctionReturn(0);
1993c833c3b5SJed Brown }
1994c833c3b5SJed Brown 
19953d8e3701SJed Brown /*@C
19963d8e3701SJed Brown    DMRefineHookRemove - remove a callback from the list of hooks to be run when interpolating a nonlinear problem to a finer grid
19973d8e3701SJed Brown 
19983d8e3701SJed Brown    Logically Collective
19993d8e3701SJed Brown 
20003d8e3701SJed Brown    Input Arguments:
20013d8e3701SJed Brown +  coarse - nonlinear solver context on which to run a hook when restricting to a coarser level
20023d8e3701SJed Brown .  refinehook - function to run when setting up a coarser level
20033d8e3701SJed Brown .  interphook - function to run to update data on finer levels (once per SNESSolve())
20043d8e3701SJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
20053d8e3701SJed Brown 
20063d8e3701SJed Brown    Level: advanced
20073d8e3701SJed Brown 
20083d8e3701SJed Brown    Notes:
20093d8e3701SJed Brown    This function does nothing if the hook is not in the list.
20103d8e3701SJed Brown 
20113d8e3701SJed Brown    This function is currently not available from Fortran.
20123d8e3701SJed Brown 
20133d8e3701SJed Brown .seealso: DMCoarsenHookRemove(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
20143d8e3701SJed Brown @*/
20153d8e3701SJed Brown PetscErrorCode DMRefineHookRemove(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx)
20163d8e3701SJed Brown {
20173d8e3701SJed Brown   PetscErrorCode   ierr;
20183d8e3701SJed Brown   DMRefineHookLink link,*p;
20193d8e3701SJed Brown 
20203d8e3701SJed Brown   PetscFunctionBegin;
20213d8e3701SJed Brown   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
20223d8e3701SJed Brown   for (p=&coarse->refinehook; *p; p=&(*p)->next) { /* Search the list of current hooks */
20233d8e3701SJed Brown     if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) {
20243d8e3701SJed Brown       link = *p;
20253d8e3701SJed Brown       *p = link->next;
20263d8e3701SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
20273d8e3701SJed Brown       break;
20283d8e3701SJed Brown     }
20293d8e3701SJed Brown   }
20303d8e3701SJed Brown   PetscFunctionReturn(0);
20313d8e3701SJed Brown }
20323d8e3701SJed Brown 
2033c833c3b5SJed Brown /*@
2034c833c3b5SJed Brown    DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd()
2035c833c3b5SJed Brown 
2036c833c3b5SJed Brown    Collective if any hooks are
2037c833c3b5SJed Brown 
2038c833c3b5SJed Brown    Input Arguments:
2039c833c3b5SJed Brown +  coarse - coarser DM to use as a base
2040e91eccc2SStefano Zampini .  interp - interpolation matrix, apply using MatInterpolate()
2041c833c3b5SJed Brown -  fine - finer DM to update
2042c833c3b5SJed Brown 
2043c833c3b5SJed Brown    Level: developer
2044c833c3b5SJed Brown 
2045c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate()
2046c833c3b5SJed Brown @*/
2047c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine)
2048c833c3b5SJed Brown {
2049c833c3b5SJed Brown   PetscErrorCode   ierr;
2050c833c3b5SJed Brown   DMRefineHookLink link;
2051c833c3b5SJed Brown 
2052c833c3b5SJed Brown   PetscFunctionBegin;
2053c833c3b5SJed Brown   for (link=fine->refinehook; link; link=link->next) {
20548865f1eaSKarl Rupp     if (link->interphook) {
20558865f1eaSKarl Rupp       ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr);
20568865f1eaSKarl Rupp     }
20574057135bSMatthew G Knepley   }
205847c6ae99SBarry Smith   PetscFunctionReturn(0);
205947c6ae99SBarry Smith }
206047c6ae99SBarry Smith 
2061eb3f98d2SBarry Smith /*@
2062eb3f98d2SBarry Smith     DMGetRefineLevel - Get's the number of refinements that have generated this DM.
2063eb3f98d2SBarry Smith 
2064eb3f98d2SBarry Smith     Not Collective
2065eb3f98d2SBarry Smith 
2066eb3f98d2SBarry Smith     Input Parameter:
2067eb3f98d2SBarry Smith .   dm - the DM object
2068eb3f98d2SBarry Smith 
2069eb3f98d2SBarry Smith     Output Parameter:
2070eb3f98d2SBarry Smith .   level - number of refinements
2071eb3f98d2SBarry Smith 
2072eb3f98d2SBarry Smith     Level: developer
2073eb3f98d2SBarry Smith 
20746a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
2075eb3f98d2SBarry Smith 
2076eb3f98d2SBarry Smith @*/
2077eb3f98d2SBarry Smith PetscErrorCode  DMGetRefineLevel(DM dm,PetscInt *level)
2078eb3f98d2SBarry Smith {
2079eb3f98d2SBarry Smith   PetscFunctionBegin;
2080eb3f98d2SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2081eb3f98d2SBarry Smith   *level = dm->levelup;
2082eb3f98d2SBarry Smith   PetscFunctionReturn(0);
2083eb3f98d2SBarry Smith }
2084eb3f98d2SBarry Smith 
2085fef3a512SBarry Smith /*@
2086fef3a512SBarry Smith     DMSetRefineLevel - Set's the number of refinements that have generated this DM.
2087fef3a512SBarry Smith 
2088fef3a512SBarry Smith     Not Collective
2089fef3a512SBarry Smith 
2090fef3a512SBarry Smith     Input Parameter:
2091fef3a512SBarry Smith +   dm - the DM object
2092fef3a512SBarry Smith -   level - number of refinements
2093fef3a512SBarry Smith 
2094fef3a512SBarry Smith     Level: advanced
2095fef3a512SBarry Smith 
209695452b02SPatrick Sanan     Notes:
209795452b02SPatrick Sanan     This value is used by PCMG to determine how many multigrid levels to use
2098fef3a512SBarry Smith 
2099fef3a512SBarry Smith .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
2100fef3a512SBarry Smith 
2101fef3a512SBarry Smith @*/
2102fef3a512SBarry Smith PetscErrorCode  DMSetRefineLevel(DM dm,PetscInt level)
2103fef3a512SBarry Smith {
2104fef3a512SBarry Smith   PetscFunctionBegin;
2105fef3a512SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2106fef3a512SBarry Smith   dm->levelup = level;
2107fef3a512SBarry Smith   PetscFunctionReturn(0);
2108fef3a512SBarry Smith }
2109fef3a512SBarry Smith 
2110ca3d3a14SMatthew G. Knepley PetscErrorCode DMGetBasisTransformDM_Internal(DM dm, DM *tdm)
2111ca3d3a14SMatthew G. Knepley {
2112ca3d3a14SMatthew G. Knepley   PetscFunctionBegin;
2113ca3d3a14SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2114ca3d3a14SMatthew G. Knepley   PetscValidPointer(tdm, 2);
2115ca3d3a14SMatthew G. Knepley   *tdm = dm->transformDM;
2116ca3d3a14SMatthew G. Knepley   PetscFunctionReturn(0);
2117ca3d3a14SMatthew G. Knepley }
2118ca3d3a14SMatthew G. Knepley 
2119ca3d3a14SMatthew G. Knepley PetscErrorCode DMGetBasisTransformVec_Internal(DM dm, Vec *tv)
2120ca3d3a14SMatthew G. Knepley {
2121ca3d3a14SMatthew G. Knepley   PetscFunctionBegin;
2122ca3d3a14SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2123ca3d3a14SMatthew G. Knepley   PetscValidPointer(tv, 2);
2124ca3d3a14SMatthew G. Knepley   *tv = dm->transform;
2125ca3d3a14SMatthew G. Knepley   PetscFunctionReturn(0);
2126ca3d3a14SMatthew G. Knepley }
2127ca3d3a14SMatthew G. Knepley 
2128ca3d3a14SMatthew G. Knepley /*@
2129c0f8e1fdSMatthew G. Knepley   DMHasBasisTransform - Whether we employ a basis transformation from functions in global vectors to functions in local vectors
2130ca3d3a14SMatthew G. Knepley 
2131ca3d3a14SMatthew G. Knepley   Input Parameter:
2132ca3d3a14SMatthew G. Knepley . dm - The DM
2133ca3d3a14SMatthew G. Knepley 
2134ca3d3a14SMatthew G. Knepley   Output Parameter:
2135ca3d3a14SMatthew G. Knepley . flg - PETSC_TRUE if a basis transformation should be done
2136ca3d3a14SMatthew G. Knepley 
2137ca3d3a14SMatthew G. Knepley   Level: developer
2138ca3d3a14SMatthew G. Knepley 
2139ca3d3a14SMatthew G. Knepley .seealso: DMPlexGlobalToLocalBasis(), DMPlexLocalToGlobalBasis()()
2140ca3d3a14SMatthew G. Knepley @*/
2141ca3d3a14SMatthew G. Knepley PetscErrorCode DMHasBasisTransform(DM dm, PetscBool *flg)
2142ca3d3a14SMatthew G. Knepley {
2143ca3d3a14SMatthew G. Knepley   Vec            tv;
2144ca3d3a14SMatthew G. Knepley   PetscErrorCode ierr;
2145ca3d3a14SMatthew G. Knepley 
2146ca3d3a14SMatthew G. Knepley   PetscFunctionBegin;
2147ca3d3a14SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2148534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg, 2);
2149ca3d3a14SMatthew G. Knepley   ierr = DMGetBasisTransformVec_Internal(dm, &tv);CHKERRQ(ierr);
2150ca3d3a14SMatthew G. Knepley   *flg = tv ? PETSC_TRUE : PETSC_FALSE;
2151ca3d3a14SMatthew G. Knepley   PetscFunctionReturn(0);
2152ca3d3a14SMatthew G. Knepley }
2153ca3d3a14SMatthew G. Knepley 
2154ca3d3a14SMatthew G. Knepley PetscErrorCode DMConstructBasisTransform_Internal(DM dm)
2155ca3d3a14SMatthew G. Knepley {
2156ca3d3a14SMatthew G. Knepley   PetscSection   s, ts;
2157ca3d3a14SMatthew G. Knepley   PetscScalar   *ta;
2158ca3d3a14SMatthew G. Knepley   PetscInt       cdim, pStart, pEnd, p, Nf, f, Nc, dof;
2159ca3d3a14SMatthew G. Knepley   PetscErrorCode ierr;
2160ca3d3a14SMatthew G. Knepley 
2161ca3d3a14SMatthew G. Knepley   PetscFunctionBegin;
2162ca3d3a14SMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
216392fd8e1eSJed Brown   ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr);
2164ca3d3a14SMatthew G. Knepley   ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr);
2165ca3d3a14SMatthew G. Knepley   ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr);
2166ca3d3a14SMatthew G. Knepley   ierr = DMClone(dm, &dm->transformDM);CHKERRQ(ierr);
216792fd8e1eSJed Brown   ierr = DMGetLocalSection(dm->transformDM, &ts);CHKERRQ(ierr);
2168ca3d3a14SMatthew G. Knepley   ierr = PetscSectionSetNumFields(ts, Nf);CHKERRQ(ierr);
2169ca3d3a14SMatthew G. Knepley   ierr = PetscSectionSetChart(ts, pStart, pEnd);CHKERRQ(ierr);
2170ca3d3a14SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
2171ca3d3a14SMatthew G. Knepley     ierr = PetscSectionGetFieldComponents(s, f, &Nc);CHKERRQ(ierr);
2172ca3d3a14SMatthew G. Knepley     /* We could start to label fields by their transformation properties */
2173ca3d3a14SMatthew G. Knepley     if (Nc != cdim) continue;
2174ca3d3a14SMatthew G. Knepley     for (p = pStart; p < pEnd; ++p) {
2175ca3d3a14SMatthew G. Knepley       ierr = PetscSectionGetFieldDof(s, p, f, &dof);CHKERRQ(ierr);
2176ca3d3a14SMatthew G. Knepley       if (!dof) continue;
2177ca3d3a14SMatthew G. Knepley       ierr = PetscSectionSetFieldDof(ts, p, f, PetscSqr(cdim));CHKERRQ(ierr);
2178ca3d3a14SMatthew G. Knepley       ierr = PetscSectionAddDof(ts, p, PetscSqr(cdim));CHKERRQ(ierr);
2179ca3d3a14SMatthew G. Knepley     }
2180ca3d3a14SMatthew G. Knepley   }
2181ca3d3a14SMatthew G. Knepley   ierr = PetscSectionSetUp(ts);CHKERRQ(ierr);
2182ca3d3a14SMatthew G. Knepley   ierr = DMCreateLocalVector(dm->transformDM, &dm->transform);CHKERRQ(ierr);
2183ca3d3a14SMatthew G. Knepley   ierr = VecGetArray(dm->transform, &ta);CHKERRQ(ierr);
2184ca3d3a14SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2185ca3d3a14SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
2186ca3d3a14SMatthew G. Knepley       ierr = PetscSectionGetFieldDof(ts, p, f, &dof);CHKERRQ(ierr);
2187ca3d3a14SMatthew G. Knepley       if (dof) {
2188ca3d3a14SMatthew G. Knepley         PetscReal          x[3] = {0.0, 0.0, 0.0};
2189ca3d3a14SMatthew G. Knepley         PetscScalar       *tva;
2190ca3d3a14SMatthew G. Knepley         const PetscScalar *A;
2191ca3d3a14SMatthew G. Knepley 
2192ca3d3a14SMatthew G. Knepley         /* TODO Get quadrature point for this dual basis vector for coordinate */
2193ca3d3a14SMatthew G. Knepley         ierr = (*dm->transformGetMatrix)(dm, x, PETSC_TRUE, &A, dm->transformCtx);CHKERRQ(ierr);
2194ca3d3a14SMatthew G. Knepley         ierr = DMPlexPointLocalFieldRef(dm->transformDM, p, f, ta, (void *) &tva);CHKERRQ(ierr);
2195580bdb30SBarry Smith         ierr = PetscArraycpy(tva, A, PetscSqr(cdim));CHKERRQ(ierr);
2196ca3d3a14SMatthew G. Knepley       }
2197ca3d3a14SMatthew G. Knepley     }
2198ca3d3a14SMatthew G. Knepley   }
2199ca3d3a14SMatthew G. Knepley   ierr = VecRestoreArray(dm->transform, &ta);CHKERRQ(ierr);
2200ca3d3a14SMatthew G. Knepley   PetscFunctionReturn(0);
2201ca3d3a14SMatthew G. Knepley }
2202ca3d3a14SMatthew G. Knepley 
2203ca3d3a14SMatthew G. Knepley PetscErrorCode DMCopyTransform(DM dm, DM newdm)
2204ca3d3a14SMatthew G. Knepley {
2205ca3d3a14SMatthew G. Knepley   PetscErrorCode ierr;
2206ca3d3a14SMatthew G. Knepley 
2207ca3d3a14SMatthew G. Knepley   PetscFunctionBegin;
2208ca3d3a14SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2209ca3d3a14SMatthew G. Knepley   PetscValidHeaderSpecific(newdm, DM_CLASSID, 2);
2210ca3d3a14SMatthew G. Knepley   newdm->transformCtx       = dm->transformCtx;
2211ca3d3a14SMatthew G. Knepley   newdm->transformSetUp     = dm->transformSetUp;
2212ca3d3a14SMatthew G. Knepley   newdm->transformDestroy   = NULL;
2213ca3d3a14SMatthew G. Knepley   newdm->transformGetMatrix = dm->transformGetMatrix;
2214ca3d3a14SMatthew G. Knepley   if (newdm->transformSetUp) {ierr = DMConstructBasisTransform_Internal(newdm);CHKERRQ(ierr);}
2215ca3d3a14SMatthew G. Knepley   PetscFunctionReturn(0);
2216ca3d3a14SMatthew G. Knepley }
2217ca3d3a14SMatthew G. Knepley 
2218bb9467b5SJed Brown /*@C
2219baf369e7SPeter Brune    DMGlobalToLocalHookAdd - adds a callback to be run when global to local is called
2220baf369e7SPeter Brune 
2221baf369e7SPeter Brune    Logically Collective
2222baf369e7SPeter Brune 
2223baf369e7SPeter Brune    Input Arguments:
2224baf369e7SPeter Brune +  dm - the DM
2225baf369e7SPeter Brune .  beginhook - function to run at the beginning of DMGlobalToLocalBegin()
2226baf369e7SPeter Brune .  endhook - function to run after DMGlobalToLocalEnd() has completed
22270298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
2228baf369e7SPeter Brune 
2229baf369e7SPeter Brune    Calling sequence for beginhook:
2230baf369e7SPeter Brune $    beginhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
2231baf369e7SPeter Brune 
2232baf369e7SPeter Brune +  dm - global DM
2233baf369e7SPeter Brune .  g - global vector
2234baf369e7SPeter Brune .  mode - mode
2235baf369e7SPeter Brune .  l - local vector
2236baf369e7SPeter Brune -  ctx - optional user-defined function context
2237baf369e7SPeter Brune 
2238baf369e7SPeter Brune 
2239baf369e7SPeter Brune    Calling sequence for endhook:
2240ec4806b8SPeter Brune $    endhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
2241baf369e7SPeter Brune 
2242baf369e7SPeter Brune +  global - global DM
2243baf369e7SPeter Brune -  ctx - optional user-defined function context
2244baf369e7SPeter Brune 
2245baf369e7SPeter Brune    Level: advanced
2246baf369e7SPeter Brune 
2247baf369e7SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
2248baf369e7SPeter Brune @*/
2249baf369e7SPeter Brune PetscErrorCode DMGlobalToLocalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx)
2250baf369e7SPeter Brune {
2251baf369e7SPeter Brune   PetscErrorCode          ierr;
2252baf369e7SPeter Brune   DMGlobalToLocalHookLink link,*p;
2253baf369e7SPeter Brune 
2254baf369e7SPeter Brune   PetscFunctionBegin;
2255baf369e7SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2256baf369e7SPeter Brune   for (p=&dm->gtolhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
225795dccacaSBarry Smith   ierr            = PetscNew(&link);CHKERRQ(ierr);
2258baf369e7SPeter Brune   link->beginhook = beginhook;
2259baf369e7SPeter Brune   link->endhook   = endhook;
2260baf369e7SPeter Brune   link->ctx       = ctx;
22610298fd71SBarry Smith   link->next      = NULL;
2262baf369e7SPeter Brune   *p              = link;
2263baf369e7SPeter Brune   PetscFunctionReturn(0);
2264baf369e7SPeter Brune }
2265baf369e7SPeter Brune 
22664c274da1SToby Isaac static PetscErrorCode DMGlobalToLocalHook_Constraints(DM dm, Vec g, InsertMode mode, Vec l, void *ctx)
22674c274da1SToby Isaac {
22684c274da1SToby Isaac   Mat cMat;
22694c274da1SToby Isaac   Vec cVec;
22704c274da1SToby Isaac   PetscSection section, cSec;
22714c274da1SToby Isaac   PetscInt pStart, pEnd, p, dof;
22724c274da1SToby Isaac   PetscErrorCode ierr;
22734c274da1SToby Isaac 
22744c274da1SToby Isaac   PetscFunctionBegin;
22754c274da1SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
22764c274da1SToby Isaac   ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr);
22774c274da1SToby Isaac   if (cMat && (mode == INSERT_VALUES || mode == INSERT_ALL_VALUES || mode == INSERT_BC_VALUES)) {
22785db9a05bSToby Isaac     PetscInt nRows;
22795db9a05bSToby Isaac 
22805db9a05bSToby Isaac     ierr = MatGetSize(cMat,&nRows,NULL);CHKERRQ(ierr);
22815db9a05bSToby Isaac     if (nRows <= 0) PetscFunctionReturn(0);
228292fd8e1eSJed Brown     ierr = DMGetLocalSection(dm,&section);CHKERRQ(ierr);
22837711e48fSToby Isaac     ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr);
22844c274da1SToby Isaac     ierr = MatMult(cMat,l,cVec);CHKERRQ(ierr);
22854c274da1SToby Isaac     ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr);
22864c274da1SToby Isaac     for (p = pStart; p < pEnd; p++) {
22874c274da1SToby Isaac       ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr);
22884c274da1SToby Isaac       if (dof) {
22894c274da1SToby Isaac         PetscScalar *vals;
22904c274da1SToby Isaac         ierr = VecGetValuesSection(cVec,cSec,p,&vals);CHKERRQ(ierr);
22914c274da1SToby Isaac         ierr = VecSetValuesSection(l,section,p,vals,INSERT_ALL_VALUES);CHKERRQ(ierr);
22924c274da1SToby Isaac       }
22934c274da1SToby Isaac     }
22944c274da1SToby Isaac     ierr = VecDestroy(&cVec);CHKERRQ(ierr);
22954c274da1SToby Isaac   }
22964c274da1SToby Isaac   PetscFunctionReturn(0);
22974c274da1SToby Isaac }
22984c274da1SToby Isaac 
229947c6ae99SBarry Smith /*@
230001729b5cSPatrick Sanan     DMGlobalToLocal - update local vectors from global vector
230101729b5cSPatrick Sanan 
2302d083f849SBarry Smith     Neighbor-wise Collective on dm
230301729b5cSPatrick Sanan 
230401729b5cSPatrick Sanan     Input Parameters:
230501729b5cSPatrick Sanan +   dm - the DM object
230601729b5cSPatrick Sanan .   g - the global vector
230701729b5cSPatrick Sanan .   mode - INSERT_VALUES or ADD_VALUES
230801729b5cSPatrick Sanan -   l - the local vector
230901729b5cSPatrick Sanan 
231001729b5cSPatrick Sanan     Notes:
231101729b5cSPatrick Sanan     The communication involved in this update can be overlapped with computation by using
231201729b5cSPatrick Sanan     DMGlobalToLocalBegin() and DMGlobalToLocalEnd().
231301729b5cSPatrick Sanan 
231401729b5cSPatrick Sanan     Level: beginner
231501729b5cSPatrick Sanan 
231601729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd()
231701729b5cSPatrick Sanan 
231801729b5cSPatrick Sanan @*/
231901729b5cSPatrick Sanan PetscErrorCode DMGlobalToLocal(DM dm,Vec g,InsertMode mode,Vec l)
232001729b5cSPatrick Sanan {
232101729b5cSPatrick Sanan   PetscErrorCode ierr;
232201729b5cSPatrick Sanan 
232301729b5cSPatrick Sanan   PetscFunctionBegin;
232401729b5cSPatrick Sanan   ierr = DMGlobalToLocalBegin(dm,g,mode,l);CHKERRQ(ierr);
232501729b5cSPatrick Sanan   ierr = DMGlobalToLocalEnd(dm,g,mode,l);CHKERRQ(ierr);
232601729b5cSPatrick Sanan   PetscFunctionReturn(0);
232701729b5cSPatrick Sanan }
232801729b5cSPatrick Sanan 
232901729b5cSPatrick Sanan /*@
233047c6ae99SBarry Smith     DMGlobalToLocalBegin - Begins updating local vectors from global vector
233147c6ae99SBarry Smith 
2332d083f849SBarry Smith     Neighbor-wise Collective on dm
233347c6ae99SBarry Smith 
233447c6ae99SBarry Smith     Input Parameters:
233547c6ae99SBarry Smith +   dm - the DM object
233647c6ae99SBarry Smith .   g - the global vector
233747c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
233847c6ae99SBarry Smith -   l - the local vector
233947c6ae99SBarry Smith 
234001729b5cSPatrick Sanan     Level: intermediate
234147c6ae99SBarry Smith 
234201729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd()
234347c6ae99SBarry Smith 
234447c6ae99SBarry Smith @*/
23457087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
234647c6ae99SBarry Smith {
23477128ae9fSMatthew G Knepley   PetscSF                 sf;
234847c6ae99SBarry Smith   PetscErrorCode          ierr;
2349baf369e7SPeter Brune   DMGlobalToLocalHookLink link;
235047c6ae99SBarry Smith 
235147c6ae99SBarry Smith   PetscFunctionBegin;
2352171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2353baf369e7SPeter Brune   for (link=dm->gtolhook; link; link=link->next) {
23548865f1eaSKarl Rupp     if (link->beginhook) {
23558865f1eaSKarl Rupp       ierr = (*link->beginhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);
23568865f1eaSKarl Rupp     }
2357baf369e7SPeter Brune   }
23581bb6d2a8SBarry Smith   ierr = DMGetSectionSF(dm, &sf);CHKERRQ(ierr);
23597128ae9fSMatthew G Knepley   if (sf) {
2360ae5cfb4aSMatthew G. Knepley     const PetscScalar *gArray;
2361ae5cfb4aSMatthew G. Knepley     PetscScalar       *lArray;
23627128ae9fSMatthew G Knepley 
236382f516ccSBarry Smith     if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
23647128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
2365ae5cfb4aSMatthew G. Knepley     ierr = VecGetArrayRead(g, &gArray);CHKERRQ(ierr);
23667128ae9fSMatthew G Knepley     ierr = PetscSFBcastBegin(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
23677128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
2368ae5cfb4aSMatthew G. Knepley     ierr = VecRestoreArrayRead(g, &gArray);CHKERRQ(ierr);
23697128ae9fSMatthew G Knepley   } else {
237033907cc2SStefano Zampini     if (!dm->ops->globaltolocalbegin) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMGlobalToLocalBegin() for type %s",((PetscObject)dm)->type_name);
2371843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
23727128ae9fSMatthew G Knepley   }
237347c6ae99SBarry Smith   PetscFunctionReturn(0);
237447c6ae99SBarry Smith }
237547c6ae99SBarry Smith 
237647c6ae99SBarry Smith /*@
237747c6ae99SBarry Smith     DMGlobalToLocalEnd - Ends updating local vectors from global vector
237847c6ae99SBarry Smith 
2379d083f849SBarry Smith     Neighbor-wise Collective on dm
238047c6ae99SBarry Smith 
238147c6ae99SBarry Smith     Input Parameters:
238247c6ae99SBarry Smith +   dm - the DM object
238347c6ae99SBarry Smith .   g - the global vector
238447c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
238547c6ae99SBarry Smith -   l - the local vector
238647c6ae99SBarry Smith 
238701729b5cSPatrick Sanan     Level: intermediate
238847c6ae99SBarry Smith 
238901729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd()
239047c6ae99SBarry Smith 
239147c6ae99SBarry Smith @*/
23927087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
239347c6ae99SBarry Smith {
23947128ae9fSMatthew G Knepley   PetscSF                 sf;
239547c6ae99SBarry Smith   PetscErrorCode          ierr;
2396ae5cfb4aSMatthew G. Knepley   const PetscScalar      *gArray;
2397ae5cfb4aSMatthew G. Knepley   PetscScalar            *lArray;
2398ca3d3a14SMatthew G. Knepley   PetscBool               transform;
2399baf369e7SPeter Brune   DMGlobalToLocalHookLink link;
240047c6ae99SBarry Smith 
240147c6ae99SBarry Smith   PetscFunctionBegin;
2402171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
24031bb6d2a8SBarry Smith   ierr = DMGetSectionSF(dm, &sf);CHKERRQ(ierr);
2404ca3d3a14SMatthew G. Knepley   ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr);
24057128ae9fSMatthew G Knepley   if (sf) {
240682f516ccSBarry Smith     if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
24077128ae9fSMatthew G Knepley 
24087128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
2409ae5cfb4aSMatthew G. Knepley     ierr = VecGetArrayRead(g, &gArray);CHKERRQ(ierr);
24107128ae9fSMatthew G Knepley     ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
24117128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
2412ae5cfb4aSMatthew G. Knepley     ierr = VecRestoreArrayRead(g, &gArray);CHKERRQ(ierr);
2413ca3d3a14SMatthew G. Knepley     if (transform) {ierr = DMPlexGlobalToLocalBasis(dm, l);CHKERRQ(ierr);}
24147128ae9fSMatthew G Knepley   } else {
241533907cc2SStefano Zampini     if (!dm->ops->globaltolocalend) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMGlobalToLocalEnd() for type %s",((PetscObject)dm)->type_name);
2416843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
24177128ae9fSMatthew G Knepley   }
24184c274da1SToby Isaac   ierr = DMGlobalToLocalHook_Constraints(dm,g,mode,l,NULL);CHKERRQ(ierr);
2419baf369e7SPeter Brune   for (link=dm->gtolhook; link; link=link->next) {
2420baf369e7SPeter Brune     if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);}
2421baf369e7SPeter Brune   }
242247c6ae99SBarry Smith   PetscFunctionReturn(0);
242347c6ae99SBarry Smith }
242447c6ae99SBarry Smith 
2425d4d07f1eSToby Isaac /*@C
2426d4d07f1eSToby Isaac    DMLocalToGlobalHookAdd - adds a callback to be run when a local to global is called
2427d4d07f1eSToby Isaac 
2428d4d07f1eSToby Isaac    Logically Collective
2429d4d07f1eSToby Isaac 
2430d4d07f1eSToby Isaac    Input Arguments:
2431d4d07f1eSToby Isaac +  dm - the DM
2432d4d07f1eSToby Isaac .  beginhook - function to run at the beginning of DMLocalToGlobalBegin()
2433d4d07f1eSToby Isaac .  endhook - function to run after DMLocalToGlobalEnd() has completed
2434d4d07f1eSToby Isaac -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
2435d4d07f1eSToby Isaac 
2436d4d07f1eSToby Isaac    Calling sequence for beginhook:
2437d4d07f1eSToby Isaac $    beginhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx)
2438d4d07f1eSToby Isaac 
2439d4d07f1eSToby Isaac +  dm - global DM
2440d4d07f1eSToby Isaac .  l - local vector
2441d4d07f1eSToby Isaac .  mode - mode
2442d4d07f1eSToby Isaac .  g - global vector
2443d4d07f1eSToby Isaac -  ctx - optional user-defined function context
2444d4d07f1eSToby Isaac 
2445d4d07f1eSToby Isaac 
2446d4d07f1eSToby Isaac    Calling sequence for endhook:
2447d4d07f1eSToby Isaac $    endhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx)
2448d4d07f1eSToby Isaac 
2449d4d07f1eSToby Isaac +  global - global DM
2450d4d07f1eSToby Isaac .  l - local vector
2451d4d07f1eSToby Isaac .  mode - mode
2452d4d07f1eSToby Isaac .  g - global vector
2453d4d07f1eSToby Isaac -  ctx - optional user-defined function context
2454d4d07f1eSToby Isaac 
2455d4d07f1eSToby Isaac    Level: advanced
2456d4d07f1eSToby Isaac 
2457d4d07f1eSToby Isaac .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
2458d4d07f1eSToby Isaac @*/
2459d4d07f1eSToby Isaac PetscErrorCode DMLocalToGlobalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx)
2460d4d07f1eSToby Isaac {
2461d4d07f1eSToby Isaac   PetscErrorCode          ierr;
2462d4d07f1eSToby Isaac   DMLocalToGlobalHookLink link,*p;
2463d4d07f1eSToby Isaac 
2464d4d07f1eSToby Isaac   PetscFunctionBegin;
2465d4d07f1eSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2466d4d07f1eSToby Isaac   for (p=&dm->ltoghook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
246795dccacaSBarry Smith   ierr            = PetscNew(&link);CHKERRQ(ierr);
2468d4d07f1eSToby Isaac   link->beginhook = beginhook;
2469d4d07f1eSToby Isaac   link->endhook   = endhook;
2470d4d07f1eSToby Isaac   link->ctx       = ctx;
2471d4d07f1eSToby Isaac   link->next      = NULL;
2472d4d07f1eSToby Isaac   *p              = link;
2473d4d07f1eSToby Isaac   PetscFunctionReturn(0);
2474d4d07f1eSToby Isaac }
2475d4d07f1eSToby Isaac 
24764c274da1SToby Isaac static PetscErrorCode DMLocalToGlobalHook_Constraints(DM dm, Vec l, InsertMode mode, Vec g, void *ctx)
24774c274da1SToby Isaac {
24784c274da1SToby Isaac   Mat cMat;
24794c274da1SToby Isaac   Vec cVec;
24804c274da1SToby Isaac   PetscSection section, cSec;
24814c274da1SToby Isaac   PetscInt pStart, pEnd, p, dof;
24824c274da1SToby Isaac   PetscErrorCode ierr;
24834c274da1SToby Isaac 
24844c274da1SToby Isaac   PetscFunctionBegin;
24854c274da1SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
24864c274da1SToby Isaac   ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr);
24874c274da1SToby Isaac   if (cMat && (mode == ADD_VALUES || mode == ADD_ALL_VALUES || mode == ADD_BC_VALUES)) {
24885db9a05bSToby Isaac     PetscInt nRows;
24895db9a05bSToby Isaac 
24905db9a05bSToby Isaac     ierr = MatGetSize(cMat,&nRows,NULL);CHKERRQ(ierr);
24915db9a05bSToby Isaac     if (nRows <= 0) PetscFunctionReturn(0);
249292fd8e1eSJed Brown     ierr = DMGetLocalSection(dm,&section);CHKERRQ(ierr);
24937711e48fSToby Isaac     ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr);
24944c274da1SToby Isaac     ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr);
24954c274da1SToby Isaac     for (p = pStart; p < pEnd; p++) {
24964c274da1SToby Isaac       ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr);
24974c274da1SToby Isaac       if (dof) {
24984c274da1SToby Isaac         PetscInt d;
24994c274da1SToby Isaac         PetscScalar *vals;
25004c274da1SToby Isaac         ierr = VecGetValuesSection(l,section,p,&vals);CHKERRQ(ierr);
25014c274da1SToby Isaac         ierr = VecSetValuesSection(cVec,cSec,p,vals,mode);CHKERRQ(ierr);
25024c274da1SToby Isaac         /* for this to be the true transpose, we have to zero the values that
25034c274da1SToby Isaac          * we just extracted */
25044c274da1SToby Isaac         for (d = 0; d < dof; d++) {
25054c274da1SToby Isaac           vals[d] = 0.;
25064c274da1SToby Isaac         }
25074c274da1SToby Isaac       }
25084c274da1SToby Isaac     }
25094c274da1SToby Isaac     ierr = MatMultTransposeAdd(cMat,cVec,l,l);CHKERRQ(ierr);
25104c274da1SToby Isaac     ierr = VecDestroy(&cVec);CHKERRQ(ierr);
25114c274da1SToby Isaac   }
25124c274da1SToby Isaac   PetscFunctionReturn(0);
25134c274da1SToby Isaac }
251401729b5cSPatrick Sanan /*@
251501729b5cSPatrick Sanan     DMLocalToGlobal - updates global vectors from local vectors
251601729b5cSPatrick Sanan 
2517d083f849SBarry Smith     Neighbor-wise Collective on dm
251801729b5cSPatrick Sanan 
251901729b5cSPatrick Sanan     Input Parameters:
252001729b5cSPatrick Sanan +   dm - the DM object
252101729b5cSPatrick Sanan .   l - the local vector
252201729b5cSPatrick Sanan .   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 base point.
252301729b5cSPatrick Sanan -   g - the global vector
252401729b5cSPatrick Sanan 
252501729b5cSPatrick Sanan     Notes:
252601729b5cSPatrick Sanan     The communication involved in this update can be overlapped with computation by using
252701729b5cSPatrick Sanan     DMLocalToGlobalBegin() and DMLocalToGlobalEnd().
252801729b5cSPatrick Sanan 
252901729b5cSPatrick Sanan     In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation.
253001729b5cSPatrick Sanan            INSERT_VALUES is not supported for DMDA; in that case simply compute the values directly into a global vector instead of a local one.
253101729b5cSPatrick Sanan 
253201729b5cSPatrick Sanan     Level: beginner
253301729b5cSPatrick Sanan 
253401729b5cSPatrick Sanan .seealso DMLocalToGlobalBegin(), DMLocalToGlobalEnd(), DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
253501729b5cSPatrick Sanan 
253601729b5cSPatrick Sanan @*/
253701729b5cSPatrick Sanan PetscErrorCode DMLocalToGlobal(DM dm,Vec l,InsertMode mode,Vec g)
253801729b5cSPatrick Sanan {
253901729b5cSPatrick Sanan   PetscErrorCode ierr;
254001729b5cSPatrick Sanan 
254101729b5cSPatrick Sanan   PetscFunctionBegin;
254201729b5cSPatrick Sanan   ierr = DMLocalToGlobalBegin(dm,l,mode,g);CHKERRQ(ierr);
254301729b5cSPatrick Sanan   ierr = DMLocalToGlobalEnd(dm,l,mode,g);CHKERRQ(ierr);
254401729b5cSPatrick Sanan   PetscFunctionReturn(0);
254501729b5cSPatrick Sanan }
25464c274da1SToby Isaac 
254747c6ae99SBarry Smith /*@
254801729b5cSPatrick Sanan     DMLocalToGlobalBegin - begins updating global vectors from local vectors
25499a42bb27SBarry Smith 
2550d083f849SBarry Smith     Neighbor-wise Collective on dm
25519a42bb27SBarry Smith 
25529a42bb27SBarry Smith     Input Parameters:
25539a42bb27SBarry Smith +   dm - the DM object
2554f6813fd5SJed Brown .   l - the local vector
25551eb28f2eSBarry 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 base point.
25561eb28f2eSBarry Smith -   g - the global vector
25579a42bb27SBarry Smith 
255895452b02SPatrick Sanan     Notes:
255995452b02SPatrick Sanan     In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation.
256084330215SMatthew G. Knepley            INSERT_VALUES is not supported for DMDA, in that case simply compute the values directly into a global vector instead of a local one.
25619a42bb27SBarry Smith 
256201729b5cSPatrick Sanan     Level: intermediate
25639a42bb27SBarry Smith 
256401729b5cSPatrick Sanan .seealso DMLocalToGlobal(), DMLocalToGlobalEnd(), DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
25659a42bb27SBarry Smith 
25669a42bb27SBarry Smith @*/
25677087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g)
25689a42bb27SBarry Smith {
25697128ae9fSMatthew G Knepley   PetscSF                 sf;
257084330215SMatthew G. Knepley   PetscSection            s, gs;
2571d4d07f1eSToby Isaac   DMLocalToGlobalHookLink link;
2572ca3d3a14SMatthew G. Knepley   Vec                     tmpl;
2573ae5cfb4aSMatthew G. Knepley   const PetscScalar      *lArray;
2574ae5cfb4aSMatthew G. Knepley   PetscScalar            *gArray;
2575ca3d3a14SMatthew G. Knepley   PetscBool               isInsert, transform;
257684330215SMatthew G. Knepley   PetscErrorCode          ierr;
25779a42bb27SBarry Smith 
25789a42bb27SBarry Smith   PetscFunctionBegin;
2579171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2580d4d07f1eSToby Isaac   for (link=dm->ltoghook; link; link=link->next) {
2581d4d07f1eSToby Isaac     if (link->beginhook) {
2582d4d07f1eSToby Isaac       ierr = (*link->beginhook)(dm,l,mode,g,link->ctx);CHKERRQ(ierr);
2583d4d07f1eSToby Isaac     }
2584d4d07f1eSToby Isaac   }
25854c274da1SToby Isaac   ierr = DMLocalToGlobalHook_Constraints(dm,l,mode,g,NULL);CHKERRQ(ierr);
25861bb6d2a8SBarry Smith   ierr = DMGetSectionSF(dm, &sf);CHKERRQ(ierr);
258792fd8e1eSJed Brown   ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr);
25887128ae9fSMatthew G Knepley   switch (mode) {
25897128ae9fSMatthew G Knepley   case INSERT_VALUES:
25907128ae9fSMatthew G Knepley   case INSERT_ALL_VALUES:
2591304ab55fSMatthew G. Knepley   case INSERT_BC_VALUES:
259284330215SMatthew G. Knepley     isInsert = PETSC_TRUE; break;
25937128ae9fSMatthew G Knepley   case ADD_VALUES:
25947128ae9fSMatthew G Knepley   case ADD_ALL_VALUES:
2595304ab55fSMatthew G. Knepley   case ADD_BC_VALUES:
259684330215SMatthew G. Knepley     isInsert = PETSC_FALSE; break;
25977128ae9fSMatthew G Knepley   default:
259882f516ccSBarry Smith     SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
25997128ae9fSMatthew G Knepley   }
2600ca3d3a14SMatthew G. Knepley   if ((sf && !isInsert) || (s && isInsert)) {
2601ca3d3a14SMatthew G. Knepley     ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr);
2602ca3d3a14SMatthew G. Knepley     if (transform) {
2603ca3d3a14SMatthew G. Knepley       ierr = DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr);
2604ca3d3a14SMatthew G. Knepley       ierr = VecCopy(l, tmpl);CHKERRQ(ierr);
2605ca3d3a14SMatthew G. Knepley       ierr = DMPlexLocalToGlobalBasis(dm, tmpl);CHKERRQ(ierr);
2606ca3d3a14SMatthew G. Knepley       ierr = VecGetArrayRead(tmpl, &lArray);CHKERRQ(ierr);
2607ca3d3a14SMatthew G. Knepley     } else {
2608ae5cfb4aSMatthew G. Knepley       ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr);
2609ca3d3a14SMatthew G. Knepley     }
26107128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
2611ca3d3a14SMatthew G. Knepley     if (sf && !isInsert) {
2612a9b180a6SBarry Smith       ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM);CHKERRQ(ierr);
261384330215SMatthew G. Knepley     } else if (s && isInsert) {
261484330215SMatthew G. Knepley       PetscInt gStart, pStart, pEnd, p;
261584330215SMatthew G. Knepley 
2616e87a4003SBarry Smith       ierr = DMGetGlobalSection(dm, &gs);CHKERRQ(ierr);
261784330215SMatthew G. Knepley       ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr);
261884330215SMatthew G. Knepley       ierr = VecGetOwnershipRange(g, &gStart, NULL);CHKERRQ(ierr);
261984330215SMatthew G. Knepley       for (p = pStart; p < pEnd; ++p) {
2620b3b16f48SMatthew G. Knepley         PetscInt dof, gdof, cdof, gcdof, off, goff, d, e;
262184330215SMatthew G. Knepley 
262284330215SMatthew G. Knepley         ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr);
262303442857SMatthew G. Knepley         ierr = PetscSectionGetDof(gs, p, &gdof);CHKERRQ(ierr);
262484330215SMatthew G. Knepley         ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr);
2625b3b16f48SMatthew G. Knepley         ierr = PetscSectionGetConstraintDof(gs, p, &gcdof);CHKERRQ(ierr);
262684330215SMatthew G. Knepley         ierr = PetscSectionGetOffset(s, p, &off);CHKERRQ(ierr);
262784330215SMatthew G. Knepley         ierr = PetscSectionGetOffset(gs, p, &goff);CHKERRQ(ierr);
2628b3b16f48SMatthew G. Knepley         /* Ignore off-process data and points with no global data */
262903442857SMatthew G. Knepley         if (!gdof || goff < 0) continue;
2630b3b16f48SMatthew G. Knepley         if (dof != gdof) SETERRQ5(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Inconsistent sizes, p: %d dof: %d gdof: %d cdof: %d gcdof: %d", p, dof, gdof, cdof, gcdof);
2631b3b16f48SMatthew G. Knepley         /* If no constraints are enforced in the global vector */
2632b3b16f48SMatthew G. Knepley         if (!gcdof) {
263384330215SMatthew G. Knepley           for (d = 0; d < dof; ++d) gArray[goff-gStart+d] = lArray[off+d];
2634b3b16f48SMatthew G. Knepley           /* If constraints are enforced in the global vector */
2635b3b16f48SMatthew G. Knepley         } else if (cdof == gcdof) {
263684330215SMatthew G. Knepley           const PetscInt *cdofs;
263784330215SMatthew G. Knepley           PetscInt        cind = 0;
263884330215SMatthew G. Knepley 
263984330215SMatthew G. Knepley           ierr = PetscSectionGetConstraintIndices(s, p, &cdofs);CHKERRQ(ierr);
2640b3b16f48SMatthew G. Knepley           for (d = 0, e = 0; d < dof; ++d) {
264184330215SMatthew G. Knepley             if ((cind < cdof) && (d == cdofs[cind])) {++cind; continue;}
2642b3b16f48SMatthew G. Knepley             gArray[goff-gStart+e++] = lArray[off+d];
264384330215SMatthew G. Knepley           }
2644b3b16f48SMatthew G. Knepley         } else SETERRQ5(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Inconsistent sizes, p: %d dof: %d gdof: %d cdof: %d gcdof: %d", p, dof, gdof, cdof, gcdof);
264584330215SMatthew G. Knepley       }
2646ca3d3a14SMatthew G. Knepley     }
26477128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
2648ca3d3a14SMatthew G. Knepley     if (transform) {
2649ca3d3a14SMatthew G. Knepley       ierr = VecRestoreArrayRead(tmpl, &lArray);CHKERRQ(ierr);
2650ca3d3a14SMatthew G. Knepley       ierr = DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr);
2651ca3d3a14SMatthew G. Knepley     } else {
2652ca3d3a14SMatthew G. Knepley       ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr);
2653ca3d3a14SMatthew G. Knepley     }
26547128ae9fSMatthew G Knepley   } else {
2655b9d85ea2SLisandro Dalcin     if (!dm->ops->localtoglobalbegin) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMLocalToGlobalBegin() for type %s",((PetscObject)dm)->type_name);
2656843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
26577128ae9fSMatthew G Knepley   }
26589a42bb27SBarry Smith   PetscFunctionReturn(0);
26599a42bb27SBarry Smith }
26609a42bb27SBarry Smith 
26619a42bb27SBarry Smith /*@
26629a42bb27SBarry Smith     DMLocalToGlobalEnd - updates global vectors from local vectors
266347c6ae99SBarry Smith 
2664d083f849SBarry Smith     Neighbor-wise Collective on dm
266547c6ae99SBarry Smith 
266647c6ae99SBarry Smith     Input Parameters:
266747c6ae99SBarry Smith +   dm - the DM object
2668f6813fd5SJed Brown .   l - the local vector
266947c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
2670f6813fd5SJed Brown -   g - the global vector
267147c6ae99SBarry Smith 
267201729b5cSPatrick Sanan     Level: intermediate
267347c6ae99SBarry Smith 
2674e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd()
267547c6ae99SBarry Smith 
267647c6ae99SBarry Smith @*/
26777087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g)
267847c6ae99SBarry Smith {
26797128ae9fSMatthew G Knepley   PetscSF                 sf;
268084330215SMatthew G. Knepley   PetscSection            s;
2681d4d07f1eSToby Isaac   DMLocalToGlobalHookLink link;
2682ca3d3a14SMatthew G. Knepley   PetscBool               isInsert, transform;
268384330215SMatthew G. Knepley   PetscErrorCode          ierr;
268447c6ae99SBarry Smith 
268547c6ae99SBarry Smith   PetscFunctionBegin;
2686171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
26871bb6d2a8SBarry Smith   ierr = DMGetSectionSF(dm, &sf);CHKERRQ(ierr);
268892fd8e1eSJed Brown   ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr);
26897128ae9fSMatthew G Knepley   switch (mode) {
26907128ae9fSMatthew G Knepley   case INSERT_VALUES:
26917128ae9fSMatthew G Knepley   case INSERT_ALL_VALUES:
269284330215SMatthew G. Knepley     isInsert = PETSC_TRUE; break;
26937128ae9fSMatthew G Knepley   case ADD_VALUES:
26947128ae9fSMatthew G Knepley   case ADD_ALL_VALUES:
269584330215SMatthew G. Knepley     isInsert = PETSC_FALSE; break;
26967128ae9fSMatthew G Knepley   default:
269782f516ccSBarry Smith     SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
26987128ae9fSMatthew G Knepley   }
269984330215SMatthew G. Knepley   if (sf && !isInsert) {
2700ae5cfb4aSMatthew G. Knepley     const PetscScalar *lArray;
2701ae5cfb4aSMatthew G. Knepley     PetscScalar       *gArray;
2702ca3d3a14SMatthew G. Knepley     Vec                tmpl;
270384330215SMatthew G. Knepley 
2704ca3d3a14SMatthew G. Knepley     ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr);
2705ca3d3a14SMatthew G. Knepley     if (transform) {
2706ca3d3a14SMatthew G. Knepley       ierr = DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr);
2707ca3d3a14SMatthew G. Knepley       ierr = VecGetArrayRead(tmpl, &lArray);CHKERRQ(ierr);
2708ca3d3a14SMatthew G. Knepley     } else {
2709ae5cfb4aSMatthew G. Knepley       ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr);
2710ca3d3a14SMatthew G. Knepley     }
27117128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
2712a9b180a6SBarry Smith     ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM);CHKERRQ(ierr);
2713ca3d3a14SMatthew G. Knepley     if (transform) {
2714ca3d3a14SMatthew G. Knepley       ierr = VecRestoreArrayRead(tmpl, &lArray);CHKERRQ(ierr);
2715ca3d3a14SMatthew G. Knepley       ierr = DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr);
2716ca3d3a14SMatthew G. Knepley     } else {
2717ae5cfb4aSMatthew G. Knepley       ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr);
2718ca3d3a14SMatthew G. Knepley     }
27197128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
272084330215SMatthew G. Knepley   } else if (s && isInsert) {
27217128ae9fSMatthew G Knepley   } else {
2722b9d85ea2SLisandro Dalcin     if (!dm->ops->localtoglobalend) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMLocalToGlobalEnd() for type %s",((PetscObject)dm)->type_name);
2723843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
27247128ae9fSMatthew G Knepley   }
2725d4d07f1eSToby Isaac   for (link=dm->ltoghook; link; link=link->next) {
2726d4d07f1eSToby Isaac     if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);}
2727d4d07f1eSToby Isaac   }
272847c6ae99SBarry Smith   PetscFunctionReturn(0);
272947c6ae99SBarry Smith }
273047c6ae99SBarry Smith 
2731f089877aSRichard Tran Mills /*@
2732bc0a1609SRichard Tran Mills    DMLocalToLocalBegin - Maps from a local vector (including ghost points
2733bc0a1609SRichard Tran Mills    that contain irrelevant values) to another local vector where the ghost
2734d78e899eSRichard Tran Mills    points in the second are set correctly. Must be followed by DMLocalToLocalEnd().
2735f089877aSRichard Tran Mills 
2736d083f849SBarry Smith    Neighbor-wise Collective on dm
2737f089877aSRichard Tran Mills 
2738f089877aSRichard Tran Mills    Input Parameters:
2739f089877aSRichard Tran Mills +  dm - the DM object
2740bc0a1609SRichard Tran Mills .  g - the original local vector
2741bc0a1609SRichard Tran Mills -  mode - one of INSERT_VALUES or ADD_VALUES
2742f089877aSRichard Tran Mills 
2743bc0a1609SRichard Tran Mills    Output Parameter:
2744bc0a1609SRichard Tran Mills .  l  - the local vector with correct ghost values
2745f089877aSRichard Tran Mills 
2746f089877aSRichard Tran Mills    Level: intermediate
2747f089877aSRichard Tran Mills 
2748bc0a1609SRichard Tran Mills    Notes:
2749bc0a1609SRichard Tran Mills    The local vectors used here need not be the same as those
2750bc0a1609SRichard Tran Mills    obtained from DMCreateLocalVector(), BUT they
2751bc0a1609SRichard Tran Mills    must have the same parallel data layout; they could, for example, be
2752bc0a1609SRichard Tran Mills    obtained with VecDuplicate() from the DM originating vectors.
2753bc0a1609SRichard Tran Mills 
2754bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalEnd(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
2755f089877aSRichard Tran Mills 
2756f089877aSRichard Tran Mills @*/
2757f089877aSRichard Tran Mills PetscErrorCode  DMLocalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
2758f089877aSRichard Tran Mills {
2759f089877aSRichard Tran Mills   PetscErrorCode          ierr;
2760f089877aSRichard Tran Mills 
2761f089877aSRichard Tran Mills   PetscFunctionBegin;
2762f089877aSRichard Tran Mills   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2763bb358533SPatrick Sanan   if (!dm->ops->localtolocalbegin) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM does not support local to local maps");
2764f089877aSRichard Tran Mills   ierr = (*dm->ops->localtolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
2765f089877aSRichard Tran Mills   PetscFunctionReturn(0);
2766f089877aSRichard Tran Mills }
2767f089877aSRichard Tran Mills 
2768f089877aSRichard Tran Mills /*@
2769bc0a1609SRichard Tran Mills    DMLocalToLocalEnd - Maps from a local vector (including ghost points
2770bc0a1609SRichard Tran Mills    that contain irrelevant values) to another local vector where the ghost
2771d78e899eSRichard Tran Mills    points in the second are set correctly. Must be preceded by DMLocalToLocalBegin().
2772f089877aSRichard Tran Mills 
2773d083f849SBarry Smith    Neighbor-wise Collective on dm
2774f089877aSRichard Tran Mills 
2775f089877aSRichard Tran Mills    Input Parameters:
2776bc0a1609SRichard Tran Mills +  da - the DM object
2777bc0a1609SRichard Tran Mills .  g - the original local vector
2778bc0a1609SRichard Tran Mills -  mode - one of INSERT_VALUES or ADD_VALUES
2779f089877aSRichard Tran Mills 
2780bc0a1609SRichard Tran Mills    Output Parameter:
2781bc0a1609SRichard Tran Mills .  l  - the local vector with correct ghost values
2782f089877aSRichard Tran Mills 
2783f089877aSRichard Tran Mills    Level: intermediate
2784f089877aSRichard Tran Mills 
2785bc0a1609SRichard Tran Mills    Notes:
2786bc0a1609SRichard Tran Mills    The local vectors used here need not be the same as those
2787bc0a1609SRichard Tran Mills    obtained from DMCreateLocalVector(), BUT they
2788bc0a1609SRichard Tran Mills    must have the same parallel data layout; they could, for example, be
2789bc0a1609SRichard Tran Mills    obtained with VecDuplicate() from the DM originating vectors.
2790bc0a1609SRichard Tran Mills 
2791bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalBegin(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
2792f089877aSRichard Tran Mills 
2793f089877aSRichard Tran Mills @*/
2794f089877aSRichard Tran Mills PetscErrorCode  DMLocalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
2795f089877aSRichard Tran Mills {
2796f089877aSRichard Tran Mills   PetscErrorCode          ierr;
2797f089877aSRichard Tran Mills 
2798f089877aSRichard Tran Mills   PetscFunctionBegin;
2799f089877aSRichard Tran Mills   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2800bb358533SPatrick Sanan   if (!dm->ops->localtolocalend) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM does not support local to local maps");
2801f089877aSRichard Tran Mills   ierr = (*dm->ops->localtolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
2802f089877aSRichard Tran Mills   PetscFunctionReturn(0);
2803f089877aSRichard Tran Mills }
2804f089877aSRichard Tran Mills 
2805f089877aSRichard Tran Mills 
280647c6ae99SBarry Smith /*@
280747c6ae99SBarry Smith     DMCoarsen - Coarsens a DM object
280847c6ae99SBarry Smith 
2809d083f849SBarry Smith     Collective on dm
281047c6ae99SBarry Smith 
281147c6ae99SBarry Smith     Input Parameter:
281247c6ae99SBarry Smith +   dm - the DM object
281391d95f02SJed Brown -   comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
281447c6ae99SBarry Smith 
281547c6ae99SBarry Smith     Output Parameter:
281647c6ae99SBarry Smith .   dmc - the coarsened DM
281747c6ae99SBarry Smith 
281847c6ae99SBarry Smith     Level: developer
281947c6ae99SBarry Smith 
2820e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
282147c6ae99SBarry Smith 
282247c6ae99SBarry Smith @*/
28237087cfbeSBarry Smith PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc)
282447c6ae99SBarry Smith {
282547c6ae99SBarry Smith   PetscErrorCode    ierr;
2826b17ce1afSJed Brown   DMCoarsenHookLink link;
282747c6ae99SBarry Smith 
282847c6ae99SBarry Smith   PetscFunctionBegin;
2829171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2830b9d85ea2SLisandro Dalcin   if (!dm->ops->coarsen) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCoarsen",((PetscObject)dm)->type_name);
283147a35634SPatrick Farrell   ierr = PetscLogEventBegin(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr);
283247c6ae99SBarry Smith   ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr);
2833b9d85ea2SLisandro Dalcin   if (*dmc) {
2834a8fb8f29SToby Isaac     ierr = DMSetCoarseDM(dm,*dmc);CHKERRQ(ierr);
283543842a1eSJed Brown     (*dmc)->ops->creatematrix = dm->ops->creatematrix;
28368cd211a4SJed Brown     ierr                      = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr);
2837644e2e5bSBarry Smith     (*dmc)->ctx               = dm->ctx;
28380598a293SJed Brown     (*dmc)->levelup           = dm->levelup;
2839656b349aSBarry Smith     (*dmc)->leveldown         = dm->leveldown + 1;
2840e4b4b23bSJed Brown     ierr                      = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr);
2841b17ce1afSJed Brown     for (link=dm->coarsenhook; link; link=link->next) {
2842b17ce1afSJed Brown       if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);}
2843b17ce1afSJed Brown     }
2844b9d85ea2SLisandro Dalcin   }
284547a35634SPatrick Farrell   ierr = PetscLogEventEnd(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr);
2846b9d85ea2SLisandro Dalcin   if (!(*dmc)) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "NULL coarse mesh produced");
2847b17ce1afSJed Brown   PetscFunctionReturn(0);
2848b17ce1afSJed Brown }
2849b17ce1afSJed Brown 
2850bb9467b5SJed Brown /*@C
2851b17ce1afSJed Brown    DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid
2852b17ce1afSJed Brown 
2853b17ce1afSJed Brown    Logically Collective
2854b17ce1afSJed Brown 
2855b17ce1afSJed Brown    Input Arguments:
2856b17ce1afSJed Brown +  fine - nonlinear solver context on which to run a hook when restricting to a coarser level
2857b17ce1afSJed Brown .  coarsenhook - function to run when setting up a coarser level
2858b17ce1afSJed Brown .  restricthook - function to run to update data on coarser levels (once per SNESSolve())
28590298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
2860b17ce1afSJed Brown 
2861b17ce1afSJed Brown    Calling sequence of coarsenhook:
2862b17ce1afSJed Brown $    coarsenhook(DM fine,DM coarse,void *ctx);
2863b17ce1afSJed Brown 
2864b17ce1afSJed Brown +  fine - fine level DM
2865b17ce1afSJed Brown .  coarse - coarse level DM to restrict problem to
2866b17ce1afSJed Brown -  ctx - optional user-defined function context
2867b17ce1afSJed Brown 
2868b17ce1afSJed Brown    Calling sequence for restricthook:
2869c833c3b5SJed Brown $    restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx)
2870b17ce1afSJed Brown 
2871b17ce1afSJed Brown +  fine - fine level DM
2872b17ce1afSJed Brown .  mrestrict - matrix restricting a fine-level solution to the coarse grid
2873c833c3b5SJed Brown .  rscale - scaling vector for restriction
2874c833c3b5SJed Brown .  inject - matrix restricting by injection
2875b17ce1afSJed Brown .  coarse - coarse level DM to update
2876b17ce1afSJed Brown -  ctx - optional user-defined function context
2877b17ce1afSJed Brown 
2878b17ce1afSJed Brown    Level: advanced
2879b17ce1afSJed Brown 
2880b17ce1afSJed Brown    Notes:
2881b17ce1afSJed Brown    This function is only needed if auxiliary data needs to be set up on coarse grids.
2882b17ce1afSJed Brown 
2883b17ce1afSJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
2884b17ce1afSJed Brown 
2885b17ce1afSJed Brown    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
2886b17ce1afSJed Brown    extract the finest level information from its context (instead of from the SNES).
2887b17ce1afSJed Brown 
2888bb9467b5SJed Brown    This function is currently not available from Fortran.
2889bb9467b5SJed Brown 
2890dc822a44SJed Brown .seealso: DMCoarsenHookRemove(), DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
2891b17ce1afSJed Brown @*/
2892b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx)
2893b17ce1afSJed Brown {
2894b17ce1afSJed Brown   PetscErrorCode    ierr;
2895b17ce1afSJed Brown   DMCoarsenHookLink link,*p;
2896b17ce1afSJed Brown 
2897b17ce1afSJed Brown   PetscFunctionBegin;
2898b17ce1afSJed Brown   PetscValidHeaderSpecific(fine,DM_CLASSID,1);
28991e3d8eccSJed Brown   for (p=&fine->coarsenhook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */
29001e3d8eccSJed Brown     if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0);
29011e3d8eccSJed Brown   }
290295dccacaSBarry Smith   ierr               = PetscNew(&link);CHKERRQ(ierr);
2903b17ce1afSJed Brown   link->coarsenhook  = coarsenhook;
2904b17ce1afSJed Brown   link->restricthook = restricthook;
2905b17ce1afSJed Brown   link->ctx          = ctx;
29060298fd71SBarry Smith   link->next         = NULL;
2907b17ce1afSJed Brown   *p                 = link;
2908b17ce1afSJed Brown   PetscFunctionReturn(0);
2909b17ce1afSJed Brown }
2910b17ce1afSJed Brown 
2911dc822a44SJed Brown /*@C
2912dc822a44SJed Brown    DMCoarsenHookRemove - remove a callback from the list of hooks to be run when restricting a nonlinear problem to the coarse grid
2913dc822a44SJed Brown 
2914dc822a44SJed Brown    Logically Collective
2915dc822a44SJed Brown 
2916dc822a44SJed Brown    Input Arguments:
2917dc822a44SJed Brown +  fine - nonlinear solver context on which to run a hook when restricting to a coarser level
2918dc822a44SJed Brown .  coarsenhook - function to run when setting up a coarser level
2919dc822a44SJed Brown .  restricthook - function to run to update data on coarser levels (once per SNESSolve())
2920dc822a44SJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
2921dc822a44SJed Brown 
2922dc822a44SJed Brown    Level: advanced
2923dc822a44SJed Brown 
2924dc822a44SJed Brown    Notes:
2925dc822a44SJed Brown    This function does nothing if the hook is not in the list.
2926dc822a44SJed Brown 
2927dc822a44SJed Brown    This function is currently not available from Fortran.
2928dc822a44SJed Brown 
2929dc822a44SJed Brown .seealso: DMCoarsenHookAdd(), DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
2930dc822a44SJed Brown @*/
2931dc822a44SJed Brown PetscErrorCode DMCoarsenHookRemove(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx)
2932dc822a44SJed Brown {
2933dc822a44SJed Brown   PetscErrorCode    ierr;
2934dc822a44SJed Brown   DMCoarsenHookLink link,*p;
2935dc822a44SJed Brown 
2936dc822a44SJed Brown   PetscFunctionBegin;
2937dc822a44SJed Brown   PetscValidHeaderSpecific(fine,DM_CLASSID,1);
2938dc822a44SJed Brown   for (p=&fine->coarsenhook; *p; p=&(*p)->next) { /* Search the list of current hooks */
2939dc822a44SJed Brown     if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) {
2940dc822a44SJed Brown       link = *p;
2941dc822a44SJed Brown       *p = link->next;
2942dc822a44SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
2943dc822a44SJed Brown       break;
2944dc822a44SJed Brown     }
2945dc822a44SJed Brown   }
2946dc822a44SJed Brown   PetscFunctionReturn(0);
2947dc822a44SJed Brown }
2948dc822a44SJed Brown 
2949dc822a44SJed Brown 
2950b17ce1afSJed Brown /*@
2951b17ce1afSJed Brown    DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd()
2952b17ce1afSJed Brown 
2953b17ce1afSJed Brown    Collective if any hooks are
2954b17ce1afSJed Brown 
2955b17ce1afSJed Brown    Input Arguments:
2956b17ce1afSJed Brown +  fine - finer DM to use as a base
2957b17ce1afSJed Brown .  restrct - restriction matrix, apply using MatRestrict()
2958e91eccc2SStefano Zampini .  rscale - scaling vector for restriction
2959b17ce1afSJed Brown .  inject - injection matrix, also use MatRestrict()
2960e91eccc2SStefano Zampini -  coarse - coarser DM to update
2961b17ce1afSJed Brown 
2962b17ce1afSJed Brown    Level: developer
2963b17ce1afSJed Brown 
2964b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict()
2965b17ce1afSJed Brown @*/
2966b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse)
2967b17ce1afSJed Brown {
2968b17ce1afSJed Brown   PetscErrorCode    ierr;
2969b17ce1afSJed Brown   DMCoarsenHookLink link;
2970b17ce1afSJed Brown 
2971b17ce1afSJed Brown   PetscFunctionBegin;
2972b17ce1afSJed Brown   for (link=fine->coarsenhook; link; link=link->next) {
29738865f1eaSKarl Rupp     if (link->restricthook) {
29748865f1eaSKarl Rupp       ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr);
29758865f1eaSKarl Rupp     }
2976b17ce1afSJed Brown   }
297747c6ae99SBarry Smith   PetscFunctionReturn(0);
297847c6ae99SBarry Smith }
297947c6ae99SBarry Smith 
2980bb9467b5SJed Brown /*@C
2981be081cd6SPeter Brune    DMSubDomainHookAdd - adds a callback to be run when restricting a problem to the coarse grid
29825dbd56e3SPeter Brune 
2983d083f849SBarry Smith    Logically Collective on global
29845dbd56e3SPeter Brune 
29855dbd56e3SPeter Brune    Input Arguments:
29865dbd56e3SPeter Brune +  global - global DM
2987ec4806b8SPeter Brune .  ddhook - function to run to pass data to the decomposition DM upon its creation
29885dbd56e3SPeter Brune .  restricthook - function to run to update data on block solve (at the beginning of the block solve)
29890298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
29905dbd56e3SPeter Brune 
2991ec4806b8SPeter Brune 
2992ec4806b8SPeter Brune    Calling sequence for ddhook:
2993ec4806b8SPeter Brune $    ddhook(DM global,DM block,void *ctx)
2994ec4806b8SPeter Brune 
2995ec4806b8SPeter Brune +  global - global DM
2996ec4806b8SPeter Brune .  block  - block DM
2997ec4806b8SPeter Brune -  ctx - optional user-defined function context
2998ec4806b8SPeter Brune 
29995dbd56e3SPeter Brune    Calling sequence for restricthook:
3000ec4806b8SPeter Brune $    restricthook(DM global,VecScatter out,VecScatter in,DM block,void *ctx)
30015dbd56e3SPeter Brune 
30025dbd56e3SPeter Brune +  global - global DM
30035dbd56e3SPeter Brune .  out    - scatter to the outer (with ghost and overlap points) block vector
30045dbd56e3SPeter Brune .  in     - scatter to block vector values only owned locally
3005ec4806b8SPeter Brune .  block  - block DM
30065dbd56e3SPeter Brune -  ctx - optional user-defined function context
30075dbd56e3SPeter Brune 
30085dbd56e3SPeter Brune    Level: advanced
30095dbd56e3SPeter Brune 
30105dbd56e3SPeter Brune    Notes:
3011ec4806b8SPeter Brune    This function is only needed if auxiliary data needs to be set up on subdomain DMs.
30125dbd56e3SPeter Brune 
30135dbd56e3SPeter Brune    If this function is called multiple times, the hooks will be run in the order they are added.
30145dbd56e3SPeter Brune 
30155dbd56e3SPeter Brune    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
3016ec4806b8SPeter Brune    extract the global information from its context (instead of from the SNES).
30175dbd56e3SPeter Brune 
3018bb9467b5SJed Brown    This function is currently not available from Fortran.
3019bb9467b5SJed Brown 
30205dbd56e3SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
30215dbd56e3SPeter Brune @*/
3022be081cd6SPeter Brune PetscErrorCode DMSubDomainHookAdd(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx)
30235dbd56e3SPeter Brune {
30245dbd56e3SPeter Brune   PetscErrorCode      ierr;
3025be081cd6SPeter Brune   DMSubDomainHookLink link,*p;
30265dbd56e3SPeter Brune 
30275dbd56e3SPeter Brune   PetscFunctionBegin;
30285dbd56e3SPeter Brune   PetscValidHeaderSpecific(global,DM_CLASSID,1);
3029b3a6b972SJed Brown   for (p=&global->subdomainhook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */
3030b3a6b972SJed Brown     if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0);
3031b3a6b972SJed Brown   }
303295dccacaSBarry Smith   ierr               = PetscNew(&link);CHKERRQ(ierr);
30335dbd56e3SPeter Brune   link->restricthook = restricthook;
3034be081cd6SPeter Brune   link->ddhook       = ddhook;
30355dbd56e3SPeter Brune   link->ctx          = ctx;
30360298fd71SBarry Smith   link->next         = NULL;
30375dbd56e3SPeter Brune   *p                 = link;
30385dbd56e3SPeter Brune   PetscFunctionReturn(0);
30395dbd56e3SPeter Brune }
30405dbd56e3SPeter Brune 
3041b3a6b972SJed Brown /*@C
3042b3a6b972SJed Brown    DMSubDomainHookRemove - remove a callback from the list to be run when restricting a problem to the coarse grid
3043b3a6b972SJed Brown 
3044b3a6b972SJed Brown    Logically Collective
3045b3a6b972SJed Brown 
3046b3a6b972SJed Brown    Input Arguments:
3047b3a6b972SJed Brown +  global - global DM
3048b3a6b972SJed Brown .  ddhook - function to run to pass data to the decomposition DM upon its creation
3049b3a6b972SJed Brown .  restricthook - function to run to update data on block solve (at the beginning of the block solve)
3050b3a6b972SJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
3051b3a6b972SJed Brown 
3052b3a6b972SJed Brown    Level: advanced
3053b3a6b972SJed Brown 
3054b3a6b972SJed Brown    Notes:
3055b3a6b972SJed Brown 
3056b3a6b972SJed Brown    This function is currently not available from Fortran.
3057b3a6b972SJed Brown 
3058b3a6b972SJed Brown .seealso: DMSubDomainHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
3059b3a6b972SJed Brown @*/
3060b3a6b972SJed Brown PetscErrorCode DMSubDomainHookRemove(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx)
3061b3a6b972SJed Brown {
3062b3a6b972SJed Brown   PetscErrorCode      ierr;
3063b3a6b972SJed Brown   DMSubDomainHookLink link,*p;
3064b3a6b972SJed Brown 
3065b3a6b972SJed Brown   PetscFunctionBegin;
3066b3a6b972SJed Brown   PetscValidHeaderSpecific(global,DM_CLASSID,1);
3067b3a6b972SJed Brown   for (p=&global->subdomainhook; *p; p=&(*p)->next) { /* Search the list of current hooks */
3068b3a6b972SJed Brown     if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) {
3069b3a6b972SJed Brown       link = *p;
3070b3a6b972SJed Brown       *p = link->next;
3071b3a6b972SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
3072b3a6b972SJed Brown       break;
3073b3a6b972SJed Brown     }
3074b3a6b972SJed Brown   }
3075b3a6b972SJed Brown   PetscFunctionReturn(0);
3076b3a6b972SJed Brown }
3077b3a6b972SJed Brown 
30785dbd56e3SPeter Brune /*@
3079be081cd6SPeter Brune    DMSubDomainRestrict - restricts user-defined problem data to a block DM by running hooks registered by DMSubDomainHookAdd()
30805dbd56e3SPeter Brune 
30815dbd56e3SPeter Brune    Collective if any hooks are
30825dbd56e3SPeter Brune 
30835dbd56e3SPeter Brune    Input Arguments:
30845dbd56e3SPeter Brune +  fine - finer DM to use as a base
3085be081cd6SPeter Brune .  oscatter - scatter from domain global vector filling subdomain global vector with overlap
3086be081cd6SPeter Brune .  gscatter - scatter from domain global vector filling subdomain local vector with ghosts
30875dbd56e3SPeter Brune -  coarse - coarer DM to update
30885dbd56e3SPeter Brune 
30895dbd56e3SPeter Brune    Level: developer
30905dbd56e3SPeter Brune 
30915dbd56e3SPeter Brune .seealso: DMCoarsenHookAdd(), MatRestrict()
30925dbd56e3SPeter Brune @*/
3093be081cd6SPeter Brune PetscErrorCode DMSubDomainRestrict(DM global,VecScatter oscatter,VecScatter gscatter,DM subdm)
30945dbd56e3SPeter Brune {
30955dbd56e3SPeter Brune   PetscErrorCode      ierr;
3096be081cd6SPeter Brune   DMSubDomainHookLink link;
30975dbd56e3SPeter Brune 
30985dbd56e3SPeter Brune   PetscFunctionBegin;
3099be081cd6SPeter Brune   for (link=global->subdomainhook; link; link=link->next) {
31008865f1eaSKarl Rupp     if (link->restricthook) {
31018865f1eaSKarl Rupp       ierr = (*link->restricthook)(global,oscatter,gscatter,subdm,link->ctx);CHKERRQ(ierr);
31028865f1eaSKarl Rupp     }
31035dbd56e3SPeter Brune   }
31045dbd56e3SPeter Brune   PetscFunctionReturn(0);
31055dbd56e3SPeter Brune }
31065dbd56e3SPeter Brune 
31075fe1f584SPeter Brune /*@
31086a7d9d85SPeter Brune     DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM.
31095fe1f584SPeter Brune 
31105fe1f584SPeter Brune     Not Collective
31115fe1f584SPeter Brune 
31125fe1f584SPeter Brune     Input Parameter:
31135fe1f584SPeter Brune .   dm - the DM object
31145fe1f584SPeter Brune 
31155fe1f584SPeter Brune     Output Parameter:
31166a7d9d85SPeter Brune .   level - number of coarsenings
31175fe1f584SPeter Brune 
31185fe1f584SPeter Brune     Level: developer
31195fe1f584SPeter Brune 
31206a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
31215fe1f584SPeter Brune 
31225fe1f584SPeter Brune @*/
31235fe1f584SPeter Brune PetscErrorCode  DMGetCoarsenLevel(DM dm,PetscInt *level)
31245fe1f584SPeter Brune {
31255fe1f584SPeter Brune   PetscFunctionBegin;
31265fe1f584SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3127b9d85ea2SLisandro Dalcin   PetscValidIntPointer(level,2);
31285fe1f584SPeter Brune   *level = dm->leveldown;
31295fe1f584SPeter Brune   PetscFunctionReturn(0);
31305fe1f584SPeter Brune }
31315fe1f584SPeter Brune 
31329a64c4a8SMatthew G. Knepley /*@
31339a64c4a8SMatthew G. Knepley     DMSetCoarsenLevel - Sets the number of coarsenings that have generated this DM.
31349a64c4a8SMatthew G. Knepley 
31359a64c4a8SMatthew G. Knepley     Not Collective
31369a64c4a8SMatthew G. Knepley 
31379a64c4a8SMatthew G. Knepley     Input Parameters:
31389a64c4a8SMatthew G. Knepley +   dm - the DM object
31399a64c4a8SMatthew G. Knepley -   level - number of coarsenings
31409a64c4a8SMatthew G. Knepley 
31419a64c4a8SMatthew G. Knepley     Level: developer
31429a64c4a8SMatthew G. Knepley 
31439a64c4a8SMatthew G. Knepley .seealso DMCoarsen(), DMGetCoarsenLevel(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
31449a64c4a8SMatthew G. Knepley @*/
31459a64c4a8SMatthew G. Knepley PetscErrorCode DMSetCoarsenLevel(DM dm,PetscInt level)
31469a64c4a8SMatthew G. Knepley {
31479a64c4a8SMatthew G. Knepley   PetscFunctionBegin;
31489a64c4a8SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
31499a64c4a8SMatthew G. Knepley   dm->leveldown = level;
31509a64c4a8SMatthew G. Knepley   PetscFunctionReturn(0);
31519a64c4a8SMatthew G. Knepley }
31529a64c4a8SMatthew G. Knepley 
31535fe1f584SPeter Brune 
31545fe1f584SPeter Brune 
315547c6ae99SBarry Smith /*@C
315647c6ae99SBarry Smith     DMRefineHierarchy - Refines a DM object, all levels at once
315747c6ae99SBarry Smith 
3158d083f849SBarry Smith     Collective on dm
315947c6ae99SBarry Smith 
316047c6ae99SBarry Smith     Input Parameter:
316147c6ae99SBarry Smith +   dm - the DM object
316247c6ae99SBarry Smith -   nlevels - the number of levels of refinement
316347c6ae99SBarry Smith 
316447c6ae99SBarry Smith     Output Parameter:
316547c6ae99SBarry Smith .   dmf - the refined DM hierarchy
316647c6ae99SBarry Smith 
316747c6ae99SBarry Smith     Level: developer
316847c6ae99SBarry Smith 
3169e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
317047c6ae99SBarry Smith 
317147c6ae99SBarry Smith @*/
31727087cfbeSBarry Smith PetscErrorCode  DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[])
317347c6ae99SBarry Smith {
317447c6ae99SBarry Smith   PetscErrorCode ierr;
317547c6ae99SBarry Smith 
317647c6ae99SBarry Smith   PetscFunctionBegin;
3177171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3178ce94432eSBarry Smith   if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
317947c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
3180b9d85ea2SLisandro Dalcin   PetscValidPointer(dmf,3);
318147c6ae99SBarry Smith   if (dm->ops->refinehierarchy) {
318247c6ae99SBarry Smith     ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr);
318347c6ae99SBarry Smith   } else if (dm->ops->refine) {
318447c6ae99SBarry Smith     PetscInt i;
318547c6ae99SBarry Smith 
3186ce94432eSBarry Smith     ierr = DMRefine(dm,PetscObjectComm((PetscObject)dm),&dmf[0]);CHKERRQ(ierr);
318747c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
3188ce94432eSBarry Smith       ierr = DMRefine(dmf[i-1],PetscObjectComm((PetscObject)dm),&dmf[i]);CHKERRQ(ierr);
318947c6ae99SBarry Smith     }
3190ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No RefineHierarchy for this DM yet");
319147c6ae99SBarry Smith   PetscFunctionReturn(0);
319247c6ae99SBarry Smith }
319347c6ae99SBarry Smith 
319447c6ae99SBarry Smith /*@C
319547c6ae99SBarry Smith     DMCoarsenHierarchy - Coarsens a DM object, all levels at once
319647c6ae99SBarry Smith 
3197d083f849SBarry Smith     Collective on dm
319847c6ae99SBarry Smith 
319947c6ae99SBarry Smith     Input Parameter:
320047c6ae99SBarry Smith +   dm - the DM object
320147c6ae99SBarry Smith -   nlevels - the number of levels of coarsening
320247c6ae99SBarry Smith 
320347c6ae99SBarry Smith     Output Parameter:
320447c6ae99SBarry Smith .   dmc - the coarsened DM hierarchy
320547c6ae99SBarry Smith 
320647c6ae99SBarry Smith     Level: developer
320747c6ae99SBarry Smith 
3208e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
320947c6ae99SBarry Smith 
321047c6ae99SBarry Smith @*/
32117087cfbeSBarry Smith PetscErrorCode  DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[])
321247c6ae99SBarry Smith {
321347c6ae99SBarry Smith   PetscErrorCode ierr;
321447c6ae99SBarry Smith 
321547c6ae99SBarry Smith   PetscFunctionBegin;
3216171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3217ce94432eSBarry Smith   if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
321847c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
321947c6ae99SBarry Smith   PetscValidPointer(dmc,3);
322047c6ae99SBarry Smith   if (dm->ops->coarsenhierarchy) {
322147c6ae99SBarry Smith     ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr);
322247c6ae99SBarry Smith   } else if (dm->ops->coarsen) {
322347c6ae99SBarry Smith     PetscInt i;
322447c6ae99SBarry Smith 
3225ce94432eSBarry Smith     ierr = DMCoarsen(dm,PetscObjectComm((PetscObject)dm),&dmc[0]);CHKERRQ(ierr);
322647c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
3227ce94432eSBarry Smith       ierr = DMCoarsen(dmc[i-1],PetscObjectComm((PetscObject)dm),&dmc[i]);CHKERRQ(ierr);
322847c6ae99SBarry Smith     }
3229ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet");
323047c6ae99SBarry Smith   PetscFunctionReturn(0);
323147c6ae99SBarry Smith }
323247c6ae99SBarry Smith 
32331a266240SBarry Smith /*@C
32341a266240SBarry Smith     DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed
32351a266240SBarry Smith 
32361a266240SBarry Smith     Not Collective
32371a266240SBarry Smith 
32381a266240SBarry Smith     Input Parameters:
32391a266240SBarry Smith +   dm - the DM object
32401a266240SBarry Smith -   destroy - the destroy function
32411a266240SBarry Smith 
32421a266240SBarry Smith     Level: intermediate
32431a266240SBarry Smith 
3244e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
32451a266240SBarry Smith 
3246f07f9ceaSJed Brown @*/
32471a266240SBarry Smith PetscErrorCode  DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**))
32481a266240SBarry Smith {
32491a266240SBarry Smith   PetscFunctionBegin;
3250171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
32511a266240SBarry Smith   dm->ctxdestroy = destroy;
32521a266240SBarry Smith   PetscFunctionReturn(0);
32531a266240SBarry Smith }
32541a266240SBarry Smith 
3255b07ff414SBarry Smith /*@
32561b2093e4SBarry Smith     DMSetApplicationContext - Set a user context into a DM object
325747c6ae99SBarry Smith 
325847c6ae99SBarry Smith     Not Collective
325947c6ae99SBarry Smith 
326047c6ae99SBarry Smith     Input Parameters:
326147c6ae99SBarry Smith +   dm - the DM object
326247c6ae99SBarry Smith -   ctx - the user context
326347c6ae99SBarry Smith 
326447c6ae99SBarry Smith     Level: intermediate
326547c6ae99SBarry Smith 
3266e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
326747c6ae99SBarry Smith 
326847c6ae99SBarry Smith @*/
32691b2093e4SBarry Smith PetscErrorCode  DMSetApplicationContext(DM dm,void *ctx)
327047c6ae99SBarry Smith {
327147c6ae99SBarry Smith   PetscFunctionBegin;
3272171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
327347c6ae99SBarry Smith   dm->ctx = ctx;
327447c6ae99SBarry Smith   PetscFunctionReturn(0);
327547c6ae99SBarry Smith }
327647c6ae99SBarry Smith 
327747c6ae99SBarry Smith /*@
32781b2093e4SBarry Smith     DMGetApplicationContext - Gets a user context from a DM object
327947c6ae99SBarry Smith 
328047c6ae99SBarry Smith     Not Collective
328147c6ae99SBarry Smith 
328247c6ae99SBarry Smith     Input Parameter:
328347c6ae99SBarry Smith .   dm - the DM object
328447c6ae99SBarry Smith 
328547c6ae99SBarry Smith     Output Parameter:
328647c6ae99SBarry Smith .   ctx - the user context
328747c6ae99SBarry Smith 
328847c6ae99SBarry Smith     Level: intermediate
328947c6ae99SBarry Smith 
3290e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
329147c6ae99SBarry Smith 
329247c6ae99SBarry Smith @*/
32931b2093e4SBarry Smith PetscErrorCode  DMGetApplicationContext(DM dm,void *ctx)
329447c6ae99SBarry Smith {
329547c6ae99SBarry Smith   PetscFunctionBegin;
3296171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
32971b2093e4SBarry Smith   *(void**)ctx = dm->ctx;
329847c6ae99SBarry Smith   PetscFunctionReturn(0);
329947c6ae99SBarry Smith }
330047c6ae99SBarry Smith 
330108da532bSDmitry Karpeev /*@C
3302df3898eeSBarry Smith     DMSetVariableBounds - sets a function to compute the lower and upper bound vectors for SNESVI.
330308da532bSDmitry Karpeev 
3304d083f849SBarry Smith     Logically Collective on dm
330508da532bSDmitry Karpeev 
330608da532bSDmitry Karpeev     Input Parameter:
330708da532bSDmitry Karpeev +   dm - the DM object
33080298fd71SBarry Smith -   f - the function that computes variable bounds used by SNESVI (use NULL to cancel a previous function that was set)
330908da532bSDmitry Karpeev 
331008da532bSDmitry Karpeev     Level: intermediate
331108da532bSDmitry Karpeev 
3312835c3ec7SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(),
331308da532bSDmitry Karpeev          DMSetJacobian()
331408da532bSDmitry Karpeev 
331508da532bSDmitry Karpeev @*/
331608da532bSDmitry Karpeev PetscErrorCode DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
331708da532bSDmitry Karpeev {
331808da532bSDmitry Karpeev   PetscFunctionBegin;
33195a84ad33SLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
332008da532bSDmitry Karpeev   dm->ops->computevariablebounds = f;
332108da532bSDmitry Karpeev   PetscFunctionReturn(0);
332208da532bSDmitry Karpeev }
332308da532bSDmitry Karpeev 
332408da532bSDmitry Karpeev /*@
332508da532bSDmitry Karpeev     DMHasVariableBounds - does the DM object have a variable bounds function?
332608da532bSDmitry Karpeev 
332708da532bSDmitry Karpeev     Not Collective
332808da532bSDmitry Karpeev 
332908da532bSDmitry Karpeev     Input Parameter:
333008da532bSDmitry Karpeev .   dm - the DM object to destroy
333108da532bSDmitry Karpeev 
333208da532bSDmitry Karpeev     Output Parameter:
333308da532bSDmitry Karpeev .   flg - PETSC_TRUE if the variable bounds function exists
333408da532bSDmitry Karpeev 
333508da532bSDmitry Karpeev     Level: developer
333608da532bSDmitry Karpeev 
333774e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
333808da532bSDmitry Karpeev 
333908da532bSDmitry Karpeev @*/
334008da532bSDmitry Karpeev PetscErrorCode DMHasVariableBounds(DM dm,PetscBool *flg)
334108da532bSDmitry Karpeev {
334208da532bSDmitry Karpeev   PetscFunctionBegin;
33435a84ad33SLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3344534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg,2);
334508da532bSDmitry Karpeev   *flg =  (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE;
334608da532bSDmitry Karpeev   PetscFunctionReturn(0);
334708da532bSDmitry Karpeev }
334808da532bSDmitry Karpeev 
334908da532bSDmitry Karpeev /*@C
335008da532bSDmitry Karpeev     DMComputeVariableBounds - compute variable bounds used by SNESVI.
335108da532bSDmitry Karpeev 
3352d083f849SBarry Smith     Logically Collective on dm
335308da532bSDmitry Karpeev 
335408da532bSDmitry Karpeev     Input Parameters:
3355907376e6SBarry Smith .   dm - the DM object
335608da532bSDmitry Karpeev 
335708da532bSDmitry Karpeev     Output parameters:
335808da532bSDmitry Karpeev +   xl - lower bound
335908da532bSDmitry Karpeev -   xu - upper bound
336008da532bSDmitry Karpeev 
3361907376e6SBarry Smith     Level: advanced
3362907376e6SBarry Smith 
336395452b02SPatrick Sanan     Notes:
336495452b02SPatrick Sanan     This is generally not called by users. It calls the function provided by the user with DMSetVariableBounds()
336508da532bSDmitry Karpeev 
336674e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
336708da532bSDmitry Karpeev 
336808da532bSDmitry Karpeev @*/
336908da532bSDmitry Karpeev PetscErrorCode DMComputeVariableBounds(DM dm, Vec xl, Vec xu)
337008da532bSDmitry Karpeev {
337108da532bSDmitry Karpeev   PetscErrorCode ierr;
33725fd66863SKarl Rupp 
337308da532bSDmitry Karpeev   PetscFunctionBegin;
33745a84ad33SLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
337508da532bSDmitry Karpeev   PetscValidHeaderSpecific(xl,VEC_CLASSID,2);
33765a84ad33SLisandro Dalcin   PetscValidHeaderSpecific(xu,VEC_CLASSID,3);
3377b9d85ea2SLisandro Dalcin   if (!dm->ops->computevariablebounds) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeVariableBounds",((PetscObject)dm)->type_name);
337808da532bSDmitry Karpeev   ierr = (*dm->ops->computevariablebounds)(dm, xl,xu);CHKERRQ(ierr);
337908da532bSDmitry Karpeev   PetscFunctionReturn(0);
338008da532bSDmitry Karpeev }
338108da532bSDmitry Karpeev 
3382b0ae01b7SPeter Brune /*@
3383b0ae01b7SPeter Brune     DMHasColoring - does the DM object have a method of providing a coloring?
3384b0ae01b7SPeter Brune 
3385b0ae01b7SPeter Brune     Not Collective
3386b0ae01b7SPeter Brune 
3387b0ae01b7SPeter Brune     Input Parameter:
3388b0ae01b7SPeter Brune .   dm - the DM object
3389b0ae01b7SPeter Brune 
3390b0ae01b7SPeter Brune     Output Parameter:
3391b0ae01b7SPeter Brune .   flg - PETSC_TRUE if the DM has facilities for DMCreateColoring().
3392b0ae01b7SPeter Brune 
3393b0ae01b7SPeter Brune     Level: developer
3394b0ae01b7SPeter Brune 
33951565f0a7SPatrick Sanan .seealso DMCreateColoring()
3396b0ae01b7SPeter Brune 
3397b0ae01b7SPeter Brune @*/
3398b0ae01b7SPeter Brune PetscErrorCode DMHasColoring(DM dm,PetscBool *flg)
3399b0ae01b7SPeter Brune {
3400b0ae01b7SPeter Brune   PetscFunctionBegin;
34015a84ad33SLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3402534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg,2);
3403b0ae01b7SPeter Brune   *flg =  (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE;
3404b0ae01b7SPeter Brune   PetscFunctionReturn(0);
3405b0ae01b7SPeter Brune }
3406b0ae01b7SPeter Brune 
34073ad4599aSBarry Smith /*@
34083ad4599aSBarry Smith     DMHasCreateRestriction - does the DM object have a method of providing a restriction?
34093ad4599aSBarry Smith 
34103ad4599aSBarry Smith     Not Collective
34113ad4599aSBarry Smith 
34123ad4599aSBarry Smith     Input Parameter:
34133ad4599aSBarry Smith .   dm - the DM object
34143ad4599aSBarry Smith 
34153ad4599aSBarry Smith     Output Parameter:
34163ad4599aSBarry Smith .   flg - PETSC_TRUE if the DM has facilities for DMCreateRestriction().
34173ad4599aSBarry Smith 
34183ad4599aSBarry Smith     Level: developer
34193ad4599aSBarry Smith 
34201565f0a7SPatrick Sanan .seealso DMCreateRestriction()
34213ad4599aSBarry Smith 
34223ad4599aSBarry Smith @*/
34233ad4599aSBarry Smith PetscErrorCode DMHasCreateRestriction(DM dm,PetscBool *flg)
34243ad4599aSBarry Smith {
34253ad4599aSBarry Smith   PetscFunctionBegin;
34265a84ad33SLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3427534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg,2);
34283ad4599aSBarry Smith   *flg =  (dm->ops->createrestriction) ? PETSC_TRUE : PETSC_FALSE;
34293ad4599aSBarry Smith   PetscFunctionReturn(0);
34303ad4599aSBarry Smith }
34313ad4599aSBarry Smith 
3432a7058e45SLawrence Mitchell 
3433a7058e45SLawrence Mitchell /*@
3434a7058e45SLawrence Mitchell     DMHasCreateInjection - does the DM object have a method of providing an injection?
3435a7058e45SLawrence Mitchell 
3436a7058e45SLawrence Mitchell     Not Collective
3437a7058e45SLawrence Mitchell 
3438a7058e45SLawrence Mitchell     Input Parameter:
3439a7058e45SLawrence Mitchell .   dm - the DM object
3440a7058e45SLawrence Mitchell 
3441a7058e45SLawrence Mitchell     Output Parameter:
3442a7058e45SLawrence Mitchell .   flg - PETSC_TRUE if the DM has facilities for DMCreateInjection().
3443a7058e45SLawrence Mitchell 
3444a7058e45SLawrence Mitchell     Level: developer
3445a7058e45SLawrence Mitchell 
34461565f0a7SPatrick Sanan .seealso DMCreateInjection()
3447a7058e45SLawrence Mitchell 
3448a7058e45SLawrence Mitchell @*/
3449a7058e45SLawrence Mitchell PetscErrorCode DMHasCreateInjection(DM dm,PetscBool *flg)
3450a7058e45SLawrence Mitchell {
34514a7a4c06SLawrence Mitchell   PetscErrorCode ierr;
34525a84ad33SLisandro Dalcin 
3453a7058e45SLawrence Mitchell   PetscFunctionBegin;
34545a84ad33SLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3455534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg,2);
34565a84ad33SLisandro Dalcin   if (dm->ops->hascreateinjection) {
34574a7a4c06SLawrence Mitchell     ierr = (*dm->ops->hascreateinjection)(dm,flg);CHKERRQ(ierr);
34585a84ad33SLisandro Dalcin   } else {
34595a84ad33SLisandro Dalcin     *flg = (dm->ops->createinjection) ? PETSC_TRUE : PETSC_FALSE;
34605a84ad33SLisandro Dalcin   }
3461a7058e45SLawrence Mitchell   PetscFunctionReturn(0);
3462a7058e45SLawrence Mitchell }
3463a7058e45SLawrence Mitchell 
34645a84ad33SLisandro Dalcin 
3465748fac09SDmitry Karpeev /*@C
346608da532bSDmitry Karpeev     DMSetVec - set the vector at which to compute residual, Jacobian and VI bounds, if the problem is nonlinear.
346708da532bSDmitry Karpeev 
3468d083f849SBarry Smith     Collective on dm
346908da532bSDmitry Karpeev 
347008da532bSDmitry Karpeev     Input Parameter:
347108da532bSDmitry Karpeev +   dm - the DM object
34720298fd71SBarry Smith -   x - location to compute residual and Jacobian, if NULL is passed to those routines; will be NULL for linear problems.
347308da532bSDmitry Karpeev 
347408da532bSDmitry Karpeev     Level: developer
347508da532bSDmitry Karpeev 
347674e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
347708da532bSDmitry Karpeev 
347808da532bSDmitry Karpeev @*/
347908da532bSDmitry Karpeev PetscErrorCode  DMSetVec(DM dm,Vec x)
348008da532bSDmitry Karpeev {
348108da532bSDmitry Karpeev   PetscErrorCode ierr;
34825fd66863SKarl Rupp 
348308da532bSDmitry Karpeev   PetscFunctionBegin;
3484b9d85ea2SLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
348508da532bSDmitry Karpeev   if (x) {
348608da532bSDmitry Karpeev     if (!dm->x) {
348708da532bSDmitry Karpeev       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
348808da532bSDmitry Karpeev     }
348908da532bSDmitry Karpeev     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
34908865f1eaSKarl Rupp   } else if (dm->x) {
349108da532bSDmitry Karpeev     ierr = VecDestroy(&dm->x);CHKERRQ(ierr);
349208da532bSDmitry Karpeev   }
349308da532bSDmitry Karpeev   PetscFunctionReturn(0);
349408da532bSDmitry Karpeev }
349508da532bSDmitry Karpeev 
34960298fd71SBarry Smith PetscFunctionList DMList              = NULL;
3497264ace61SBarry Smith PetscBool         DMRegisterAllCalled = PETSC_FALSE;
3498264ace61SBarry Smith 
3499264ace61SBarry Smith /*@C
3500264ace61SBarry Smith   DMSetType - Builds a DM, for a particular DM implementation.
3501264ace61SBarry Smith 
3502d083f849SBarry Smith   Collective on dm
3503264ace61SBarry Smith 
3504264ace61SBarry Smith   Input Parameters:
3505264ace61SBarry Smith + dm     - The DM object
3506264ace61SBarry Smith - method - The name of the DM type
3507264ace61SBarry Smith 
3508264ace61SBarry Smith   Options Database Key:
3509264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types
3510264ace61SBarry Smith 
3511264ace61SBarry Smith   Notes:
3512e1589f56SBarry Smith   See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D).
3513264ace61SBarry Smith 
3514264ace61SBarry Smith   Level: intermediate
3515264ace61SBarry Smith 
3516264ace61SBarry Smith .seealso: DMGetType(), DMCreate()
3517264ace61SBarry Smith @*/
351819fd82e9SBarry Smith PetscErrorCode  DMSetType(DM dm, DMType method)
3519264ace61SBarry Smith {
3520264ace61SBarry Smith   PetscErrorCode (*r)(DM);
3521264ace61SBarry Smith   PetscBool      match;
3522264ace61SBarry Smith   PetscErrorCode ierr;
3523264ace61SBarry Smith 
3524264ace61SBarry Smith   PetscFunctionBegin;
3525264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
3526251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr);
3527264ace61SBarry Smith   if (match) PetscFunctionReturn(0);
3528264ace61SBarry Smith 
35290f51fdf8SToby Isaac   ierr = DMRegisterAll();CHKERRQ(ierr);
35301c9cd337SJed Brown   ierr = PetscFunctionListFind(DMList,method,&r);CHKERRQ(ierr);
3531ce94432eSBarry Smith   if (!r) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method);
3532264ace61SBarry Smith 
3533264ace61SBarry Smith   if (dm->ops->destroy) {
3534264ace61SBarry Smith     ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr);
3535264ace61SBarry Smith   }
3536d57f96a3SLisandro Dalcin   ierr = PetscMemzero(dm->ops,sizeof(*dm->ops));CHKERRQ(ierr);
3537264ace61SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr);
3538d57f96a3SLisandro Dalcin   ierr = (*r)(dm);CHKERRQ(ierr);
3539264ace61SBarry Smith   PetscFunctionReturn(0);
3540264ace61SBarry Smith }
3541264ace61SBarry Smith 
3542264ace61SBarry Smith /*@C
3543264ace61SBarry Smith   DMGetType - Gets the DM type name (as a string) from the DM.
3544264ace61SBarry Smith 
3545264ace61SBarry Smith   Not Collective
3546264ace61SBarry Smith 
3547264ace61SBarry Smith   Input Parameter:
3548264ace61SBarry Smith . dm  - The DM
3549264ace61SBarry Smith 
3550264ace61SBarry Smith   Output Parameter:
3551264ace61SBarry Smith . type - The DM type name
3552264ace61SBarry Smith 
3553264ace61SBarry Smith   Level: intermediate
3554264ace61SBarry Smith 
3555264ace61SBarry Smith .seealso: DMSetType(), DMCreate()
3556264ace61SBarry Smith @*/
355719fd82e9SBarry Smith PetscErrorCode  DMGetType(DM dm, DMType *type)
3558264ace61SBarry Smith {
3559264ace61SBarry Smith   PetscErrorCode ierr;
3560264ace61SBarry Smith 
3561264ace61SBarry Smith   PetscFunctionBegin;
3562264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
3563c959eef4SJed Brown   PetscValidPointer(type,2);
3564607a6623SBarry Smith   ierr = DMRegisterAll();CHKERRQ(ierr);
3565264ace61SBarry Smith   *type = ((PetscObject)dm)->type_name;
3566264ace61SBarry Smith   PetscFunctionReturn(0);
3567264ace61SBarry Smith }
3568264ace61SBarry Smith 
356967a56275SMatthew G Knepley /*@C
357067a56275SMatthew G Knepley   DMConvert - Converts a DM to another DM, either of the same or different type.
357167a56275SMatthew G Knepley 
3572d083f849SBarry Smith   Collective on dm
357367a56275SMatthew G Knepley 
357467a56275SMatthew G Knepley   Input Parameters:
357567a56275SMatthew G Knepley + dm - the DM
357667a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type)
357767a56275SMatthew G Knepley 
357867a56275SMatthew G Knepley   Output Parameter:
357967a56275SMatthew G Knepley . M - pointer to new DM
358067a56275SMatthew G Knepley 
358167a56275SMatthew G Knepley   Notes:
358267a56275SMatthew G Knepley   Cannot be used to convert a sequential DM to parallel or parallel to sequential,
358367a56275SMatthew G Knepley   the MPI communicator of the generated DM is always the same as the communicator
358467a56275SMatthew G Knepley   of the input DM.
358567a56275SMatthew G Knepley 
358667a56275SMatthew G Knepley   Level: intermediate
358767a56275SMatthew G Knepley 
358867a56275SMatthew G Knepley .seealso: DMCreate()
358967a56275SMatthew G Knepley @*/
359019fd82e9SBarry Smith PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M)
359167a56275SMatthew G Knepley {
359267a56275SMatthew G Knepley   DM             B;
359367a56275SMatthew G Knepley   char           convname[256];
3594c067b6caSMatthew G. Knepley   PetscBool      sametype/*, issame */;
359567a56275SMatthew G Knepley   PetscErrorCode ierr;
359667a56275SMatthew G Knepley 
359767a56275SMatthew G Knepley   PetscFunctionBegin;
359867a56275SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
359967a56275SMatthew G Knepley   PetscValidType(dm,1);
360067a56275SMatthew G Knepley   PetscValidPointer(M,3);
3601251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr);
3602c067b6caSMatthew G. Knepley   /* ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr); */
3603c067b6caSMatthew G. Knepley   if (sametype) {
3604c067b6caSMatthew G. Knepley     *M   = dm;
3605c067b6caSMatthew G. Knepley     ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr);
3606c067b6caSMatthew G. Knepley     PetscFunctionReturn(0);
3607c067b6caSMatthew G. Knepley   } else {
36080298fd71SBarry Smith     PetscErrorCode (*conv)(DM, DMType, DM*) = NULL;
360967a56275SMatthew G Knepley 
361067a56275SMatthew G Knepley     /*
361167a56275SMatthew G Knepley        Order of precedence:
361267a56275SMatthew G Knepley        1) See if a specialized converter is known to the current DM.
361367a56275SMatthew G Knepley        2) See if a specialized converter is known to the desired DM class.
361467a56275SMatthew G Knepley        3) See if a good general converter is registered for the desired class
361567a56275SMatthew G Knepley        4) See if a good general converter is known for the current matrix.
361667a56275SMatthew G Knepley        5) Use a really basic converter.
361767a56275SMatthew G Knepley     */
361867a56275SMatthew G Knepley 
361967a56275SMatthew G Knepley     /* 1) See if a specialized converter is known to the current DM and the desired class */
3620a126751eSBarry Smith     ierr = PetscStrncpy(convname,"DMConvert_",sizeof(convname));CHKERRQ(ierr);
3621a126751eSBarry Smith     ierr = PetscStrlcat(convname,((PetscObject) dm)->type_name,sizeof(convname));CHKERRQ(ierr);
3622a126751eSBarry Smith     ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
3623a126751eSBarry Smith     ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
3624a126751eSBarry Smith     ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
36250005d66cSJed Brown     ierr = PetscObjectQueryFunction((PetscObject)dm,convname,&conv);CHKERRQ(ierr);
362667a56275SMatthew G Knepley     if (conv) goto foundconv;
362767a56275SMatthew G Knepley 
362867a56275SMatthew G Knepley     /* 2)  See if a specialized converter is known to the desired DM class. */
362982f516ccSBarry Smith     ierr = DMCreate(PetscObjectComm((PetscObject)dm), &B);CHKERRQ(ierr);
363067a56275SMatthew G Knepley     ierr = DMSetType(B, newtype);CHKERRQ(ierr);
3631a126751eSBarry Smith     ierr = PetscStrncpy(convname,"DMConvert_",sizeof(convname));CHKERRQ(ierr);
3632a126751eSBarry Smith     ierr = PetscStrlcat(convname,((PetscObject) dm)->type_name,sizeof(convname));CHKERRQ(ierr);
3633a126751eSBarry Smith     ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
3634a126751eSBarry Smith     ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
3635a126751eSBarry Smith     ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
36360005d66cSJed Brown     ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
363767a56275SMatthew G Knepley     if (conv) {
3638fcfd50ebSBarry Smith       ierr = DMDestroy(&B);CHKERRQ(ierr);
363967a56275SMatthew G Knepley       goto foundconv;
364067a56275SMatthew G Knepley     }
364167a56275SMatthew G Knepley 
364267a56275SMatthew G Knepley #if 0
364367a56275SMatthew G Knepley     /* 3) See if a good general converter is registered for the desired class */
364467a56275SMatthew G Knepley     conv = B->ops->convertfrom;
3645fcfd50ebSBarry Smith     ierr = DMDestroy(&B);CHKERRQ(ierr);
364667a56275SMatthew G Knepley     if (conv) goto foundconv;
364767a56275SMatthew G Knepley 
364867a56275SMatthew G Knepley     /* 4) See if a good general converter is known for the current matrix */
364967a56275SMatthew G Knepley     if (dm->ops->convert) {
365067a56275SMatthew G Knepley       conv = dm->ops->convert;
365167a56275SMatthew G Knepley     }
365267a56275SMatthew G Knepley     if (conv) goto foundconv;
365367a56275SMatthew G Knepley #endif
365467a56275SMatthew G Knepley 
365567a56275SMatthew G Knepley     /* 5) Use a really basic converter. */
365682f516ccSBarry Smith     SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype);
365767a56275SMatthew G Knepley 
365867a56275SMatthew G Knepley foundconv:
365967a56275SMatthew G Knepley     ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
366067a56275SMatthew G Knepley     ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr);
366112fa691eSMatthew G. Knepley     /* Things that are independent of DM type: We should consult DMClone() here */
366290b157c4SStefano Zampini     {
366390b157c4SStefano Zampini       PetscBool             isper;
366412fa691eSMatthew G. Knepley       const PetscReal      *maxCell, *L;
366512fa691eSMatthew G. Knepley       const DMBoundaryType *bd;
366690b157c4SStefano Zampini       ierr = DMGetPeriodicity(dm, &isper, &maxCell, &L, &bd);CHKERRQ(ierr);
366790b157c4SStefano Zampini       ierr = DMSetPeriodicity(*M, isper, maxCell,  L,  bd);CHKERRQ(ierr);
366812fa691eSMatthew G. Knepley     }
366967a56275SMatthew G Knepley     ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
367067a56275SMatthew G Knepley   }
367167a56275SMatthew G Knepley   ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr);
367267a56275SMatthew G Knepley   PetscFunctionReturn(0);
367367a56275SMatthew G Knepley }
3674264ace61SBarry Smith 
3675264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
3676264ace61SBarry Smith 
3677264ace61SBarry Smith /*@C
36781c84c290SBarry Smith   DMRegister -  Adds a new DM component implementation
36791c84c290SBarry Smith 
36801c84c290SBarry Smith   Not Collective
36811c84c290SBarry Smith 
36821c84c290SBarry Smith   Input Parameters:
36831c84c290SBarry Smith + name        - The name of a new user-defined creation routine
36841c84c290SBarry Smith - create_func - The creation routine itself
36851c84c290SBarry Smith 
36861c84c290SBarry Smith   Notes:
36871c84c290SBarry Smith   DMRegister() may be called multiple times to add several user-defined DMs
36881c84c290SBarry Smith 
36891c84c290SBarry Smith 
36901c84c290SBarry Smith   Sample usage:
36911c84c290SBarry Smith .vb
3692bdf89e91SBarry Smith     DMRegister("my_da", MyDMCreate);
36931c84c290SBarry Smith .ve
36941c84c290SBarry Smith 
36951c84c290SBarry Smith   Then, your DM type can be chosen with the procedural interface via
36961c84c290SBarry Smith .vb
36971c84c290SBarry Smith     DMCreate(MPI_Comm, DM *);
36981c84c290SBarry Smith     DMSetType(DM,"my_da");
36991c84c290SBarry Smith .ve
37001c84c290SBarry Smith    or at runtime via the option
37011c84c290SBarry Smith .vb
37021c84c290SBarry Smith     -da_type my_da
37031c84c290SBarry Smith .ve
3704264ace61SBarry Smith 
3705264ace61SBarry Smith   Level: advanced
37061c84c290SBarry Smith 
3707bdf89e91SBarry Smith .seealso: DMRegisterAll(), DMRegisterDestroy()
37081c84c290SBarry Smith 
3709264ace61SBarry Smith @*/
3710bdf89e91SBarry Smith PetscErrorCode  DMRegister(const char sname[],PetscErrorCode (*function)(DM))
3711264ace61SBarry Smith {
3712264ace61SBarry Smith   PetscErrorCode ierr;
3713264ace61SBarry Smith 
3714264ace61SBarry Smith   PetscFunctionBegin;
37151d36bdfdSBarry Smith   ierr = DMInitializePackage();CHKERRQ(ierr);
3716a240a19fSJed Brown   ierr = PetscFunctionListAdd(&DMList,sname,function);CHKERRQ(ierr);
3717264ace61SBarry Smith   PetscFunctionReturn(0);
3718264ace61SBarry Smith }
3719264ace61SBarry Smith 
3720b859378eSBarry Smith /*@C
372155849f57SBarry Smith   DMLoad - Loads a DM that has been stored in binary  with DMView().
3722b859378eSBarry Smith 
3723d083f849SBarry Smith   Collective on viewer
3724b859378eSBarry Smith 
3725b859378eSBarry Smith   Input Parameters:
3726b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or
3727b859378eSBarry Smith            some related function before a call to DMLoad().
3728b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
3729b859378eSBarry Smith            HDF5 file viewer, obtained from PetscViewerHDF5Open()
3730b859378eSBarry Smith 
3731b859378eSBarry Smith    Level: intermediate
3732b859378eSBarry Smith 
3733b859378eSBarry Smith   Notes:
373455849f57SBarry Smith    The type is determined by the data in the file, any type set into the DM before this call is ignored.
3735b859378eSBarry Smith 
3736b859378eSBarry Smith   Notes for advanced users:
3737b859378eSBarry Smith   Most users should not need to know the details of the binary storage
3738b859378eSBarry Smith   format, since DMLoad() and DMView() completely hide these details.
3739b859378eSBarry Smith   But for anyone who's interested, the standard binary matrix storage
3740b859378eSBarry Smith   format is
3741b859378eSBarry Smith .vb
3742b859378eSBarry Smith      has not yet been determined
3743b859378eSBarry Smith .ve
3744b859378eSBarry Smith 
3745b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad()
3746b859378eSBarry Smith @*/
3747b859378eSBarry Smith PetscErrorCode  DMLoad(DM newdm, PetscViewer viewer)
3748b859378eSBarry Smith {
37499331c7a4SMatthew G. Knepley   PetscBool      isbinary, ishdf5;
3750b859378eSBarry Smith   PetscErrorCode ierr;
3751b859378eSBarry Smith 
3752b859378eSBarry Smith   PetscFunctionBegin;
3753b859378eSBarry Smith   PetscValidHeaderSpecific(newdm,DM_CLASSID,1);
3754b859378eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
3755fb694a9eSVaclav Hapla   ierr = PetscViewerCheckReadable(viewer);CHKERRQ(ierr);
375632c0f0efSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
37579331c7a4SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr);
37589331c7a4SMatthew G. Knepley   if (isbinary) {
37599331c7a4SMatthew G. Knepley     PetscInt classid;
37609331c7a4SMatthew G. Knepley     char     type[256];
3761b859378eSBarry Smith 
3762060da220SMatthew G. Knepley     ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr);
37639200755eSBarry Smith     if (classid != DM_FILE_CLASSID) SETERRQ1(PetscObjectComm((PetscObject)newdm),PETSC_ERR_ARG_WRONG,"Not DM next in file, classid found %d",(int)classid);
3764060da220SMatthew G. Knepley     ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr);
376532c0f0efSBarry Smith     ierr = DMSetType(newdm, type);CHKERRQ(ierr);
37669331c7a4SMatthew G. Knepley     if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);}
37679331c7a4SMatthew G. Knepley   } else if (ishdf5) {
37689331c7a4SMatthew G. Knepley     if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);}
37699331c7a4SMatthew G. Knepley   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()");
3770b859378eSBarry Smith   PetscFunctionReturn(0);
3771b859378eSBarry Smith }
3772b859378eSBarry Smith 
3773b2e4378dSMatthew G. Knepley /*@
3774b2e4378dSMatthew G. Knepley   DMGetLocalBoundingBox - Returns the bounding box for the piece of the DM on this process.
3775b2e4378dSMatthew G. Knepley 
3776b2e4378dSMatthew G. Knepley   Not collective
3777b2e4378dSMatthew G. Knepley 
3778b2e4378dSMatthew G. Knepley   Input Parameter:
3779b2e4378dSMatthew G. Knepley . dm - the DM
3780b2e4378dSMatthew G. Knepley 
3781b2e4378dSMatthew G. Knepley   Output Parameters:
3782b2e4378dSMatthew G. Knepley + lmin - local minimum coordinates (length coord dim, optional)
3783b2e4378dSMatthew G. Knepley - lmax - local maximim coordinates (length coord dim, optional)
3784b2e4378dSMatthew G. Knepley 
3785b2e4378dSMatthew G. Knepley   Level: beginner
3786b2e4378dSMatthew G. Knepley 
3787b2e4378dSMatthew G. Knepley   Note: If the DM is a DMDA and has no coordinates, the index bounds are returned instead.
3788b2e4378dSMatthew G. Knepley 
3789b2e4378dSMatthew G. Knepley 
3790b2e4378dSMatthew G. Knepley .seealso: DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetBoundingBox()
3791b2e4378dSMatthew G. Knepley @*/
3792b2e4378dSMatthew G. Knepley PetscErrorCode DMGetLocalBoundingBox(DM dm, PetscReal lmin[], PetscReal lmax[])
3793b2e4378dSMatthew G. Knepley {
3794b2e4378dSMatthew G. Knepley   Vec                coords = NULL;
3795b2e4378dSMatthew G. Knepley   PetscReal          min[3] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MAX_REAL};
3796b2e4378dSMatthew G. Knepley   PetscReal          max[3] = {PETSC_MIN_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL};
3797b2e4378dSMatthew G. Knepley   const PetscScalar *local_coords;
3798b2e4378dSMatthew G. Knepley   PetscInt           N, Ni;
3799b2e4378dSMatthew G. Knepley   PetscInt           cdim, i, j;
3800b2e4378dSMatthew G. Knepley   PetscErrorCode     ierr;
3801b2e4378dSMatthew G. Knepley 
3802b2e4378dSMatthew G. Knepley   PetscFunctionBegin;
3803b2e4378dSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3804b2e4378dSMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
3805b2e4378dSMatthew G. Knepley   ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr);
3806b2e4378dSMatthew G. Knepley   if (coords) {
3807b2e4378dSMatthew G. Knepley     ierr = VecGetArrayRead(coords, &local_coords);CHKERRQ(ierr);
3808b2e4378dSMatthew G. Knepley     ierr = VecGetLocalSize(coords, &N);CHKERRQ(ierr);
3809b2e4378dSMatthew G. Knepley     Ni   = N/cdim;
3810b2e4378dSMatthew G. Knepley     for (i = 0; i < Ni; ++i) {
3811b2e4378dSMatthew G. Knepley       for (j = 0; j < 3; ++j) {
3812b2e4378dSMatthew G. Knepley         min[j] = j < cdim ? PetscMin(min[j], PetscRealPart(local_coords[i*cdim+j])) : 0;
3813b2e4378dSMatthew G. Knepley         max[j] = j < cdim ? PetscMax(max[j], PetscRealPart(local_coords[i*cdim+j])) : 0;
3814b2e4378dSMatthew G. Knepley       }
3815b2e4378dSMatthew G. Knepley     }
3816b2e4378dSMatthew G. Knepley     ierr = VecRestoreArrayRead(coords, &local_coords);CHKERRQ(ierr);
3817b2e4378dSMatthew G. Knepley   } else {
3818b2e4378dSMatthew G. Knepley     PetscBool isda;
3819b2e4378dSMatthew G. Knepley 
3820b2e4378dSMatthew G. Knepley     ierr = PetscObjectTypeCompare((PetscObject) dm, DMDA, &isda);CHKERRQ(ierr);
3821b2e4378dSMatthew G. Knepley     if (isda) {ierr = DMGetLocalBoundingIndices_DMDA(dm, min, max);CHKERRQ(ierr);}
3822b2e4378dSMatthew G. Knepley   }
3823b2e4378dSMatthew G. Knepley   if (lmin) {ierr = PetscArraycpy(lmin, min, cdim);CHKERRQ(ierr);}
3824b2e4378dSMatthew G. Knepley   if (lmax) {ierr = PetscArraycpy(lmax, max, cdim);CHKERRQ(ierr);}
3825b2e4378dSMatthew G. Knepley   PetscFunctionReturn(0);
3826b2e4378dSMatthew G. Knepley }
3827b2e4378dSMatthew G. Knepley 
3828b2e4378dSMatthew G. Knepley /*@
3829b2e4378dSMatthew G. Knepley   DMGetBoundingBox - Returns the global bounding box for the DM.
3830b2e4378dSMatthew G. Knepley 
3831b2e4378dSMatthew G. Knepley   Collective
3832b2e4378dSMatthew G. Knepley 
3833b2e4378dSMatthew G. Knepley   Input Parameter:
3834b2e4378dSMatthew G. Knepley . dm - the DM
3835b2e4378dSMatthew G. Knepley 
3836b2e4378dSMatthew G. Knepley   Output Parameters:
3837b2e4378dSMatthew G. Knepley + gmin - global minimum coordinates (length coord dim, optional)
3838b2e4378dSMatthew G. Knepley - gmax - global maximim coordinates (length coord dim, optional)
3839b2e4378dSMatthew G. Knepley 
3840b2e4378dSMatthew G. Knepley   Level: beginner
3841b2e4378dSMatthew G. Knepley 
3842b2e4378dSMatthew G. Knepley .seealso: DMGetLocalBoundingBox(), DMGetCoordinates(), DMGetCoordinatesLocal()
3843b2e4378dSMatthew G. Knepley @*/
3844b2e4378dSMatthew G. Knepley PetscErrorCode DMGetBoundingBox(DM dm, PetscReal gmin[], PetscReal gmax[])
3845b2e4378dSMatthew G. Knepley {
3846b2e4378dSMatthew G. Knepley   PetscReal      lmin[3], lmax[3];
38476ce308c4SMatthew G. Knepley   PetscInt       cdim;
38486ce308c4SMatthew G. Knepley   PetscMPIInt    count;
3849b2e4378dSMatthew G. Knepley   PetscErrorCode ierr;
3850b2e4378dSMatthew G. Knepley 
3851b2e4378dSMatthew G. Knepley   PetscFunctionBegin;
3852b2e4378dSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3853b2e4378dSMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
3854b2e4378dSMatthew G. Knepley   ierr = PetscMPIIntCast(cdim, &count);CHKERRQ(ierr);
3855b2e4378dSMatthew G. Knepley   ierr = DMGetLocalBoundingBox(dm, lmin, lmax);CHKERRQ(ierr);
3856b2e4378dSMatthew G. Knepley   if (gmin) {ierr = MPIU_Allreduce(lmin, gmin, count, MPIU_REAL, MPIU_MIN, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);}
3857b2e4378dSMatthew G. Knepley   if (gmax) {ierr = MPIU_Allreduce(lmax, gmax, count, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);}
3858b2e4378dSMatthew G. Knepley   PetscFunctionReturn(0);
3859b2e4378dSMatthew G. Knepley }
3860b2e4378dSMatthew G. Knepley 
38617da65231SMatthew G Knepley /******************************** FEM Support **********************************/
38627da65231SMatthew G Knepley 
3863a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[])
3864a6dfd86eSKarl Rupp {
38651d47ebbbSSatish Balay   PetscInt       f;
38661b30c384SMatthew G Knepley   PetscErrorCode ierr;
38671b30c384SMatthew G Knepley 
38687da65231SMatthew G Knepley   PetscFunctionBegin;
386974778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
38701d47ebbbSSatish Balay   for (f = 0; f < len; ++f) {
387157622a8eSBarry Smith     ierr = PetscPrintf(PETSC_COMM_SELF, "  | %g |\n", (double)PetscRealPart(x[f]));CHKERRQ(ierr);
38727da65231SMatthew G Knepley   }
38737da65231SMatthew G Knepley   PetscFunctionReturn(0);
38747da65231SMatthew G Knepley }
38757da65231SMatthew G Knepley 
3876a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[])
3877a6dfd86eSKarl Rupp {
38781b30c384SMatthew G Knepley   PetscInt       f, g;
38797da65231SMatthew G Knepley   PetscErrorCode ierr;
38807da65231SMatthew G Knepley 
38817da65231SMatthew G Knepley   PetscFunctionBegin;
388274778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
38831d47ebbbSSatish Balay   for (f = 0; f < rows; ++f) {
388474778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  |");CHKERRQ(ierr);
38851d47ebbbSSatish Balay     for (g = 0; g < cols; ++g) {
3886e3556bceSMatthew G. Knepley       ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5g", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr);
38877da65231SMatthew G Knepley     }
388874778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr);
38897da65231SMatthew G Knepley   }
38907da65231SMatthew G Knepley   PetscFunctionReturn(0);
38917da65231SMatthew G Knepley }
3892e7c4fc90SDmitry Karpeev 
38936113b454SMatthew G. Knepley PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X)
3894e759306cSMatthew G. Knepley {
38950c5b8624SToby Isaac   PetscInt          localSize, bs;
38960c5b8624SToby Isaac   PetscMPIInt       size;
38970c5b8624SToby Isaac   Vec               x, xglob;
38980c5b8624SToby Isaac   const PetscScalar *xarray;
3899e759306cSMatthew G. Knepley   PetscErrorCode    ierr;
3900e759306cSMatthew G. Knepley 
3901e759306cSMatthew G. Knepley   PetscFunctionBegin;
39029852e123SBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm),&size);CHKERRQ(ierr);
3903e759306cSMatthew G. Knepley   ierr = VecDuplicate(X, &x);CHKERRQ(ierr);
3904e759306cSMatthew G. Knepley   ierr = VecCopy(X, x);CHKERRQ(ierr);
39056113b454SMatthew G. Knepley   ierr = VecChop(x, tol);CHKERRQ(ierr);
39060c5b8624SToby Isaac   ierr = PetscPrintf(PetscObjectComm((PetscObject) dm),"%s:\n",name);CHKERRQ(ierr);
39070c5b8624SToby Isaac   if (size > 1) {
39080c5b8624SToby Isaac     ierr = VecGetLocalSize(x,&localSize);CHKERRQ(ierr);
39090c5b8624SToby Isaac     ierr = VecGetArrayRead(x,&xarray);CHKERRQ(ierr);
39100c5b8624SToby Isaac     ierr = VecGetBlockSize(x,&bs);CHKERRQ(ierr);
39110c5b8624SToby Isaac     ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject) dm),bs,localSize,PETSC_DETERMINE,xarray,&xglob);CHKERRQ(ierr);
39120c5b8624SToby Isaac   } else {
39130c5b8624SToby Isaac     xglob = x;
39140c5b8624SToby Isaac   }
39150c5b8624SToby Isaac   ierr = VecView(xglob,PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject) dm)));CHKERRQ(ierr);
39160c5b8624SToby Isaac   if (size > 1) {
39170c5b8624SToby Isaac     ierr = VecDestroy(&xglob);CHKERRQ(ierr);
39180c5b8624SToby Isaac     ierr = VecRestoreArrayRead(x,&xarray);CHKERRQ(ierr);
39190c5b8624SToby Isaac   }
3920e759306cSMatthew G. Knepley   ierr = VecDestroy(&x);CHKERRQ(ierr);
3921e759306cSMatthew G. Knepley   PetscFunctionReturn(0);
3922e759306cSMatthew G. Knepley }
3923e759306cSMatthew G. Knepley 
392488ed4aceSMatthew G Knepley /*@
39251bb6d2a8SBarry Smith   DMGetSection - Get the PetscSection encoding the local data layout for the DM.   This is equivalent to DMGetLocalSection(). Deprecated in v3.12
3926061576a5SJed Brown 
3927061576a5SJed Brown   Input Parameter:
3928061576a5SJed Brown . dm - The DM
3929061576a5SJed Brown 
3930061576a5SJed Brown   Output Parameter:
3931061576a5SJed Brown . section - The PetscSection
3932061576a5SJed Brown 
3933061576a5SJed Brown   Options Database Keys:
3934061576a5SJed Brown . -dm_petscsection_view - View the Section created by the DM
3935061576a5SJed Brown 
3936061576a5SJed Brown   Level: advanced
3937061576a5SJed Brown 
3938061576a5SJed Brown   Notes:
3939061576a5SJed Brown   Use DMGetLocalSection() in new code.
3940061576a5SJed Brown 
3941061576a5SJed Brown   This gets a borrowed reference, so the user should not destroy this PetscSection.
3942061576a5SJed Brown 
3943061576a5SJed Brown .seealso: DMGetLocalSection(), DMSetLocalSection(), DMGetGlobalSection()
3944061576a5SJed Brown @*/
3945061576a5SJed Brown PetscErrorCode DMGetSection(DM dm, PetscSection *section)
3946061576a5SJed Brown {
3947061576a5SJed Brown   PetscErrorCode ierr;
3948061576a5SJed Brown 
3949061576a5SJed Brown   PetscFunctionBegin;
3950061576a5SJed Brown   ierr = DMGetLocalSection(dm,section);CHKERRQ(ierr);
3951061576a5SJed Brown   PetscFunctionReturn(0);
3952061576a5SJed Brown }
3953061576a5SJed Brown 
3954061576a5SJed Brown /*@
3955061576a5SJed Brown   DMGetLocalSection - Get the PetscSection encoding the local data layout for the DM.
395688ed4aceSMatthew G Knepley 
395788ed4aceSMatthew G Knepley   Input Parameter:
395888ed4aceSMatthew G Knepley . dm - The DM
395988ed4aceSMatthew G Knepley 
396088ed4aceSMatthew G Knepley   Output Parameter:
396188ed4aceSMatthew G Knepley . section - The PetscSection
396288ed4aceSMatthew G Knepley 
3963e5893cccSMatthew G. Knepley   Options Database Keys:
3964e5893cccSMatthew G. Knepley . -dm_petscsection_view - View the Section created by the DM
3965e5893cccSMatthew G. Knepley 
396688ed4aceSMatthew G Knepley   Level: intermediate
396788ed4aceSMatthew G Knepley 
396888ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
396988ed4aceSMatthew G Knepley 
3970061576a5SJed Brown .seealso: DMSetLocalSection(), DMGetGlobalSection()
397188ed4aceSMatthew G Knepley @*/
3972061576a5SJed Brown PetscErrorCode DMGetLocalSection(DM dm, PetscSection *section)
39730adebc6cSBarry Smith {
3974fd59a867SMatthew G. Knepley   PetscErrorCode ierr;
3975fd59a867SMatthew G. Knepley 
397688ed4aceSMatthew G Knepley   PetscFunctionBegin;
397788ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
397888ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
39791bb6d2a8SBarry Smith   if (!dm->localSection && dm->ops->createlocalsection) {
3980e5e52638SMatthew G. Knepley     PetscInt d;
3981e5e52638SMatthew G. Knepley 
3982e5e52638SMatthew G. Knepley     if (dm->setfromoptionscalled) for (d = 0; d < dm->Nds; ++d) {ierr = PetscDSSetFromOptions(dm->probs[d].ds);CHKERRQ(ierr);}
39831bb6d2a8SBarry Smith     ierr = (*dm->ops->createlocalsection)(dm);CHKERRQ(ierr);
39841bb6d2a8SBarry Smith     if (dm->localSection) {ierr = PetscObjectViewFromOptions((PetscObject) dm->localSection, NULL, "-dm_petscsection_view");CHKERRQ(ierr);}
39852f0f8703SMatthew G. Knepley   }
39861bb6d2a8SBarry Smith   *section = dm->localSection;
398788ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
398888ed4aceSMatthew G Knepley }
398988ed4aceSMatthew G Knepley 
399088ed4aceSMatthew G Knepley /*@
39911bb6d2a8SBarry Smith   DMSetSection - Set the PetscSection encoding the local data layout for the DM.  This is equivalent to DMSetLocalSection(). Deprecated in v3.12
3992061576a5SJed Brown 
3993061576a5SJed Brown   Input Parameters:
3994061576a5SJed Brown + dm - The DM
3995061576a5SJed Brown - section - The PetscSection
3996061576a5SJed Brown 
3997061576a5SJed Brown   Level: advanced
3998061576a5SJed Brown 
3999061576a5SJed Brown   Notes:
4000061576a5SJed Brown   Use DMSetLocalSection() in new code.
4001061576a5SJed Brown 
4002061576a5SJed Brown   Any existing Section will be destroyed
4003061576a5SJed Brown 
4004061576a5SJed Brown .seealso: DMSetLocalSection(), DMGetLocalSection(), DMSetGlobalSection()
4005061576a5SJed Brown @*/
4006061576a5SJed Brown PetscErrorCode DMSetSection(DM dm, PetscSection section)
4007061576a5SJed Brown {
4008061576a5SJed Brown   PetscErrorCode ierr;
4009061576a5SJed Brown 
4010061576a5SJed Brown   PetscFunctionBegin;
4011061576a5SJed Brown   ierr = DMSetLocalSection(dm,section);CHKERRQ(ierr);
4012061576a5SJed Brown   PetscFunctionReturn(0);
4013061576a5SJed Brown }
4014061576a5SJed Brown 
4015061576a5SJed Brown /*@
4016061576a5SJed Brown   DMSetLocalSection - Set the PetscSection encoding the local data layout for the DM.
401788ed4aceSMatthew G Knepley 
401888ed4aceSMatthew G Knepley   Input Parameters:
401988ed4aceSMatthew G Knepley + dm - The DM
402088ed4aceSMatthew G Knepley - section - The PetscSection
402188ed4aceSMatthew G Knepley 
402288ed4aceSMatthew G Knepley   Level: intermediate
402388ed4aceSMatthew G Knepley 
402488ed4aceSMatthew G Knepley   Note: Any existing Section will be destroyed
402588ed4aceSMatthew G Knepley 
4026061576a5SJed Brown .seealso: DMGetLocalSection(), DMSetGlobalSection()
402788ed4aceSMatthew G Knepley @*/
4028061576a5SJed Brown PetscErrorCode DMSetLocalSection(DM dm, PetscSection section)
40290adebc6cSBarry Smith {
4030c473ab19SMatthew G. Knepley   PetscInt       numFields = 0;
4031af122d2aSMatthew G Knepley   PetscInt       f;
403288ed4aceSMatthew G Knepley   PetscErrorCode ierr;
403388ed4aceSMatthew G Knepley 
403488ed4aceSMatthew G Knepley   PetscFunctionBegin;
403588ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4036b9d85ea2SLisandro Dalcin   if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
40371d799100SJed Brown   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
40381bb6d2a8SBarry Smith   ierr = PetscSectionDestroy(&dm->localSection);CHKERRQ(ierr);
40391bb6d2a8SBarry Smith   dm->localSection = section;
40401bb6d2a8SBarry Smith   if (section) {ierr = PetscSectionGetNumFields(dm->localSection, &numFields);CHKERRQ(ierr);}
4041af122d2aSMatthew G Knepley   if (numFields) {
4042af122d2aSMatthew G Knepley     ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr);
4043af122d2aSMatthew G Knepley     for (f = 0; f < numFields; ++f) {
40440f21e855SMatthew G. Knepley       PetscObject disc;
4045af122d2aSMatthew G Knepley       const char *name;
4046af122d2aSMatthew G Knepley 
40471bb6d2a8SBarry Smith       ierr = PetscSectionGetFieldName(dm->localSection, f, &name);CHKERRQ(ierr);
404844a7f3ddSMatthew G. Knepley       ierr = DMGetField(dm, f, NULL, &disc);CHKERRQ(ierr);
40490f21e855SMatthew G. Knepley       ierr = PetscObjectSetName(disc, name);CHKERRQ(ierr);
4050af122d2aSMatthew G Knepley     }
4051af122d2aSMatthew G Knepley   }
4052e87a4003SBarry Smith   /* The global section will be rebuilt in the next call to DMGetGlobalSection(). */
40531bb6d2a8SBarry Smith   ierr = PetscSectionDestroy(&dm->globalSection);CHKERRQ(ierr);
405488ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
405588ed4aceSMatthew G Knepley }
405688ed4aceSMatthew G Knepley 
40579435951eSToby Isaac /*@
4058b7385021SStefano Zampini   DMGetDefaultConstraints - Get the PetscSection and Mat that specify the local constraint interpolation. See DMSetDefaultConstraints() for a description of the purpose of constraint interpolation.
40599435951eSToby Isaac 
4060e228b242SToby Isaac   not collective
4061e228b242SToby Isaac 
40629435951eSToby Isaac   Input Parameter:
40639435951eSToby Isaac . dm - The DM
40649435951eSToby Isaac 
40659435951eSToby Isaac   Output Parameter:
40669435951eSToby Isaac + section - The PetscSection describing the range of the constraint matrix: relates rows of the constraint matrix to dofs of the default section.  Returns NULL if there are no local constraints.
40679435951eSToby Isaac - mat - The Mat that interpolates local constraints: its width should be the layout size of the default section.  Returns NULL if there are no local constraints.
40689435951eSToby Isaac 
40699435951eSToby Isaac   Level: advanced
40709435951eSToby Isaac 
40719435951eSToby Isaac   Note: This gets borrowed references, so the user should not destroy the PetscSection or the Mat.
40729435951eSToby Isaac 
40739435951eSToby Isaac .seealso: DMSetDefaultConstraints()
40749435951eSToby Isaac @*/
40759435951eSToby Isaac PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat)
40769435951eSToby Isaac {
40779435951eSToby Isaac   PetscErrorCode ierr;
40789435951eSToby Isaac 
40799435951eSToby Isaac   PetscFunctionBegin;
40809435951eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
40819435951eSToby Isaac   if (!dm->defaultConstraintSection && !dm->defaultConstraintMat && dm->ops->createdefaultconstraints) {ierr = (*dm->ops->createdefaultconstraints)(dm);CHKERRQ(ierr);}
408245a75d81SToby Isaac   if (section) {*section = dm->defaultConstraintSection;}
408345a75d81SToby Isaac   if (mat) {*mat = dm->defaultConstraintMat;}
40849435951eSToby Isaac   PetscFunctionReturn(0);
40859435951eSToby Isaac }
40869435951eSToby Isaac 
40879435951eSToby Isaac /*@
4088b7385021SStefano Zampini   DMSetDefaultConstraints - Set the PetscSection and Mat that specify the local constraint interpolation.
40899435951eSToby Isaac 
40909435951eSToby Isaac   If a constraint matrix is specified, then it is applied during DMGlobalToLocalEnd() when mode is INSERT_VALUES, INSERT_BC_VALUES, or INSERT_ALL_VALUES.  Without a constraint matrix, the local vector l returned by DMGlobalToLocalEnd() contains values that have been scattered from a global vector without modification; with a constraint matrix A, l is modified by computing c = A * l, l[s[i]] = c[i], where the scatter s is defined by the PetscSection returned by DMGetDefaultConstraintMatrix().
40919435951eSToby Isaac 
40929435951eSToby Isaac   If a constraint matrix is specified, then its adjoint is applied during DMLocalToGlobalBegin() when mode is ADD_VALUES, ADD_BC_VALUES, or ADD_ALL_VALUES.  Without a constraint matrix, the local vector l is accumulated into a global vector without modification; with a constraint matrix A, l is first modified by computing c[i] = l[s[i]], l[s[i]] = 0, l = l + A'*c, which is the adjoint of the operation described above.
40939435951eSToby Isaac 
4094e228b242SToby Isaac   collective on dm
4095e228b242SToby Isaac 
40969435951eSToby Isaac   Input Parameters:
40979435951eSToby Isaac + dm - The DM
4098e228b242SToby Isaac + section - The PetscSection describing the range of the constraint matrix: relates rows of the constraint matrix to dofs of the default section.  Must have a local communicator (PETSC_COMM_SELF or derivative).
4099e228b242SToby Isaac - mat - The Mat that interpolates local constraints: its width should be the layout size of the default section:  NULL indicates no constraints.  Must have a local communicator (PETSC_COMM_SELF or derivative).
41009435951eSToby Isaac 
41019435951eSToby Isaac   Level: advanced
41029435951eSToby Isaac 
41039435951eSToby Isaac   Note: This increments the references of the PetscSection and the Mat, so they user can destroy them
41049435951eSToby Isaac 
41059435951eSToby Isaac .seealso: DMGetDefaultConstraints()
41069435951eSToby Isaac @*/
41079435951eSToby Isaac PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat)
41089435951eSToby Isaac {
4109e228b242SToby Isaac   PetscMPIInt result;
41109435951eSToby Isaac   PetscErrorCode ierr;
41119435951eSToby Isaac 
41129435951eSToby Isaac   PetscFunctionBegin;
41139435951eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4114e228b242SToby Isaac   if (section) {
4115e228b242SToby Isaac     PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
4116e228b242SToby Isaac     ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)section),&result);CHKERRQ(ierr);
4117f60917d2SBarry Smith     if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint section must have local communicator");
4118e228b242SToby Isaac   }
4119e228b242SToby Isaac   if (mat) {
4120e228b242SToby Isaac     PetscValidHeaderSpecific(mat,MAT_CLASSID,3);
4121e228b242SToby Isaac     ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)mat),&result);CHKERRQ(ierr);
4122f60917d2SBarry Smith     if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint matrix must have local communicator");
4123e228b242SToby Isaac   }
41249435951eSToby Isaac   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
41259435951eSToby Isaac   ierr = PetscSectionDestroy(&dm->defaultConstraintSection);CHKERRQ(ierr);
41269435951eSToby Isaac   dm->defaultConstraintSection = section;
41279435951eSToby Isaac   ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
41289435951eSToby Isaac   ierr = MatDestroy(&dm->defaultConstraintMat);CHKERRQ(ierr);
41299435951eSToby Isaac   dm->defaultConstraintMat = mat;
41309435951eSToby Isaac   PetscFunctionReturn(0);
41319435951eSToby Isaac }
41329435951eSToby Isaac 
4133497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG)
4134507e4973SMatthew G. Knepley /*
4135507e4973SMatthew G. Knepley   DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections.
4136507e4973SMatthew G. Knepley 
4137507e4973SMatthew G. Knepley   Input Parameters:
4138507e4973SMatthew G. Knepley + dm - The DM
4139507e4973SMatthew G. Knepley . localSection - PetscSection describing the local data layout
4140507e4973SMatthew G. Knepley - globalSection - PetscSection describing the global data layout
4141507e4973SMatthew G. Knepley 
4142507e4973SMatthew G. Knepley   Level: intermediate
4143507e4973SMatthew G. Knepley 
41441bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMSetSectionSF()
4145507e4973SMatthew G. Knepley */
4146f741bcd2SMatthew G. Knepley static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection)
4147507e4973SMatthew G. Knepley {
4148507e4973SMatthew G. Knepley   MPI_Comm        comm;
4149507e4973SMatthew G. Knepley   PetscLayout     layout;
4150507e4973SMatthew G. Knepley   const PetscInt *ranges;
4151507e4973SMatthew G. Knepley   PetscInt        pStart, pEnd, p, nroots;
4152507e4973SMatthew G. Knepley   PetscMPIInt     size, rank;
4153507e4973SMatthew G. Knepley   PetscBool       valid = PETSC_TRUE, gvalid;
4154507e4973SMatthew G. Knepley   PetscErrorCode  ierr;
4155507e4973SMatthew G. Knepley 
4156507e4973SMatthew G. Knepley   PetscFunctionBegin;
4157507e4973SMatthew G. Knepley   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
4158507e4973SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4159507e4973SMatthew G. Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
4160507e4973SMatthew G. Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
4161507e4973SMatthew G. Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
4162507e4973SMatthew G. Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
4163507e4973SMatthew G. Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
4164507e4973SMatthew G. Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
4165507e4973SMatthew G. Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
4166507e4973SMatthew G. Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
4167507e4973SMatthew G. Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
4168507e4973SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
4169f741bcd2SMatthew G. Knepley     PetscInt       dof, cdof, off, gdof, gcdof, goff, gsize, d;
4170507e4973SMatthew G. Knepley 
4171507e4973SMatthew G. Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
4172507e4973SMatthew G. Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
4173507e4973SMatthew G. Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
4174507e4973SMatthew G. Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
4175507e4973SMatthew G. Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
4176507e4973SMatthew G. Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
4177507e4973SMatthew G. Knepley     if (!gdof) continue; /* Censored point */
4178507e4973SMatthew G. Knepley     if ((gdof < 0 ? -(gdof+1) : gdof) != dof) {ierr = PetscSynchronizedPrintf(comm, "[%d]Global dof %d for point %d not equal to local dof %d\n", rank, gdof, p, dof);CHKERRQ(ierr); valid = PETSC_FALSE;}
4179507e4973SMatthew G. Knepley     if (gcdof && (gcdof != cdof)) {ierr = PetscSynchronizedPrintf(comm, "[%d]Global constraints %d for point %d not equal to local constraints %d\n", rank, gcdof, p, cdof);CHKERRQ(ierr); valid = PETSC_FALSE;}
4180507e4973SMatthew G. Knepley     if (gdof < 0) {
4181507e4973SMatthew G. Knepley       gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
4182507e4973SMatthew G. Knepley       for (d = 0; d < gsize; ++d) {
4183507e4973SMatthew G. Knepley         PetscInt offset = -(goff+1) + d, r;
4184507e4973SMatthew G. Knepley 
4185507e4973SMatthew G. Knepley         ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr);
4186507e4973SMatthew G. Knepley         if (r < 0) r = -(r+2);
4187507e4973SMatthew G. Knepley         if ((r < 0) || (r >= size)) {ierr = PetscSynchronizedPrintf(comm, "[%d]Point %d mapped to invalid process %d (%d, %d)\n", rank, p, r, gdof, goff);CHKERRQ(ierr); valid = PETSC_FALSE;break;}
4188507e4973SMatthew G. Knepley       }
4189507e4973SMatthew G. Knepley     }
4190507e4973SMatthew G. Knepley   }
4191507e4973SMatthew G. Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
4192507e4973SMatthew G. Knepley   ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr);
4193b2566f29SBarry Smith   ierr = MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRQ(ierr);
4194507e4973SMatthew G. Knepley   if (!gvalid) {
4195507e4973SMatthew G. Knepley     ierr = DMView(dm, NULL);CHKERRQ(ierr);
4196507e4973SMatthew G. Knepley     SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections");
4197507e4973SMatthew G. Knepley   }
4198507e4973SMatthew G. Knepley   PetscFunctionReturn(0);
4199507e4973SMatthew G. Knepley }
4200f741bcd2SMatthew G. Knepley #endif
4201507e4973SMatthew G. Knepley 
420288ed4aceSMatthew G Knepley /*@
4203e87a4003SBarry Smith   DMGetGlobalSection - Get the PetscSection encoding the global data layout for the DM.
420488ed4aceSMatthew G Knepley 
4205d083f849SBarry Smith   Collective on dm
42068b1ab98fSJed Brown 
420788ed4aceSMatthew G Knepley   Input Parameter:
420888ed4aceSMatthew G Knepley . dm - The DM
420988ed4aceSMatthew G Knepley 
421088ed4aceSMatthew G Knepley   Output Parameter:
421188ed4aceSMatthew G Knepley . section - The PetscSection
421288ed4aceSMatthew G Knepley 
421388ed4aceSMatthew G Knepley   Level: intermediate
421488ed4aceSMatthew G Knepley 
421588ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
421688ed4aceSMatthew G Knepley 
421792fd8e1eSJed Brown .seealso: DMSetLocalSection(), DMGetLocalSection()
421888ed4aceSMatthew G Knepley @*/
4219e87a4003SBarry Smith PetscErrorCode DMGetGlobalSection(DM dm, PetscSection *section)
42200adebc6cSBarry Smith {
422188ed4aceSMatthew G Knepley   PetscErrorCode ierr;
422288ed4aceSMatthew G Knepley 
422388ed4aceSMatthew G Knepley   PetscFunctionBegin;
422488ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
422588ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
42261bb6d2a8SBarry Smith   if (!dm->globalSection) {
4227fd59a867SMatthew G. Knepley     PetscSection s;
4228fd59a867SMatthew G. Knepley 
422992fd8e1eSJed Brown     ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr);
4230fd59a867SMatthew G. Knepley     if (!s)  SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a default PetscSection in order to create a global PetscSection");
423133907cc2SStefano Zampini     if (!dm->sf) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a point PetscSF in order to create a global PetscSection");
42321bb6d2a8SBarry Smith     ierr = PetscSectionCreateGlobalSection(s, dm->sf, PETSC_FALSE, PETSC_FALSE, &dm->globalSection);CHKERRQ(ierr);
4233cf06b437SMatthew G. Knepley     ierr = PetscLayoutDestroy(&dm->map);CHKERRQ(ierr);
42341bb6d2a8SBarry Smith     ierr = PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->globalSection, &dm->map);CHKERRQ(ierr);
42351bb6d2a8SBarry Smith     ierr = PetscSectionViewFromOptions(dm->globalSection, NULL, "-global_section_view");CHKERRQ(ierr);
423688ed4aceSMatthew G Knepley   }
42371bb6d2a8SBarry Smith   *section = dm->globalSection;
423888ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
423988ed4aceSMatthew G Knepley }
424088ed4aceSMatthew G Knepley 
4241b21d0597SMatthew G Knepley /*@
4242e87a4003SBarry Smith   DMSetGlobalSection - Set the PetscSection encoding the global data layout for the DM.
4243b21d0597SMatthew G Knepley 
4244b21d0597SMatthew G Knepley   Input Parameters:
4245b21d0597SMatthew G Knepley + dm - The DM
42465080bbdbSMatthew G Knepley - section - The PetscSection, or NULL
4247b21d0597SMatthew G Knepley 
4248b21d0597SMatthew G Knepley   Level: intermediate
4249b21d0597SMatthew G Knepley 
4250b21d0597SMatthew G Knepley   Note: Any existing Section will be destroyed
4251b21d0597SMatthew G Knepley 
425292fd8e1eSJed Brown .seealso: DMGetGlobalSection(), DMSetLocalSection()
4253b21d0597SMatthew G Knepley @*/
4254e87a4003SBarry Smith PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section)
42550adebc6cSBarry Smith {
4256b21d0597SMatthew G Knepley   PetscErrorCode ierr;
4257b21d0597SMatthew G Knepley 
4258b21d0597SMatthew G Knepley   PetscFunctionBegin;
4259b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
42605080bbdbSMatthew G Knepley   if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
42611d799100SJed Brown   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
42621bb6d2a8SBarry Smith   ierr = PetscSectionDestroy(&dm->globalSection);CHKERRQ(ierr);
42631bb6d2a8SBarry Smith   dm->globalSection = section;
4264497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG)
42651bb6d2a8SBarry Smith   if (section) {ierr = DMDefaultSectionCheckConsistency_Internal(dm, dm->localSection, section);CHKERRQ(ierr);}
4266507e4973SMatthew G. Knepley #endif
4267b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
4268b21d0597SMatthew G Knepley }
4269b21d0597SMatthew G Knepley 
427088ed4aceSMatthew G Knepley /*@
42711bb6d2a8SBarry Smith   DMGetSectionSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set,
427288ed4aceSMatthew G Knepley   it is created from the default PetscSection layouts in the DM.
427388ed4aceSMatthew G Knepley 
427488ed4aceSMatthew G Knepley   Input Parameter:
427588ed4aceSMatthew G Knepley . dm - The DM
427688ed4aceSMatthew G Knepley 
427788ed4aceSMatthew G Knepley   Output Parameter:
427888ed4aceSMatthew G Knepley . sf - The PetscSF
427988ed4aceSMatthew G Knepley 
428088ed4aceSMatthew G Knepley   Level: intermediate
428188ed4aceSMatthew G Knepley 
428288ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
428388ed4aceSMatthew G Knepley 
42841bb6d2a8SBarry Smith .seealso: DMSetSectionSF(), DMCreateSectionSF()
428588ed4aceSMatthew G Knepley @*/
42861bb6d2a8SBarry Smith PetscErrorCode DMGetSectionSF(DM dm, PetscSF *sf)
42870adebc6cSBarry Smith {
428888ed4aceSMatthew G Knepley   PetscInt       nroots;
428988ed4aceSMatthew G Knepley   PetscErrorCode ierr;
429088ed4aceSMatthew G Knepley 
429188ed4aceSMatthew G Knepley   PetscFunctionBegin;
429288ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
429388ed4aceSMatthew G Knepley   PetscValidPointer(sf, 2);
42941bb6d2a8SBarry Smith   if (!dm->sectionSF) {
42951bb6d2a8SBarry Smith     ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm),&dm->sectionSF);CHKERRQ(ierr);
429633907cc2SStefano Zampini   }
42971bb6d2a8SBarry Smith   ierr = PetscSFGetGraph(dm->sectionSF, &nroots, NULL, NULL, NULL);CHKERRQ(ierr);
429888ed4aceSMatthew G Knepley   if (nroots < 0) {
429988ed4aceSMatthew G Knepley     PetscSection section, gSection;
430088ed4aceSMatthew G Knepley 
430192fd8e1eSJed Brown     ierr = DMGetLocalSection(dm, &section);CHKERRQ(ierr);
430231ea6d37SMatthew G Knepley     if (section) {
4303e87a4003SBarry Smith       ierr = DMGetGlobalSection(dm, &gSection);CHKERRQ(ierr);
43041bb6d2a8SBarry Smith       ierr = DMCreateSectionSF(dm, section, gSection);CHKERRQ(ierr);
430531ea6d37SMatthew G Knepley     } else {
43060298fd71SBarry Smith       *sf = NULL;
430731ea6d37SMatthew G Knepley       PetscFunctionReturn(0);
430831ea6d37SMatthew G Knepley     }
430988ed4aceSMatthew G Knepley   }
43101bb6d2a8SBarry Smith   *sf = dm->sectionSF;
431188ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
431288ed4aceSMatthew G Knepley }
431388ed4aceSMatthew G Knepley 
431488ed4aceSMatthew G Knepley /*@
43151bb6d2a8SBarry Smith   DMSetSectionSF - Set the PetscSF encoding the parallel dof overlap for the DM
431688ed4aceSMatthew G Knepley 
431788ed4aceSMatthew G Knepley   Input Parameters:
431888ed4aceSMatthew G Knepley + dm - The DM
431988ed4aceSMatthew G Knepley - sf - The PetscSF
432088ed4aceSMatthew G Knepley 
432188ed4aceSMatthew G Knepley   Level: intermediate
432288ed4aceSMatthew G Knepley 
432388ed4aceSMatthew G Knepley   Note: Any previous SF is destroyed
432488ed4aceSMatthew G Knepley 
43251bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMCreateSectionSF()
432688ed4aceSMatthew G Knepley @*/
43271bb6d2a8SBarry Smith PetscErrorCode DMSetSectionSF(DM dm, PetscSF sf)
43280adebc6cSBarry Smith {
432988ed4aceSMatthew G Knepley   PetscErrorCode ierr;
433088ed4aceSMatthew G Knepley 
433188ed4aceSMatthew G Knepley   PetscFunctionBegin;
433288ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4333b9d85ea2SLisandro Dalcin   if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
433433907cc2SStefano Zampini   ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr);
43351bb6d2a8SBarry Smith   ierr = PetscSFDestroy(&dm->sectionSF);CHKERRQ(ierr);
43361bb6d2a8SBarry Smith   dm->sectionSF = sf;
433788ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
433888ed4aceSMatthew G Knepley }
433988ed4aceSMatthew G Knepley 
434088ed4aceSMatthew G Knepley /*@C
43411bb6d2a8SBarry Smith   DMCreateSectionSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections
434288ed4aceSMatthew G Knepley   describing the data layout.
434388ed4aceSMatthew G Knepley 
434488ed4aceSMatthew G Knepley   Input Parameters:
434588ed4aceSMatthew G Knepley + dm - The DM
434688ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout
434788ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout
434888ed4aceSMatthew G Knepley 
43491bb6d2a8SBarry Smith   Notes: One usually uses DMGetSectionSF() to obtain the PetscSF
435088ed4aceSMatthew G Knepley 
43511bb6d2a8SBarry Smith   Level: developer
43521bb6d2a8SBarry Smith 
43531bb6d2a8SBarry Smith   Developer Note: Since this routine has for arguments the two sections from the DM and puts the resulting PetscSF
43541bb6d2a8SBarry Smith                   directly into the DM, perhaps this function should not take the local and global sections as
43551bb6d2a8SBarry Smith                   input and should just obtain them from the DM?
43561bb6d2a8SBarry Smith 
43571bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMSetSectionSF(), DMGetLocalSection(), DMGetGlobalSection()
435888ed4aceSMatthew G Knepley @*/
43591bb6d2a8SBarry Smith PetscErrorCode DMCreateSectionSF(DM dm, PetscSection localSection, PetscSection globalSection)
436088ed4aceSMatthew G Knepley {
436182f516ccSBarry Smith   MPI_Comm       comm;
436288ed4aceSMatthew G Knepley   PetscLayout    layout;
436388ed4aceSMatthew G Knepley   const PetscInt *ranges;
436488ed4aceSMatthew G Knepley   PetscInt       *local;
436588ed4aceSMatthew G Knepley   PetscSFNode    *remote;
4366ecd73843SMatthew G. Knepley   PetscInt       pStart, pEnd, p, nroots, nleaves = 0, l;
436788ed4aceSMatthew G Knepley   PetscMPIInt    size, rank;
436888ed4aceSMatthew G Knepley   PetscErrorCode ierr;
436988ed4aceSMatthew G Knepley 
437088ed4aceSMatthew G Knepley   PetscFunctionBegin;
437188ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4372367003a6SStefano Zampini   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
437388ed4aceSMatthew G Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
437488ed4aceSMatthew G Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
437588ed4aceSMatthew G Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
437688ed4aceSMatthew G Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
437788ed4aceSMatthew G Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
437888ed4aceSMatthew G Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
437988ed4aceSMatthew G Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
438088ed4aceSMatthew G Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
438188ed4aceSMatthew G Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
4382ecd73843SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
43836636e97aSMatthew G Knepley     PetscInt gdof, gcdof;
438488ed4aceSMatthew G Knepley 
43856636e97aSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
43866636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
4387235fbf56SMatthew G. Knepley     if (gcdof > (gdof < 0 ? -(gdof+1) : gdof)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point %d has %d constraints > %d dof", p, gcdof, (gdof < 0 ? -(gdof+1) : gdof));
43886636e97aSMatthew G Knepley     nleaves += gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
438988ed4aceSMatthew G Knepley   }
4390785e854fSJed Brown   ierr = PetscMalloc1(nleaves, &local);CHKERRQ(ierr);
4391785e854fSJed Brown   ierr = PetscMalloc1(nleaves, &remote);CHKERRQ(ierr);
439288ed4aceSMatthew G Knepley   for (p = pStart, l = 0; p < pEnd; ++p) {
43931f588964SMatthew G Knepley     const PetscInt *cind;
43946636e97aSMatthew G Knepley     PetscInt       dof, cdof, off, gdof, gcdof, goff, gsize, d, c;
439588ed4aceSMatthew G Knepley 
439688ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
439788ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
439888ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
439988ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr);
440088ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
44016636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
440288ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
44036636e97aSMatthew G Knepley     if (!gdof) continue; /* Censored point */
44046636e97aSMatthew G Knepley     gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
44056636e97aSMatthew G Knepley     if (gsize != dof-cdof) {
4406057b4bcdSMatthew 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);
44076636e97aSMatthew G Knepley       cdof = 0; /* Ignore constraints */
44086636e97aSMatthew G Knepley     }
440988ed4aceSMatthew G Knepley     for (d = 0, c = 0; d < dof; ++d) {
441088ed4aceSMatthew G Knepley       if ((c < cdof) && (cind[c] == d)) {++c; continue;}
441188ed4aceSMatthew G Knepley       local[l+d-c] = off+d;
441288ed4aceSMatthew G Knepley     }
441388ed4aceSMatthew G Knepley     if (gdof < 0) {
44146636e97aSMatthew G Knepley       for (d = 0; d < gsize; ++d, ++l) {
441588ed4aceSMatthew G Knepley         PetscInt offset = -(goff+1) + d, r;
441688ed4aceSMatthew G Knepley 
441705376888SMatthew G. Knepley         ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr);
441831d3f06eSJed Brown         if (r < 0) r = -(r+2);
441905376888SMatthew G. Knepley         if ((r < 0) || (r >= size)) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point %d mapped to invalid process %d (%d, %d)", p, r, gdof, goff);
442088ed4aceSMatthew G Knepley         remote[l].rank  = r;
442188ed4aceSMatthew G Knepley         remote[l].index = offset - ranges[r];
442288ed4aceSMatthew G Knepley       }
442388ed4aceSMatthew G Knepley     } else {
44246636e97aSMatthew G Knepley       for (d = 0; d < gsize; ++d, ++l) {
442588ed4aceSMatthew G Knepley         remote[l].rank  = rank;
442688ed4aceSMatthew G Knepley         remote[l].index = goff+d - ranges[rank];
442788ed4aceSMatthew G Knepley       }
442888ed4aceSMatthew G Knepley     }
442988ed4aceSMatthew G Knepley   }
44306636e97aSMatthew G Knepley   if (l != nleaves) SETERRQ2(comm, PETSC_ERR_PLIB, "Iteration error, l %d != nleaves %d", l, nleaves);
443188ed4aceSMatthew G Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
44321bb6d2a8SBarry Smith   ierr = PetscSFSetGraph(dm->sectionSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr);
443388ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
443488ed4aceSMatthew G Knepley }
4435af122d2aSMatthew G Knepley 
4436b21d0597SMatthew G Knepley /*@
4437b21d0597SMatthew G Knepley   DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM.
4438b21d0597SMatthew G Knepley 
4439b21d0597SMatthew G Knepley   Input Parameter:
4440b21d0597SMatthew G Knepley . dm - The DM
4441b21d0597SMatthew G Knepley 
4442b21d0597SMatthew G Knepley   Output Parameter:
4443b21d0597SMatthew G Knepley . sf - The PetscSF
4444b21d0597SMatthew G Knepley 
4445b21d0597SMatthew G Knepley   Level: intermediate
4446b21d0597SMatthew G Knepley 
4447b21d0597SMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
4448b21d0597SMatthew G Knepley 
44491bb6d2a8SBarry Smith .seealso: DMSetPointSF(), DMGetSectionSF(), DMSetSectionSF(), DMCreateSectionSF()
4450b21d0597SMatthew G Knepley @*/
44510adebc6cSBarry Smith PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf)
44520adebc6cSBarry Smith {
4453b21d0597SMatthew G Knepley   PetscFunctionBegin;
4454b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4455b21d0597SMatthew G Knepley   PetscValidPointer(sf, 2);
4456b21d0597SMatthew G Knepley   *sf = dm->sf;
4457b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
4458b21d0597SMatthew G Knepley }
4459b21d0597SMatthew G Knepley 
4460057b4bcdSMatthew G Knepley /*@
4461057b4bcdSMatthew G Knepley   DMSetPointSF - Set the PetscSF encoding the parallel section point overlap for the DM.
4462057b4bcdSMatthew G Knepley 
4463057b4bcdSMatthew G Knepley   Input Parameters:
4464057b4bcdSMatthew G Knepley + dm - The DM
4465057b4bcdSMatthew G Knepley - sf - The PetscSF
4466057b4bcdSMatthew G Knepley 
4467057b4bcdSMatthew G Knepley   Level: intermediate
4468057b4bcdSMatthew G Knepley 
44691bb6d2a8SBarry Smith .seealso: DMGetPointSF(), DMGetSectionSF(), DMSetSectionSF(), DMCreateSectionSF()
4470057b4bcdSMatthew G Knepley @*/
44710adebc6cSBarry Smith PetscErrorCode DMSetPointSF(DM dm, PetscSF sf)
44720adebc6cSBarry Smith {
4473057b4bcdSMatthew G Knepley   PetscErrorCode ierr;
4474057b4bcdSMatthew G Knepley 
4475057b4bcdSMatthew G Knepley   PetscFunctionBegin;
4476057b4bcdSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4477b9d85ea2SLisandro Dalcin   if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
4478057b4bcdSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr);
447933907cc2SStefano Zampini   ierr = PetscSFDestroy(&dm->sf);CHKERRQ(ierr);
4480057b4bcdSMatthew G Knepley   dm->sf = sf;
4481057b4bcdSMatthew G Knepley   PetscFunctionReturn(0);
4482057b4bcdSMatthew G Knepley }
4483057b4bcdSMatthew G Knepley 
448434aa8a36SMatthew G. Knepley static PetscErrorCode DMSetDefaultAdjacency_Private(DM dm, PetscInt f, PetscObject disc)
448534aa8a36SMatthew G. Knepley {
448634aa8a36SMatthew G. Knepley   PetscClassId   id;
448734aa8a36SMatthew G. Knepley   PetscErrorCode ierr;
448834aa8a36SMatthew G. Knepley 
448934aa8a36SMatthew G. Knepley   PetscFunctionBegin;
449034aa8a36SMatthew G. Knepley   ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr);
449134aa8a36SMatthew G. Knepley   if (id == PETSCFE_CLASSID) {
449234aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr);
449334aa8a36SMatthew G. Knepley   } else if (id == PETSCFV_CLASSID) {
449434aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(dm, f, PETSC_TRUE, PETSC_FALSE);CHKERRQ(ierr);
449517c1d62eSMatthew G. Knepley   } else {
449617c1d62eSMatthew G. Knepley     ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr);
449734aa8a36SMatthew G. Knepley   }
449834aa8a36SMatthew G. Knepley   PetscFunctionReturn(0);
449934aa8a36SMatthew G. Knepley }
450034aa8a36SMatthew G. Knepley 
450144a7f3ddSMatthew G. Knepley static PetscErrorCode DMFieldEnlarge_Static(DM dm, PetscInt NfNew)
450244a7f3ddSMatthew G. Knepley {
450344a7f3ddSMatthew G. Knepley   RegionField   *tmpr;
450444a7f3ddSMatthew G. Knepley   PetscInt       Nf = dm->Nf, f;
450544a7f3ddSMatthew G. Knepley   PetscErrorCode ierr;
450644a7f3ddSMatthew G. Knepley 
450744a7f3ddSMatthew G. Knepley   PetscFunctionBegin;
450844a7f3ddSMatthew G. Knepley   if (Nf >= NfNew) PetscFunctionReturn(0);
450944a7f3ddSMatthew G. Knepley   ierr = PetscMalloc1(NfNew, &tmpr);CHKERRQ(ierr);
451044a7f3ddSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpr[f] = dm->fields[f];
451144a7f3ddSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) {tmpr[f].disc = NULL; tmpr[f].label = NULL;}
451244a7f3ddSMatthew G. Knepley   ierr = PetscFree(dm->fields);CHKERRQ(ierr);
451344a7f3ddSMatthew G. Knepley   dm->Nf     = NfNew;
451444a7f3ddSMatthew G. Knepley   dm->fields = tmpr;
451544a7f3ddSMatthew G. Knepley   PetscFunctionReturn(0);
451644a7f3ddSMatthew G. Knepley }
451744a7f3ddSMatthew G. Knepley 
451844a7f3ddSMatthew G. Knepley /*@
451944a7f3ddSMatthew G. Knepley   DMClearFields - Remove all fields from the DM
452044a7f3ddSMatthew G. Knepley 
4521d083f849SBarry Smith   Logically collective on dm
452244a7f3ddSMatthew G. Knepley 
452344a7f3ddSMatthew G. Knepley   Input Parameter:
452444a7f3ddSMatthew G. Knepley . dm - The DM
452544a7f3ddSMatthew G. Knepley 
452644a7f3ddSMatthew G. Knepley   Level: intermediate
452744a7f3ddSMatthew G. Knepley 
452844a7f3ddSMatthew G. Knepley .seealso: DMGetNumFields(), DMSetNumFields(), DMSetField()
452944a7f3ddSMatthew G. Knepley @*/
453044a7f3ddSMatthew G. Knepley PetscErrorCode DMClearFields(DM dm)
453144a7f3ddSMatthew G. Knepley {
453244a7f3ddSMatthew G. Knepley   PetscInt       f;
453344a7f3ddSMatthew G. Knepley   PetscErrorCode ierr;
453444a7f3ddSMatthew G. Knepley 
453544a7f3ddSMatthew G. Knepley   PetscFunctionBegin;
453644a7f3ddSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
453744a7f3ddSMatthew G. Knepley   for (f = 0; f < dm->Nf; ++f) {
453844a7f3ddSMatthew G. Knepley     ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr);
453944a7f3ddSMatthew G. Knepley     ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr);
454044a7f3ddSMatthew G. Knepley   }
454144a7f3ddSMatthew G. Knepley   ierr = PetscFree(dm->fields);CHKERRQ(ierr);
454244a7f3ddSMatthew G. Knepley   dm->fields = NULL;
454344a7f3ddSMatthew G. Knepley   dm->Nf     = 0;
454444a7f3ddSMatthew G. Knepley   PetscFunctionReturn(0);
454544a7f3ddSMatthew G. Knepley }
454644a7f3ddSMatthew G. Knepley 
4547689b5837SMatthew G. Knepley /*@
4548689b5837SMatthew G. Knepley   DMGetNumFields - Get the number of fields in the DM
4549689b5837SMatthew G. Knepley 
4550689b5837SMatthew G. Knepley   Not collective
4551689b5837SMatthew G. Knepley 
4552689b5837SMatthew G. Knepley   Input Parameter:
4553689b5837SMatthew G. Knepley . dm - The DM
4554689b5837SMatthew G. Knepley 
4555689b5837SMatthew G. Knepley   Output Parameter:
4556689b5837SMatthew G. Knepley . Nf - The number of fields
4557689b5837SMatthew G. Knepley 
4558689b5837SMatthew G. Knepley   Level: intermediate
4559689b5837SMatthew G. Knepley 
4560689b5837SMatthew G. Knepley .seealso: DMSetNumFields(), DMSetField()
4561689b5837SMatthew G. Knepley @*/
45620f21e855SMatthew G. Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields)
45630f21e855SMatthew G. Knepley {
45640f21e855SMatthew G. Knepley   PetscFunctionBegin;
45650f21e855SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4566534a8f05SLisandro Dalcin   PetscValidIntPointer(numFields, 2);
456744a7f3ddSMatthew G. Knepley   *numFields = dm->Nf;
4568af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
4569af122d2aSMatthew G Knepley }
4570af122d2aSMatthew G Knepley 
4571689b5837SMatthew G. Knepley /*@
4572689b5837SMatthew G. Knepley   DMSetNumFields - Set the number of fields in the DM
4573689b5837SMatthew G. Knepley 
4574d083f849SBarry Smith   Logically collective on dm
4575689b5837SMatthew G. Knepley 
4576689b5837SMatthew G. Knepley   Input Parameters:
4577689b5837SMatthew G. Knepley + dm - The DM
4578689b5837SMatthew G. Knepley - Nf - The number of fields
4579689b5837SMatthew G. Knepley 
4580689b5837SMatthew G. Knepley   Level: intermediate
4581689b5837SMatthew G. Knepley 
4582689b5837SMatthew G. Knepley .seealso: DMGetNumFields(), DMSetField()
4583689b5837SMatthew G. Knepley @*/
4584af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields)
4585af122d2aSMatthew G Knepley {
45860f21e855SMatthew G. Knepley   PetscInt       Nf, f;
4587af122d2aSMatthew G Knepley   PetscErrorCode ierr;
4588af122d2aSMatthew G Knepley 
4589af122d2aSMatthew G Knepley   PetscFunctionBegin;
4590af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
459144a7f3ddSMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
45920f21e855SMatthew G. Knepley   for (f = Nf; f < numFields; ++f) {
45930f21e855SMatthew G. Knepley     PetscContainer obj;
45940f21e855SMatthew G. Knepley 
45950f21e855SMatthew G. Knepley     ierr = PetscContainerCreate(PetscObjectComm((PetscObject) dm), &obj);CHKERRQ(ierr);
459644a7f3ddSMatthew G. Knepley     ierr = DMAddField(dm, NULL, (PetscObject) obj);CHKERRQ(ierr);
45970f21e855SMatthew G. Knepley     ierr = PetscContainerDestroy(&obj);CHKERRQ(ierr);
4598af122d2aSMatthew G Knepley   }
4599af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
4600af122d2aSMatthew G Knepley }
4601af122d2aSMatthew G Knepley 
4602c1929be8SMatthew G. Knepley /*@
4603c1929be8SMatthew G. Knepley   DMGetField - Return the discretization object for a given DM field
4604c1929be8SMatthew G. Knepley 
4605c1929be8SMatthew G. Knepley   Not collective
4606c1929be8SMatthew G. Knepley 
4607c1929be8SMatthew G. Knepley   Input Parameters:
4608c1929be8SMatthew G. Knepley + dm - The DM
4609c1929be8SMatthew G. Knepley - f  - The field number
4610c1929be8SMatthew G. Knepley 
461144a7f3ddSMatthew G. Knepley   Output Parameters:
461244a7f3ddSMatthew G. Knepley + label - The label indicating the support of the field, or NULL for the entire mesh
461344a7f3ddSMatthew G. Knepley - field - The discretization object
4614c1929be8SMatthew G. Knepley 
461544a7f3ddSMatthew G. Knepley   Level: intermediate
4616c1929be8SMatthew G. Knepley 
461744a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMSetField()
4618c1929be8SMatthew G. Knepley @*/
461944a7f3ddSMatthew G. Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, DMLabel *label, PetscObject *field)
4620af122d2aSMatthew G Knepley {
4621af122d2aSMatthew G Knepley   PetscFunctionBegin;
4622af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
462344a7f3ddSMatthew G. Knepley   PetscValidPointer(field, 3);
462444a7f3ddSMatthew G. Knepley   if ((f < 0) || (f >= dm->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, dm->Nf);
462544a7f3ddSMatthew G. Knepley   if (label) *label = dm->fields[f].label;
462644a7f3ddSMatthew G. Knepley   if (field) *field = dm->fields[f].disc;
4627decb47aaSMatthew G. Knepley   PetscFunctionReturn(0);
4628decb47aaSMatthew G. Knepley }
4629decb47aaSMatthew G. Knepley 
4630c1929be8SMatthew G. Knepley /*@
4631c1929be8SMatthew G. Knepley   DMSetField - Set the discretization object for a given DM field
4632c1929be8SMatthew G. Knepley 
4633d083f849SBarry Smith   Logically collective on dm
4634c1929be8SMatthew G. Knepley 
4635c1929be8SMatthew G. Knepley   Input Parameters:
4636c1929be8SMatthew G. Knepley + dm    - The DM
4637c1929be8SMatthew G. Knepley . f     - The field number
463844a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh
4639c1929be8SMatthew G. Knepley - field - The discretization object
4640c1929be8SMatthew G. Knepley 
464144a7f3ddSMatthew G. Knepley   Level: intermediate
4642c1929be8SMatthew G. Knepley 
464344a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMGetField()
4644c1929be8SMatthew G. Knepley @*/
464544a7f3ddSMatthew G. Knepley PetscErrorCode DMSetField(DM dm, PetscInt f, DMLabel label, PetscObject field)
4646decb47aaSMatthew G. Knepley {
4647decb47aaSMatthew G. Knepley   PetscErrorCode ierr;
4648decb47aaSMatthew G. Knepley 
4649decb47aaSMatthew G. Knepley   PetscFunctionBegin;
4650decb47aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4651e5e52638SMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3);
465244a7f3ddSMatthew G. Knepley   PetscValidHeader(field, 4);
4653e5e52638SMatthew G. Knepley   if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
465444a7f3ddSMatthew G. Knepley   ierr = DMFieldEnlarge_Static(dm, f+1);CHKERRQ(ierr);
465544a7f3ddSMatthew G. Knepley   ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr);
465644a7f3ddSMatthew G. Knepley   ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr);
465744a7f3ddSMatthew G. Knepley   dm->fields[f].label = label;
465844a7f3ddSMatthew G. Knepley   dm->fields[f].disc  = field;
465944a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
466044a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr);
466134aa8a36SMatthew G. Knepley   ierr = DMSetDefaultAdjacency_Private(dm, f, field);CHKERRQ(ierr);
46622df9ee95SMatthew G. Knepley   ierr = DMClearDS(dm);CHKERRQ(ierr);
466344a7f3ddSMatthew G. Knepley   PetscFunctionReturn(0);
466444a7f3ddSMatthew G. Knepley }
466544a7f3ddSMatthew G. Knepley 
466644a7f3ddSMatthew G. Knepley /*@
466744a7f3ddSMatthew G. Knepley   DMAddField - Add the discretization object for the given DM field
466844a7f3ddSMatthew G. Knepley 
4669d083f849SBarry Smith   Logically collective on dm
467044a7f3ddSMatthew G. Knepley 
467144a7f3ddSMatthew G. Knepley   Input Parameters:
467244a7f3ddSMatthew G. Knepley + dm    - The DM
467344a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh
467444a7f3ddSMatthew G. Knepley - field - The discretization object
467544a7f3ddSMatthew G. Knepley 
467644a7f3ddSMatthew G. Knepley   Level: intermediate
467744a7f3ddSMatthew G. Knepley 
467844a7f3ddSMatthew G. Knepley .seealso: DMSetField(), DMGetField()
467944a7f3ddSMatthew G. Knepley @*/
468044a7f3ddSMatthew G. Knepley PetscErrorCode DMAddField(DM dm, DMLabel label, PetscObject field)
468144a7f3ddSMatthew G. Knepley {
468244a7f3ddSMatthew G. Knepley   PetscInt       Nf = dm->Nf;
468344a7f3ddSMatthew G. Knepley   PetscErrorCode ierr;
468444a7f3ddSMatthew G. Knepley 
468544a7f3ddSMatthew G. Knepley   PetscFunctionBegin;
468644a7f3ddSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
468744a7f3ddSMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3);
468844a7f3ddSMatthew G. Knepley   PetscValidHeader(field, 3);
468944a7f3ddSMatthew G. Knepley   ierr = DMFieldEnlarge_Static(dm, Nf+1);CHKERRQ(ierr);
469044a7f3ddSMatthew G. Knepley   dm->fields[Nf].label = label;
469144a7f3ddSMatthew G. Knepley   dm->fields[Nf].disc  = field;
469244a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
469344a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr);
469434aa8a36SMatthew G. Knepley   ierr = DMSetDefaultAdjacency_Private(dm, Nf, field);CHKERRQ(ierr);
46952df9ee95SMatthew G. Knepley   ierr = DMClearDS(dm);CHKERRQ(ierr);
4696af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
4697af122d2aSMatthew G Knepley }
46986636e97aSMatthew G Knepley 
4699e5e52638SMatthew G. Knepley /*@
4700e5e52638SMatthew G. Knepley   DMCopyFields - Copy the discretizations for the DM into another DM
4701e5e52638SMatthew G. Knepley 
4702d083f849SBarry Smith   Collective on dm
4703e5e52638SMatthew G. Knepley 
4704e5e52638SMatthew G. Knepley   Input Parameter:
4705e5e52638SMatthew G. Knepley . dm - The DM
4706e5e52638SMatthew G. Knepley 
4707e5e52638SMatthew G. Knepley   Output Parameter:
4708e5e52638SMatthew G. Knepley . newdm - The DM
4709e5e52638SMatthew G. Knepley 
4710e5e52638SMatthew G. Knepley   Level: advanced
4711e5e52638SMatthew G. Knepley 
4712e5e52638SMatthew G. Knepley .seealso: DMGetField(), DMSetField(), DMAddField(), DMCopyDS(), DMGetDS(), DMGetCellDS()
4713e5e52638SMatthew G. Knepley @*/
4714e5e52638SMatthew G. Knepley PetscErrorCode DMCopyFields(DM dm, DM newdm)
4715e5e52638SMatthew G. Knepley {
4716e5e52638SMatthew G. Knepley   PetscInt       Nf, f;
4717e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4718e5e52638SMatthew G. Knepley 
4719e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4720e5e52638SMatthew G. Knepley   if (dm == newdm) PetscFunctionReturn(0);
4721e5e52638SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4722e5e52638SMatthew G. Knepley   ierr = DMClearFields(newdm);CHKERRQ(ierr);
4723e5e52638SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
4724e5e52638SMatthew G. Knepley     DMLabel     label;
4725e5e52638SMatthew G. Knepley     PetscObject field;
472634aa8a36SMatthew G. Knepley     PetscBool   useCone, useClosure;
4727e5e52638SMatthew G. Knepley 
4728e5e52638SMatthew G. Knepley     ierr = DMGetField(dm, f, &label, &field);CHKERRQ(ierr);
4729e5e52638SMatthew G. Knepley     ierr = DMSetField(newdm, f, label, field);CHKERRQ(ierr);
473034aa8a36SMatthew G. Knepley     ierr = DMGetAdjacency(dm, f, &useCone, &useClosure);CHKERRQ(ierr);
473134aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(newdm, f, useCone, useClosure);CHKERRQ(ierr);
473234aa8a36SMatthew G. Knepley   }
473334aa8a36SMatthew G. Knepley   PetscFunctionReturn(0);
473434aa8a36SMatthew G. Knepley }
473534aa8a36SMatthew G. Knepley 
473634aa8a36SMatthew G. Knepley /*@
473734aa8a36SMatthew G. Knepley   DMGetAdjacency - Returns the flags for determining variable influence
473834aa8a36SMatthew G. Knepley 
473934aa8a36SMatthew G. Knepley   Not collective
474034aa8a36SMatthew G. Knepley 
474134aa8a36SMatthew G. Knepley   Input Parameters:
474234aa8a36SMatthew G. Knepley + dm - The DM object
474334aa8a36SMatthew G. Knepley - f  - The field number, or PETSC_DEFAULT for the default adjacency
474434aa8a36SMatthew G. Knepley 
474534aa8a36SMatthew G. Knepley   Output Parameter:
474634aa8a36SMatthew G. Knepley + useCone    - Flag for variable influence starting with the cone operation
474734aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
474834aa8a36SMatthew G. Knepley 
474934aa8a36SMatthew G. Knepley   Notes:
475034aa8a36SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
475134aa8a36SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
475234aa8a36SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4753979e053dSMatthew G. Knepley   Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another.
475434aa8a36SMatthew G. Knepley 
475534aa8a36SMatthew G. Knepley   Level: developer
475634aa8a36SMatthew G. Knepley 
475734aa8a36SMatthew G. Knepley .seealso: DMSetAdjacency(), DMGetField(), DMSetField()
475834aa8a36SMatthew G. Knepley @*/
475934aa8a36SMatthew G. Knepley PetscErrorCode DMGetAdjacency(DM dm, PetscInt f, PetscBool *useCone, PetscBool *useClosure)
476034aa8a36SMatthew G. Knepley {
476134aa8a36SMatthew G. Knepley   PetscFunctionBegin;
476234aa8a36SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4763534a8f05SLisandro Dalcin   if (useCone)    PetscValidBoolPointer(useCone, 3);
4764534a8f05SLisandro Dalcin   if (useClosure) PetscValidBoolPointer(useClosure, 4);
476534aa8a36SMatthew G. Knepley   if (f < 0) {
476634aa8a36SMatthew G. Knepley     if (useCone)    *useCone    = dm->adjacency[0];
476734aa8a36SMatthew G. Knepley     if (useClosure) *useClosure = dm->adjacency[1];
476834aa8a36SMatthew G. Knepley   } else {
476934aa8a36SMatthew G. Knepley     PetscInt       Nf;
477034aa8a36SMatthew G. Knepley     PetscErrorCode ierr;
477134aa8a36SMatthew G. Knepley 
477234aa8a36SMatthew G. Knepley     ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
477334aa8a36SMatthew G. Knepley     if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf);
477434aa8a36SMatthew G. Knepley     if (useCone)    *useCone    = dm->fields[f].adjacency[0];
477534aa8a36SMatthew G. Knepley     if (useClosure) *useClosure = dm->fields[f].adjacency[1];
477634aa8a36SMatthew G. Knepley   }
477734aa8a36SMatthew G. Knepley   PetscFunctionReturn(0);
477834aa8a36SMatthew G. Knepley }
477934aa8a36SMatthew G. Knepley 
478034aa8a36SMatthew G. Knepley /*@
478134aa8a36SMatthew G. Knepley   DMSetAdjacency - Set the flags for determining variable influence
478234aa8a36SMatthew G. Knepley 
478334aa8a36SMatthew G. Knepley   Not collective
478434aa8a36SMatthew G. Knepley 
478534aa8a36SMatthew G. Knepley   Input Parameters:
478634aa8a36SMatthew G. Knepley + dm         - The DM object
478734aa8a36SMatthew G. Knepley . f          - The field number
478834aa8a36SMatthew G. Knepley . useCone    - Flag for variable influence starting with the cone operation
478934aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
479034aa8a36SMatthew G. Knepley 
479134aa8a36SMatthew G. Knepley   Notes:
479234aa8a36SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
479334aa8a36SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
479434aa8a36SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4795979e053dSMatthew G. Knepley   Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another.
479634aa8a36SMatthew G. Knepley 
479734aa8a36SMatthew G. Knepley   Level: developer
479834aa8a36SMatthew G. Knepley 
479934aa8a36SMatthew G. Knepley .seealso: DMGetAdjacency(), DMGetField(), DMSetField()
480034aa8a36SMatthew G. Knepley @*/
480134aa8a36SMatthew G. Knepley PetscErrorCode DMSetAdjacency(DM dm, PetscInt f, PetscBool useCone, PetscBool useClosure)
480234aa8a36SMatthew G. Knepley {
480334aa8a36SMatthew G. Knepley   PetscFunctionBegin;
480434aa8a36SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
480534aa8a36SMatthew G. Knepley   if (f < 0) {
480634aa8a36SMatthew G. Knepley     dm->adjacency[0] = useCone;
480734aa8a36SMatthew G. Knepley     dm->adjacency[1] = useClosure;
480834aa8a36SMatthew G. Knepley   } else {
480934aa8a36SMatthew G. Knepley     PetscInt       Nf;
481034aa8a36SMatthew G. Knepley     PetscErrorCode ierr;
481134aa8a36SMatthew G. Knepley 
481234aa8a36SMatthew G. Knepley     ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
481334aa8a36SMatthew G. Knepley     if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf);
481434aa8a36SMatthew G. Knepley     dm->fields[f].adjacency[0] = useCone;
481534aa8a36SMatthew G. Knepley     dm->fields[f].adjacency[1] = useClosure;
4816e5e52638SMatthew G. Knepley   }
4817e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4818e5e52638SMatthew G. Knepley }
4819e5e52638SMatthew G. Knepley 
4820b0441da4SMatthew G. Knepley /*@
4821b0441da4SMatthew G. Knepley   DMGetBasicAdjacency - Returns the flags for determining variable influence, using either the default or field 0 if it is defined
4822b0441da4SMatthew G. Knepley 
4823b0441da4SMatthew G. Knepley   Not collective
4824b0441da4SMatthew G. Knepley 
4825b0441da4SMatthew G. Knepley   Input Parameters:
4826b0441da4SMatthew G. Knepley . dm - The DM object
4827b0441da4SMatthew G. Knepley 
4828b0441da4SMatthew G. Knepley   Output Parameter:
4829b0441da4SMatthew G. Knepley + useCone    - Flag for variable influence starting with the cone operation
4830b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
4831b0441da4SMatthew G. Knepley 
4832b0441da4SMatthew G. Knepley   Notes:
4833b0441da4SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
4834b0441da4SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
4835b0441da4SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4836b0441da4SMatthew G. Knepley 
4837b0441da4SMatthew G. Knepley   Level: developer
4838b0441da4SMatthew G. Knepley 
4839b0441da4SMatthew G. Knepley .seealso: DMSetBasicAdjacency(), DMGetField(), DMSetField()
4840b0441da4SMatthew G. Knepley @*/
4841b0441da4SMatthew G. Knepley PetscErrorCode DMGetBasicAdjacency(DM dm, PetscBool *useCone, PetscBool *useClosure)
4842b0441da4SMatthew G. Knepley {
4843b0441da4SMatthew G. Knepley   PetscInt       Nf;
4844b0441da4SMatthew G. Knepley   PetscErrorCode ierr;
4845b0441da4SMatthew G. Knepley 
4846b0441da4SMatthew G. Knepley   PetscFunctionBegin;
4847b0441da4SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4848534a8f05SLisandro Dalcin   if (useCone)    PetscValidBoolPointer(useCone, 3);
4849534a8f05SLisandro Dalcin   if (useClosure) PetscValidBoolPointer(useClosure, 4);
4850b0441da4SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4851b0441da4SMatthew G. Knepley   if (!Nf) {
4852b0441da4SMatthew G. Knepley     ierr = DMGetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr);
4853b0441da4SMatthew G. Knepley   } else {
4854b0441da4SMatthew G. Knepley     ierr = DMGetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr);
4855b0441da4SMatthew G. Knepley   }
4856b0441da4SMatthew G. Knepley   PetscFunctionReturn(0);
4857b0441da4SMatthew G. Knepley }
4858b0441da4SMatthew G. Knepley 
4859b0441da4SMatthew G. Knepley /*@
4860b0441da4SMatthew G. Knepley   DMSetBasicAdjacency - Set the flags for determining variable influence, using either the default or field 0 if it is defined
4861b0441da4SMatthew G. Knepley 
4862b0441da4SMatthew G. Knepley   Not collective
4863b0441da4SMatthew G. Knepley 
4864b0441da4SMatthew G. Knepley   Input Parameters:
4865b0441da4SMatthew G. Knepley + dm         - The DM object
4866b0441da4SMatthew G. Knepley . useCone    - Flag for variable influence starting with the cone operation
4867b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
4868b0441da4SMatthew G. Knepley 
4869b0441da4SMatthew G. Knepley   Notes:
4870b0441da4SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
4871b0441da4SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
4872b0441da4SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4873b0441da4SMatthew G. Knepley 
4874b0441da4SMatthew G. Knepley   Level: developer
4875b0441da4SMatthew G. Knepley 
4876b0441da4SMatthew G. Knepley .seealso: DMGetBasicAdjacency(), DMGetField(), DMSetField()
4877b0441da4SMatthew G. Knepley @*/
4878b0441da4SMatthew G. Knepley PetscErrorCode DMSetBasicAdjacency(DM dm, PetscBool useCone, PetscBool useClosure)
4879b0441da4SMatthew G. Knepley {
4880b0441da4SMatthew G. Knepley   PetscInt       Nf;
4881b0441da4SMatthew G. Knepley   PetscErrorCode ierr;
4882b0441da4SMatthew G. Knepley 
4883b0441da4SMatthew G. Knepley   PetscFunctionBegin;
4884b0441da4SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4885b0441da4SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4886b0441da4SMatthew G. Knepley   if (!Nf) {
4887b0441da4SMatthew G. Knepley     ierr = DMSetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr);
4888b0441da4SMatthew G. Knepley   } else {
4889b0441da4SMatthew G. Knepley     ierr = DMSetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr);
4890e5e52638SMatthew G. Knepley   }
4891e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4892e5e52638SMatthew G. Knepley }
4893e5e52638SMatthew G. Knepley 
4894e5e52638SMatthew G. Knepley static PetscErrorCode DMDSEnlarge_Static(DM dm, PetscInt NdsNew)
4895e5e52638SMatthew G. Knepley {
4896e5e52638SMatthew G. Knepley   DMSpace       *tmpd;
4897e5e52638SMatthew G. Knepley   PetscInt       Nds = dm->Nds, s;
4898e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4899e5e52638SMatthew G. Knepley 
4900e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4901e5e52638SMatthew G. Knepley   if (Nds >= NdsNew) PetscFunctionReturn(0);
4902e5e52638SMatthew G. Knepley   ierr = PetscMalloc1(NdsNew, &tmpd);CHKERRQ(ierr);
4903e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) tmpd[s] = dm->probs[s];
4904b3cf3223SMatthew G. Knepley   for (s = Nds; s < NdsNew; ++s) {tmpd[s].ds = NULL; tmpd[s].label = NULL; tmpd[s].fields = NULL;}
4905e5e52638SMatthew G. Knepley   ierr = PetscFree(dm->probs);CHKERRQ(ierr);
4906e5e52638SMatthew G. Knepley   dm->Nds   = NdsNew;
4907e5e52638SMatthew G. Knepley   dm->probs = tmpd;
4908e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4909e5e52638SMatthew G. Knepley }
4910e5e52638SMatthew G. Knepley 
4911e5e52638SMatthew G. Knepley /*@
4912e5e52638SMatthew G. Knepley   DMGetNumDS - Get the number of discrete systems in the DM
4913e5e52638SMatthew G. Knepley 
4914e5e52638SMatthew G. Knepley   Not collective
4915e5e52638SMatthew G. Knepley 
4916e5e52638SMatthew G. Knepley   Input Parameter:
4917e5e52638SMatthew G. Knepley . dm - The DM
4918e5e52638SMatthew G. Knepley 
4919e5e52638SMatthew G. Knepley   Output Parameter:
4920e5e52638SMatthew G. Knepley . Nds - The number of PetscDS objects
4921e5e52638SMatthew G. Knepley 
4922e5e52638SMatthew G. Knepley   Level: intermediate
4923e5e52638SMatthew G. Knepley 
4924e5e52638SMatthew G. Knepley .seealso: DMGetDS(), DMGetCellDS()
4925e5e52638SMatthew G. Knepley @*/
4926e5e52638SMatthew G. Knepley PetscErrorCode DMGetNumDS(DM dm, PetscInt *Nds)
4927e5e52638SMatthew G. Knepley {
4928e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4929e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4930534a8f05SLisandro Dalcin   PetscValidIntPointer(Nds, 2);
4931e5e52638SMatthew G. Knepley   *Nds = dm->Nds;
4932e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4933e5e52638SMatthew G. Knepley }
4934e5e52638SMatthew G. Knepley 
4935e5e52638SMatthew G. Knepley /*@
4936e5e52638SMatthew G. Knepley   DMClearDS - Remove all discrete systems from the DM
4937e5e52638SMatthew G. Knepley 
4938d083f849SBarry Smith   Logically collective on dm
4939e5e52638SMatthew G. Knepley 
4940e5e52638SMatthew G. Knepley   Input Parameter:
4941e5e52638SMatthew G. Knepley . dm - The DM
4942e5e52638SMatthew G. Knepley 
4943e5e52638SMatthew G. Knepley   Level: intermediate
4944e5e52638SMatthew G. Knepley 
4945e5e52638SMatthew G. Knepley .seealso: DMGetNumDS(), DMGetDS(), DMSetField()
4946e5e52638SMatthew G. Knepley @*/
4947e5e52638SMatthew G. Knepley PetscErrorCode DMClearDS(DM dm)
4948e5e52638SMatthew G. Knepley {
4949e5e52638SMatthew G. Knepley   PetscInt       s;
4950e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4951e5e52638SMatthew G. Knepley 
4952e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4953e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4954e5e52638SMatthew G. Knepley   for (s = 0; s < dm->Nds; ++s) {
4955e5e52638SMatthew G. Knepley     ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr);
4956e5e52638SMatthew G. Knepley     ierr = DMLabelDestroy(&dm->probs[s].label);CHKERRQ(ierr);
4957b3cf3223SMatthew G. Knepley     ierr = ISDestroy(&dm->probs[s].fields);CHKERRQ(ierr);
4958e5e52638SMatthew G. Knepley   }
4959e5e52638SMatthew G. Knepley   ierr = PetscFree(dm->probs);CHKERRQ(ierr);
4960e5e52638SMatthew G. Knepley   dm->probs = NULL;
4961e5e52638SMatthew G. Knepley   dm->Nds   = 0;
4962e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4963e5e52638SMatthew G. Knepley }
4964e5e52638SMatthew G. Knepley 
4965e5e52638SMatthew G. Knepley /*@
4966e5e52638SMatthew G. Knepley   DMGetDS - Get the default PetscDS
4967e5e52638SMatthew G. Knepley 
4968e5e52638SMatthew G. Knepley   Not collective
4969e5e52638SMatthew G. Knepley 
4970e5e52638SMatthew G. Knepley   Input Parameter:
4971e5e52638SMatthew G. Knepley . dm    - The DM
4972e5e52638SMatthew G. Knepley 
4973e5e52638SMatthew G. Knepley   Output Parameter:
4974e5e52638SMatthew G. Knepley . prob - The default PetscDS
4975e5e52638SMatthew G. Knepley 
4976e5e52638SMatthew G. Knepley   Level: intermediate
4977e5e52638SMatthew G. Knepley 
4978e5e52638SMatthew G. Knepley .seealso: DMGetCellDS(), DMGetRegionDS()
4979e5e52638SMatthew G. Knepley @*/
4980e5e52638SMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *prob)
4981e5e52638SMatthew G. Knepley {
4982b0143b4dSMatthew G. Knepley   PetscErrorCode ierr;
4983b0143b4dSMatthew G. Knepley 
4984e5e52638SMatthew G. Knepley   PetscFunctionBeginHot;
4985e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4986e5e52638SMatthew G. Knepley   PetscValidPointer(prob, 2);
4987b0143b4dSMatthew G. Knepley   if (dm->Nds <= 0) {
4988b0143b4dSMatthew G. Knepley     PetscDS ds;
4989b0143b4dSMatthew G. Knepley 
4990b0143b4dSMatthew G. Knepley     ierr = PetscDSCreate(PetscObjectComm((PetscObject) dm), &ds);CHKERRQ(ierr);
4991b3cf3223SMatthew G. Knepley     ierr = DMSetRegionDS(dm, NULL, NULL, ds);CHKERRQ(ierr);
4992b0143b4dSMatthew G. Knepley     ierr = PetscDSDestroy(&ds);CHKERRQ(ierr);
4993b0143b4dSMatthew G. Knepley   }
4994b0143b4dSMatthew G. Knepley   *prob = dm->probs[0].ds;
4995e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4996e5e52638SMatthew G. Knepley }
4997e5e52638SMatthew G. Knepley 
4998e5e52638SMatthew G. Knepley /*@
4999e5e52638SMatthew G. Knepley   DMGetCellDS - Get the PetscDS defined on a given cell
5000e5e52638SMatthew G. Knepley 
5001e5e52638SMatthew G. Knepley   Not collective
5002e5e52638SMatthew G. Knepley 
5003e5e52638SMatthew G. Knepley   Input Parameters:
5004e5e52638SMatthew G. Knepley + dm    - The DM
5005e5e52638SMatthew G. Knepley - point - Cell for the DS
5006e5e52638SMatthew G. Knepley 
5007e5e52638SMatthew G. Knepley   Output Parameter:
5008e5e52638SMatthew G. Knepley . prob - The PetscDS defined on the given cell
5009e5e52638SMatthew G. Knepley 
5010e5e52638SMatthew G. Knepley   Level: developer
5011e5e52638SMatthew G. Knepley 
5012b0143b4dSMatthew G. Knepley .seealso: DMGetDS(), DMSetRegionDS()
5013e5e52638SMatthew G. Knepley @*/
5014e5e52638SMatthew G. Knepley PetscErrorCode DMGetCellDS(DM dm, PetscInt point, PetscDS *prob)
5015e5e52638SMatthew G. Knepley {
5016e5e52638SMatthew G. Knepley   PetscDS        probDef = NULL;
5017e5e52638SMatthew G. Knepley   PetscInt       s;
5018e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5019e5e52638SMatthew G. Knepley 
5020e5e52638SMatthew G. Knepley   PetscFunctionBeginHot;
5021e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5022e5e52638SMatthew G. Knepley   PetscValidPointer(prob, 3);
5023e5e52638SMatthew G. Knepley   *prob = NULL;
5024e5e52638SMatthew G. Knepley   for (s = 0; s < dm->Nds; ++s) {
5025e5e52638SMatthew G. Knepley     PetscInt val;
5026e5e52638SMatthew G. Knepley 
5027e5e52638SMatthew G. Knepley     if (!dm->probs[s].label) {probDef = dm->probs[s].ds;}
5028e5e52638SMatthew G. Knepley     else {
5029e5e52638SMatthew G. Knepley       ierr = DMLabelGetValue(dm->probs[s].label, point, &val);CHKERRQ(ierr);
5030e5e52638SMatthew G. Knepley       if (val >= 0) {*prob = dm->probs[s].ds; break;}
5031e5e52638SMatthew G. Knepley     }
5032e5e52638SMatthew G. Knepley   }
5033e5e52638SMatthew G. Knepley   if (!*prob) *prob = probDef;
5034e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5035e5e52638SMatthew G. Knepley }
5036e5e52638SMatthew G. Knepley 
5037e5e52638SMatthew G. Knepley /*@
5038e5e52638SMatthew G. Knepley   DMGetRegionDS - Get the PetscDS for a given mesh region, defined by a DMLabel
5039e5e52638SMatthew G. Knepley 
5040e5e52638SMatthew G. Knepley   Not collective
5041e5e52638SMatthew G. Knepley 
5042e5e52638SMatthew G. Knepley   Input Parameters:
5043e5e52638SMatthew G. Knepley + dm    - The DM
5044e5e52638SMatthew G. Knepley - label - The DMLabel defining the mesh region, or NULL for the entire mesh
5045e5e52638SMatthew G. Knepley 
5046b3cf3223SMatthew G. Knepley   Output Parameters:
5047b3cf3223SMatthew G. Knepley + fields - The IS containing the DM field numbers for the fields in this DS, or NULL
5048b3cf3223SMatthew G. Knepley - prob - The PetscDS defined on the given region, or NULL
5049e5e52638SMatthew G. Knepley 
5050e5e52638SMatthew G. Knepley   Note: If the label is missing, this function returns an error
5051e5e52638SMatthew G. Knepley 
5052e5e52638SMatthew G. Knepley   Level: advanced
5053e5e52638SMatthew G. Knepley 
5054e5e52638SMatthew G. Knepley .seealso: DMGetRegionNumDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS()
5055e5e52638SMatthew G. Knepley @*/
5056b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionDS(DM dm, DMLabel label, IS *fields, PetscDS *ds)
5057e5e52638SMatthew G. Knepley {
5058e5e52638SMatthew G. Knepley   PetscInt Nds = dm->Nds, s;
5059e5e52638SMatthew G. Knepley 
5060e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5061e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5062e5e52638SMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2);
5063b3cf3223SMatthew G. Knepley   if (fields) {PetscValidPointer(fields, 3); *fields = NULL;}
5064b3cf3223SMatthew G. Knepley   if (ds)     {PetscValidPointer(ds, 4);     *ds     = NULL;}
5065e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
5066b3cf3223SMatthew G. Knepley     if (dm->probs[s].label == label) {
5067b3cf3223SMatthew G. Knepley       if (fields) *fields = dm->probs[s].fields;
5068b3cf3223SMatthew G. Knepley       if (ds)     *ds     = dm->probs[s].ds;
5069b3cf3223SMatthew G. Knepley       PetscFunctionReturn(0);
5070b3cf3223SMatthew G. Knepley     }
5071e5e52638SMatthew G. Knepley   }
50722df9ee95SMatthew G. Knepley   PetscFunctionReturn(0);
5073e5e52638SMatthew G. Knepley }
5074e5e52638SMatthew G. Knepley 
5075e5e52638SMatthew G. Knepley /*@
5076e5e52638SMatthew G. Knepley   DMGetRegionNumDS - Get the PetscDS for a given mesh region, defined by the region number
5077e5e52638SMatthew G. Knepley 
5078e5e52638SMatthew G. Knepley   Not collective
5079e5e52638SMatthew G. Knepley 
5080e5e52638SMatthew G. Knepley   Input Parameters:
5081e5e52638SMatthew G. Knepley + dm  - The DM
5082e5e52638SMatthew G. Knepley - num - The region number, in [0, Nds)
5083e5e52638SMatthew G. Knepley 
5084e5e52638SMatthew G. Knepley   Output Parameters:
5085b3cf3223SMatthew G. Knepley + label  - The region label, or NULL
5086b3cf3223SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL
5087b3cf3223SMatthew G. Knepley - prob   - The PetscDS defined on the given region, or NULL
5088e5e52638SMatthew G. Knepley 
5089e5e52638SMatthew G. Knepley   Level: advanced
5090e5e52638SMatthew G. Knepley 
5091e5e52638SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS()
5092e5e52638SMatthew G. Knepley @*/
5093b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionNumDS(DM dm, PetscInt num, DMLabel *label, IS *fields, PetscDS *ds)
5094e5e52638SMatthew G. Knepley {
5095e5e52638SMatthew G. Knepley   PetscInt       Nds;
5096e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5097e5e52638SMatthew G. Knepley 
5098e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5099e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5100e5e52638SMatthew G. Knepley   ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr);
5101e5e52638SMatthew G. Knepley   if ((num < 0) || (num >= Nds)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Region number %D is not in [0, %D)", num, Nds);
5102e5e52638SMatthew G. Knepley   if (label) {
5103e5e52638SMatthew G. Knepley     PetscValidPointer(label, 3);
5104e5e52638SMatthew G. Knepley     *label = dm->probs[num].label;
5105e5e52638SMatthew G. Knepley   }
5106b3cf3223SMatthew G. Knepley   if (fields) {
5107b3cf3223SMatthew G. Knepley     PetscValidPointer(fields, 4);
5108b3cf3223SMatthew G. Knepley     *fields = dm->probs[num].fields;
5109b3cf3223SMatthew G. Knepley   }
5110e5e52638SMatthew G. Knepley   if (ds) {
5111b3cf3223SMatthew G. Knepley     PetscValidPointer(ds, 5);
5112e5e52638SMatthew G. Knepley     *ds = dm->probs[num].ds;
5113e5e52638SMatthew G. Knepley   }
5114e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5115e5e52638SMatthew G. Knepley }
5116e5e52638SMatthew G. Knepley 
5117e5e52638SMatthew G. Knepley /*@
5118e5e52638SMatthew G. Knepley   DMSetRegionDS - Set the PetscDS for a given mesh region, defined by a DMLabel
5119e5e52638SMatthew G. Knepley 
5120d083f849SBarry Smith   Collective on dm
5121e5e52638SMatthew G. Knepley 
5122e5e52638SMatthew G. Knepley   Input Parameters:
5123e5e52638SMatthew G. Knepley + dm     - The DM
5124e5e52638SMatthew G. Knepley . label  - The DMLabel defining the mesh region, or NULL for the entire mesh
5125b3cf3223SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL for all fields
5126e5e52638SMatthew G. Knepley - prob   - The PetscDS defined on the given cell
5127e5e52638SMatthew G. Knepley 
5128b3cf3223SMatthew G. Knepley   Note: If the label has a DS defined, it will be replaced. Otherwise, it will be added to the DM. If DS is replaced,
5129b3cf3223SMatthew G. Knepley   the fields argument is ignored.
5130e5e52638SMatthew G. Knepley 
5131e5e52638SMatthew G. Knepley   Level: advanced
5132e5e52638SMatthew G. Knepley 
5133e5e52638SMatthew G. Knepley .seealso: DMGetRegionDS(), DMGetDS(), DMGetCellDS()
5134e5e52638SMatthew G. Knepley @*/
5135b3cf3223SMatthew G. Knepley PetscErrorCode DMSetRegionDS(DM dm, DMLabel label, IS fields, PetscDS ds)
5136e5e52638SMatthew G. Knepley {
5137e5e52638SMatthew G. Knepley   PetscInt       Nds = dm->Nds, s;
5138e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5139e5e52638SMatthew G. Knepley 
5140e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5141e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5142e5e52638SMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2);
5143e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 3);
5144e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
5145e5e52638SMatthew G. Knepley     if (dm->probs[s].label == label) {
5146b3cf3223SMatthew G. Knepley       ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr);
5147e5e52638SMatthew G. Knepley       dm->probs[s].ds = ds;
5148e5e52638SMatthew G. Knepley       PetscFunctionReturn(0);
5149e5e52638SMatthew G. Knepley     }
5150e5e52638SMatthew G. Knepley   }
51511b5e6740SSatish Balay   ierr = DMDSEnlarge_Static(dm, Nds+1);CHKERRQ(ierr);
5152e5e52638SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
5153b3cf3223SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) fields);CHKERRQ(ierr);
5154e5e52638SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) ds);CHKERRQ(ierr);
5155e5e52638SMatthew G. Knepley   if (!label) {
5156e5e52638SMatthew G. Knepley     /* Put the NULL label at the front, so it is returned as the default */
5157e5e52638SMatthew G. Knepley     for (s = Nds-1; s >=0; --s) dm->probs[s+1] = dm->probs[s];
5158e5e52638SMatthew G. Knepley     Nds = 0;
5159e5e52638SMatthew G. Knepley   }
5160e5e52638SMatthew G. Knepley   dm->probs[Nds].label  = label;
5161b3cf3223SMatthew G. Knepley   dm->probs[Nds].fields = fields;
5162e5e52638SMatthew G. Knepley   dm->probs[Nds].ds     = ds;
5163e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5164e5e52638SMatthew G. Knepley }
5165e5e52638SMatthew G. Knepley 
5166e5e52638SMatthew G. Knepley /*@
5167e5e52638SMatthew G. Knepley   DMCreateDS - Create the discrete systems for the DM based upon the fields added to the DM
5168e5e52638SMatthew G. Knepley 
5169d083f849SBarry Smith   Collective on dm
5170e5e52638SMatthew G. Knepley 
5171e5e52638SMatthew G. Knepley   Input Parameter:
5172e5e52638SMatthew G. Knepley . dm - The DM
5173e5e52638SMatthew G. Knepley 
5174e5e52638SMatthew G. Knepley   Note: If the label has a DS defined, it will be replaced. Otherwise, it will be added to the DM.
5175e5e52638SMatthew G. Knepley 
5176e5e52638SMatthew G. Knepley   Level: intermediate
5177e5e52638SMatthew G. Knepley 
5178e5e52638SMatthew G. Knepley .seealso: DMSetField, DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS()
5179e5e52638SMatthew G. Knepley @*/
5180e5e52638SMatthew G. Knepley PetscErrorCode DMCreateDS(DM dm)
5181e5e52638SMatthew G. Knepley {
5182e5e52638SMatthew G. Knepley   MPI_Comm       comm;
5183e5e52638SMatthew G. Knepley   PetscDS        prob, probh = NULL;
5184b3cf3223SMatthew G. Knepley   PetscInt       dimEmbed, Nf = dm->Nf, f, s, field = 0, fieldh = 0;
5185e5e52638SMatthew G. Knepley   PetscBool      doSetup = PETSC_TRUE;
5186e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5187e5e52638SMatthew G. Knepley 
5188e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5189e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5190e5e52638SMatthew G. Knepley   if (!dm->fields) PetscFunctionReturn(0);
5191e5e52638SMatthew G. Knepley   /* Can only handle two label cases right now:
5192e5e52638SMatthew G. Knepley    1) NULL
5193e5e52638SMatthew G. Knepley    2) Hybrid cells
5194e5e52638SMatthew G. Knepley   */
5195e5e52638SMatthew G. Knepley   ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr);
5196e5e52638SMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr);
5197e5e52638SMatthew G. Knepley   /* Create default DS */
5198b3cf3223SMatthew G. Knepley   ierr = DMGetRegionDS(dm, NULL, NULL, &prob);CHKERRQ(ierr);
51992df9ee95SMatthew G. Knepley   if (!prob) {
5200b3cf3223SMatthew G. Knepley     IS        fields;
5201b3cf3223SMatthew G. Knepley     PetscInt *fld, nf;
5202b3cf3223SMatthew G. Knepley 
5203b3cf3223SMatthew G. Knepley     for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) ++nf;
5204b3cf3223SMatthew G. Knepley     ierr = PetscMalloc1(nf, &fld);CHKERRQ(ierr);
5205b3cf3223SMatthew G. Knepley     for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) fld[nf++] = f;
520688f0c812SMatthew G. Knepley     ierr = ISCreate(PETSC_COMM_SELF, &fields);CHKERRQ(ierr);
520788f0c812SMatthew G. Knepley     ierr = PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_");CHKERRQ(ierr);
520888f0c812SMatthew G. Knepley     ierr = ISSetType(fields, ISGENERAL);CHKERRQ(ierr);
520988f0c812SMatthew G. Knepley     ierr = ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER);CHKERRQ(ierr);
521088f0c812SMatthew G. Knepley 
52112df9ee95SMatthew G. Knepley     ierr = PetscDSCreate(comm, &prob);CHKERRQ(ierr);
5212b3cf3223SMatthew G. Knepley     ierr = DMSetRegionDS(dm, NULL, fields, prob);CHKERRQ(ierr);
52132df9ee95SMatthew G. Knepley     ierr = PetscDSDestroy(&prob);CHKERRQ(ierr);
5214b3cf3223SMatthew G. Knepley     ierr = ISDestroy(&fields);CHKERRQ(ierr);
5215b3cf3223SMatthew G. Knepley     ierr = DMGetRegionDS(dm, NULL, NULL, &prob);CHKERRQ(ierr);
52162df9ee95SMatthew G. Knepley   }
5217e5e52638SMatthew G. Knepley   ierr = PetscDSSetCoordinateDimension(prob, dimEmbed);CHKERRQ(ierr);
5218e5e52638SMatthew G. Knepley   /* Optionally create hybrid DS */
5219b3cf3223SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
5220e5e52638SMatthew G. Knepley     DMLabel  label = dm->fields[f].label;
5221e5e52638SMatthew G. Knepley     PetscInt lStart, lEnd;
5222e5e52638SMatthew G. Knepley 
5223e5e52638SMatthew G. Knepley     if (label) {
52240122748bSMatthew G. Knepley       DM        plex;
5225a2d47024SMatthew G. Knepley       IS        fields;
5226a2d47024SMatthew G. Knepley       PetscInt *fld;
52270122748bSMatthew G. Knepley       PetscInt  depth, pMax[4];
52280122748bSMatthew G. Knepley 
52290122748bSMatthew G. Knepley       ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr);
52300122748bSMatthew G. Knepley       ierr = DMPlexGetDepth(plex, &depth);CHKERRQ(ierr);
52310122748bSMatthew G. Knepley       ierr = DMPlexGetHybridBounds(plex, depth >= 0 ? &pMax[depth] : NULL, depth>1 ? &pMax[depth-1] : NULL, depth>2 ? &pMax[1] : NULL, &pMax[0]);CHKERRQ(ierr);
52320122748bSMatthew G. Knepley       ierr = DMDestroy(&plex);CHKERRQ(ierr);
52330122748bSMatthew G. Knepley 
5234e5e52638SMatthew G. Knepley       ierr = DMLabelGetBounds(label, &lStart, &lEnd);CHKERRQ(ierr);
5235e5e52638SMatthew G. Knepley       if (lStart < pMax[depth]) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only support labels over hybrid cells right now");
5236e5e52638SMatthew G. Knepley       ierr = PetscDSCreate(comm, &probh);CHKERRQ(ierr);
5237a2d47024SMatthew G. Knepley       ierr = PetscMalloc1(1, &fld);CHKERRQ(ierr);
5238a2d47024SMatthew G. Knepley       fld[0] = f;
5239a2d47024SMatthew G. Knepley       ierr = ISCreate(PETSC_COMM_SELF, &fields);CHKERRQ(ierr);
5240a2d47024SMatthew G. Knepley       ierr = PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_");CHKERRQ(ierr);
5241a2d47024SMatthew G. Knepley       ierr = ISSetType(fields, ISGENERAL);CHKERRQ(ierr);
5242a2d47024SMatthew G. Knepley       ierr = ISGeneralSetIndices(fields, 1, fld, PETSC_OWN_POINTER);CHKERRQ(ierr);
5243a2d47024SMatthew G. Knepley       ierr = DMSetRegionDS(dm, label, fields, probh);CHKERRQ(ierr);
5244a2d47024SMatthew G. Knepley       ierr = ISDestroy(&fields);CHKERRQ(ierr);
5245e5e52638SMatthew G. Knepley       ierr = PetscDSSetHybrid(probh, PETSC_TRUE);CHKERRQ(ierr);
5246e5e52638SMatthew G. Knepley       ierr = PetscDSSetCoordinateDimension(probh, dimEmbed);CHKERRQ(ierr);
5247e5e52638SMatthew G. Knepley       break;
5248e5e52638SMatthew G. Knepley     }
5249e5e52638SMatthew G. Knepley   }
5250e5e52638SMatthew G. Knepley   /* Set fields in DSes */
5251b3cf3223SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
5252e5e52638SMatthew G. Knepley     DMLabel     label = dm->fields[f].label;
5253e5e52638SMatthew G. Knepley     PetscObject disc  = dm->fields[f].disc;
5254e5e52638SMatthew G. Knepley 
5255e5e52638SMatthew G. Knepley     if (!label) {
5256e5e52638SMatthew G. Knepley       ierr = PetscDSSetDiscretization(prob,  field++,  disc);CHKERRQ(ierr);
5257e5e52638SMatthew G. Knepley       if (probh) {
5258e5e52638SMatthew G. Knepley         PetscFE subfe;
5259e5e52638SMatthew G. Knepley 
5260e5e52638SMatthew G. Knepley         ierr = PetscFEGetHeightSubspace((PetscFE) disc, 1, &subfe);CHKERRQ(ierr);
5261e5e52638SMatthew G. Knepley         ierr = PetscDSSetDiscretization(probh, fieldh++, (PetscObject) subfe);CHKERRQ(ierr);
5262e5e52638SMatthew G. Knepley       }
5263e5e52638SMatthew G. Knepley     } else {
5264e5e52638SMatthew G. Knepley       ierr = PetscDSSetDiscretization(probh, fieldh++, disc);CHKERRQ(ierr);
5265e5e52638SMatthew G. Knepley     }
5266e5e52638SMatthew G. Knepley     /* We allow people to have placeholder fields and construct the Section by hand */
5267e5e52638SMatthew G. Knepley     {
5268e5e52638SMatthew G. Knepley       PetscClassId id;
5269e5e52638SMatthew G. Knepley 
5270e5e52638SMatthew G. Knepley       ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr);
5271e5e52638SMatthew G. Knepley       if ((id != PETSCFE_CLASSID) && (id != PETSCFV_CLASSID)) doSetup = PETSC_FALSE;
5272e5e52638SMatthew G. Knepley     }
5273e5e52638SMatthew G. Knepley   }
5274e5e52638SMatthew G. Knepley   ierr = PetscDSDestroy(&probh);CHKERRQ(ierr);
5275e5e52638SMatthew G. Knepley   /* Setup DSes */
5276e5e52638SMatthew G. Knepley   if (doSetup) {
5277e5e52638SMatthew G. Knepley     for (s = 0; s < dm->Nds; ++s) {ierr = PetscDSSetUp(dm->probs[s].ds);CHKERRQ(ierr);}
5278e5e52638SMatthew G. Knepley   }
5279e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5280e5e52638SMatthew G. Knepley }
5281e5e52638SMatthew G. Knepley 
5282e5e52638SMatthew G. Knepley /*@
5283e5e52638SMatthew G. Knepley   DMCopyDS - Copy the discrete systems for the DM into another DM
5284e5e52638SMatthew G. Knepley 
5285d083f849SBarry Smith   Collective on dm
5286e5e52638SMatthew G. Knepley 
5287e5e52638SMatthew G. Knepley   Input Parameter:
5288e5e52638SMatthew G. Knepley . dm - The DM
5289e5e52638SMatthew G. Knepley 
5290e5e52638SMatthew G. Knepley   Output Parameter:
5291e5e52638SMatthew G. Knepley . newdm - The DM
5292e5e52638SMatthew G. Knepley 
5293e5e52638SMatthew G. Knepley   Level: advanced
5294e5e52638SMatthew G. Knepley 
5295e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS()
5296e5e52638SMatthew G. Knepley @*/
5297e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDS(DM dm, DM newdm)
5298e5e52638SMatthew G. Knepley {
5299e5e52638SMatthew G. Knepley   PetscInt       Nds, s;
5300e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5301e5e52638SMatthew G. Knepley 
5302e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5303e5e52638SMatthew G. Knepley   if (dm == newdm) PetscFunctionReturn(0);
5304e5e52638SMatthew G. Knepley   ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr);
5305e5e52638SMatthew G. Knepley   ierr = DMClearDS(newdm);CHKERRQ(ierr);
5306e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
5307e5e52638SMatthew G. Knepley     DMLabel label;
5308b3cf3223SMatthew G. Knepley     IS      fields;
5309e5e52638SMatthew G. Knepley     PetscDS ds;
5310e5e52638SMatthew G. Knepley 
5311b3cf3223SMatthew G. Knepley     ierr = DMGetRegionNumDS(dm, s, &label, &fields, &ds);CHKERRQ(ierr);
5312b3cf3223SMatthew G. Knepley     ierr = DMSetRegionDS(newdm, label, fields, ds);CHKERRQ(ierr);
5313e5e52638SMatthew G. Knepley   }
5314e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5315e5e52638SMatthew G. Knepley }
5316e5e52638SMatthew G. Knepley 
5317e5e52638SMatthew G. Knepley /*@
5318e5e52638SMatthew G. Knepley   DMCopyDisc - Copy the fields and discrete systems for the DM into another DM
5319e5e52638SMatthew G. Knepley 
5320d083f849SBarry Smith   Collective on dm
5321e5e52638SMatthew G. Knepley 
5322e5e52638SMatthew G. Knepley   Input Parameter:
5323e5e52638SMatthew G. Knepley . dm - The DM
5324e5e52638SMatthew G. Knepley 
5325e5e52638SMatthew G. Knepley   Output Parameter:
5326e5e52638SMatthew G. Knepley . newdm - The DM
5327e5e52638SMatthew G. Knepley 
5328e5e52638SMatthew G. Knepley   Level: advanced
5329e5e52638SMatthew G. Knepley 
5330e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMCopyDS()
5331e5e52638SMatthew G. Knepley @*/
5332e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDisc(DM dm, DM newdm)
5333e5e52638SMatthew G. Knepley {
5334e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5335e5e52638SMatthew G. Knepley 
5336e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5337e5e52638SMatthew G. Knepley   if (dm == newdm) PetscFunctionReturn(0);
5338e5e52638SMatthew G. Knepley   ierr = DMCopyFields(dm, newdm);CHKERRQ(ierr);
5339e5e52638SMatthew G. Knepley   ierr = DMCopyDS(dm, newdm);CHKERRQ(ierr);
5340e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5341e5e52638SMatthew G. Knepley }
5342e5e52638SMatthew G. Knepley 
5343b64e0483SPeter Brune PetscErrorCode DMRestrictHook_Coordinates(DM dm,DM dmc,void *ctx)
5344b64e0483SPeter Brune {
5345b64e0483SPeter Brune   DM dm_coord,dmc_coord;
5346b64e0483SPeter Brune   PetscErrorCode ierr;
5347b64e0483SPeter Brune   Vec coords,ccoords;
53486dbf9973SLawrence Mitchell   Mat inject;
5349b64e0483SPeter Brune   PetscFunctionBegin;
5350b64e0483SPeter Brune   ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr);
5351b64e0483SPeter Brune   ierr = DMGetCoordinateDM(dmc,&dmc_coord);CHKERRQ(ierr);
5352b64e0483SPeter Brune   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
5353b64e0483SPeter Brune   ierr = DMGetCoordinates(dmc,&ccoords);CHKERRQ(ierr);
5354b64e0483SPeter Brune   if (coords && !ccoords) {
5355b64e0483SPeter Brune     ierr = DMCreateGlobalVector(dmc_coord,&ccoords);CHKERRQ(ierr);
53566668ed41SLisandro Dalcin     ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr);
53576dbf9973SLawrence Mitchell     ierr = DMCreateInjection(dmc_coord,dm_coord,&inject);CHKERRQ(ierr);
53582adcf181SLawrence Mitchell     ierr = MatRestrict(inject,coords,ccoords);CHKERRQ(ierr);
53596dbf9973SLawrence Mitchell     ierr = MatDestroy(&inject);CHKERRQ(ierr);
5360b64e0483SPeter Brune     ierr = DMSetCoordinates(dmc,ccoords);CHKERRQ(ierr);
5361b64e0483SPeter Brune     ierr = VecDestroy(&ccoords);CHKERRQ(ierr);
5362b64e0483SPeter Brune   }
5363b64e0483SPeter Brune   PetscFunctionReturn(0);
5364b64e0483SPeter Brune }
5365b64e0483SPeter Brune 
536603dadc2fSPeter Brune static PetscErrorCode DMSubDomainHook_Coordinates(DM dm,DM subdm,void *ctx)
536703dadc2fSPeter Brune {
536803dadc2fSPeter Brune   DM dm_coord,subdm_coord;
536903dadc2fSPeter Brune   PetscErrorCode ierr;
537003dadc2fSPeter Brune   Vec coords,ccoords,clcoords;
537103dadc2fSPeter Brune   VecScatter *scat_i,*scat_g;
537203dadc2fSPeter Brune   PetscFunctionBegin;
537303dadc2fSPeter Brune   ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr);
537403dadc2fSPeter Brune   ierr = DMGetCoordinateDM(subdm,&subdm_coord);CHKERRQ(ierr);
537503dadc2fSPeter Brune   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
537603dadc2fSPeter Brune   ierr = DMGetCoordinates(subdm,&ccoords);CHKERRQ(ierr);
537703dadc2fSPeter Brune   if (coords && !ccoords) {
537803dadc2fSPeter Brune     ierr = DMCreateGlobalVector(subdm_coord,&ccoords);CHKERRQ(ierr);
53796668ed41SLisandro Dalcin     ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr);
538003dadc2fSPeter Brune     ierr = DMCreateLocalVector(subdm_coord,&clcoords);CHKERRQ(ierr);
538124640c55SToby Isaac     ierr = PetscObjectSetName((PetscObject)clcoords,"coordinates");CHKERRQ(ierr);
538203dadc2fSPeter Brune     ierr = DMCreateDomainDecompositionScatters(dm_coord,1,&subdm_coord,NULL,&scat_i,&scat_g);CHKERRQ(ierr);
538303dadc2fSPeter Brune     ierr = VecScatterBegin(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
538403dadc2fSPeter Brune     ierr = VecScatterEnd(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
53851ed9ada7SJunchao Zhang     ierr = VecScatterBegin(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
538603dadc2fSPeter Brune     ierr = VecScatterEnd(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
538703dadc2fSPeter Brune     ierr = DMSetCoordinates(subdm,ccoords);CHKERRQ(ierr);
538803dadc2fSPeter Brune     ierr = DMSetCoordinatesLocal(subdm,clcoords);CHKERRQ(ierr);
538903dadc2fSPeter Brune     ierr = VecScatterDestroy(&scat_i[0]);CHKERRQ(ierr);
539003dadc2fSPeter Brune     ierr = VecScatterDestroy(&scat_g[0]);CHKERRQ(ierr);
539103dadc2fSPeter Brune     ierr = VecDestroy(&ccoords);CHKERRQ(ierr);
539203dadc2fSPeter Brune     ierr = VecDestroy(&clcoords);CHKERRQ(ierr);
539303dadc2fSPeter Brune     ierr = PetscFree(scat_i);CHKERRQ(ierr);
539403dadc2fSPeter Brune     ierr = PetscFree(scat_g);CHKERRQ(ierr);
539503dadc2fSPeter Brune   }
539603dadc2fSPeter Brune   PetscFunctionReturn(0);
539703dadc2fSPeter Brune }
539803dadc2fSPeter Brune 
5399c73cfb54SMatthew G. Knepley /*@
5400c73cfb54SMatthew G. Knepley   DMGetDimension - Return the topological dimension of the DM
5401c73cfb54SMatthew G. Knepley 
5402c73cfb54SMatthew G. Knepley   Not collective
5403c73cfb54SMatthew G. Knepley 
5404c73cfb54SMatthew G. Knepley   Input Parameter:
5405c73cfb54SMatthew G. Knepley . dm - The DM
5406c73cfb54SMatthew G. Knepley 
5407c73cfb54SMatthew G. Knepley   Output Parameter:
5408c73cfb54SMatthew G. Knepley . dim - The topological dimension
5409c73cfb54SMatthew G. Knepley 
5410c73cfb54SMatthew G. Knepley   Level: beginner
5411c73cfb54SMatthew G. Knepley 
5412c73cfb54SMatthew G. Knepley .seealso: DMSetDimension(), DMCreate()
5413c73cfb54SMatthew G. Knepley @*/
5414c73cfb54SMatthew G. Knepley PetscErrorCode DMGetDimension(DM dm, PetscInt *dim)
5415c73cfb54SMatthew G. Knepley {
5416c73cfb54SMatthew G. Knepley   PetscFunctionBegin;
5417c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5418534a8f05SLisandro Dalcin   PetscValidIntPointer(dim, 2);
5419c73cfb54SMatthew G. Knepley   *dim = dm->dim;
5420c73cfb54SMatthew G. Knepley   PetscFunctionReturn(0);
5421c73cfb54SMatthew G. Knepley }
5422c73cfb54SMatthew G. Knepley 
5423c73cfb54SMatthew G. Knepley /*@
5424c73cfb54SMatthew G. Knepley   DMSetDimension - Set the topological dimension of the DM
5425c73cfb54SMatthew G. Knepley 
5426c73cfb54SMatthew G. Knepley   Collective on dm
5427c73cfb54SMatthew G. Knepley 
5428c73cfb54SMatthew G. Knepley   Input Parameters:
5429c73cfb54SMatthew G. Knepley + dm - The DM
5430c73cfb54SMatthew G. Knepley - dim - The topological dimension
5431c73cfb54SMatthew G. Knepley 
5432c73cfb54SMatthew G. Knepley   Level: beginner
5433c73cfb54SMatthew G. Knepley 
5434c73cfb54SMatthew G. Knepley .seealso: DMGetDimension(), DMCreate()
5435c73cfb54SMatthew G. Knepley @*/
5436c73cfb54SMatthew G. Knepley PetscErrorCode DMSetDimension(DM dm, PetscInt dim)
5437c73cfb54SMatthew G. Knepley {
5438e5e52638SMatthew G. Knepley   PetscDS        ds;
5439f17e8794SMatthew G. Knepley   PetscErrorCode ierr;
5440f17e8794SMatthew G. Knepley 
5441c73cfb54SMatthew G. Knepley   PetscFunctionBegin;
5442c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5443c73cfb54SMatthew G. Knepley   PetscValidLogicalCollectiveInt(dm, dim, 2);
5444c73cfb54SMatthew G. Knepley   dm->dim = dim;
5445e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
5446e5e52638SMatthew G. Knepley   if (ds->dimEmbed < 0) {ierr = PetscDSSetCoordinateDimension(ds, dm->dim);CHKERRQ(ierr);}
5447c73cfb54SMatthew G. Knepley   PetscFunctionReturn(0);
5448c73cfb54SMatthew G. Knepley }
5449c73cfb54SMatthew G. Knepley 
5450793f3fe5SMatthew G. Knepley /*@
5451793f3fe5SMatthew G. Knepley   DMGetDimPoints - Get the half-open interval for all points of a given dimension
5452793f3fe5SMatthew G. Knepley 
5453d083f849SBarry Smith   Collective on dm
5454793f3fe5SMatthew G. Knepley 
5455793f3fe5SMatthew G. Knepley   Input Parameters:
5456793f3fe5SMatthew G. Knepley + dm - the DM
5457793f3fe5SMatthew G. Knepley - dim - the dimension
5458793f3fe5SMatthew G. Knepley 
5459793f3fe5SMatthew G. Knepley   Output Parameters:
5460793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension
5461aa049354SPatrick Sanan - pEnd - The first point following points of the given dimension
5462793f3fe5SMatthew G. Knepley 
5463793f3fe5SMatthew G. Knepley   Note:
5464793f3fe5SMatthew G. Knepley   The points are vertices in the Hasse diagram encoding the topology. This is explained in
5465a8d69d7bSBarry Smith   https://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme,
5466793f3fe5SMatthew G. Knepley   then the interval is empty.
5467793f3fe5SMatthew G. Knepley 
5468793f3fe5SMatthew G. Knepley   Level: intermediate
5469793f3fe5SMatthew G. Knepley 
5470793f3fe5SMatthew G. Knepley .seealso: DMPLEX, DMPlexGetDepthStratum(), DMPlexGetHeightStratum()
5471793f3fe5SMatthew G. Knepley @*/
5472793f3fe5SMatthew G. Knepley PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd)
5473793f3fe5SMatthew G. Knepley {
5474793f3fe5SMatthew G. Knepley   PetscInt       d;
5475793f3fe5SMatthew G. Knepley   PetscErrorCode ierr;
5476793f3fe5SMatthew G. Knepley 
5477793f3fe5SMatthew G. Knepley   PetscFunctionBegin;
5478793f3fe5SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5479793f3fe5SMatthew G. Knepley   ierr = DMGetDimension(dm, &d);CHKERRQ(ierr);
5480793f3fe5SMatthew G. Knepley   if ((dim < 0) || (dim > d)) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %d 1", dim, d);
5481b9d85ea2SLisandro Dalcin   if (!dm->ops->getdimpoints) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "DM type %s does not implement DMGetDimPoints",((PetscObject)dm)->type_name);
5482793f3fe5SMatthew G. Knepley   ierr = (*dm->ops->getdimpoints)(dm, dim, pStart, pEnd);CHKERRQ(ierr);
5483793f3fe5SMatthew G. Knepley   PetscFunctionReturn(0);
5484793f3fe5SMatthew G. Knepley }
5485793f3fe5SMatthew G. Knepley 
54866636e97aSMatthew G Knepley /*@
54876636e97aSMatthew G Knepley   DMSetCoordinates - Sets into the DM a global vector that holds the coordinates
54886636e97aSMatthew G Knepley 
5489d083f849SBarry Smith   Collective on dm
54906636e97aSMatthew G Knepley 
54916636e97aSMatthew G Knepley   Input Parameters:
54926636e97aSMatthew G Knepley + dm - the DM
54936636e97aSMatthew G Knepley - c - coordinate vector
54946636e97aSMatthew G Knepley 
54952dd40e9bSPatrick Sanan   Notes:
54962dd40e9bSPatrick Sanan   The coordinates do include those for ghost points, which are in the local vector.
54972dd40e9bSPatrick Sanan 
54982dd40e9bSPatrick Sanan   The vector c should be destroyed by the caller.
54996636e97aSMatthew G Knepley 
55006636e97aSMatthew G Knepley   Level: intermediate
55016636e97aSMatthew G Knepley 
55022dd40e9bSPatrick Sanan .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
55036636e97aSMatthew G Knepley @*/
55046636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c)
55056636e97aSMatthew G Knepley {
55066636e97aSMatthew G Knepley   PetscErrorCode ierr;
55076636e97aSMatthew G Knepley 
55086636e97aSMatthew G Knepley   PetscFunctionBegin;
55096636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
55106636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
55116636e97aSMatthew G Knepley   ierr            = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
55126636e97aSMatthew G Knepley   ierr            = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
55136636e97aSMatthew G Knepley   dm->coordinates = c;
55146636e97aSMatthew G Knepley   ierr            = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
5515b64e0483SPeter Brune   ierr            = DMCoarsenHookAdd(dm,DMRestrictHook_Coordinates,NULL,NULL);CHKERRQ(ierr);
551603dadc2fSPeter Brune   ierr            = DMSubDomainHookAdd(dm,DMSubDomainHook_Coordinates,NULL,NULL);CHKERRQ(ierr);
55176636e97aSMatthew G Knepley   PetscFunctionReturn(0);
55186636e97aSMatthew G Knepley }
55196636e97aSMatthew G Knepley 
55206636e97aSMatthew G Knepley /*@
55216636e97aSMatthew G Knepley   DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates
55226636e97aSMatthew G Knepley 
55237058e716SVaclav Hapla   Not collective
55246636e97aSMatthew G Knepley 
55256636e97aSMatthew G Knepley    Input Parameters:
55266636e97aSMatthew G Knepley +  dm - the DM
55276636e97aSMatthew G Knepley -  c - coordinate vector
55286636e97aSMatthew G Knepley 
55292dd40e9bSPatrick Sanan   Notes:
55306636e97aSMatthew G Knepley   The coordinates of ghost points can be set using DMSetCoordinates()
55316636e97aSMatthew G Knepley   followed by DMGetCoordinatesLocal(). This is intended to enable the
55326636e97aSMatthew G Knepley   setting of ghost coordinates outside of the domain.
55336636e97aSMatthew G Knepley 
55342dd40e9bSPatrick Sanan   The vector c should be destroyed by the caller.
55352dd40e9bSPatrick Sanan 
55366636e97aSMatthew G Knepley   Level: intermediate
55376636e97aSMatthew G Knepley 
55386636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM()
55396636e97aSMatthew G Knepley @*/
55406636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c)
55416636e97aSMatthew G Knepley {
55426636e97aSMatthew G Knepley   PetscErrorCode ierr;
55436636e97aSMatthew G Knepley 
55446636e97aSMatthew G Knepley   PetscFunctionBegin;
55456636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
55466636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
55476636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
55486636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
55498865f1eaSKarl Rupp 
55506636e97aSMatthew G Knepley   dm->coordinatesLocal = c;
55518865f1eaSKarl Rupp 
55526636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
55536636e97aSMatthew G Knepley   PetscFunctionReturn(0);
55546636e97aSMatthew G Knepley }
55556636e97aSMatthew G Knepley 
55566636e97aSMatthew G Knepley /*@
55576636e97aSMatthew G Knepley   DMGetCoordinates - Gets a global vector with the coordinates associated with the DM.
55586636e97aSMatthew G Knepley 
5559d083f849SBarry Smith   Collective on dm
55606636e97aSMatthew G Knepley 
55616636e97aSMatthew G Knepley   Input Parameter:
55626636e97aSMatthew G Knepley . dm - the DM
55636636e97aSMatthew G Knepley 
55646636e97aSMatthew G Knepley   Output Parameter:
55656636e97aSMatthew G Knepley . c - global coordinate vector
55666636e97aSMatthew G Knepley 
55676636e97aSMatthew G Knepley   Note:
55686636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
55696636e97aSMatthew G Knepley 
55706636e97aSMatthew G Knepley   Each process has only the local coordinates (does NOT have the ghost coordinates).
55716636e97aSMatthew G Knepley 
55726636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
55736636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
55746636e97aSMatthew G Knepley 
55756636e97aSMatthew G Knepley   Level: intermediate
55766636e97aSMatthew G Knepley 
55776636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
55786636e97aSMatthew G Knepley @*/
55796636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c)
55806636e97aSMatthew G Knepley {
55816636e97aSMatthew G Knepley   PetscErrorCode ierr;
55826636e97aSMatthew G Knepley 
55836636e97aSMatthew G Knepley   PetscFunctionBegin;
55846636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
55856636e97aSMatthew G Knepley   PetscValidPointer(c,2);
55861f588964SMatthew G Knepley   if (!dm->coordinates && dm->coordinatesLocal) {
55870298fd71SBarry Smith     DM        cdm = NULL;
55881970a576SMatthew G. Knepley     PetscBool localized;
55896636e97aSMatthew G Knepley 
55906636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
55916636e97aSMatthew G Knepley     ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr);
55921970a576SMatthew G. Knepley     ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
55931970a576SMatthew G. Knepley     /* Block size is not correctly set by CreateGlobalVector() if coordinates are localized */
55941970a576SMatthew G. Knepley     if (localized) {
55951970a576SMatthew G. Knepley       PetscInt cdim;
55961970a576SMatthew G. Knepley 
55971970a576SMatthew G. Knepley       ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
55981970a576SMatthew G. Knepley       ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr);
55991970a576SMatthew G. Knepley     }
56006636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr);
56016636e97aSMatthew G Knepley     ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
56026636e97aSMatthew G Knepley     ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
56036636e97aSMatthew G Knepley   }
56046636e97aSMatthew G Knepley   *c = dm->coordinates;
56056636e97aSMatthew G Knepley   PetscFunctionReturn(0);
56066636e97aSMatthew G Knepley }
56076636e97aSMatthew G Knepley 
56086636e97aSMatthew G Knepley /*@
560981e9a530SVaclav Hapla   DMGetCoordinatesLocalSetUp - Prepares a local vector of coordinates, so that DMGetCoordinatesLocalNoncollective() can be used as non-collective afterwards.
561081e9a530SVaclav Hapla 
5611d083f849SBarry Smith   Collective on dm
561281e9a530SVaclav Hapla 
561381e9a530SVaclav Hapla   Input Parameter:
561481e9a530SVaclav Hapla . dm - the DM
561581e9a530SVaclav Hapla 
561681e9a530SVaclav Hapla   Level: advanced
561781e9a530SVaclav Hapla 
561881e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalNoncollective()
561981e9a530SVaclav Hapla @*/
562081e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalSetUp(DM dm)
562181e9a530SVaclav Hapla {
562281e9a530SVaclav Hapla   PetscErrorCode ierr;
562381e9a530SVaclav Hapla 
562481e9a530SVaclav Hapla   PetscFunctionBegin;
562581e9a530SVaclav Hapla   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
562681e9a530SVaclav Hapla   if (!dm->coordinatesLocal && dm->coordinates) {
56271970a576SMatthew G. Knepley     DM        cdm = NULL;
56281970a576SMatthew G. Knepley     PetscBool localized;
56291970a576SMatthew G. Knepley 
563081e9a530SVaclav Hapla     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
563181e9a530SVaclav Hapla     ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr);
56321970a576SMatthew G. Knepley     ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
56331970a576SMatthew G. Knepley     /* Block size is not correctly set by CreateLocalVector() if coordinates are localized */
56341970a576SMatthew G. Knepley     if (localized) {
56351970a576SMatthew G. Knepley       PetscInt cdim;
56361970a576SMatthew G. Knepley 
56371970a576SMatthew G. Knepley       ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
56381970a576SMatthew G. Knepley       ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr);
56391970a576SMatthew G. Knepley     }
564081e9a530SVaclav Hapla     ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr);
564181e9a530SVaclav Hapla     ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
564281e9a530SVaclav Hapla     ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
564381e9a530SVaclav Hapla   }
564481e9a530SVaclav Hapla   PetscFunctionReturn(0);
564581e9a530SVaclav Hapla }
564681e9a530SVaclav Hapla 
564781e9a530SVaclav Hapla /*@
56486636e97aSMatthew G Knepley   DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM.
56496636e97aSMatthew G Knepley 
5650d083f849SBarry Smith   Collective on dm
56516636e97aSMatthew G Knepley 
56526636e97aSMatthew G Knepley   Input Parameter:
56536636e97aSMatthew G Knepley . dm - the DM
56546636e97aSMatthew G Knepley 
56556636e97aSMatthew G Knepley   Output Parameter:
56566636e97aSMatthew G Knepley . c - coordinate vector
56576636e97aSMatthew G Knepley 
56586636e97aSMatthew G Knepley   Note:
56596636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
56606636e97aSMatthew G Knepley 
56616636e97aSMatthew G Knepley   Each process has the local and ghost coordinates
56626636e97aSMatthew G Knepley 
56636636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
56646636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
56656636e97aSMatthew G Knepley 
56666636e97aSMatthew G Knepley   Level: intermediate
56676636e97aSMatthew G Knepley 
566881e9a530SVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM(), DMGetCoordinatesLocalNoncollective()
56696636e97aSMatthew G Knepley @*/
56706636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c)
56716636e97aSMatthew G Knepley {
56726636e97aSMatthew G Knepley   PetscErrorCode ierr;
56736636e97aSMatthew G Knepley 
56746636e97aSMatthew G Knepley   PetscFunctionBegin;
56756636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
56766636e97aSMatthew G Knepley   PetscValidPointer(c,2);
567781e9a530SVaclav Hapla   ierr = DMGetCoordinatesLocalSetUp(dm);CHKERRQ(ierr);
56786636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
56796636e97aSMatthew G Knepley   PetscFunctionReturn(0);
56806636e97aSMatthew G Knepley }
56816636e97aSMatthew G Knepley 
568281e9a530SVaclav Hapla /*@
568381e9a530SVaclav Hapla   DMGetCoordinatesLocalNoncollective - Non-collective version of DMGetCoordinatesLocal(). Fails if global coordinates have been set and DMGetCoordinatesLocalSetUp() not called.
568481e9a530SVaclav Hapla 
568581e9a530SVaclav Hapla   Not collective
568681e9a530SVaclav Hapla 
568781e9a530SVaclav Hapla   Input Parameter:
568881e9a530SVaclav Hapla . dm - the DM
568981e9a530SVaclav Hapla 
569081e9a530SVaclav Hapla   Output Parameter:
569181e9a530SVaclav Hapla . c - coordinate vector
569281e9a530SVaclav Hapla 
569381e9a530SVaclav Hapla   Level: advanced
569481e9a530SVaclav Hapla 
569581e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalSetUp(), DMGetCoordinatesLocal(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
569681e9a530SVaclav Hapla @*/
569781e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalNoncollective(DM dm, Vec *c)
569881e9a530SVaclav Hapla {
569981e9a530SVaclav Hapla   PetscFunctionBegin;
570081e9a530SVaclav Hapla   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
570181e9a530SVaclav Hapla   PetscValidPointer(c,2);
570281e9a530SVaclav Hapla   if (!dm->coordinatesLocal && dm->coordinates) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called");
57036636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
57046636e97aSMatthew G Knepley   PetscFunctionReturn(0);
57056636e97aSMatthew G Knepley }
57066636e97aSMatthew G Knepley 
57072db98f8dSVaclav Hapla /*@
57082db98f8dSVaclav Hapla   DMGetCoordinatesLocalTuple - Gets a local vector with the coordinates of specified points and section describing its layout.
57092db98f8dSVaclav Hapla 
57102db98f8dSVaclav Hapla   Not collective
57112db98f8dSVaclav Hapla 
57122db98f8dSVaclav Hapla   Input Parameter:
57132db98f8dSVaclav Hapla + dm - the DM
57142db98f8dSVaclav Hapla - p - the IS of points whose coordinates will be returned
57152db98f8dSVaclav Hapla 
57162db98f8dSVaclav Hapla   Output Parameter:
57172db98f8dSVaclav Hapla + pCoordSection - the PetscSection describing the layout of pCoord, i.e. each point corresponds to one point in p, and DOFs correspond to coordinates
57182db98f8dSVaclav Hapla - pCoord - the Vec with coordinates of points in p
57192db98f8dSVaclav Hapla 
57202db98f8dSVaclav Hapla   Note:
57212db98f8dSVaclav Hapla   DMGetCoordinatesLocalSetUp() must be called first. This function employs DMGetCoordinatesLocalNoncollective() so it is not collective.
57222db98f8dSVaclav Hapla 
57232db98f8dSVaclav Hapla   This creates a new vector, so the user SHOULD destroy this vector
57242db98f8dSVaclav Hapla 
57252db98f8dSVaclav Hapla   Each process has the local and ghost coordinates
57262db98f8dSVaclav Hapla 
57272db98f8dSVaclav Hapla   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
57282db98f8dSVaclav Hapla   and (x_0,y_0,z_0,x_1,y_1,z_1...)
57292db98f8dSVaclav Hapla 
57302db98f8dSVaclav Hapla   Level: advanced
57312db98f8dSVaclav Hapla 
57322db98f8dSVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinatesLocal(), DMGetCoordinatesLocalNoncollective(), DMGetCoordinatesLocalSetUp(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
57332db98f8dSVaclav Hapla @*/
57342db98f8dSVaclav Hapla PetscErrorCode DMGetCoordinatesLocalTuple(DM dm, IS p, PetscSection *pCoordSection, Vec *pCoord)
57352db98f8dSVaclav Hapla {
57362db98f8dSVaclav Hapla   PetscSection        cs, newcs;
57372db98f8dSVaclav Hapla   Vec                 coords;
57382db98f8dSVaclav Hapla   const PetscScalar   *arr;
57392db98f8dSVaclav Hapla   PetscScalar         *newarr=NULL;
57402db98f8dSVaclav Hapla   PetscInt            n;
57412db98f8dSVaclav Hapla   PetscErrorCode      ierr;
57422db98f8dSVaclav Hapla 
57432db98f8dSVaclav Hapla   PetscFunctionBegin;
57442db98f8dSVaclav Hapla   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
57452db98f8dSVaclav Hapla   PetscValidHeaderSpecific(p, IS_CLASSID, 2);
57462db98f8dSVaclav Hapla   if (pCoordSection) PetscValidPointer(pCoordSection, 3);
57472db98f8dSVaclav Hapla   if (pCoord) PetscValidPointer(pCoord, 4);
57482db98f8dSVaclav Hapla   if (!dm->coordinatesLocal) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called or coordinates not set");
57491bb6d2a8SBarry Smith   if (!dm->coordinateDM || !dm->coordinateDM->localSection) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM not supported");
57501bb6d2a8SBarry Smith   cs = dm->coordinateDM->localSection;
57512db98f8dSVaclav Hapla   coords = dm->coordinatesLocal;
57522db98f8dSVaclav Hapla   ierr = VecGetArrayRead(coords, &arr);CHKERRQ(ierr);
57532db98f8dSVaclav Hapla   ierr = PetscSectionExtractDofsFromArray(cs, MPIU_SCALAR, arr, p, &newcs, pCoord ? ((void**)&newarr) : NULL);CHKERRQ(ierr);
57542db98f8dSVaclav Hapla   ierr = VecRestoreArrayRead(coords, &arr);CHKERRQ(ierr);
57552db98f8dSVaclav Hapla   if (pCoord) {
57562db98f8dSVaclav Hapla     ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr);
57572db98f8dSVaclav Hapla     /* set array in two steps to mimic PETSC_OWN_POINTER */
57582db98f8dSVaclav Hapla     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)p), 1, n, NULL, pCoord);CHKERRQ(ierr);
57592db98f8dSVaclav Hapla     ierr = VecReplaceArray(*pCoord, newarr);CHKERRQ(ierr);
5760ad9ac99dSVaclav Hapla   } else {
5761ad9ac99dSVaclav Hapla     ierr = PetscFree(newarr);CHKERRQ(ierr);
57622db98f8dSVaclav Hapla   }
5763ad9ac99dSVaclav Hapla   if (pCoordSection) {*pCoordSection = newcs;}
5764ad9ac99dSVaclav Hapla   else               {ierr = PetscSectionDestroy(&newcs);CHKERRQ(ierr);}
57652db98f8dSVaclav Hapla   PetscFunctionReturn(0);
57662db98f8dSVaclav Hapla }
57672db98f8dSVaclav Hapla 
5768f19dbd58SToby Isaac PetscErrorCode DMGetCoordinateField(DM dm, DMField *field)
5769f19dbd58SToby Isaac {
5770f19dbd58SToby Isaac   PetscErrorCode ierr;
5771f19dbd58SToby Isaac 
5772f19dbd58SToby Isaac   PetscFunctionBegin;
5773f19dbd58SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5774f19dbd58SToby Isaac   PetscValidPointer(field,2);
5775f19dbd58SToby Isaac   if (!dm->coordinateField) {
5776f19dbd58SToby Isaac     if (dm->ops->createcoordinatefield) {
5777f19dbd58SToby Isaac       ierr = (*dm->ops->createcoordinatefield)(dm,&dm->coordinateField);CHKERRQ(ierr);
5778f19dbd58SToby Isaac     }
5779f19dbd58SToby Isaac   }
5780f19dbd58SToby Isaac   *field = dm->coordinateField;
5781f19dbd58SToby Isaac   PetscFunctionReturn(0);
5782f19dbd58SToby Isaac }
5783f19dbd58SToby Isaac 
5784f19dbd58SToby Isaac PetscErrorCode DMSetCoordinateField(DM dm, DMField field)
5785f19dbd58SToby Isaac {
5786f19dbd58SToby Isaac   PetscErrorCode ierr;
5787f19dbd58SToby Isaac 
5788f19dbd58SToby Isaac   PetscFunctionBegin;
5789f19dbd58SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5790f19dbd58SToby Isaac   if (field) PetscValidHeaderSpecific(field,DMFIELD_CLASSID,2);
5791c4e6da2cSBarry Smith   ierr = PetscObjectReference((PetscObject)field);CHKERRQ(ierr);
5792f19dbd58SToby Isaac   ierr = DMFieldDestroy(&dm->coordinateField);CHKERRQ(ierr);
5793f19dbd58SToby Isaac   dm->coordinateField = field;
5794f19dbd58SToby Isaac   PetscFunctionReturn(0);
5795f19dbd58SToby Isaac }
5796f19dbd58SToby Isaac 
57976636e97aSMatthew G Knepley /*@
57981cfe2091SMatthew G. Knepley   DMGetCoordinateDM - Gets the DM that prescribes coordinate layout and scatters between global and local coordinates
57996636e97aSMatthew G Knepley 
5800d083f849SBarry Smith   Collective on dm
58016636e97aSMatthew G Knepley 
58026636e97aSMatthew G Knepley   Input Parameter:
58036636e97aSMatthew G Knepley . dm - the DM
58046636e97aSMatthew G Knepley 
58056636e97aSMatthew G Knepley   Output Parameter:
58066636e97aSMatthew G Knepley . cdm - coordinate DM
58076636e97aSMatthew G Knepley 
58086636e97aSMatthew G Knepley   Level: intermediate
58096636e97aSMatthew G Knepley 
58101cfe2091SMatthew G. Knepley .seealso: DMSetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
58116636e97aSMatthew G Knepley @*/
58126636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm)
58136636e97aSMatthew G Knepley {
58146636e97aSMatthew G Knepley   PetscErrorCode ierr;
58156636e97aSMatthew G Knepley 
58166636e97aSMatthew G Knepley   PetscFunctionBegin;
58176636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
58186636e97aSMatthew G Knepley   PetscValidPointer(cdm,2);
58196636e97aSMatthew G Knepley   if (!dm->coordinateDM) {
5820308f8a94SToby Isaac     DM cdm;
5821308f8a94SToby Isaac 
582282f516ccSBarry Smith     if (!dm->ops->createcoordinatedm) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unable to create coordinates for this DM");
5823308f8a94SToby Isaac     ierr = (*dm->ops->createcoordinatedm)(dm, &cdm);CHKERRQ(ierr);
5824308f8a94SToby Isaac     /* Just in case the DM sets the coordinate DM when creating it (DMP4est can do this, because it may not setup
5825308f8a94SToby Isaac      * until the call to CreateCoordinateDM) */
5826308f8a94SToby Isaac     ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr);
5827308f8a94SToby Isaac     dm->coordinateDM = cdm;
58286636e97aSMatthew G Knepley   }
58296636e97aSMatthew G Knepley   *cdm = dm->coordinateDM;
58306636e97aSMatthew G Knepley   PetscFunctionReturn(0);
58316636e97aSMatthew G Knepley }
5832e87bb0d3SMatthew G Knepley 
58331cfe2091SMatthew G. Knepley /*@
58341cfe2091SMatthew G. Knepley   DMSetCoordinateDM - Sets the DM that prescribes coordinate layout and scatters between global and local coordinates
58351cfe2091SMatthew G. Knepley 
5836d083f849SBarry Smith   Logically Collective on dm
58371cfe2091SMatthew G. Knepley 
58381cfe2091SMatthew G. Knepley   Input Parameters:
58391cfe2091SMatthew G. Knepley + dm - the DM
58401cfe2091SMatthew G. Knepley - cdm - coordinate DM
58411cfe2091SMatthew G. Knepley 
58421cfe2091SMatthew G. Knepley   Level: intermediate
58431cfe2091SMatthew G. Knepley 
58441cfe2091SMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
58451cfe2091SMatthew G. Knepley @*/
58461cfe2091SMatthew G. Knepley PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm)
58471cfe2091SMatthew G. Knepley {
58481cfe2091SMatthew G. Knepley   PetscErrorCode ierr;
58491cfe2091SMatthew G. Knepley 
58501cfe2091SMatthew G. Knepley   PetscFunctionBegin;
58511cfe2091SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
58521cfe2091SMatthew G. Knepley   PetscValidHeaderSpecific(cdm,DM_CLASSID,2);
5853f26b38b9SToby Isaac   ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr);
58541cfe2091SMatthew G. Knepley   ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr);
58551cfe2091SMatthew G. Knepley   dm->coordinateDM = cdm;
58561cfe2091SMatthew G. Knepley   PetscFunctionReturn(0);
58571cfe2091SMatthew G. Knepley }
58581cfe2091SMatthew G. Knepley 
585946e270d4SMatthew G. Knepley /*@
586046e270d4SMatthew G. Knepley   DMGetCoordinateDim - Retrieve the dimension of embedding space for coordinate values.
586146e270d4SMatthew G. Knepley 
586246e270d4SMatthew G. Knepley   Not Collective
586346e270d4SMatthew G. Knepley 
586446e270d4SMatthew G. Knepley   Input Parameter:
586546e270d4SMatthew G. Knepley . dm - The DM object
586646e270d4SMatthew G. Knepley 
586746e270d4SMatthew G. Knepley   Output Parameter:
586846e270d4SMatthew G. Knepley . dim - The embedding dimension
586946e270d4SMatthew G. Knepley 
587046e270d4SMatthew G. Knepley   Level: intermediate
587146e270d4SMatthew G. Knepley 
587292fd8e1eSJed Brown .seealso: DMSetCoordinateDim(), DMGetCoordinateSection(), DMGetCoordinateDM(), DMGetLocalSection(), DMSetLocalSection()
587346e270d4SMatthew G. Knepley @*/
587446e270d4SMatthew G. Knepley PetscErrorCode DMGetCoordinateDim(DM dm, PetscInt *dim)
587546e270d4SMatthew G. Knepley {
587646e270d4SMatthew G. Knepley   PetscFunctionBegin;
587746e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5878534a8f05SLisandro Dalcin   PetscValidIntPointer(dim, 2);
58799a9a41abSToby Isaac   if (dm->dimEmbed == PETSC_DEFAULT) {
58809a9a41abSToby Isaac     dm->dimEmbed = dm->dim;
58819a9a41abSToby Isaac   }
588246e270d4SMatthew G. Knepley   *dim = dm->dimEmbed;
588346e270d4SMatthew G. Knepley   PetscFunctionReturn(0);
588446e270d4SMatthew G. Knepley }
588546e270d4SMatthew G. Knepley 
588646e270d4SMatthew G. Knepley /*@
588746e270d4SMatthew G. Knepley   DMSetCoordinateDim - Set the dimension of the embedding space for coordinate values.
588846e270d4SMatthew G. Knepley 
588946e270d4SMatthew G. Knepley   Not Collective
589046e270d4SMatthew G. Knepley 
589146e270d4SMatthew G. Knepley   Input Parameters:
589246e270d4SMatthew G. Knepley + dm  - The DM object
589346e270d4SMatthew G. Knepley - dim - The embedding dimension
589446e270d4SMatthew G. Knepley 
589546e270d4SMatthew G. Knepley   Level: intermediate
589646e270d4SMatthew G. Knepley 
589792fd8e1eSJed Brown .seealso: DMGetCoordinateDim(), DMSetCoordinateSection(), DMGetCoordinateSection(), DMGetLocalSection(), DMSetLocalSection()
589846e270d4SMatthew G. Knepley @*/
589946e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateDim(DM dm, PetscInt dim)
590046e270d4SMatthew G. Knepley {
5901e5e52638SMatthew G. Knepley   PetscDS        ds;
5902f17e8794SMatthew G. Knepley   PetscErrorCode ierr;
5903f17e8794SMatthew G. Knepley 
590446e270d4SMatthew G. Knepley   PetscFunctionBegin;
590546e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
590646e270d4SMatthew G. Knepley   dm->dimEmbed = dim;
5907e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
5908e5e52638SMatthew G. Knepley   ierr = PetscDSSetCoordinateDimension(ds, dim);CHKERRQ(ierr);
590946e270d4SMatthew G. Knepley   PetscFunctionReturn(0);
591046e270d4SMatthew G. Knepley }
591146e270d4SMatthew G. Knepley 
5912e8abe2deSMatthew G. Knepley /*@
5913e8abe2deSMatthew G. Knepley   DMGetCoordinateSection - Retrieve the layout of coordinate values over the mesh.
5914e8abe2deSMatthew G. Knepley 
5915d083f849SBarry Smith   Collective on dm
5916e8abe2deSMatthew G. Knepley 
5917e8abe2deSMatthew G. Knepley   Input Parameter:
5918e8abe2deSMatthew G. Knepley . dm - The DM object
5919e8abe2deSMatthew G. Knepley 
5920e8abe2deSMatthew G. Knepley   Output Parameter:
5921e8abe2deSMatthew G. Knepley . section - The PetscSection object
5922e8abe2deSMatthew G. Knepley 
5923e8abe2deSMatthew G. Knepley   Level: intermediate
5924e8abe2deSMatthew G. Knepley 
592592fd8e1eSJed Brown .seealso: DMGetCoordinateDM(), DMGetLocalSection(), DMSetLocalSection()
5926e8abe2deSMatthew G. Knepley @*/
5927e8abe2deSMatthew G. Knepley PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section)
5928e8abe2deSMatthew G. Knepley {
5929e8abe2deSMatthew G. Knepley   DM             cdm;
5930e8abe2deSMatthew G. Knepley   PetscErrorCode ierr;
5931e8abe2deSMatthew G. Knepley 
5932e8abe2deSMatthew G. Knepley   PetscFunctionBegin;
5933e8abe2deSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5934e8abe2deSMatthew G. Knepley   PetscValidPointer(section, 2);
5935e8abe2deSMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
593692fd8e1eSJed Brown   ierr = DMGetLocalSection(cdm, section);CHKERRQ(ierr);
5937e8abe2deSMatthew G. Knepley   PetscFunctionReturn(0);
5938e8abe2deSMatthew G. Knepley }
5939e8abe2deSMatthew G. Knepley 
5940e8abe2deSMatthew G. Knepley /*@
5941e8abe2deSMatthew G. Knepley   DMSetCoordinateSection - Set the layout of coordinate values over the mesh.
5942e8abe2deSMatthew G. Knepley 
5943e8abe2deSMatthew G. Knepley   Not Collective
5944e8abe2deSMatthew G. Knepley 
5945e8abe2deSMatthew G. Knepley   Input Parameters:
5946e8abe2deSMatthew G. Knepley + dm      - The DM object
594746e270d4SMatthew G. Knepley . dim     - The embedding dimension, or PETSC_DETERMINE
5948e8abe2deSMatthew G. Knepley - section - The PetscSection object
5949e8abe2deSMatthew G. Knepley 
5950e8abe2deSMatthew G. Knepley   Level: intermediate
5951e8abe2deSMatthew G. Knepley 
595292fd8e1eSJed Brown .seealso: DMGetCoordinateSection(), DMGetLocalSection(), DMSetLocalSection()
5953e8abe2deSMatthew G. Knepley @*/
595446e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateSection(DM dm, PetscInt dim, PetscSection section)
5955e8abe2deSMatthew G. Knepley {
5956e8abe2deSMatthew G. Knepley   DM             cdm;
5957e8abe2deSMatthew G. Knepley   PetscErrorCode ierr;
5958e8abe2deSMatthew G. Knepley 
5959e8abe2deSMatthew G. Knepley   PetscFunctionBegin;
5960e8abe2deSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
596146e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,3);
5962e8abe2deSMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
596392fd8e1eSJed Brown   ierr = DMSetLocalSection(cdm, section);CHKERRQ(ierr);
596446e270d4SMatthew G. Knepley   if (dim == PETSC_DETERMINE) {
59654c1069a6SMatthew G. Knepley     PetscInt d = PETSC_DEFAULT;
596646e270d4SMatthew G. Knepley     PetscInt pStart, pEnd, vStart, vEnd, v, dd;
596746e270d4SMatthew G. Knepley 
596846e270d4SMatthew G. Knepley     ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
596946e270d4SMatthew G. Knepley     ierr = DMGetDimPoints(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
597046e270d4SMatthew G. Knepley     pStart = PetscMax(vStart, pStart);
597146e270d4SMatthew G. Knepley     pEnd   = PetscMin(vEnd, pEnd);
597246e270d4SMatthew G. Knepley     for (v = pStart; v < pEnd; ++v) {
597346e270d4SMatthew G. Knepley       ierr = PetscSectionGetDof(section, v, &dd);CHKERRQ(ierr);
597446e270d4SMatthew G. Knepley       if (dd) {d = dd; break;}
597546e270d4SMatthew G. Knepley     }
5976ebfe4b0dSMatthew G. Knepley     if (d >= 0) {ierr = DMSetCoordinateDim(dm, d);CHKERRQ(ierr);}
597746e270d4SMatthew G. Knepley   }
5978e8abe2deSMatthew G. Knepley   PetscFunctionReturn(0);
5979e8abe2deSMatthew G. Knepley }
5980e8abe2deSMatthew G. Knepley 
59815dc8c3f7SMatthew G. Knepley /*@C
598290b157c4SStefano Zampini   DMGetPeriodicity - Get the description of mesh periodicity
59835dc8c3f7SMatthew G. Knepley 
59845dc8c3f7SMatthew G. Knepley   Input Parameters:
598590b157c4SStefano Zampini . dm      - The DM object
598690b157c4SStefano Zampini 
598790b157c4SStefano Zampini   Output Parameters:
598890b157c4SStefano Zampini + per     - Whether the DM is periodic or not
59895dc8c3f7SMatthew G. Knepley . maxCell - Over distances greater than this, we can assume a point has crossed over to another sheet, when trying to localize cell coordinates
59905dc8c3f7SMatthew G. Knepley . L       - If we assume the mesh is a torus, this is the length of each coordinate
59915dc8c3f7SMatthew G. Knepley - bd      - This describes the type of periodicity in each topological dimension
59925dc8c3f7SMatthew G. Knepley 
59935dc8c3f7SMatthew G. Knepley   Level: developer
59945dc8c3f7SMatthew G. Knepley 
59955dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity()
59965dc8c3f7SMatthew G. Knepley @*/
599790b157c4SStefano Zampini PetscErrorCode DMGetPeriodicity(DM dm, PetscBool *per, const PetscReal **maxCell, const PetscReal **L, const DMBoundaryType **bd)
5998c6b900c6SMatthew G. Knepley {
5999c6b900c6SMatthew G. Knepley   PetscFunctionBegin;
6000c6b900c6SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
600190b157c4SStefano Zampini   if (per)     *per     = dm->periodic;
6002c6b900c6SMatthew G. Knepley   if (L)       *L       = dm->L;
6003c6b900c6SMatthew G. Knepley   if (maxCell) *maxCell = dm->maxCell;
60045dc8c3f7SMatthew G. Knepley   if (bd)      *bd      = dm->bdtype;
6005c6b900c6SMatthew G. Knepley   PetscFunctionReturn(0);
6006c6b900c6SMatthew G. Knepley }
6007c6b900c6SMatthew G. Knepley 
60085dc8c3f7SMatthew G. Knepley /*@C
60095dc8c3f7SMatthew G. Knepley   DMSetPeriodicity - Set the description of mesh periodicity
60105dc8c3f7SMatthew G. Knepley 
60115dc8c3f7SMatthew G. Knepley   Input Parameters:
60125dc8c3f7SMatthew G. Knepley + dm      - The DM object
601390b157c4SStefano Zampini . per     - Whether the DM is periodic or not. If maxCell is not provided, coordinates need to be localized
60145dc8c3f7SMatthew G. Knepley . maxCell - Over distances greater than this, we can assume a point has crossed over to another sheet, when trying to localize cell coordinates
60155dc8c3f7SMatthew G. Knepley . L       - If we assume the mesh is a torus, this is the length of each coordinate
60165dc8c3f7SMatthew G. Knepley - bd      - This describes the type of periodicity in each topological dimension
60175dc8c3f7SMatthew G. Knepley 
60185dc8c3f7SMatthew G. Knepley   Level: developer
60195dc8c3f7SMatthew G. Knepley 
60205dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity()
60215dc8c3f7SMatthew G. Knepley @*/
602290b157c4SStefano Zampini PetscErrorCode DMSetPeriodicity(DM dm, PetscBool per, const PetscReal maxCell[], const PetscReal L[], const DMBoundaryType bd[])
6023c6b900c6SMatthew G. Knepley {
6024c6b900c6SMatthew G. Knepley   PetscInt       dim, d;
6025c6b900c6SMatthew G. Knepley   PetscErrorCode ierr;
6026c6b900c6SMatthew G. Knepley 
6027c6b900c6SMatthew G. Knepley   PetscFunctionBegin;
6028c6b900c6SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
602990b157c4SStefano Zampini   PetscValidLogicalCollectiveBool(dm,per,2);
603090b157c4SStefano Zampini   if (maxCell) {
6031534a8f05SLisandro Dalcin     PetscValidRealPointer(maxCell,3);
6032534a8f05SLisandro Dalcin     PetscValidRealPointer(L,4);
603390b157c4SStefano Zampini     PetscValidPointer(bd,5);
603490b157c4SStefano Zampini   }
60355dc8c3f7SMatthew G. Knepley   ierr = PetscFree3(dm->L,dm->maxCell,dm->bdtype);CHKERRQ(ierr);
60365dc8c3f7SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
603790b157c4SStefano Zampini   if (maxCell) {
60385dc8c3f7SMatthew G. Knepley     ierr = PetscMalloc3(dim,&dm->L,dim,&dm->maxCell,dim,&dm->bdtype);CHKERRQ(ierr);
60395dc8c3f7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {dm->L[d] = L[d]; dm->maxCell[d] = maxCell[d]; dm->bdtype[d] = bd[d];}
604090b157c4SStefano Zampini   }
6041072d7d67SStefano Zampini   dm->periodic = per;
6042c6b900c6SMatthew G. Knepley   PetscFunctionReturn(0);
6043c6b900c6SMatthew G. Knepley }
6044c6b900c6SMatthew G. Knepley 
60452e17dfb7SMatthew G. Knepley /*@
60462e17dfb7SMatthew G. Knepley   DMLocalizeCoordinate - If a mesh is periodic (a torus with lengths L_i, some of which can be infinite), project the coordinate onto [0, L_i) in each dimension.
60472e17dfb7SMatthew G. Knepley 
60482e17dfb7SMatthew G. Knepley   Input Parameters:
60492e17dfb7SMatthew G. Knepley + dm     - The DM
605065da65dcSMatthew G. Knepley . in     - The input coordinate point (dim numbers)
605165da65dcSMatthew G. Knepley - endpoint - Include the endpoint L_i
60522e17dfb7SMatthew G. Knepley 
60532e17dfb7SMatthew G. Knepley   Output Parameter:
60542e17dfb7SMatthew G. Knepley . out - The localized coordinate point
60552e17dfb7SMatthew G. Knepley 
60562e17dfb7SMatthew G. Knepley   Level: developer
60572e17dfb7SMatthew G. Knepley 
60582e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate()
60592e17dfb7SMatthew G. Knepley @*/
606065da65dcSMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate(DM dm, const PetscScalar in[], PetscBool endpoint, PetscScalar out[])
60612e17dfb7SMatthew G. Knepley {
60622e17dfb7SMatthew G. Knepley   PetscInt       dim, d;
60632e17dfb7SMatthew G. Knepley   PetscErrorCode ierr;
60642e17dfb7SMatthew G. Knepley 
60652e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
60662e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr);
60672e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
60682e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] = in[d];
60692e17dfb7SMatthew G. Knepley   } else {
607065da65dcSMatthew G. Knepley     if (endpoint) {
607165da65dcSMatthew G. Knepley       for (d = 0; d < dim; ++d) {
6072da3333bfSMatthew G. Knepley         if ((PetscAbsReal(PetscRealPart(in[d])/dm->L[d] - PetscFloorReal(PetscRealPart(in[d])/dm->L[d])) < PETSC_SMALL) && (PetscRealPart(in[d])/dm->L[d] > PETSC_SMALL)) {
6073da3333bfSMatthew G. Knepley           out[d] = in[d] - dm->L[d]*(PetscFloorReal(PetscRealPart(in[d])/dm->L[d]) - 1);
607465da65dcSMatthew G. Knepley         } else {
6075da3333bfSMatthew G. Knepley           out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]);
607665da65dcSMatthew G. Knepley         }
607765da65dcSMatthew G. Knepley       }
607865da65dcSMatthew G. Knepley     } else {
60792e17dfb7SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
60801118d4bcSLisandro Dalcin         out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]);
60812e17dfb7SMatthew G. Knepley       }
60822e17dfb7SMatthew G. Knepley     }
608365da65dcSMatthew G. Knepley   }
60842e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
60852e17dfb7SMatthew G. Knepley }
60862e17dfb7SMatthew G. Knepley 
60872e17dfb7SMatthew G. Knepley /*
60882e17dfb7SMatthew G. Knepley   DMLocalizeCoordinate_Internal - If a mesh is periodic, and the input point is far from the anchor, pick the coordinate sheet of the torus which moves it closer.
60892e17dfb7SMatthew G. Knepley 
60902e17dfb7SMatthew G. Knepley   Input Parameters:
60912e17dfb7SMatthew G. Knepley + dm     - The DM
60922e17dfb7SMatthew G. Knepley . dim    - The spatial dimension
60932e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it
60942e17dfb7SMatthew G. Knepley - in     - The input coordinate point (dim numbers)
60952e17dfb7SMatthew G. Knepley 
60962e17dfb7SMatthew G. Knepley   Output Parameter:
60972e17dfb7SMatthew G. Knepley . out - The localized coordinate point
60982e17dfb7SMatthew G. Knepley 
60992e17dfb7SMatthew G. Knepley   Level: developer
61002e17dfb7SMatthew G. Knepley 
61012e17dfb7SMatthew G. Knepley   Note: This is meant to get a set of coordinates close to each other, as in a cell. The anchor is usually the one of the vertices on a containing cell
61022e17dfb7SMatthew G. Knepley 
61032e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate()
61042e17dfb7SMatthew G. Knepley */
61052e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[])
61062e17dfb7SMatthew G. Knepley {
61072e17dfb7SMatthew G. Knepley   PetscInt d;
61082e17dfb7SMatthew G. Knepley 
61092e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
61102e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
61112e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] = in[d];
61122e17dfb7SMatthew G. Knepley   } else {
61132e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
6114908eca10SMatthew G. Knepley       if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) {
61152e17dfb7SMatthew G. Knepley         out[d] = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d];
61162e17dfb7SMatthew G. Knepley       } else {
61172e17dfb7SMatthew G. Knepley         out[d] = in[d];
61182e17dfb7SMatthew G. Knepley       }
61192e17dfb7SMatthew G. Knepley     }
61202e17dfb7SMatthew G. Knepley   }
61212e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
61222e17dfb7SMatthew G. Knepley }
61232e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinateReal_Internal(DM dm, PetscInt dim, const PetscReal anchor[], const PetscReal in[], PetscReal out[])
61242e17dfb7SMatthew G. Knepley {
61252e17dfb7SMatthew G. Knepley   PetscInt d;
61262e17dfb7SMatthew G. Knepley 
61272e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
61282e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
61292e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] = in[d];
61302e17dfb7SMatthew G. Knepley   } else {
61312e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
6132908eca10SMatthew G. Knepley       if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsReal(anchor[d] - in[d]) > dm->maxCell[d])) {
61332e17dfb7SMatthew G. Knepley         out[d] = anchor[d] > in[d] ? dm->L[d] + in[d] : in[d] - dm->L[d];
61342e17dfb7SMatthew G. Knepley       } else {
61352e17dfb7SMatthew G. Knepley         out[d] = in[d];
61362e17dfb7SMatthew G. Knepley       }
61372e17dfb7SMatthew G. Knepley     }
61382e17dfb7SMatthew G. Knepley   }
61392e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
61402e17dfb7SMatthew G. Knepley }
61412e17dfb7SMatthew G. Knepley 
61422e17dfb7SMatthew G. Knepley /*
61432e17dfb7SMatthew G. Knepley   DMLocalizeAddCoordinate_Internal - If a mesh is periodic, and the input point is far from the anchor, pick the coordinate sheet of the torus which moves it closer.
61442e17dfb7SMatthew G. Knepley 
61452e17dfb7SMatthew G. Knepley   Input Parameters:
61462e17dfb7SMatthew G. Knepley + dm     - The DM
61472e17dfb7SMatthew G. Knepley . dim    - The spatial dimension
61482e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it
61492e17dfb7SMatthew G. Knepley . in     - The input coordinate delta (dim numbers)
61502e17dfb7SMatthew G. Knepley - out    - The input coordinate point (dim numbers)
61512e17dfb7SMatthew G. Knepley 
61522e17dfb7SMatthew G. Knepley   Output Parameter:
61532e17dfb7SMatthew G. Knepley . out    - The localized coordinate in + out
61542e17dfb7SMatthew G. Knepley 
61552e17dfb7SMatthew G. Knepley   Level: developer
61562e17dfb7SMatthew G. Knepley 
61572e17dfb7SMatthew G. Knepley   Note: This is meant to get a set of coordinates close to each other, as in a cell. The anchor is usually the one of the vertices on a containing cell
61582e17dfb7SMatthew G. Knepley 
61592e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeCoordinate()
61602e17dfb7SMatthew G. Knepley */
61612e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeAddCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[])
61622e17dfb7SMatthew G. Knepley {
61632e17dfb7SMatthew G. Knepley   PetscInt d;
61642e17dfb7SMatthew G. Knepley 
61652e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
61662e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
61672e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] += in[d];
61682e17dfb7SMatthew G. Knepley   } else {
61692e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
6170908eca10SMatthew G. Knepley       if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) {
61712e17dfb7SMatthew G. Knepley         out[d] += PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d];
61722e17dfb7SMatthew G. Knepley       } else {
61732e17dfb7SMatthew G. Knepley         out[d] += in[d];
61742e17dfb7SMatthew G. Knepley       }
61752e17dfb7SMatthew G. Knepley     }
61762e17dfb7SMatthew G. Knepley   }
61772e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
61782e17dfb7SMatthew G. Knepley }
61792e17dfb7SMatthew G. Knepley 
618036447a5eSToby Isaac /*@
61818f700142SStefano Zampini   DMGetCoordinatesLocalizedLocal - Check if the DM coordinates have been localized for cells on this process
61828f700142SStefano Zampini 
61838f700142SStefano Zampini   Not collective
618436447a5eSToby Isaac 
618536447a5eSToby Isaac   Input Parameter:
618636447a5eSToby Isaac . dm - The DM
618736447a5eSToby Isaac 
618836447a5eSToby Isaac   Output Parameter:
618936447a5eSToby Isaac   areLocalized - True if localized
619036447a5eSToby Isaac 
619136447a5eSToby Isaac   Level: developer
619236447a5eSToby Isaac 
61938f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMGetCoordinatesLocalized(), DMSetPeriodicity()
619436447a5eSToby Isaac @*/
61958f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalizedLocal(DM dm,PetscBool *areLocalized)
619636447a5eSToby Isaac {
619736447a5eSToby Isaac   DM             cdm;
619836447a5eSToby Isaac   PetscSection   coordSection;
619946a3a80fSLisandro Dalcin   PetscInt       cStart, cEnd, sStart, sEnd, c, dof;
620046a3a80fSLisandro Dalcin   PetscBool      isPlex, alreadyLocalized;
620136447a5eSToby Isaac   PetscErrorCode ierr;
620236447a5eSToby Isaac 
620336447a5eSToby Isaac   PetscFunctionBegin;
620436447a5eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6205534a8f05SLisandro Dalcin   PetscValidBoolPointer(areLocalized, 2);
62068b09590cSToby Isaac   *areLocalized = PETSC_FALSE;
620746a3a80fSLisandro Dalcin 
620836447a5eSToby Isaac   /* We need some generic way of refering to cells/vertices */
620936447a5eSToby Isaac   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
621046a3a80fSLisandro Dalcin   ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isPlex);CHKERRQ(ierr);
62119f7230bfSMatthew G. Knepley   if (!isPlex) PetscFunctionReturn(0);
621246a3a80fSLisandro Dalcin 
62139f7230bfSMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
621446a3a80fSLisandro Dalcin   ierr = DMPlexGetHeightStratum(cdm, 0, &cStart, &cEnd);CHKERRQ(ierr);
621536447a5eSToby Isaac   ierr = PetscSectionGetChart(coordSection, &sStart, &sEnd);CHKERRQ(ierr);
621636447a5eSToby Isaac   alreadyLocalized = PETSC_FALSE;
621746a3a80fSLisandro Dalcin   for (c = cStart; c < cEnd; ++c) {
621846a3a80fSLisandro Dalcin     if (c < sStart || c >= sEnd) continue;
621936447a5eSToby Isaac     ierr = PetscSectionGetDof(coordSection, c, &dof);CHKERRQ(ierr);
622046a3a80fSLisandro Dalcin     if (dof) { alreadyLocalized = PETSC_TRUE; break; }
622136447a5eSToby Isaac   }
62228f700142SStefano Zampini   *areLocalized = alreadyLocalized;
622336447a5eSToby Isaac   PetscFunctionReturn(0);
622436447a5eSToby Isaac }
622536447a5eSToby Isaac 
62268f700142SStefano Zampini /*@
62278f700142SStefano Zampini   DMGetCoordinatesLocalized - Check if the DM coordinates have been localized for cells
62288f700142SStefano Zampini 
62298f700142SStefano Zampini   Collective on dm
62308f700142SStefano Zampini 
62318f700142SStefano Zampini   Input Parameter:
62328f700142SStefano Zampini . dm - The DM
62338f700142SStefano Zampini 
62348f700142SStefano Zampini   Output Parameter:
62358f700142SStefano Zampini   areLocalized - True if localized
62368f700142SStefano Zampini 
62378f700142SStefano Zampini   Level: developer
62388f700142SStefano Zampini 
62398f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMSetPeriodicity(), DMGetCoordinatesLocalizedLocal()
62408f700142SStefano Zampini @*/
62418f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalized(DM dm,PetscBool *areLocalized)
62428f700142SStefano Zampini {
62438f700142SStefano Zampini   PetscBool      localized;
62448f700142SStefano Zampini   PetscErrorCode ierr;
62458f700142SStefano Zampini 
62468f700142SStefano Zampini   PetscFunctionBegin;
62478f700142SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6248534a8f05SLisandro Dalcin   PetscValidBoolPointer(areLocalized, 2);
62498f700142SStefano Zampini   ierr = DMGetCoordinatesLocalizedLocal(dm,&localized);CHKERRQ(ierr);
62508f700142SStefano Zampini   ierr = MPIU_Allreduce(&localized,areLocalized,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
62518f700142SStefano Zampini   PetscFunctionReturn(0);
62528f700142SStefano Zampini }
625336447a5eSToby Isaac 
62542e17dfb7SMatthew G. Knepley /*@
6255492b8470SStefano Zampini   DMLocalizeCoordinates - If a mesh is periodic, create local coordinates for cells having periodic faces
62562e17dfb7SMatthew G. Knepley 
62578f700142SStefano Zampini   Collective on dm
62588f700142SStefano Zampini 
62592e17dfb7SMatthew G. Knepley   Input Parameter:
62602e17dfb7SMatthew G. Knepley . dm - The DM
62612e17dfb7SMatthew G. Knepley 
62622e17dfb7SMatthew G. Knepley   Level: developer
62632e17dfb7SMatthew G. Knepley 
62648f700142SStefano Zampini .seealso: DMSetPeriodicity(), DMLocalizeCoordinate(), DMLocalizeAddCoordinate()
62652e17dfb7SMatthew G. Knepley @*/
62662e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinates(DM dm)
62672e17dfb7SMatthew G. Knepley {
62682e17dfb7SMatthew G. Knepley   DM             cdm;
62692e17dfb7SMatthew G. Knepley   PetscSection   coordSection, cSection;
62702e17dfb7SMatthew G. Knepley   Vec            coordinates,  cVec;
62713e922f36SToby Isaac   PetscScalar   *coords, *coords2, *anchor, *localized;
62723e922f36SToby Isaac   PetscInt       Nc, vStart, vEnd, v, sStart, sEnd, newStart = PETSC_MAX_INT, newEnd = PETSC_MIN_INT, dof, d, off, off2, bs, coordSize;
6273e0ae35bbSToby Isaac   PetscBool      alreadyLocalized, alreadyLocalizedGlobal;
62743e922f36SToby Isaac   PetscInt       maxHeight = 0, h;
62753e922f36SToby Isaac   PetscInt       *pStart = NULL, *pEnd = NULL;
62762e17dfb7SMatthew G. Knepley   PetscErrorCode ierr;
62772e17dfb7SMatthew G. Knepley 
62782e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
62792e17dfb7SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
628092c9c85fSStefano Zampini   if (!dm->periodic) PetscFunctionReturn(0);
6281f7cbd40bSStefano Zampini   ierr = DMGetCoordinatesLocalized(dm, &alreadyLocalized);CHKERRQ(ierr);
6282f7cbd40bSStefano Zampini   if (alreadyLocalized) PetscFunctionReturn(0);
6283f7cbd40bSStefano Zampini 
62842e17dfb7SMatthew G. Knepley   /* We need some generic way of refering to cells/vertices */
62852e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
62862e17dfb7SMatthew G. Knepley   {
62872e17dfb7SMatthew G. Knepley     PetscBool isplex;
62882e17dfb7SMatthew G. Knepley 
62892e17dfb7SMatthew G. Knepley     ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isplex);CHKERRQ(ierr);
62902e17dfb7SMatthew G. Knepley     if (isplex) {
62912e17dfb7SMatthew G. Knepley       ierr = DMPlexGetDepthStratum(cdm, 0, &vStart, &vEnd);CHKERRQ(ierr);
62923e922f36SToby Isaac       ierr = DMPlexGetMaxProjectionHeight(cdm,&maxHeight);CHKERRQ(ierr);
629369291d52SBarry Smith       ierr = DMGetWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr);
62943e922f36SToby Isaac       pEnd = &pStart[maxHeight + 1];
62953e922f36SToby Isaac       newStart = vStart;
62963e922f36SToby Isaac       newEnd   = vEnd;
62973e922f36SToby Isaac       for (h = 0; h <= maxHeight; h++) {
62983e922f36SToby Isaac         ierr = DMPlexGetHeightStratum(cdm, h, &pStart[h], &pEnd[h]);CHKERRQ(ierr);
62993e922f36SToby Isaac         newStart = PetscMin(newStart,pStart[h]);
63003e922f36SToby Isaac         newEnd   = PetscMax(newEnd,pEnd[h]);
63013e922f36SToby Isaac       }
63022e17dfb7SMatthew G. Knepley     } else SETERRQ(PetscObjectComm((PetscObject) cdm), PETSC_ERR_ARG_WRONG, "Coordinate localization requires a DMPLEX coordinate DM");
63032e17dfb7SMatthew G. Knepley   }
63042e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
630543eeeb2dSStefano Zampini   if (!coordinates) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Missing local coordinates vector");
63062e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
63073e922f36SToby Isaac   ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr);
6308e0ae35bbSToby Isaac   ierr = PetscSectionGetChart(coordSection,&sStart,&sEnd);CHKERRQ(ierr);
63093e922f36SToby Isaac 
63102e17dfb7SMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &cSection);CHKERRQ(ierr);
63112e17dfb7SMatthew G. Knepley   ierr = PetscSectionSetNumFields(cSection, 1);CHKERRQ(ierr);
63122e17dfb7SMatthew G. Knepley   ierr = PetscSectionGetFieldComponents(coordSection, 0, &Nc);CHKERRQ(ierr);
63132e17dfb7SMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(cSection, 0, Nc);CHKERRQ(ierr);
63143e922f36SToby Isaac   ierr = PetscSectionSetChart(cSection, newStart, newEnd);CHKERRQ(ierr);
63153e922f36SToby Isaac 
631669291d52SBarry Smith   ierr = DMGetWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr);
63173e922f36SToby Isaac   localized = &anchor[bs];
63183e922f36SToby Isaac   alreadyLocalized = alreadyLocalizedGlobal = PETSC_TRUE;
63193e922f36SToby Isaac   for (h = 0; h <= maxHeight; h++) {
63203e922f36SToby Isaac     PetscInt cStart = pStart[h], cEnd = pEnd[h], c;
63213e922f36SToby Isaac 
63223e922f36SToby Isaac     for (c = cStart; c < cEnd; ++c) {
63233e922f36SToby Isaac       PetscScalar *cellCoords = NULL;
63243e922f36SToby Isaac       PetscInt     b;
63253e922f36SToby Isaac 
63263e922f36SToby Isaac       if (c < sStart || c >= sEnd) alreadyLocalized = PETSC_FALSE;
63273e922f36SToby Isaac       ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
63283e922f36SToby Isaac       for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b];
63293e922f36SToby Isaac       for (d = 0; d < dof/bs; ++d) {
63303e922f36SToby Isaac         ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], localized);CHKERRQ(ierr);
63313e922f36SToby Isaac         for (b = 0; b < bs; b++) {
63323e922f36SToby Isaac           if (cellCoords[d*bs + b] != localized[b]) break;
63333e922f36SToby Isaac         }
63343e922f36SToby Isaac         if (b < bs) break;
63353e922f36SToby Isaac       }
63363e922f36SToby Isaac       if (d < dof/bs) {
63373e922f36SToby Isaac         if (c >= sStart && c < sEnd) {
63383e922f36SToby Isaac           PetscInt cdof;
63393e922f36SToby Isaac 
63403e922f36SToby Isaac           ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr);
63413e922f36SToby Isaac           if (cdof != dof) alreadyLocalized = PETSC_FALSE;
63423e922f36SToby Isaac         }
63433e922f36SToby Isaac         ierr = PetscSectionSetDof(cSection, c, dof);CHKERRQ(ierr);
63443e922f36SToby Isaac         ierr = PetscSectionSetFieldDof(cSection, c, 0, dof);CHKERRQ(ierr);
63453e922f36SToby Isaac       }
63463e922f36SToby Isaac       ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
63473e922f36SToby Isaac     }
63483e922f36SToby Isaac   }
63493e922f36SToby Isaac   ierr = MPI_Allreduce(&alreadyLocalized,&alreadyLocalizedGlobal,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
63503e922f36SToby Isaac   if (alreadyLocalizedGlobal) {
635169291d52SBarry Smith     ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr);
63523e922f36SToby Isaac     ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr);
635369291d52SBarry Smith     ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr);
63543e922f36SToby Isaac     PetscFunctionReturn(0);
63553e922f36SToby Isaac   }
63562e17dfb7SMatthew G. Knepley   for (v = vStart; v < vEnd; ++v) {
63572e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr);
63582e17dfb7SMatthew G. Knepley     ierr = PetscSectionSetDof(cSection, v, dof);CHKERRQ(ierr);
63592e17dfb7SMatthew G. Knepley     ierr = PetscSectionSetFieldDof(cSection, v, 0, dof);CHKERRQ(ierr);
63602e17dfb7SMatthew G. Knepley   }
63612e17dfb7SMatthew G. Knepley   ierr = PetscSectionSetUp(cSection);CHKERRQ(ierr);
63622e17dfb7SMatthew G. Knepley   ierr = PetscSectionGetStorageSize(cSection, &coordSize);CHKERRQ(ierr);
6363c2be7e5eSLisandro Dalcin   ierr = VecCreate(PETSC_COMM_SELF, &cVec);CHKERRQ(ierr);
63642e17dfb7SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject)cVec,"coordinates");CHKERRQ(ierr);
63652e17dfb7SMatthew G. Knepley   ierr = VecSetBlockSize(cVec, bs);CHKERRQ(ierr);
63662e17dfb7SMatthew G. Knepley   ierr = VecSetSizes(cVec, coordSize, PETSC_DETERMINE);CHKERRQ(ierr);
63672e17dfb7SMatthew G. Knepley   ierr = VecSetType(cVec, VECSTANDARD);CHKERRQ(ierr);
6368c2be7e5eSLisandro Dalcin   ierr = VecGetArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr);
63692e17dfb7SMatthew G. Knepley   ierr = VecGetArray(cVec, &coords2);CHKERRQ(ierr);
63702e17dfb7SMatthew G. Knepley   for (v = vStart; v < vEnd; ++v) {
63712e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr);
63722e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
63732e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetOffset(cSection,     v, &off2);CHKERRQ(ierr);
63742e17dfb7SMatthew G. Knepley     for (d = 0; d < dof; ++d) coords2[off2+d] = coords[off+d];
63752e17dfb7SMatthew G. Knepley   }
63763e922f36SToby Isaac   for (h = 0; h <= maxHeight; h++) {
63773e922f36SToby Isaac     PetscInt cStart = pStart[h], cEnd = pEnd[h], c;
63783e922f36SToby Isaac 
63792e17dfb7SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
63802e17dfb7SMatthew G. Knepley       PetscScalar *cellCoords = NULL;
63813e922f36SToby Isaac       PetscInt     b, cdof;
63822e17dfb7SMatthew G. Knepley 
63833e922f36SToby Isaac       ierr = PetscSectionGetDof(cSection,c,&cdof);CHKERRQ(ierr);
63843e922f36SToby Isaac       if (!cdof) continue;
63852e17dfb7SMatthew G. Knepley       ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
63862e17dfb7SMatthew G. Knepley       ierr = PetscSectionGetOffset(cSection, c, &off2);CHKERRQ(ierr);
63872e17dfb7SMatthew G. Knepley       for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b];
63882e17dfb7SMatthew G. Knepley       for (d = 0; d < dof/bs; ++d) {ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], &coords2[off2+d*bs]);CHKERRQ(ierr);}
63892e17dfb7SMatthew G. Knepley       ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
63902e17dfb7SMatthew G. Knepley     }
63913e922f36SToby Isaac   }
639269291d52SBarry Smith   ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr);
639369291d52SBarry Smith   ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr);
6394c2be7e5eSLisandro Dalcin   ierr = VecRestoreArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr);
63952e17dfb7SMatthew G. Knepley   ierr = VecRestoreArray(cVec, &coords2);CHKERRQ(ierr);
63962e17dfb7SMatthew G. Knepley   ierr = DMSetCoordinateSection(dm, PETSC_DETERMINE, cSection);CHKERRQ(ierr);
63972e17dfb7SMatthew G. Knepley   ierr = DMSetCoordinatesLocal(dm, cVec);CHKERRQ(ierr);
63982e17dfb7SMatthew G. Knepley   ierr = VecDestroy(&cVec);CHKERRQ(ierr);
63992e17dfb7SMatthew G. Knepley   ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr);
64002e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
64012e17dfb7SMatthew G. Knepley }
64022e17dfb7SMatthew G. Knepley 
6403e87bb0d3SMatthew G Knepley /*@
64043a93e3b7SToby Isaac   DMLocatePoints - Locate the points in v in the mesh and return a PetscSF of the containing cells
6405e87bb0d3SMatthew G Knepley 
6406d083f849SBarry Smith   Collective on v (see explanation below)
6407e87bb0d3SMatthew G Knepley 
6408e87bb0d3SMatthew G Knepley   Input Parameters:
6409e87bb0d3SMatthew G Knepley + dm - The DM
64103a93e3b7SToby Isaac . v - The Vec of points
641162a38674SMatthew G. Knepley . ltype - The type of point location, e.g. DM_POINTLOCATION_NONE or DM_POINTLOCATION_NEAREST
64123a93e3b7SToby Isaac - cells - Points to either NULL, or a PetscSF with guesses for which cells contain each point.
6413e87bb0d3SMatthew G Knepley 
641461e3bb9bSMatthew G Knepley   Output Parameter:
641562a38674SMatthew G. Knepley + v - The Vec of points, which now contains the nearest mesh points to the given points if DM_POINTLOCATION_NEAREST is used
641662a38674SMatthew G. Knepley - cells - The PetscSF containing the ranks and local indices of the containing points.
64173a93e3b7SToby Isaac 
6418e87bb0d3SMatthew G Knepley 
6419e87bb0d3SMatthew G Knepley   Level: developer
642061e3bb9bSMatthew G Knepley 
642162a38674SMatthew G. Knepley   Notes:
64223a93e3b7SToby Isaac   To do a search of the local cells of the mesh, v should have PETSC_COMM_SELF as its communicator.
642362a38674SMatthew G. Knepley   To do a search of all the cells in the distributed mesh, v should have the same communicator as dm.
64243a93e3b7SToby Isaac 
64253a93e3b7SToby Isaac   If *cellSF is NULL on input, a PetscSF will be created.
642662a38674SMatthew G. Knepley   If *cellSF is not NULL on input, it should point to an existing PetscSF, whose graph will be used as initial guesses.
64273a93e3b7SToby Isaac 
64283a93e3b7SToby Isaac   An array that maps each point to its containing cell can be obtained with
64293a93e3b7SToby Isaac 
643062a38674SMatthew G. Knepley $    const PetscSFNode *cells;
643162a38674SMatthew G. Knepley $    PetscInt           nFound;
6432a6216909SToby Isaac $    const PetscInt    *found;
643362a38674SMatthew G. Knepley $
6434a6216909SToby Isaac $    PetscSFGetGraph(cellSF,NULL,&nFound,&found,&cells);
64353a93e3b7SToby Isaac 
64363a93e3b7SToby Isaac   Where cells[i].rank is the rank of the cell containing point found[i] (or i if found == NULL), and cells[i].index is
64373a93e3b7SToby Isaac   the index of the cell in its rank's local numbering.
64383a93e3b7SToby Isaac 
643962a38674SMatthew G. Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMPointLocationType
644061e3bb9bSMatthew G Knepley @*/
644162a38674SMatthew G. Knepley PetscErrorCode DMLocatePoints(DM dm, Vec v, DMPointLocationType ltype, PetscSF *cellSF)
6442e87bb0d3SMatthew G Knepley {
6443735aa83eSMatthew G Knepley   PetscErrorCode ierr;
6444735aa83eSMatthew G Knepley 
6445e87bb0d3SMatthew G Knepley   PetscFunctionBegin;
6446e87bb0d3SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6447e87bb0d3SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
6448e0fc9d1bSMatthew G. Knepley   PetscValidPointer(cellSF,4);
64493a93e3b7SToby Isaac   if (*cellSF) {
64503a93e3b7SToby Isaac     PetscMPIInt result;
64513a93e3b7SToby Isaac 
6452e0fc9d1bSMatthew G. Knepley     PetscValidHeaderSpecific(*cellSF,PETSCSF_CLASSID,4);
6453a4f09dd6SDave May     ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)v),PetscObjectComm((PetscObject)*cellSF),&result);CHKERRQ(ierr);
64543a93e3b7SToby Isaac     if (result != MPI_IDENT && result != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"cellSF must have a communicator congruent to v's");
6455e0fc9d1bSMatthew G. Knepley   } else {
64563a93e3b7SToby Isaac     ierr = PetscSFCreate(PetscObjectComm((PetscObject)v),cellSF);CHKERRQ(ierr);
64573a93e3b7SToby Isaac   }
6458b9d85ea2SLisandro Dalcin   if (!dm->ops->locatepoints) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Point location not available for this DM");
645947a35634SPatrick Farrell   ierr = PetscLogEventBegin(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr);
646062a38674SMatthew G. Knepley   ierr = (*dm->ops->locatepoints)(dm,v,ltype,*cellSF);CHKERRQ(ierr);
646147a35634SPatrick Farrell   ierr = PetscLogEventEnd(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr);
6462e87bb0d3SMatthew G Knepley   PetscFunctionReturn(0);
6463e87bb0d3SMatthew G Knepley }
646414f150ffSMatthew G. Knepley 
6465f4d763aaSMatthew G. Knepley /*@
6466f4d763aaSMatthew G. Knepley   DMGetOutputDM - Retrieve the DM associated with the layout for output
6467f4d763aaSMatthew G. Knepley 
64688f700142SStefano Zampini   Collective on dm
64698f700142SStefano Zampini 
6470f4d763aaSMatthew G. Knepley   Input Parameter:
6471f4d763aaSMatthew G. Knepley . dm - The original DM
6472f4d763aaSMatthew G. Knepley 
6473f4d763aaSMatthew G. Knepley   Output Parameter:
6474f4d763aaSMatthew G. Knepley . odm - The DM which provides the layout for output
6475f4d763aaSMatthew G. Knepley 
6476f4d763aaSMatthew G. Knepley   Level: intermediate
6477f4d763aaSMatthew G. Knepley 
6478e87a4003SBarry Smith .seealso: VecView(), DMGetGlobalSection()
6479f4d763aaSMatthew G. Knepley @*/
648014f150ffSMatthew G. Knepley PetscErrorCode DMGetOutputDM(DM dm, DM *odm)
648114f150ffSMatthew G. Knepley {
6482c26acbdeSMatthew G. Knepley   PetscSection   section;
64832d4e4a49SMatthew G. Knepley   PetscBool      hasConstraints, ghasConstraints;
648414f150ffSMatthew G. Knepley   PetscErrorCode ierr;
648514f150ffSMatthew G. Knepley 
648614f150ffSMatthew G. Knepley   PetscFunctionBegin;
648714f150ffSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
648814f150ffSMatthew G. Knepley   PetscValidPointer(odm,2);
648992fd8e1eSJed Brown   ierr = DMGetLocalSection(dm, &section);CHKERRQ(ierr);
6490c26acbdeSMatthew G. Knepley   ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr);
6491127fe6b9SMatthew G. Knepley   ierr = MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);
64922d4e4a49SMatthew G. Knepley   if (!ghasConstraints) {
6493c26acbdeSMatthew G. Knepley     *odm = dm;
6494c26acbdeSMatthew G. Knepley     PetscFunctionReturn(0);
6495c26acbdeSMatthew G. Knepley   }
649614f150ffSMatthew G. Knepley   if (!dm->dmBC) {
6497c26acbdeSMatthew G. Knepley     PetscSection newSection, gsection;
649814f150ffSMatthew G. Knepley     PetscSF      sf;
649914f150ffSMatthew G. Knepley 
650014f150ffSMatthew G. Knepley     ierr = DMClone(dm, &dm->dmBC);CHKERRQ(ierr);
6501e5e52638SMatthew G. Knepley     ierr = DMCopyDisc(dm, dm->dmBC);CHKERRQ(ierr);
650214f150ffSMatthew G. Knepley     ierr = PetscSectionClone(section, &newSection);CHKERRQ(ierr);
650392fd8e1eSJed Brown     ierr = DMSetLocalSection(dm->dmBC, newSection);CHKERRQ(ierr);
650414f150ffSMatthew G. Knepley     ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr);
650514f150ffSMatthew G. Knepley     ierr = DMGetPointSF(dm->dmBC, &sf);CHKERRQ(ierr);
650615b58121SMatthew G. Knepley     ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr);
6507e87a4003SBarry Smith     ierr = DMSetGlobalSection(dm->dmBC, gsection);CHKERRQ(ierr);
650814f150ffSMatthew G. Knepley     ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr);
650914f150ffSMatthew G. Knepley   }
651014f150ffSMatthew G. Knepley   *odm = dm->dmBC;
651114f150ffSMatthew G. Knepley   PetscFunctionReturn(0);
651214f150ffSMatthew G. Knepley }
6513f4d763aaSMatthew G. Knepley 
6514f4d763aaSMatthew G. Knepley /*@
6515cdb7a50dSMatthew G. Knepley   DMGetOutputSequenceNumber - Retrieve the sequence number/value for output
6516f4d763aaSMatthew G. Knepley 
6517f4d763aaSMatthew G. Knepley   Input Parameter:
6518f4d763aaSMatthew G. Knepley . dm - The original DM
6519f4d763aaSMatthew G. Knepley 
6520cdb7a50dSMatthew G. Knepley   Output Parameters:
6521cdb7a50dSMatthew G. Knepley + num - The output sequence number
6522cdb7a50dSMatthew G. Knepley - val - The output sequence value
6523f4d763aaSMatthew G. Knepley 
6524f4d763aaSMatthew G. Knepley   Level: intermediate
6525f4d763aaSMatthew G. Knepley 
6526f4d763aaSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
6527f4d763aaSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
6528f4d763aaSMatthew G. Knepley 
6529f4d763aaSMatthew G. Knepley .seealso: VecView()
6530f4d763aaSMatthew G. Knepley @*/
6531cdb7a50dSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val)
6532f4d763aaSMatthew G. Knepley {
6533f4d763aaSMatthew G. Knepley   PetscFunctionBegin;
6534f4d763aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6535534a8f05SLisandro Dalcin   if (num) {PetscValidIntPointer(num,2); *num = dm->outputSequenceNum;}
6536534a8f05SLisandro Dalcin   if (val) {PetscValidRealPointer(val,3);*val = dm->outputSequenceVal;}
6537f4d763aaSMatthew G. Knepley   PetscFunctionReturn(0);
6538f4d763aaSMatthew G. Knepley }
6539f4d763aaSMatthew G. Knepley 
6540f4d763aaSMatthew G. Knepley /*@
6541cdb7a50dSMatthew G. Knepley   DMSetOutputSequenceNumber - Set the sequence number/value for output
6542f4d763aaSMatthew G. Knepley 
6543f4d763aaSMatthew G. Knepley   Input Parameters:
6544f4d763aaSMatthew G. Knepley + dm - The original DM
6545cdb7a50dSMatthew G. Knepley . num - The output sequence number
6546cdb7a50dSMatthew G. Knepley - val - The output sequence value
6547f4d763aaSMatthew G. Knepley 
6548f4d763aaSMatthew G. Knepley   Level: intermediate
6549f4d763aaSMatthew G. Knepley 
6550f4d763aaSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
6551f4d763aaSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
6552f4d763aaSMatthew G. Knepley 
6553f4d763aaSMatthew G. Knepley .seealso: VecView()
6554f4d763aaSMatthew G. Knepley @*/
6555cdb7a50dSMatthew G. Knepley PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val)
6556f4d763aaSMatthew G. Knepley {
6557f4d763aaSMatthew G. Knepley   PetscFunctionBegin;
6558f4d763aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6559f4d763aaSMatthew G. Knepley   dm->outputSequenceNum = num;
6560cdb7a50dSMatthew G. Knepley   dm->outputSequenceVal = val;
6561cdb7a50dSMatthew G. Knepley   PetscFunctionReturn(0);
6562cdb7a50dSMatthew G. Knepley }
6563cdb7a50dSMatthew G. Knepley 
6564cdb7a50dSMatthew G. Knepley /*@C
6565cdb7a50dSMatthew G. Knepley   DMOutputSequenceLoad - Retrieve the sequence value from a Viewer
6566cdb7a50dSMatthew G. Knepley 
6567cdb7a50dSMatthew G. Knepley   Input Parameters:
6568cdb7a50dSMatthew G. Knepley + dm   - The original DM
6569cdb7a50dSMatthew G. Knepley . name - The sequence name
6570cdb7a50dSMatthew G. Knepley - num  - The output sequence number
6571cdb7a50dSMatthew G. Knepley 
6572cdb7a50dSMatthew G. Knepley   Output Parameter:
6573cdb7a50dSMatthew G. Knepley . val  - The output sequence value
6574cdb7a50dSMatthew G. Knepley 
6575cdb7a50dSMatthew G. Knepley   Level: intermediate
6576cdb7a50dSMatthew G. Knepley 
6577cdb7a50dSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
6578cdb7a50dSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
6579cdb7a50dSMatthew G. Knepley 
6580cdb7a50dSMatthew G. Knepley .seealso: DMGetOutputSequenceNumber(), DMSetOutputSequenceNumber(), VecView()
6581cdb7a50dSMatthew G. Knepley @*/
6582cdb7a50dSMatthew G. Knepley PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val)
6583cdb7a50dSMatthew G. Knepley {
6584cdb7a50dSMatthew G. Knepley   PetscBool      ishdf5;
6585cdb7a50dSMatthew G. Knepley   PetscErrorCode ierr;
6586cdb7a50dSMatthew G. Knepley 
6587cdb7a50dSMatthew G. Knepley   PetscFunctionBegin;
6588cdb7a50dSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6589cdb7a50dSMatthew G. Knepley   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
6590534a8f05SLisandro Dalcin   PetscValidRealPointer(val,4);
6591cdb7a50dSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr);
6592cdb7a50dSMatthew G. Knepley   if (ishdf5) {
6593cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5)
6594cdb7a50dSMatthew G. Knepley     PetscScalar value;
6595cdb7a50dSMatthew G. Knepley 
659639d25373SMatthew G. Knepley     ierr = DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer);CHKERRQ(ierr);
65974aeb217fSMatthew G. Knepley     *val = PetscRealPart(value);
6598cdb7a50dSMatthew G. Knepley #endif
6599cdb7a50dSMatthew G. Knepley   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()");
6600f4d763aaSMatthew G. Knepley   PetscFunctionReturn(0);
6601f4d763aaSMatthew G. Knepley }
66028e4ac7eaSMatthew G. Knepley 
66038e4ac7eaSMatthew G. Knepley /*@
66048e4ac7eaSMatthew G. Knepley   DMGetUseNatural - Get the flag for creating a mapping to the natural order on distribution
66058e4ac7eaSMatthew G. Knepley 
66068e4ac7eaSMatthew G. Knepley   Not collective
66078e4ac7eaSMatthew G. Knepley 
66088e4ac7eaSMatthew G. Knepley   Input Parameter:
66098e4ac7eaSMatthew G. Knepley . dm - The DM
66108e4ac7eaSMatthew G. Knepley 
66118e4ac7eaSMatthew G. Knepley   Output Parameter:
66128e4ac7eaSMatthew G. Knepley . useNatural - The flag to build the mapping to a natural order during distribution
66138e4ac7eaSMatthew G. Knepley 
66148e4ac7eaSMatthew G. Knepley   Level: beginner
66158e4ac7eaSMatthew G. Knepley 
66168e4ac7eaSMatthew G. Knepley .seealso: DMSetUseNatural(), DMCreate()
66178e4ac7eaSMatthew G. Knepley @*/
66188e4ac7eaSMatthew G. Knepley PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural)
66198e4ac7eaSMatthew G. Knepley {
66208e4ac7eaSMatthew G. Knepley   PetscFunctionBegin;
66218e4ac7eaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6622534a8f05SLisandro Dalcin   PetscValidBoolPointer(useNatural, 2);
66238e4ac7eaSMatthew G. Knepley   *useNatural = dm->useNatural;
66248e4ac7eaSMatthew G. Knepley   PetscFunctionReturn(0);
66258e4ac7eaSMatthew G. Knepley }
66268e4ac7eaSMatthew G. Knepley 
66278e4ac7eaSMatthew G. Knepley /*@
66285d3b26e6SMatthew G. Knepley   DMSetUseNatural - Set the flag for creating a mapping to the natural order after distribution
66298e4ac7eaSMatthew G. Knepley 
66308e4ac7eaSMatthew G. Knepley   Collective on dm
66318e4ac7eaSMatthew G. Knepley 
66328e4ac7eaSMatthew G. Knepley   Input Parameters:
66338e4ac7eaSMatthew G. Knepley + dm - The DM
66348e4ac7eaSMatthew G. Knepley - useNatural - The flag to build the mapping to a natural order during distribution
66358e4ac7eaSMatthew G. Knepley 
66365d3b26e6SMatthew G. Knepley   Note: This also causes the map to be build after DMCreateSubDM() and DMCreateSuperDM()
66375d3b26e6SMatthew G. Knepley 
66388e4ac7eaSMatthew G. Knepley   Level: beginner
66398e4ac7eaSMatthew G. Knepley 
66405d3b26e6SMatthew G. Knepley .seealso: DMGetUseNatural(), DMCreate(), DMPlexDistribute(), DMCreateSubDM(), DMCreateSuperDM()
66418e4ac7eaSMatthew G. Knepley @*/
66428e4ac7eaSMatthew G. Knepley PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural)
66438e4ac7eaSMatthew G. Knepley {
66448e4ac7eaSMatthew G. Knepley   PetscFunctionBegin;
66458e4ac7eaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
66468833efb5SBlaise Bourdin   PetscValidLogicalCollectiveBool(dm, useNatural, 2);
66478e4ac7eaSMatthew G. Knepley   dm->useNatural = useNatural;
66488e4ac7eaSMatthew G. Knepley   PetscFunctionReturn(0);
66498e4ac7eaSMatthew G. Knepley }
6650c58f1c22SToby Isaac 
6651c58f1c22SToby Isaac 
6652c58f1c22SToby Isaac /*@C
6653c58f1c22SToby Isaac   DMCreateLabel - Create a label of the given name if it does not already exist
6654c58f1c22SToby Isaac 
6655c58f1c22SToby Isaac   Not Collective
6656c58f1c22SToby Isaac 
6657c58f1c22SToby Isaac   Input Parameters:
6658c58f1c22SToby Isaac + dm   - The DM object
6659c58f1c22SToby Isaac - name - The label name
6660c58f1c22SToby Isaac 
6661c58f1c22SToby Isaac   Level: intermediate
6662c58f1c22SToby Isaac 
6663c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6664c58f1c22SToby Isaac @*/
6665c58f1c22SToby Isaac PetscErrorCode DMCreateLabel(DM dm, const char name[])
6666c58f1c22SToby Isaac {
66675d80c0bfSVaclav Hapla   PetscBool      flg;
66685d80c0bfSVaclav Hapla   DMLabel        label;
6669c58f1c22SToby Isaac   PetscErrorCode ierr;
6670c58f1c22SToby Isaac 
6671c58f1c22SToby Isaac   PetscFunctionBegin;
6672c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6673c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
66745d80c0bfSVaclav Hapla   ierr = DMHasLabel(dm, name, &flg);CHKERRQ(ierr);
6675c58f1c22SToby Isaac   if (!flg) {
66765d80c0bfSVaclav Hapla     ierr = DMLabelCreate(PETSC_COMM_SELF, name, &label);CHKERRQ(ierr);
66775d80c0bfSVaclav Hapla     ierr = DMAddLabel(dm, label);CHKERRQ(ierr);
66785d80c0bfSVaclav Hapla     ierr = DMLabelDestroy(&label);CHKERRQ(ierr);
6679c58f1c22SToby Isaac   }
6680c58f1c22SToby Isaac   PetscFunctionReturn(0);
6681c58f1c22SToby Isaac }
6682c58f1c22SToby Isaac 
6683c58f1c22SToby Isaac /*@C
6684c58f1c22SToby Isaac   DMGetLabelValue - Get the value in a Sieve Label for the given point, with 0 as the default
6685c58f1c22SToby Isaac 
6686c58f1c22SToby Isaac   Not Collective
6687c58f1c22SToby Isaac 
6688c58f1c22SToby Isaac   Input Parameters:
6689c58f1c22SToby Isaac + dm   - The DM object
6690c58f1c22SToby Isaac . name - The label name
6691c58f1c22SToby Isaac - point - The mesh point
6692c58f1c22SToby Isaac 
6693c58f1c22SToby Isaac   Output Parameter:
6694c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label
6695c58f1c22SToby Isaac 
6696c58f1c22SToby Isaac   Level: beginner
6697c58f1c22SToby Isaac 
6698c58f1c22SToby Isaac .seealso: DMLabelGetValue(), DMSetLabelValue(), DMGetStratumIS()
6699c58f1c22SToby Isaac @*/
6700c58f1c22SToby Isaac PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value)
6701c58f1c22SToby Isaac {
6702c58f1c22SToby Isaac   DMLabel        label;
6703c58f1c22SToby Isaac   PetscErrorCode ierr;
6704c58f1c22SToby Isaac 
6705c58f1c22SToby Isaac   PetscFunctionBegin;
6706c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6707c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6708c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
670913903a91SSatish Balay   if (!label) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name);
6710c58f1c22SToby Isaac   ierr = DMLabelGetValue(label, point, value);CHKERRQ(ierr);
6711c58f1c22SToby Isaac   PetscFunctionReturn(0);
6712c58f1c22SToby Isaac }
6713c58f1c22SToby Isaac 
6714c58f1c22SToby Isaac /*@C
6715c58f1c22SToby Isaac   DMSetLabelValue - Add a point to a Sieve Label with given value
6716c58f1c22SToby Isaac 
6717c58f1c22SToby Isaac   Not Collective
6718c58f1c22SToby Isaac 
6719c58f1c22SToby Isaac   Input Parameters:
6720c58f1c22SToby Isaac + dm   - The DM object
6721c58f1c22SToby Isaac . name - The label name
6722c58f1c22SToby Isaac . point - The mesh point
6723c58f1c22SToby Isaac - value - The label value for this point
6724c58f1c22SToby Isaac 
6725c58f1c22SToby Isaac   Output Parameter:
6726c58f1c22SToby Isaac 
6727c58f1c22SToby Isaac   Level: beginner
6728c58f1c22SToby Isaac 
6729c58f1c22SToby Isaac .seealso: DMLabelSetValue(), DMGetStratumIS(), DMClearLabelValue()
6730c58f1c22SToby Isaac @*/
6731c58f1c22SToby Isaac PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value)
6732c58f1c22SToby Isaac {
6733c58f1c22SToby Isaac   DMLabel        label;
6734c58f1c22SToby Isaac   PetscErrorCode ierr;
6735c58f1c22SToby Isaac 
6736c58f1c22SToby Isaac   PetscFunctionBegin;
6737c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6738c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6739c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6740c58f1c22SToby Isaac   if (!label) {
6741c58f1c22SToby Isaac     ierr = DMCreateLabel(dm, name);CHKERRQ(ierr);
6742c58f1c22SToby Isaac     ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6743c58f1c22SToby Isaac   }
6744c58f1c22SToby Isaac   ierr = DMLabelSetValue(label, point, value);CHKERRQ(ierr);
6745c58f1c22SToby Isaac   PetscFunctionReturn(0);
6746c58f1c22SToby Isaac }
6747c58f1c22SToby Isaac 
6748c58f1c22SToby Isaac /*@C
6749c58f1c22SToby Isaac   DMClearLabelValue - Remove a point from a Sieve Label with given value
6750c58f1c22SToby Isaac 
6751c58f1c22SToby Isaac   Not Collective
6752c58f1c22SToby Isaac 
6753c58f1c22SToby Isaac   Input Parameters:
6754c58f1c22SToby Isaac + dm   - The DM object
6755c58f1c22SToby Isaac . name - The label name
6756c58f1c22SToby Isaac . point - The mesh point
6757c58f1c22SToby Isaac - value - The label value for this point
6758c58f1c22SToby Isaac 
6759c58f1c22SToby Isaac   Output Parameter:
6760c58f1c22SToby Isaac 
6761c58f1c22SToby Isaac   Level: beginner
6762c58f1c22SToby Isaac 
6763c58f1c22SToby Isaac .seealso: DMLabelClearValue(), DMSetLabelValue(), DMGetStratumIS()
6764c58f1c22SToby Isaac @*/
6765c58f1c22SToby Isaac PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value)
6766c58f1c22SToby Isaac {
6767c58f1c22SToby Isaac   DMLabel        label;
6768c58f1c22SToby Isaac   PetscErrorCode ierr;
6769c58f1c22SToby Isaac 
6770c58f1c22SToby Isaac   PetscFunctionBegin;
6771c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6772c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6773c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6774c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6775c58f1c22SToby Isaac   ierr = DMLabelClearValue(label, point, value);CHKERRQ(ierr);
6776c58f1c22SToby Isaac   PetscFunctionReturn(0);
6777c58f1c22SToby Isaac }
6778c58f1c22SToby Isaac 
6779c58f1c22SToby Isaac /*@C
6780c58f1c22SToby Isaac   DMGetLabelSize - Get the number of different integer ids in a Label
6781c58f1c22SToby Isaac 
6782c58f1c22SToby Isaac   Not Collective
6783c58f1c22SToby Isaac 
6784c58f1c22SToby Isaac   Input Parameters:
6785c58f1c22SToby Isaac + dm   - The DM object
6786c58f1c22SToby Isaac - name - The label name
6787c58f1c22SToby Isaac 
6788c58f1c22SToby Isaac   Output Parameter:
6789c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist
6790c58f1c22SToby Isaac 
6791c58f1c22SToby Isaac   Level: beginner
6792c58f1c22SToby Isaac 
6793df813f42SMatthew G. Knepley .seealso: DMLabelGetNumValues(), DMSetLabelValue()
6794c58f1c22SToby Isaac @*/
6795c58f1c22SToby Isaac PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size)
6796c58f1c22SToby Isaac {
6797c58f1c22SToby Isaac   DMLabel        label;
6798c58f1c22SToby Isaac   PetscErrorCode ierr;
6799c58f1c22SToby Isaac 
6800c58f1c22SToby Isaac   PetscFunctionBegin;
6801c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6802c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6803534a8f05SLisandro Dalcin   PetscValidIntPointer(size, 3);
6804c58f1c22SToby Isaac   ierr  = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6805c58f1c22SToby Isaac   *size = 0;
6806c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6807c58f1c22SToby Isaac   ierr = DMLabelGetNumValues(label, size);CHKERRQ(ierr);
6808c58f1c22SToby Isaac   PetscFunctionReturn(0);
6809c58f1c22SToby Isaac }
6810c58f1c22SToby Isaac 
6811c58f1c22SToby Isaac /*@C
6812c58f1c22SToby Isaac   DMGetLabelIdIS - Get the integer ids in a label
6813c58f1c22SToby Isaac 
6814c58f1c22SToby Isaac   Not Collective
6815c58f1c22SToby Isaac 
6816c58f1c22SToby Isaac   Input Parameters:
6817c58f1c22SToby Isaac + mesh - The DM object
6818c58f1c22SToby Isaac - name - The label name
6819c58f1c22SToby Isaac 
6820c58f1c22SToby Isaac   Output Parameter:
6821c58f1c22SToby Isaac . ids - The integer ids, or NULL if the label does not exist
6822c58f1c22SToby Isaac 
6823c58f1c22SToby Isaac   Level: beginner
6824c58f1c22SToby Isaac 
6825c58f1c22SToby Isaac .seealso: DMLabelGetValueIS(), DMGetLabelSize()
6826c58f1c22SToby Isaac @*/
6827c58f1c22SToby Isaac PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids)
6828c58f1c22SToby Isaac {
6829c58f1c22SToby Isaac   DMLabel        label;
6830c58f1c22SToby Isaac   PetscErrorCode ierr;
6831c58f1c22SToby Isaac 
6832c58f1c22SToby Isaac   PetscFunctionBegin;
6833c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6834c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6835c58f1c22SToby Isaac   PetscValidPointer(ids, 3);
6836c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6837c58f1c22SToby Isaac   *ids = NULL;
6838dab2e251SBlaise Bourdin  if (label) {
6839c58f1c22SToby Isaac     ierr = DMLabelGetValueIS(label, ids);CHKERRQ(ierr);
6840dab2e251SBlaise Bourdin   } else {
6841dab2e251SBlaise Bourdin     /* returning an empty IS */
6842dab2e251SBlaise Bourdin     ierr = ISCreateGeneral(PETSC_COMM_SELF,0,NULL,PETSC_USE_POINTER,ids);CHKERRQ(ierr);
6843dab2e251SBlaise Bourdin   }
6844c58f1c22SToby Isaac   PetscFunctionReturn(0);
6845c58f1c22SToby Isaac }
6846c58f1c22SToby Isaac 
6847c58f1c22SToby Isaac /*@C
6848c58f1c22SToby Isaac   DMGetStratumSize - Get the number of points in a label stratum
6849c58f1c22SToby Isaac 
6850c58f1c22SToby Isaac   Not Collective
6851c58f1c22SToby Isaac 
6852c58f1c22SToby Isaac   Input Parameters:
6853c58f1c22SToby Isaac + dm - The DM object
6854c58f1c22SToby Isaac . name - The label name
6855c58f1c22SToby Isaac - value - The stratum value
6856c58f1c22SToby Isaac 
6857c58f1c22SToby Isaac   Output Parameter:
6858c58f1c22SToby Isaac . size - The stratum size
6859c58f1c22SToby Isaac 
6860c58f1c22SToby Isaac   Level: beginner
6861c58f1c22SToby Isaac 
6862c58f1c22SToby Isaac .seealso: DMLabelGetStratumSize(), DMGetLabelSize(), DMGetLabelIds()
6863c58f1c22SToby Isaac @*/
6864c58f1c22SToby Isaac PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size)
6865c58f1c22SToby Isaac {
6866c58f1c22SToby Isaac   DMLabel        label;
6867c58f1c22SToby Isaac   PetscErrorCode ierr;
6868c58f1c22SToby Isaac 
6869c58f1c22SToby Isaac   PetscFunctionBegin;
6870c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6871c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6872534a8f05SLisandro Dalcin   PetscValidIntPointer(size, 4);
6873c58f1c22SToby Isaac   ierr  = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6874c58f1c22SToby Isaac   *size = 0;
6875c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6876c58f1c22SToby Isaac   ierr = DMLabelGetStratumSize(label, value, size);CHKERRQ(ierr);
6877c58f1c22SToby Isaac   PetscFunctionReturn(0);
6878c58f1c22SToby Isaac }
6879c58f1c22SToby Isaac 
6880c58f1c22SToby Isaac /*@C
6881c58f1c22SToby Isaac   DMGetStratumIS - Get the points in a label stratum
6882c58f1c22SToby Isaac 
6883c58f1c22SToby Isaac   Not Collective
6884c58f1c22SToby Isaac 
6885c58f1c22SToby Isaac   Input Parameters:
6886c58f1c22SToby Isaac + dm - The DM object
6887c58f1c22SToby Isaac . name - The label name
6888c58f1c22SToby Isaac - value - The stratum value
6889c58f1c22SToby Isaac 
6890c58f1c22SToby Isaac   Output Parameter:
6891c58f1c22SToby Isaac . points - The stratum points, or NULL if the label does not exist or does not have that value
6892c58f1c22SToby Isaac 
6893c58f1c22SToby Isaac   Level: beginner
6894c58f1c22SToby Isaac 
6895c58f1c22SToby Isaac .seealso: DMLabelGetStratumIS(), DMGetStratumSize()
6896c58f1c22SToby Isaac @*/
6897c58f1c22SToby Isaac PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points)
6898c58f1c22SToby Isaac {
6899c58f1c22SToby Isaac   DMLabel        label;
6900c58f1c22SToby Isaac   PetscErrorCode ierr;
6901c58f1c22SToby Isaac 
6902c58f1c22SToby Isaac   PetscFunctionBegin;
6903c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6904c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6905c58f1c22SToby Isaac   PetscValidPointer(points, 4);
6906c58f1c22SToby Isaac   ierr    = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6907c58f1c22SToby Isaac   *points = NULL;
6908c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6909c58f1c22SToby Isaac   ierr = DMLabelGetStratumIS(label, value, points);CHKERRQ(ierr);
6910c58f1c22SToby Isaac   PetscFunctionReturn(0);
6911c58f1c22SToby Isaac }
6912c58f1c22SToby Isaac 
69134de306b1SToby Isaac /*@C
69149044fa66SMatthew G. Knepley   DMSetStratumIS - Set the points in a label stratum
69154de306b1SToby Isaac 
69164de306b1SToby Isaac   Not Collective
69174de306b1SToby Isaac 
69184de306b1SToby Isaac   Input Parameters:
69194de306b1SToby Isaac + dm - The DM object
69204de306b1SToby Isaac . name - The label name
69214de306b1SToby Isaac . value - The stratum value
69224de306b1SToby Isaac - points - The stratum points
69234de306b1SToby Isaac 
69244de306b1SToby Isaac   Level: beginner
69254de306b1SToby Isaac 
69264de306b1SToby Isaac .seealso: DMLabelSetStratumIS(), DMGetStratumSize()
69274de306b1SToby Isaac @*/
69284de306b1SToby Isaac PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points)
69294de306b1SToby Isaac {
69304de306b1SToby Isaac   DMLabel        label;
69314de306b1SToby Isaac   PetscErrorCode ierr;
69324de306b1SToby Isaac 
69334de306b1SToby Isaac   PetscFunctionBegin;
69344de306b1SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
69354de306b1SToby Isaac   PetscValidCharPointer(name, 2);
69364de306b1SToby Isaac   PetscValidPointer(points, 4);
69374de306b1SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
69384de306b1SToby Isaac   if (!label) PetscFunctionReturn(0);
69394de306b1SToby Isaac   ierr = DMLabelSetStratumIS(label, value, points);CHKERRQ(ierr);
69404de306b1SToby Isaac   PetscFunctionReturn(0);
69414de306b1SToby Isaac }
69424de306b1SToby Isaac 
6943c58f1c22SToby Isaac /*@C
6944c58f1c22SToby Isaac   DMClearLabelStratum - Remove all points from a stratum from a Sieve Label
6945c58f1c22SToby Isaac 
6946c58f1c22SToby Isaac   Not Collective
6947c58f1c22SToby Isaac 
6948c58f1c22SToby Isaac   Input Parameters:
6949c58f1c22SToby Isaac + dm   - The DM object
6950c58f1c22SToby Isaac . name - The label name
6951c58f1c22SToby Isaac - value - The label value for this point
6952c58f1c22SToby Isaac 
6953c58f1c22SToby Isaac   Output Parameter:
6954c58f1c22SToby Isaac 
6955c58f1c22SToby Isaac   Level: beginner
6956c58f1c22SToby Isaac 
6957c58f1c22SToby Isaac .seealso: DMLabelClearStratum(), DMSetLabelValue(), DMGetStratumIS(), DMClearLabelValue()
6958c58f1c22SToby Isaac @*/
6959c58f1c22SToby Isaac PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value)
6960c58f1c22SToby Isaac {
6961c58f1c22SToby Isaac   DMLabel        label;
6962c58f1c22SToby Isaac   PetscErrorCode ierr;
6963c58f1c22SToby Isaac 
6964c58f1c22SToby Isaac   PetscFunctionBegin;
6965c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6966c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6967c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6968c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6969c58f1c22SToby Isaac   ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr);
6970c58f1c22SToby Isaac   PetscFunctionReturn(0);
6971c58f1c22SToby Isaac }
6972c58f1c22SToby Isaac 
6973c58f1c22SToby Isaac /*@
6974c58f1c22SToby Isaac   DMGetNumLabels - Return the number of labels defined by the mesh
6975c58f1c22SToby Isaac 
6976c58f1c22SToby Isaac   Not Collective
6977c58f1c22SToby Isaac 
6978c58f1c22SToby Isaac   Input Parameter:
6979c58f1c22SToby Isaac . dm   - The DM object
6980c58f1c22SToby Isaac 
6981c58f1c22SToby Isaac   Output Parameter:
6982c58f1c22SToby Isaac . numLabels - the number of Labels
6983c58f1c22SToby Isaac 
6984c58f1c22SToby Isaac   Level: intermediate
6985c58f1c22SToby Isaac 
6986c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6987c58f1c22SToby Isaac @*/
6988c58f1c22SToby Isaac PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels)
6989c58f1c22SToby Isaac {
69905d80c0bfSVaclav Hapla   DMLabelLink next = dm->labels;
6991c58f1c22SToby Isaac   PetscInt  n    = 0;
6992c58f1c22SToby Isaac 
6993c58f1c22SToby Isaac   PetscFunctionBegin;
6994c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6995534a8f05SLisandro Dalcin   PetscValidIntPointer(numLabels, 2);
6996c58f1c22SToby Isaac   while (next) {++n; next = next->next;}
6997c58f1c22SToby Isaac   *numLabels = n;
6998c58f1c22SToby Isaac   PetscFunctionReturn(0);
6999c58f1c22SToby Isaac }
7000c58f1c22SToby Isaac 
7001c58f1c22SToby Isaac /*@C
7002c58f1c22SToby Isaac   DMGetLabelName - Return the name of nth label
7003c58f1c22SToby Isaac 
7004c58f1c22SToby Isaac   Not Collective
7005c58f1c22SToby Isaac 
7006c58f1c22SToby Isaac   Input Parameters:
7007c58f1c22SToby Isaac + dm - The DM object
7008c58f1c22SToby Isaac - n  - the label number
7009c58f1c22SToby Isaac 
7010c58f1c22SToby Isaac   Output Parameter:
7011c58f1c22SToby Isaac . name - the label name
7012c58f1c22SToby Isaac 
7013c58f1c22SToby Isaac   Level: intermediate
7014c58f1c22SToby Isaac 
7015c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7016c58f1c22SToby Isaac @*/
7017c58f1c22SToby Isaac PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name)
7018c58f1c22SToby Isaac {
70195d80c0bfSVaclav Hapla   DMLabelLink    next = dm->labels;
7020c58f1c22SToby Isaac   PetscInt       l    = 0;
7021d67d17b1SMatthew G. Knepley   PetscErrorCode ierr;
7022c58f1c22SToby Isaac 
7023c58f1c22SToby Isaac   PetscFunctionBegin;
7024c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7025c58f1c22SToby Isaac   PetscValidPointer(name, 3);
7026c58f1c22SToby Isaac   while (next) {
7027c58f1c22SToby Isaac     if (l == n) {
7028d67d17b1SMatthew G. Knepley       ierr = PetscObjectGetName((PetscObject) next->label, name);CHKERRQ(ierr);
7029c58f1c22SToby Isaac       PetscFunctionReturn(0);
7030c58f1c22SToby Isaac     }
7031c58f1c22SToby Isaac     ++l;
7032c58f1c22SToby Isaac     next = next->next;
7033c58f1c22SToby Isaac   }
7034c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n);
7035c58f1c22SToby Isaac }
7036c58f1c22SToby Isaac 
7037c58f1c22SToby Isaac /*@C
7038c58f1c22SToby Isaac   DMHasLabel - Determine whether the mesh has a label of a given name
7039c58f1c22SToby Isaac 
7040c58f1c22SToby Isaac   Not Collective
7041c58f1c22SToby Isaac 
7042c58f1c22SToby Isaac   Input Parameters:
7043c58f1c22SToby Isaac + dm   - The DM object
7044c58f1c22SToby Isaac - name - The label name
7045c58f1c22SToby Isaac 
7046c58f1c22SToby Isaac   Output Parameter:
7047c58f1c22SToby Isaac . hasLabel - PETSC_TRUE if the label is present
7048c58f1c22SToby Isaac 
7049c58f1c22SToby Isaac   Level: intermediate
7050c58f1c22SToby Isaac 
7051c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7052c58f1c22SToby Isaac @*/
7053c58f1c22SToby Isaac PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel)
7054c58f1c22SToby Isaac {
70555d80c0bfSVaclav Hapla   DMLabelLink    next = dm->labels;
7056d67d17b1SMatthew G. Knepley   const char    *lname;
7057c58f1c22SToby Isaac   PetscErrorCode ierr;
7058c58f1c22SToby Isaac 
7059c58f1c22SToby Isaac   PetscFunctionBegin;
7060c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7061c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
7062534a8f05SLisandro Dalcin   PetscValidBoolPointer(hasLabel, 3);
7063c58f1c22SToby Isaac   *hasLabel = PETSC_FALSE;
7064c58f1c22SToby Isaac   while (next) {
7065d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
7066d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, hasLabel);CHKERRQ(ierr);
7067c58f1c22SToby Isaac     if (*hasLabel) break;
7068c58f1c22SToby Isaac     next = next->next;
7069c58f1c22SToby Isaac   }
7070c58f1c22SToby Isaac   PetscFunctionReturn(0);
7071c58f1c22SToby Isaac }
7072c58f1c22SToby Isaac 
7073c58f1c22SToby Isaac /*@C
7074c58f1c22SToby Isaac   DMGetLabel - Return the label of a given name, or NULL
7075c58f1c22SToby Isaac 
7076c58f1c22SToby Isaac   Not Collective
7077c58f1c22SToby Isaac 
7078c58f1c22SToby Isaac   Input Parameters:
7079c58f1c22SToby Isaac + dm   - The DM object
7080c58f1c22SToby Isaac - name - The label name
7081c58f1c22SToby Isaac 
7082c58f1c22SToby Isaac   Output Parameter:
7083c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent
7084c58f1c22SToby Isaac 
7085c58f1c22SToby Isaac   Level: intermediate
7086c58f1c22SToby Isaac 
7087c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7088c58f1c22SToby Isaac @*/
7089c58f1c22SToby Isaac PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label)
7090c58f1c22SToby Isaac {
70915d80c0bfSVaclav Hapla   DMLabelLink    next = dm->labels;
7092c58f1c22SToby Isaac   PetscBool      hasLabel;
7093d67d17b1SMatthew G. Knepley   const char    *lname;
7094c58f1c22SToby Isaac   PetscErrorCode ierr;
7095c58f1c22SToby Isaac 
7096c58f1c22SToby Isaac   PetscFunctionBegin;
7097c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7098c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
7099c58f1c22SToby Isaac   PetscValidPointer(label, 3);
7100c58f1c22SToby Isaac   *label = NULL;
7101c58f1c22SToby Isaac   while (next) {
7102d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
7103d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr);
7104c58f1c22SToby Isaac     if (hasLabel) {
7105c58f1c22SToby Isaac       *label = next->label;
7106c58f1c22SToby Isaac       break;
7107c58f1c22SToby Isaac     }
7108c58f1c22SToby Isaac     next = next->next;
7109c58f1c22SToby Isaac   }
7110c58f1c22SToby Isaac   PetscFunctionReturn(0);
7111c58f1c22SToby Isaac }
7112c58f1c22SToby Isaac 
7113c58f1c22SToby Isaac /*@C
7114c58f1c22SToby Isaac   DMGetLabelByNum - Return the nth label
7115c58f1c22SToby Isaac 
7116c58f1c22SToby Isaac   Not Collective
7117c58f1c22SToby Isaac 
7118c58f1c22SToby Isaac   Input Parameters:
7119c58f1c22SToby Isaac + dm - The DM object
7120c58f1c22SToby Isaac - n  - the label number
7121c58f1c22SToby Isaac 
7122c58f1c22SToby Isaac   Output Parameter:
7123c58f1c22SToby Isaac . label - the label
7124c58f1c22SToby Isaac 
7125c58f1c22SToby Isaac   Level: intermediate
7126c58f1c22SToby Isaac 
7127c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7128c58f1c22SToby Isaac @*/
7129c58f1c22SToby Isaac PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label)
7130c58f1c22SToby Isaac {
71315d80c0bfSVaclav Hapla   DMLabelLink next = dm->labels;
7132c58f1c22SToby Isaac   PetscInt    l    = 0;
7133c58f1c22SToby Isaac 
7134c58f1c22SToby Isaac   PetscFunctionBegin;
7135c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7136c58f1c22SToby Isaac   PetscValidPointer(label, 3);
7137c58f1c22SToby Isaac   while (next) {
7138c58f1c22SToby Isaac     if (l == n) {
7139c58f1c22SToby Isaac       *label = next->label;
7140c58f1c22SToby Isaac       PetscFunctionReturn(0);
7141c58f1c22SToby Isaac     }
7142c58f1c22SToby Isaac     ++l;
7143c58f1c22SToby Isaac     next = next->next;
7144c58f1c22SToby Isaac   }
7145c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n);
7146c58f1c22SToby Isaac }
7147c58f1c22SToby Isaac 
7148c58f1c22SToby Isaac /*@C
7149c58f1c22SToby Isaac   DMAddLabel - Add the label to this mesh
7150c58f1c22SToby Isaac 
7151c58f1c22SToby Isaac   Not Collective
7152c58f1c22SToby Isaac 
7153c58f1c22SToby Isaac   Input Parameters:
7154c58f1c22SToby Isaac + dm   - The DM object
7155c58f1c22SToby Isaac - label - The DMLabel
7156c58f1c22SToby Isaac 
7157c58f1c22SToby Isaac   Level: developer
7158c58f1c22SToby Isaac 
7159c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7160c58f1c22SToby Isaac @*/
7161c58f1c22SToby Isaac PetscErrorCode DMAddLabel(DM dm, DMLabel label)
7162c58f1c22SToby Isaac {
71635d80c0bfSVaclav Hapla   DMLabelLink    l, *p, tmpLabel;
7164c58f1c22SToby Isaac   PetscBool      hasLabel;
7165d67d17b1SMatthew G. Knepley   const char    *lname;
71665d80c0bfSVaclav Hapla   PetscBool      flg;
7167c58f1c22SToby Isaac   PetscErrorCode ierr;
7168c58f1c22SToby Isaac 
7169c58f1c22SToby Isaac   PetscFunctionBegin;
7170c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7171d67d17b1SMatthew G. Knepley   ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr);
7172d67d17b1SMatthew G. Knepley   ierr = DMHasLabel(dm, lname, &hasLabel);CHKERRQ(ierr);
7173d67d17b1SMatthew G. Knepley   if (hasLabel) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname);
7174c58f1c22SToby Isaac   ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr);
7175c58f1c22SToby Isaac   tmpLabel->label  = label;
7176c58f1c22SToby Isaac   tmpLabel->output = PETSC_TRUE;
71775d80c0bfSVaclav Hapla   for (p=&dm->labels; (l=*p); p=&l->next) {}
71785d80c0bfSVaclav Hapla   *p = tmpLabel;
717908f633c4SVaclav Hapla   ierr = PetscObjectReference((PetscObject)label);CHKERRQ(ierr);
71805d80c0bfSVaclav Hapla   ierr = PetscStrcmp(lname, "depth", &flg);CHKERRQ(ierr);
71815d80c0bfSVaclav Hapla   if (flg) dm->depthLabel = label;
7182c58f1c22SToby Isaac   PetscFunctionReturn(0);
7183c58f1c22SToby Isaac }
7184c58f1c22SToby Isaac 
7185c58f1c22SToby Isaac /*@C
7186e5472504SVaclav Hapla   DMRemoveLabel - Remove the label given by name from this mesh
7187c58f1c22SToby Isaac 
7188c58f1c22SToby Isaac   Not Collective
7189c58f1c22SToby Isaac 
7190c58f1c22SToby Isaac   Input Parameters:
7191c58f1c22SToby Isaac + dm   - The DM object
7192c58f1c22SToby Isaac - name - The label name
7193c58f1c22SToby Isaac 
7194c58f1c22SToby Isaac   Output Parameter:
7195c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent
7196c58f1c22SToby Isaac 
7197c58f1c22SToby Isaac   Level: developer
7198c58f1c22SToby Isaac 
7199e5472504SVaclav Hapla   Notes:
7200e5472504SVaclav Hapla   DMRemoveLabel(dm,name,NULL) removes the label from dm and calls
7201e5472504SVaclav Hapla   DMLabelDestroy() on the label.
7202e5472504SVaclav Hapla 
7203e5472504SVaclav Hapla   DMRemoveLabel(dm,name,&label) removes the label from dm, but it DOES NOT
7204e5472504SVaclav Hapla   call DMLabelDestroy(). Instead, the label is returned and the user is
7205e5472504SVaclav Hapla   responsible of calling DMLabelDestroy() at some point.
7206e5472504SVaclav Hapla 
7207e5472504SVaclav Hapla .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabel(), DMGetLabelValue(), DMSetLabelValue(), DMLabelDestroy(), DMRemoveLabelBySelf()
7208c58f1c22SToby Isaac @*/
7209c58f1c22SToby Isaac PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label)
7210c58f1c22SToby Isaac {
721195d578d6SVaclav Hapla   DMLabelLink    link, *pnext;
7212c58f1c22SToby Isaac   PetscBool      hasLabel;
7213d67d17b1SMatthew G. Knepley   const char    *lname;
7214c58f1c22SToby Isaac   PetscErrorCode ierr;
7215c58f1c22SToby Isaac 
7216c58f1c22SToby Isaac   PetscFunctionBegin;
7217c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7218e5472504SVaclav Hapla   PetscValidCharPointer(name, 2);
7219e5472504SVaclav Hapla   if (label) {
7220e5472504SVaclav Hapla     PetscValidPointer(label, 3);
7221c58f1c22SToby Isaac     *label = NULL;
7222e5472504SVaclav Hapla   }
72235d80c0bfSVaclav Hapla   for (pnext=&dm->labels; (link=*pnext); pnext=&link->next) {
722495d578d6SVaclav Hapla     ierr = PetscObjectGetName((PetscObject) link->label, &lname);CHKERRQ(ierr);
7225d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr);
7226c58f1c22SToby Isaac     if (hasLabel) {
722795d578d6SVaclav Hapla       *pnext = link->next; /* Remove from list */
7228c58f1c22SToby Isaac       ierr = PetscStrcmp(name, "depth", &hasLabel);CHKERRQ(ierr);
722995d578d6SVaclav Hapla       if (hasLabel) dm->depthLabel = NULL;
723095d578d6SVaclav Hapla       if (label) *label = link->label;
723195d578d6SVaclav Hapla       else       {ierr = DMLabelDestroy(&link->label);CHKERRQ(ierr);}
723295d578d6SVaclav Hapla       ierr = PetscFree(link);CHKERRQ(ierr);
7233c58f1c22SToby Isaac       break;
7234c58f1c22SToby Isaac     }
7235c58f1c22SToby Isaac   }
7236c58f1c22SToby Isaac   PetscFunctionReturn(0);
7237c58f1c22SToby Isaac }
7238c58f1c22SToby Isaac 
7239306894acSVaclav Hapla /*@
7240306894acSVaclav Hapla   DMRemoveLabelBySelf - Remove the label from this mesh
7241306894acSVaclav Hapla 
7242306894acSVaclav Hapla   Not Collective
7243306894acSVaclav Hapla 
7244306894acSVaclav Hapla   Input Parameters:
7245306894acSVaclav Hapla + dm   - The DM object
7246306894acSVaclav Hapla . label - (Optional) The DMLabel to be removed from the DM
7247306894acSVaclav Hapla - failNotFound - Should it fail if the label is not found in the DM?
7248306894acSVaclav Hapla 
7249306894acSVaclav Hapla   Level: developer
7250306894acSVaclav Hapla 
7251306894acSVaclav Hapla   Notes:
7252306894acSVaclav Hapla   Only exactly the same instance is removed if found, name match is ignored.
7253306894acSVaclav Hapla   If the DM has an exclusive reference to the label, it gets destroyed and
7254306894acSVaclav Hapla   *label nullified.
7255306894acSVaclav Hapla 
7256306894acSVaclav Hapla .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabel() DMGetLabelValue(), DMSetLabelValue(), DMLabelDestroy(), DMRemoveLabel()
7257306894acSVaclav Hapla @*/
7258306894acSVaclav Hapla PetscErrorCode DMRemoveLabelBySelf(DM dm, DMLabel *label, PetscBool failNotFound)
7259306894acSVaclav Hapla {
726043e45a93SVaclav Hapla   DMLabelLink    link, *pnext;
7261306894acSVaclav Hapla   PetscBool      hasLabel = PETSC_FALSE;
7262306894acSVaclav Hapla   PetscErrorCode ierr;
7263306894acSVaclav Hapla 
7264306894acSVaclav Hapla   PetscFunctionBegin;
7265306894acSVaclav Hapla   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7266306894acSVaclav Hapla   PetscValidPointer(label, 2);
7267f39a9ae0SVaclav Hapla   if (!*label && !failNotFound) PetscFunctionReturn(0);
7268306894acSVaclav Hapla   PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 2);
7269306894acSVaclav Hapla   PetscValidLogicalCollectiveBool(dm,failNotFound,3);
72705d80c0bfSVaclav Hapla   for (pnext=&dm->labels; (link=*pnext); pnext=&link->next) {
727143e45a93SVaclav Hapla     if (*label == link->label) {
7272306894acSVaclav Hapla       hasLabel = PETSC_TRUE;
727343e45a93SVaclav Hapla       *pnext = link->next; /* Remove from list */
7274306894acSVaclav Hapla       if (*label == dm->depthLabel) dm->depthLabel = NULL;
727543e45a93SVaclav Hapla       if (((PetscObject) link->label)->refct < 2) *label = NULL; /* nullify if exclusive reference */
727643e45a93SVaclav Hapla       ierr = DMLabelDestroy(&link->label);CHKERRQ(ierr);
727743e45a93SVaclav Hapla       ierr = PetscFree(link);CHKERRQ(ierr);
7278306894acSVaclav Hapla       break;
7279306894acSVaclav Hapla     }
7280306894acSVaclav Hapla   }
7281306894acSVaclav Hapla   if (!hasLabel && failNotFound) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Given label not found in DM");
7282306894acSVaclav Hapla   PetscFunctionReturn(0);
7283306894acSVaclav Hapla }
7284306894acSVaclav Hapla 
7285c58f1c22SToby Isaac /*@C
7286c58f1c22SToby Isaac   DMGetLabelOutput - Get the output flag for a given label
7287c58f1c22SToby Isaac 
7288c58f1c22SToby Isaac   Not Collective
7289c58f1c22SToby Isaac 
7290c58f1c22SToby Isaac   Input Parameters:
7291c58f1c22SToby Isaac + dm   - The DM object
7292c58f1c22SToby Isaac - name - The label name
7293c58f1c22SToby Isaac 
7294c58f1c22SToby Isaac   Output Parameter:
7295c58f1c22SToby Isaac . output - The flag for output
7296c58f1c22SToby Isaac 
7297c58f1c22SToby Isaac   Level: developer
7298c58f1c22SToby Isaac 
7299c58f1c22SToby Isaac .seealso: DMSetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7300c58f1c22SToby Isaac @*/
7301c58f1c22SToby Isaac PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output)
7302c58f1c22SToby Isaac {
73035d80c0bfSVaclav Hapla   DMLabelLink    next = dm->labels;
7304d67d17b1SMatthew G. Knepley   const char    *lname;
7305c58f1c22SToby Isaac   PetscErrorCode ierr;
7306c58f1c22SToby Isaac 
7307c58f1c22SToby Isaac   PetscFunctionBegin;
7308c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7309c58f1c22SToby Isaac   PetscValidPointer(name, 2);
7310c58f1c22SToby Isaac   PetscValidPointer(output, 3);
7311c58f1c22SToby Isaac   while (next) {
7312c58f1c22SToby Isaac     PetscBool flg;
7313c58f1c22SToby Isaac 
7314d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
7315d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr);
7316c58f1c22SToby Isaac     if (flg) {*output = next->output; PetscFunctionReturn(0);}
7317c58f1c22SToby Isaac     next = next->next;
7318c58f1c22SToby Isaac   }
7319c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name);
7320c58f1c22SToby Isaac }
7321c58f1c22SToby Isaac 
7322c58f1c22SToby Isaac /*@C
7323c58f1c22SToby Isaac   DMSetLabelOutput - Set the output flag for a given label
7324c58f1c22SToby Isaac 
7325c58f1c22SToby Isaac   Not Collective
7326c58f1c22SToby Isaac 
7327c58f1c22SToby Isaac   Input Parameters:
7328c58f1c22SToby Isaac + dm     - The DM object
7329c58f1c22SToby Isaac . name   - The label name
7330c58f1c22SToby Isaac - output - The flag for output
7331c58f1c22SToby Isaac 
7332c58f1c22SToby Isaac   Level: developer
7333c58f1c22SToby Isaac 
7334c58f1c22SToby Isaac .seealso: DMGetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7335c58f1c22SToby Isaac @*/
7336c58f1c22SToby Isaac PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output)
7337c58f1c22SToby Isaac {
73385d80c0bfSVaclav Hapla   DMLabelLink    next = dm->labels;
7339d67d17b1SMatthew G. Knepley   const char    *lname;
7340c58f1c22SToby Isaac   PetscErrorCode ierr;
7341c58f1c22SToby Isaac 
7342c58f1c22SToby Isaac   PetscFunctionBegin;
7343c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7344534a8f05SLisandro Dalcin   PetscValidCharPointer(name, 2);
7345c58f1c22SToby Isaac   while (next) {
7346c58f1c22SToby Isaac     PetscBool flg;
7347c58f1c22SToby Isaac 
7348d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
7349d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr);
7350c58f1c22SToby Isaac     if (flg) {next->output = output; PetscFunctionReturn(0);}
7351c58f1c22SToby Isaac     next = next->next;
7352c58f1c22SToby Isaac   }
7353c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name);
7354c58f1c22SToby Isaac }
7355c58f1c22SToby Isaac 
7356c58f1c22SToby Isaac /*@
7357c58f1c22SToby Isaac   DMCopyLabels - Copy labels from one mesh to another with a superset of the points
7358c58f1c22SToby Isaac 
7359d083f849SBarry Smith   Collective on dmA
7360c58f1c22SToby Isaac 
7361c58f1c22SToby Isaac   Input Parameter:
73625d80c0bfSVaclav Hapla + dmA - The DM object with initial labels
73632e17dfb7SMatthew G. Knepley . dmB - The DM object with copied labels
73645d80c0bfSVaclav Hapla . mode - Copy labels by pointers (PETSC_OWN_POINTER) or duplicate them (PETSC_COPY_VALUES)
73655d80c0bfSVaclav Hapla - all  - Copy all labels including "depth" and "dim" (PETSC_TRUE) which are otherwise ignored (PETSC_FALSE)
7366c58f1c22SToby Isaac 
7367c58f1c22SToby Isaac   Level: intermediate
7368c58f1c22SToby Isaac 
7369c58f1c22SToby Isaac   Note: This is typically used when interpolating or otherwise adding to a mesh
7370c58f1c22SToby Isaac 
73715d80c0bfSVaclav Hapla .seealso: DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMGetCoordinateSection(), DMShareLabels()
7372c58f1c22SToby Isaac @*/
73735d80c0bfSVaclav Hapla PetscErrorCode DMCopyLabels(DM dmA, DM dmB, PetscCopyMode mode, PetscBool all)
7374c58f1c22SToby Isaac {
7375c58f1c22SToby Isaac   DMLabel        label, labelNew;
7376c58f1c22SToby Isaac   const char    *name;
7377c58f1c22SToby Isaac   PetscBool      flg;
73785d80c0bfSVaclav Hapla   DMLabelLink    link;
73795d80c0bfSVaclav Hapla   PetscErrorCode ierr;
7380c58f1c22SToby Isaac 
73815d80c0bfSVaclav Hapla   PetscFunctionBegin;
73825d80c0bfSVaclav Hapla   PetscValidHeaderSpecific(dmA, DM_CLASSID, 1);
73835d80c0bfSVaclav Hapla   PetscValidHeaderSpecific(dmB, DM_CLASSID, 2);
73845d80c0bfSVaclav Hapla   PetscValidLogicalCollectiveEnum(dmA, mode,3);
73855d80c0bfSVaclav Hapla   PetscValidLogicalCollectiveBool(dmA, all, 4);
73865d80c0bfSVaclav Hapla   if (mode==PETSC_USE_POINTER) SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_SUP, "PETSC_USE_POINTER not supported for objects");
73875d80c0bfSVaclav Hapla   if (dmA == dmB) PetscFunctionReturn(0);
73885d80c0bfSVaclav Hapla   for (link=dmA->labels; link; link=link->next) {
73895d80c0bfSVaclav Hapla     label=link->label;
73905d80c0bfSVaclav Hapla     ierr = PetscObjectGetName((PetscObject)label, &name);CHKERRQ(ierr);
73915d80c0bfSVaclav Hapla     if (!all) {
7392c58f1c22SToby Isaac       ierr = PetscStrcmp(name, "depth", &flg);CHKERRQ(ierr);
7393c58f1c22SToby Isaac       if (flg) continue;
73947d5acc75SStefano Zampini       ierr = PetscStrcmp(name, "dim", &flg);CHKERRQ(ierr);
73957d5acc75SStefano Zampini       if (flg) continue;
73965d80c0bfSVaclav Hapla     } else {
73975d80c0bfSVaclav Hapla       dmB->depthLabel = dmA->depthLabel;
73985d80c0bfSVaclav Hapla     }
73995d80c0bfSVaclav Hapla     if (mode==PETSC_COPY_VALUES) {
7400c58f1c22SToby Isaac       ierr = DMLabelDuplicate(label, &labelNew);CHKERRQ(ierr);
74015d80c0bfSVaclav Hapla     } else {
74025d80c0bfSVaclav Hapla       labelNew = label;
74035d80c0bfSVaclav Hapla     }
7404c58f1c22SToby Isaac     ierr = DMAddLabel(dmB, labelNew);CHKERRQ(ierr);
74055d80c0bfSVaclav Hapla     if (mode==PETSC_COPY_VALUES) {ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr);}
7406c58f1c22SToby Isaac   }
7407c58f1c22SToby Isaac   PetscFunctionReturn(0);
7408c58f1c22SToby Isaac }
7409a8fb8f29SToby Isaac 
7410a8fb8f29SToby Isaac /*@
7411a8fb8f29SToby Isaac   DMGetCoarseDM - Get the coarse mesh from which this was obtained by refinement
7412a8fb8f29SToby Isaac 
7413a8fb8f29SToby Isaac   Input Parameter:
7414a8fb8f29SToby Isaac . dm - The DM object
7415a8fb8f29SToby Isaac 
7416a8fb8f29SToby Isaac   Output Parameter:
7417a8fb8f29SToby Isaac . cdm - The coarse DM
7418a8fb8f29SToby Isaac 
7419a8fb8f29SToby Isaac   Level: intermediate
7420a8fb8f29SToby Isaac 
7421a8fb8f29SToby Isaac .seealso: DMSetCoarseDM()
7422a8fb8f29SToby Isaac @*/
7423a8fb8f29SToby Isaac PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm)
7424a8fb8f29SToby Isaac {
7425a8fb8f29SToby Isaac   PetscFunctionBegin;
7426a8fb8f29SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7427a8fb8f29SToby Isaac   PetscValidPointer(cdm, 2);
7428a8fb8f29SToby Isaac   *cdm = dm->coarseMesh;
7429a8fb8f29SToby Isaac   PetscFunctionReturn(0);
7430a8fb8f29SToby Isaac }
7431a8fb8f29SToby Isaac 
7432a8fb8f29SToby Isaac /*@
7433a8fb8f29SToby Isaac   DMSetCoarseDM - Set the coarse mesh from which this was obtained by refinement
7434a8fb8f29SToby Isaac 
7435a8fb8f29SToby Isaac   Input Parameters:
7436a8fb8f29SToby Isaac + dm - The DM object
7437a8fb8f29SToby Isaac - cdm - The coarse DM
7438a8fb8f29SToby Isaac 
7439a8fb8f29SToby Isaac   Level: intermediate
7440a8fb8f29SToby Isaac 
7441a8fb8f29SToby Isaac .seealso: DMGetCoarseDM()
7442a8fb8f29SToby Isaac @*/
7443a8fb8f29SToby Isaac PetscErrorCode DMSetCoarseDM(DM dm, DM cdm)
7444a8fb8f29SToby Isaac {
7445a8fb8f29SToby Isaac   PetscErrorCode ierr;
7446a8fb8f29SToby Isaac 
7447a8fb8f29SToby Isaac   PetscFunctionBegin;
7448a8fb8f29SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7449a8fb8f29SToby Isaac   if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2);
7450a8fb8f29SToby Isaac   ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr);
7451a8fb8f29SToby Isaac   ierr = DMDestroy(&dm->coarseMesh);CHKERRQ(ierr);
7452a8fb8f29SToby Isaac   dm->coarseMesh = cdm;
7453a8fb8f29SToby Isaac   PetscFunctionReturn(0);
7454a8fb8f29SToby Isaac }
7455a8fb8f29SToby Isaac 
745688bdff64SToby Isaac /*@
745788bdff64SToby Isaac   DMGetFineDM - Get the fine mesh from which this was obtained by refinement
745888bdff64SToby Isaac 
745988bdff64SToby Isaac   Input Parameter:
746088bdff64SToby Isaac . dm - The DM object
746188bdff64SToby Isaac 
746288bdff64SToby Isaac   Output Parameter:
746388bdff64SToby Isaac . fdm - The fine DM
746488bdff64SToby Isaac 
746588bdff64SToby Isaac   Level: intermediate
746688bdff64SToby Isaac 
746788bdff64SToby Isaac .seealso: DMSetFineDM()
746888bdff64SToby Isaac @*/
746988bdff64SToby Isaac PetscErrorCode DMGetFineDM(DM dm, DM *fdm)
747088bdff64SToby Isaac {
747188bdff64SToby Isaac   PetscFunctionBegin;
747288bdff64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
747388bdff64SToby Isaac   PetscValidPointer(fdm, 2);
747488bdff64SToby Isaac   *fdm = dm->fineMesh;
747588bdff64SToby Isaac   PetscFunctionReturn(0);
747688bdff64SToby Isaac }
747788bdff64SToby Isaac 
747888bdff64SToby Isaac /*@
747988bdff64SToby Isaac   DMSetFineDM - Set the fine mesh from which this was obtained by refinement
748088bdff64SToby Isaac 
748188bdff64SToby Isaac   Input Parameters:
748288bdff64SToby Isaac + dm - The DM object
748388bdff64SToby Isaac - fdm - The fine DM
748488bdff64SToby Isaac 
748588bdff64SToby Isaac   Level: intermediate
748688bdff64SToby Isaac 
748788bdff64SToby Isaac .seealso: DMGetFineDM()
748888bdff64SToby Isaac @*/
748988bdff64SToby Isaac PetscErrorCode DMSetFineDM(DM dm, DM fdm)
749088bdff64SToby Isaac {
749188bdff64SToby Isaac   PetscErrorCode ierr;
749288bdff64SToby Isaac 
749388bdff64SToby Isaac   PetscFunctionBegin;
749488bdff64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
749588bdff64SToby Isaac   if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2);
749688bdff64SToby Isaac   ierr = PetscObjectReference((PetscObject)fdm);CHKERRQ(ierr);
749788bdff64SToby Isaac   ierr = DMDestroy(&dm->fineMesh);CHKERRQ(ierr);
749888bdff64SToby Isaac   dm->fineMesh = fdm;
749988bdff64SToby Isaac   PetscFunctionReturn(0);
750088bdff64SToby Isaac }
750188bdff64SToby Isaac 
7502a6ba4734SToby Isaac /*=== DMBoundary code ===*/
7503a6ba4734SToby Isaac 
7504a6ba4734SToby Isaac PetscErrorCode DMCopyBoundary(DM dm, DM dmNew)
7505a6ba4734SToby Isaac {
7506e5e52638SMatthew G. Knepley   PetscInt       d;
7507a6ba4734SToby Isaac   PetscErrorCode ierr;
7508a6ba4734SToby Isaac 
7509a6ba4734SToby Isaac   PetscFunctionBegin;
7510e5e52638SMatthew G. Knepley   for (d = 0; d < dm->Nds; ++d) {
7511e5e52638SMatthew G. Knepley     ierr = PetscDSCopyBoundary(dm->probs[d].ds, dmNew->probs[d].ds);CHKERRQ(ierr);
7512e5e52638SMatthew G. Knepley   }
7513a6ba4734SToby Isaac   PetscFunctionReturn(0);
7514a6ba4734SToby Isaac }
7515a6ba4734SToby Isaac 
7516a6ba4734SToby Isaac /*@C
7517a6ba4734SToby Isaac   DMAddBoundary - Add a boundary condition to the model
7518a6ba4734SToby Isaac 
7519a6ba4734SToby Isaac   Input Parameters:
75204c258f51SMatthew G. Knepley + dm          - The DM, with a PetscDS that matches the problem being constrained
7521f971fd6bSMatthew G. Knepley . type        - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
7522a6ba4734SToby Isaac . name        - The BC name
7523a6ba4734SToby Isaac . labelname   - The label defining constrained points
7524a6ba4734SToby Isaac . field       - The field to constrain
7525e8ecbf3fSStefano Zampini . numcomps    - The number of constrained field components (0 will constrain all fields)
7526a6ba4734SToby Isaac . comps       - An array of constrained component numbers
7527a6ba4734SToby Isaac . bcFunc      - A pointwise function giving boundary values
7528a6ba4734SToby Isaac . numids      - The number of DMLabel ids for constrained points
7529a6ba4734SToby Isaac . ids         - An array of ids for constrained points
7530a6ba4734SToby Isaac - ctx         - An optional user context for bcFunc
7531a6ba4734SToby Isaac 
7532a6ba4734SToby Isaac   Options Database Keys:
7533a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
7534a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
7535a6ba4734SToby Isaac 
7536a6ba4734SToby Isaac   Level: developer
7537a6ba4734SToby Isaac 
7538a6ba4734SToby Isaac .seealso: DMGetBoundary()
7539a6ba4734SToby Isaac @*/
7540a30ec4eaSSatish Balay PetscErrorCode DMAddBoundary(DM dm, DMBoundaryConditionType type, const char name[], const char labelname[], PetscInt field, PetscInt numcomps, const PetscInt *comps, void (*bcFunc)(void), PetscInt numids, const PetscInt *ids, void *ctx)
7541a6ba4734SToby Isaac {
7542e5e52638SMatthew G. Knepley   PetscDS        ds;
7543a6ba4734SToby Isaac   PetscErrorCode ierr;
7544a6ba4734SToby Isaac 
7545a6ba4734SToby Isaac   PetscFunctionBegin;
7546a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7547e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7548e5e52638SMatthew G. Knepley   ierr = PetscDSAddBoundary(ds, type,name, labelname, field, numcomps, comps, bcFunc, numids, ids, ctx);CHKERRQ(ierr);
7549a6ba4734SToby Isaac   PetscFunctionReturn(0);
7550a6ba4734SToby Isaac }
7551a6ba4734SToby Isaac 
7552a6ba4734SToby Isaac /*@
7553a6ba4734SToby Isaac   DMGetNumBoundary - Get the number of registered BC
7554a6ba4734SToby Isaac 
7555a6ba4734SToby Isaac   Input Parameters:
7556a6ba4734SToby Isaac . dm - The mesh object
7557a6ba4734SToby Isaac 
7558a6ba4734SToby Isaac   Output Parameters:
7559a6ba4734SToby Isaac . numBd - The number of BC
7560a6ba4734SToby Isaac 
7561a6ba4734SToby Isaac   Level: intermediate
7562a6ba4734SToby Isaac 
7563a6ba4734SToby Isaac .seealso: DMAddBoundary(), DMGetBoundary()
7564a6ba4734SToby Isaac @*/
7565a6ba4734SToby Isaac PetscErrorCode DMGetNumBoundary(DM dm, PetscInt *numBd)
7566a6ba4734SToby Isaac {
7567e5e52638SMatthew G. Knepley   PetscDS        ds;
756858ebd649SToby Isaac   PetscErrorCode ierr;
7569a6ba4734SToby Isaac 
7570a6ba4734SToby Isaac   PetscFunctionBegin;
7571a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7572e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7573e5e52638SMatthew G. Knepley   ierr = PetscDSGetNumBoundary(ds, numBd);CHKERRQ(ierr);
7574a6ba4734SToby Isaac   PetscFunctionReturn(0);
7575a6ba4734SToby Isaac }
7576a6ba4734SToby Isaac 
7577a6ba4734SToby Isaac /*@C
75781c531cf8SMatthew G. Knepley   DMGetBoundary - Get a model boundary condition
7579a6ba4734SToby Isaac 
7580a6ba4734SToby Isaac   Input Parameters:
7581a6ba4734SToby Isaac + dm          - The mesh object
7582a6ba4734SToby Isaac - bd          - The BC number
7583a6ba4734SToby Isaac 
7584a6ba4734SToby Isaac   Output Parameters:
7585f971fd6bSMatthew G. Knepley + type        - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
7586a6ba4734SToby Isaac . name        - The BC name
7587a6ba4734SToby Isaac . labelname   - The label defining constrained points
7588a6ba4734SToby Isaac . field       - The field to constrain
7589a6ba4734SToby Isaac . numcomps    - The number of constrained field components
7590a6ba4734SToby Isaac . comps       - An array of constrained component numbers
7591a6ba4734SToby Isaac . bcFunc      - A pointwise function giving boundary values
7592a6ba4734SToby Isaac . numids      - The number of DMLabel ids for constrained points
7593a6ba4734SToby Isaac . ids         - An array of ids for constrained points
7594a6ba4734SToby Isaac - ctx         - An optional user context for bcFunc
7595a6ba4734SToby Isaac 
7596a6ba4734SToby Isaac   Options Database Keys:
7597a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
7598a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
7599a6ba4734SToby Isaac 
7600a6ba4734SToby Isaac   Level: developer
7601a6ba4734SToby Isaac 
7602a6ba4734SToby Isaac .seealso: DMAddBoundary()
7603a6ba4734SToby Isaac @*/
7604a30ec4eaSSatish Balay PetscErrorCode DMGetBoundary(DM dm, PetscInt bd, DMBoundaryConditionType *type, const char **name, const char **labelname, PetscInt *field, PetscInt *numcomps, const PetscInt **comps, void (**func)(void), PetscInt *numids, const PetscInt **ids, void **ctx)
7605a6ba4734SToby Isaac {
7606e5e52638SMatthew G. Knepley   PetscDS        ds;
760758ebd649SToby Isaac   PetscErrorCode ierr;
7608a6ba4734SToby Isaac 
7609a6ba4734SToby Isaac   PetscFunctionBegin;
7610a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7611e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7612e5e52638SMatthew G. Knepley   ierr = PetscDSGetBoundary(ds, bd, type, name, labelname, field, numcomps, comps, func, numids, ids, ctx);CHKERRQ(ierr);
7613a6ba4734SToby Isaac   PetscFunctionReturn(0);
7614a6ba4734SToby Isaac }
7615a6ba4734SToby Isaac 
7616e6f8dbb6SToby Isaac static PetscErrorCode DMPopulateBoundary(DM dm)
7617e6f8dbb6SToby Isaac {
7618e5e52638SMatthew G. Knepley   PetscDS        ds;
7619dff059c6SToby Isaac   DMBoundary    *lastnext;
7620e6f8dbb6SToby Isaac   DSBoundary     dsbound;
7621e6f8dbb6SToby Isaac   PetscErrorCode ierr;
7622e6f8dbb6SToby Isaac 
7623e6f8dbb6SToby Isaac   PetscFunctionBegin;
7624e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7625e5e52638SMatthew G. Knepley   dsbound = ds->boundary;
762647a1f5adSToby Isaac   if (dm->boundary) {
762747a1f5adSToby Isaac     DMBoundary next = dm->boundary;
762847a1f5adSToby Isaac 
762947a1f5adSToby Isaac     /* quick check to see if the PetscDS has changed */
763047a1f5adSToby Isaac     if (next->dsboundary == dsbound) PetscFunctionReturn(0);
763147a1f5adSToby Isaac     /* the PetscDS has changed: tear down and rebuild */
763247a1f5adSToby Isaac     while (next) {
763347a1f5adSToby Isaac       DMBoundary b = next;
763447a1f5adSToby Isaac 
763547a1f5adSToby Isaac       next = b->next;
763647a1f5adSToby Isaac       ierr = PetscFree(b);CHKERRQ(ierr);
7637a6ba4734SToby Isaac     }
763847a1f5adSToby Isaac     dm->boundary = NULL;
7639a6ba4734SToby Isaac   }
764047a1f5adSToby Isaac 
7641dff059c6SToby Isaac   lastnext = &(dm->boundary);
7642e6f8dbb6SToby Isaac   while (dsbound) {
7643e6f8dbb6SToby Isaac     DMBoundary dmbound;
7644e6f8dbb6SToby Isaac 
7645e6f8dbb6SToby Isaac     ierr = PetscNew(&dmbound);CHKERRQ(ierr);
7646e6f8dbb6SToby Isaac     dmbound->dsboundary = dsbound;
7647e6f8dbb6SToby Isaac     ierr = DMGetLabel(dm, dsbound->labelname, &(dmbound->label));CHKERRQ(ierr);
7648994fe344SLisandro Dalcin     if (!dmbound->label) {ierr = PetscInfo2(dm, "DSBoundary %s wants label %s, which is not in this dm.\n",dsbound->name,dsbound->labelname);CHKERRQ(ierr);}
764947a1f5adSToby Isaac     /* push on the back instead of the front so that it is in the same order as in the PetscDS */
7650dff059c6SToby Isaac     *lastnext = dmbound;
7651dff059c6SToby Isaac     lastnext = &(dmbound->next);
7652dff059c6SToby Isaac     dsbound = dsbound->next;
7653a6ba4734SToby Isaac   }
7654a6ba4734SToby Isaac   PetscFunctionReturn(0);
7655a6ba4734SToby Isaac }
7656a6ba4734SToby Isaac 
7657a6ba4734SToby Isaac PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd)
7658a6ba4734SToby Isaac {
7659b95f2879SToby Isaac   DMBoundary     b;
7660a6ba4734SToby Isaac   PetscErrorCode ierr;
7661a6ba4734SToby Isaac 
7662a6ba4734SToby Isaac   PetscFunctionBegin;
7663a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7664534a8f05SLisandro Dalcin   PetscValidBoolPointer(isBd, 3);
7665a6ba4734SToby Isaac   *isBd = PETSC_FALSE;
7666e6f8dbb6SToby Isaac   ierr = DMPopulateBoundary(dm);CHKERRQ(ierr);
7667b95f2879SToby Isaac   b = dm->boundary;
7668a6ba4734SToby Isaac   while (b && !(*isBd)) {
7669e6f8dbb6SToby Isaac     DMLabel    label = b->label;
7670e6f8dbb6SToby Isaac     DSBoundary dsb = b->dsboundary;
76713424c85cSToby Isaac 
76723424c85cSToby Isaac     if (label) {
7673a6ba4734SToby Isaac       PetscInt i;
7674a6ba4734SToby Isaac 
7675e6f8dbb6SToby Isaac       for (i = 0; i < dsb->numids && !(*isBd); ++i) {
7676e6f8dbb6SToby Isaac         ierr = DMLabelStratumHasPoint(label, dsb->ids[i], point, isBd);CHKERRQ(ierr);
7677a6ba4734SToby Isaac       }
7678a6ba4734SToby Isaac     }
7679a6ba4734SToby Isaac     b = b->next;
7680a6ba4734SToby Isaac   }
7681a6ba4734SToby Isaac   PetscFunctionReturn(0);
7682a6ba4734SToby Isaac }
76834d6f44ffSToby Isaac 
76844d6f44ffSToby Isaac /*@C
76854d6f44ffSToby Isaac   DMProjectFunction - This projects the given function into the function space provided.
76864d6f44ffSToby Isaac 
76874d6f44ffSToby Isaac   Input Parameters:
76884d6f44ffSToby Isaac + dm      - The DM
76890709b2feSToby Isaac . time    - The time
76904d6f44ffSToby Isaac . funcs   - The coordinate functions to evaluate, one per field
76914d6f44ffSToby Isaac . ctxs    - Optional array of contexts to pass to each coordinate function.  ctxs itself may be null.
76924d6f44ffSToby Isaac - mode    - The insertion mode for values
76934d6f44ffSToby Isaac 
76944d6f44ffSToby Isaac   Output Parameter:
76954d6f44ffSToby Isaac . X - vector
76964d6f44ffSToby Isaac 
76974d6f44ffSToby Isaac    Calling sequence of func:
76980709b2feSToby Isaac $    func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx);
76994d6f44ffSToby Isaac 
77004d6f44ffSToby Isaac +  dim - The spatial dimension
77014d6f44ffSToby Isaac .  x   - The coordinates
77024d6f44ffSToby Isaac .  Nf  - The number of fields
77034d6f44ffSToby Isaac .  u   - The output field values
77044d6f44ffSToby Isaac -  ctx - optional user-defined function context
77054d6f44ffSToby Isaac 
77064d6f44ffSToby Isaac   Level: developer
77074d6f44ffSToby Isaac 
77082716604bSToby Isaac .seealso: DMComputeL2Diff()
77094d6f44ffSToby Isaac @*/
77100709b2feSToby Isaac PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X)
77114d6f44ffSToby Isaac {
77124d6f44ffSToby Isaac   Vec            localX;
77134d6f44ffSToby Isaac   PetscErrorCode ierr;
77144d6f44ffSToby Isaac 
77154d6f44ffSToby Isaac   PetscFunctionBegin;
77164d6f44ffSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
77174d6f44ffSToby Isaac   ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr);
77180709b2feSToby Isaac   ierr = DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr);
77194d6f44ffSToby Isaac   ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr);
77204d6f44ffSToby Isaac   ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr);
77214d6f44ffSToby Isaac   ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr);
77224d6f44ffSToby Isaac   PetscFunctionReturn(0);
77234d6f44ffSToby Isaac }
77244d6f44ffSToby Isaac 
77250709b2feSToby Isaac PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX)
77264d6f44ffSToby Isaac {
77274d6f44ffSToby Isaac   PetscErrorCode ierr;
77284d6f44ffSToby Isaac 
77294d6f44ffSToby Isaac   PetscFunctionBegin;
77304d6f44ffSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
77314d6f44ffSToby Isaac   PetscValidHeaderSpecific(localX,VEC_CLASSID,5);
77320918c465SMatthew G. Knepley   if (!dm->ops->projectfunctionlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLocal",((PetscObject)dm)->type_name);
77330709b2feSToby Isaac   ierr = (dm->ops->projectfunctionlocal) (dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr);
77344d6f44ffSToby Isaac   PetscFunctionReturn(0);
77354d6f44ffSToby Isaac }
77364d6f44ffSToby Isaac 
77372c53366bSMatthew G. Knepley PetscErrorCode DMProjectFunctionLabel(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X)
77382c53366bSMatthew G. Knepley {
77392c53366bSMatthew G. Knepley   Vec            localX;
77402c53366bSMatthew G. Knepley   PetscErrorCode ierr;
77412c53366bSMatthew G. Knepley 
77422c53366bSMatthew G. Knepley   PetscFunctionBegin;
77432c53366bSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
77442c53366bSMatthew G. Knepley   ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr);
77452c53366bSMatthew G. Knepley   ierr = DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr);
77462c53366bSMatthew G. Knepley   ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr);
77472c53366bSMatthew G. Knepley   ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr);
77482c53366bSMatthew G. Knepley   ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr);
77492c53366bSMatthew G. Knepley   PetscFunctionReturn(0);
77502c53366bSMatthew G. Knepley }
77512c53366bSMatthew G. Knepley 
77521c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFunctionLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX)
77534d6f44ffSToby Isaac {
77544d6f44ffSToby Isaac   PetscErrorCode ierr;
77554d6f44ffSToby Isaac 
77564d6f44ffSToby Isaac   PetscFunctionBegin;
77574d6f44ffSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
77584d6f44ffSToby Isaac   PetscValidHeaderSpecific(localX,VEC_CLASSID,5);
77590918c465SMatthew G. Knepley   if (!dm->ops->projectfunctionlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLabelLocal",((PetscObject)dm)->type_name);
77601c531cf8SMatthew G. Knepley   ierr = (dm->ops->projectfunctionlabellocal) (dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr);
77614d6f44ffSToby Isaac   PetscFunctionReturn(0);
77624d6f44ffSToby Isaac }
77632716604bSToby Isaac 
77648c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal(DM dm, PetscReal time, Vec localU,
77658c6c5593SMatthew G. Knepley                                    void (**funcs)(PetscInt, PetscInt, PetscInt,
77668c6c5593SMatthew G. Knepley                                                   const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
77678c6c5593SMatthew G. Knepley                                                   const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
7768191494d9SMatthew G. Knepley                                                   PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]),
77698c6c5593SMatthew G. Knepley                                    InsertMode mode, Vec localX)
77708c6c5593SMatthew G. Knepley {
77718c6c5593SMatthew G. Knepley   PetscErrorCode ierr;
77728c6c5593SMatthew G. Knepley 
77738c6c5593SMatthew G. Knepley   PetscFunctionBegin;
77748c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
77758c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localU,VEC_CLASSID,3);
77768c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localX,VEC_CLASSID,6);
77770918c465SMatthew G. Knepley   if (!dm->ops->projectfieldlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name);
77788c6c5593SMatthew G. Knepley   ierr = (dm->ops->projectfieldlocal) (dm, time, localU, funcs, mode, localX);CHKERRQ(ierr);
77798c6c5593SMatthew G. Knepley   PetscFunctionReturn(0);
77808c6c5593SMatthew G. Knepley }
77818c6c5593SMatthew G. Knepley 
77821c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU,
77838c6c5593SMatthew G. Knepley                                         void (**funcs)(PetscInt, PetscInt, PetscInt,
77848c6c5593SMatthew G. Knepley                                                        const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
77858c6c5593SMatthew G. Knepley                                                        const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
7786191494d9SMatthew G. Knepley                                                        PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]),
77878c6c5593SMatthew G. Knepley                                         InsertMode mode, Vec localX)
77888c6c5593SMatthew G. Knepley {
77898c6c5593SMatthew G. Knepley   PetscErrorCode ierr;
77908c6c5593SMatthew G. Knepley 
77918c6c5593SMatthew G. Knepley   PetscFunctionBegin;
77928c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
77938c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localU,VEC_CLASSID,6);
77948c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localX,VEC_CLASSID,9);
77950918c465SMatthew G. Knepley   if (!dm->ops->projectfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name);
77961c531cf8SMatthew G. Knepley   ierr = (dm->ops->projectfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX);CHKERRQ(ierr);
77978c6c5593SMatthew G. Knepley   PetscFunctionReturn(0);
77988c6c5593SMatthew G. Knepley }
77998c6c5593SMatthew G. Knepley 
78002716604bSToby Isaac /*@C
78012716604bSToby Isaac   DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h.
78022716604bSToby Isaac 
78032716604bSToby Isaac   Input Parameters:
78042716604bSToby Isaac + dm    - The DM
78050709b2feSToby Isaac . time  - The time
78062716604bSToby Isaac . funcs - The functions to evaluate for each field component
78072716604bSToby Isaac . ctxs  - Optional array of contexts to pass to each function, or NULL.
7808574a98acSMatthew G. Knepley - X     - The coefficient vector u_h, a global vector
78092716604bSToby Isaac 
78102716604bSToby Isaac   Output Parameter:
78112716604bSToby Isaac . diff - The diff ||u - u_h||_2
78122716604bSToby Isaac 
78132716604bSToby Isaac   Level: developer
78142716604bSToby Isaac 
78151189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff()
78162716604bSToby Isaac @*/
78170709b2feSToby Isaac PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff)
78182716604bSToby Isaac {
78192716604bSToby Isaac   PetscErrorCode ierr;
78202716604bSToby Isaac 
78212716604bSToby Isaac   PetscFunctionBegin;
78222716604bSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7823b698f381SToby Isaac   PetscValidHeaderSpecific(X,VEC_CLASSID,5);
78240918c465SMatthew G. Knepley   if (!dm->ops->computel2diff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2Diff",((PetscObject)dm)->type_name);
78250709b2feSToby Isaac   ierr = (dm->ops->computel2diff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr);
78262716604bSToby Isaac   PetscFunctionReturn(0);
78272716604bSToby Isaac }
7828b698f381SToby Isaac 
7829b698f381SToby Isaac /*@C
7830b698f381SToby Isaac   DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h.
7831b698f381SToby Isaac 
7832d083f849SBarry Smith   Collective on dm
7833d083f849SBarry Smith 
7834b698f381SToby Isaac   Input Parameters:
7835b698f381SToby Isaac + dm    - The DM
7836b698f381SToby Isaac , time  - The time
7837b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component
7838b698f381SToby Isaac . ctxs  - Optional array of contexts to pass to each function, or NULL.
7839574a98acSMatthew G. Knepley . X     - The coefficient vector u_h, a global vector
7840b698f381SToby Isaac - n     - The vector to project along
7841b698f381SToby Isaac 
7842b698f381SToby Isaac   Output Parameter:
7843b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2
7844b698f381SToby Isaac 
7845b698f381SToby Isaac   Level: developer
7846b698f381SToby Isaac 
7847b698f381SToby Isaac .seealso: DMProjectFunction(), DMComputeL2Diff()
7848b698f381SToby Isaac @*/
7849b698f381SToby Isaac PetscErrorCode DMComputeL2GradientDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, const PetscReal n[], PetscReal *diff)
7850b698f381SToby Isaac {
7851b698f381SToby Isaac   PetscErrorCode ierr;
7852b698f381SToby Isaac 
7853b698f381SToby Isaac   PetscFunctionBegin;
7854b698f381SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7855b698f381SToby Isaac   PetscValidHeaderSpecific(X,VEC_CLASSID,5);
7856b698f381SToby Isaac   if (!dm->ops->computel2gradientdiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2GradientDiff",((PetscObject)dm)->type_name);
7857b698f381SToby Isaac   ierr = (dm->ops->computel2gradientdiff)(dm,time,funcs,ctxs,X,n,diff);CHKERRQ(ierr);
7858b698f381SToby Isaac   PetscFunctionReturn(0);
7859b698f381SToby Isaac }
7860b698f381SToby Isaac 
78612a16baeaSToby Isaac /*@C
78622a16baeaSToby Isaac   DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components.
78632a16baeaSToby Isaac 
7864d083f849SBarry Smith   Collective on dm
7865d083f849SBarry Smith 
78662a16baeaSToby Isaac   Input Parameters:
78672a16baeaSToby Isaac + dm    - The DM
78682a16baeaSToby Isaac . time  - The time
78692a16baeaSToby Isaac . funcs - The functions to evaluate for each field component
78702a16baeaSToby Isaac . ctxs  - Optional array of contexts to pass to each function, or NULL.
7871574a98acSMatthew G. Knepley - X     - The coefficient vector u_h, a global vector
78722a16baeaSToby Isaac 
78732a16baeaSToby Isaac   Output Parameter:
78742a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2
78752a16baeaSToby Isaac 
78762a16baeaSToby Isaac   Level: developer
78772a16baeaSToby Isaac 
78781189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff()
78792a16baeaSToby Isaac @*/
78801189c1efSToby Isaac PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[])
78812a16baeaSToby Isaac {
78822a16baeaSToby Isaac   PetscErrorCode ierr;
78832a16baeaSToby Isaac 
78842a16baeaSToby Isaac   PetscFunctionBegin;
78852a16baeaSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
78862a16baeaSToby Isaac   PetscValidHeaderSpecific(X,VEC_CLASSID,5);
78870918c465SMatthew G. Knepley   if (!dm->ops->computel2fielddiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2FieldDiff",((PetscObject)dm)->type_name);
78882a16baeaSToby Isaac   ierr = (dm->ops->computel2fielddiff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr);
78892a16baeaSToby Isaac   PetscFunctionReturn(0);
78902a16baeaSToby Isaac }
78912a16baeaSToby Isaac 
7892df0b854cSToby Isaac /*@C
7893df0b854cSToby Isaac   DMAdaptLabel - Adapt a dm based on a label with values interpreted as coarsening and refining flags.  Specific implementations of DM maybe have
7894cd3c525cSToby Isaac                  specialized flags, but all implementations should accept flag values DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN.
7895df0b854cSToby Isaac 
7896df0b854cSToby Isaac   Collective on dm
7897df0b854cSToby Isaac 
7898df0b854cSToby Isaac   Input parameters:
7899df0b854cSToby Isaac + dm - the pre-adaptation DM object
7900a1b0c543SToby Isaac - label - label with the flags
7901df0b854cSToby Isaac 
7902df0b854cSToby Isaac   Output parameters:
79030d1cd5e0SMatthew G. Knepley . dmAdapt - the adapted DM object: may be NULL if an adapted DM could not be produced.
7904df0b854cSToby Isaac 
7905df0b854cSToby Isaac   Level: intermediate
79060d1cd5e0SMatthew G. Knepley 
79070d1cd5e0SMatthew G. Knepley .seealso: DMAdaptMetric(), DMCoarsen(), DMRefine()
7908df0b854cSToby Isaac @*/
79090d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptLabel(DM dm, DMLabel label, DM *dmAdapt)
7910df0b854cSToby Isaac {
7911df0b854cSToby Isaac   PetscErrorCode ierr;
7912df0b854cSToby Isaac 
7913df0b854cSToby Isaac   PetscFunctionBegin;
7914df0b854cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7915a1b0c543SToby Isaac   PetscValidPointer(label,2);
79160d1cd5e0SMatthew G. Knepley   PetscValidPointer(dmAdapt,3);
79170d1cd5e0SMatthew G. Knepley   *dmAdapt = NULL;
79186f25b0d8SLisandro Dalcin   if (!dm->ops->adaptlabel) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptLabel",((PetscObject)dm)->type_name);
79190d1cd5e0SMatthew G. Knepley   ierr = (dm->ops->adaptlabel)(dm, label, dmAdapt);CHKERRQ(ierr);
79200d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
79210d1cd5e0SMatthew G. Knepley }
79220d1cd5e0SMatthew G. Knepley 
79230d1cd5e0SMatthew G. Knepley /*@C
79240d1cd5e0SMatthew G. Knepley   DMAdaptMetric - Generates a mesh adapted to the specified metric field using the pragmatic library.
79250d1cd5e0SMatthew G. Knepley 
79260d1cd5e0SMatthew G. Knepley   Input Parameters:
79270d1cd5e0SMatthew G. Knepley + dm - The DM object
79280d1cd5e0SMatthew G. Knepley . metric - The metric to which the mesh is adapted, defined vertex-wise.
79296f25b0d8SLisandro Dalcin - bdLabel - Label for boundary tags, which will be preserved in the output mesh. bdLabel should be NULL if there is no such label, and should be different from "_boundary_".
79300d1cd5e0SMatthew G. Knepley 
79310d1cd5e0SMatthew G. Knepley   Output Parameter:
79320d1cd5e0SMatthew G. Knepley . dmAdapt  - Pointer to the DM object containing the adapted mesh
79330d1cd5e0SMatthew G. Knepley 
79340d1cd5e0SMatthew G. Knepley   Note: The label in the adapted mesh will be registered under the name of the input DMLabel object
79350d1cd5e0SMatthew G. Knepley 
79360d1cd5e0SMatthew G. Knepley   Level: advanced
79370d1cd5e0SMatthew G. Knepley 
79380d1cd5e0SMatthew G. Knepley .seealso: DMAdaptLabel(), DMCoarsen(), DMRefine()
79390d1cd5e0SMatthew G. Knepley @*/
79400d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptMetric(DM dm, Vec metric, DMLabel bdLabel, DM *dmAdapt)
79410d1cd5e0SMatthew G. Knepley {
79420d1cd5e0SMatthew G. Knepley   PetscErrorCode ierr;
79430d1cd5e0SMatthew G. Knepley 
79440d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
79450d1cd5e0SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
79460d1cd5e0SMatthew G. Knepley   PetscValidHeaderSpecific(metric, VEC_CLASSID, 2);
79470d1cd5e0SMatthew G. Knepley   if (bdLabel) PetscValidPointer(bdLabel, 3);
79480d1cd5e0SMatthew G. Knepley   PetscValidPointer(dmAdapt, 4);
79496f25b0d8SLisandro Dalcin   *dmAdapt = NULL;
79506f25b0d8SLisandro Dalcin   if (!dm->ops->adaptmetric) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptMetric",((PetscObject)dm)->type_name);
79510d1cd5e0SMatthew G. Knepley   ierr = (dm->ops->adaptmetric)(dm, metric, bdLabel, dmAdapt);CHKERRQ(ierr);
7952df0b854cSToby Isaac   PetscFunctionReturn(0);
7953df0b854cSToby Isaac }
7954c4088d22SMatthew G. Knepley 
7955502a2867SDave May /*@C
7956502a2867SDave May  DMGetNeighbors - Gets an array containing the MPI rank of all the processes neighbors
7957502a2867SDave May 
7958502a2867SDave May  Not Collective
7959502a2867SDave May 
7960502a2867SDave May  Input Parameter:
7961502a2867SDave May  . dm    - The DM
7962502a2867SDave May 
7963502a2867SDave May  Output Parameter:
7964502a2867SDave May  . nranks - the number of neighbours
7965502a2867SDave May  . ranks - the neighbors ranks
7966502a2867SDave May 
7967502a2867SDave May  Notes:
7968502a2867SDave May  Do not free the array, it is freed when the DM is destroyed.
7969502a2867SDave May 
7970502a2867SDave May  Level: beginner
7971502a2867SDave May 
7972dec1416fSJunchao Zhang  .seealso: DMDAGetNeighbors(), PetscSFGetRootRanks()
7973502a2867SDave May @*/
7974502a2867SDave May PetscErrorCode DMGetNeighbors(DM dm,PetscInt *nranks,const PetscMPIInt *ranks[])
7975502a2867SDave May {
7976502a2867SDave May   PetscErrorCode ierr;
7977502a2867SDave May 
7978502a2867SDave May   PetscFunctionBegin;
7979502a2867SDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
79800918c465SMatthew G. Knepley   if (!dm->ops->getneighbors) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMGetNeighbors",((PetscObject)dm)->type_name);
7981502a2867SDave May   ierr = (dm->ops->getneighbors)(dm,nranks,ranks);CHKERRQ(ierr);
7982502a2867SDave May   PetscFunctionReturn(0);
7983502a2867SDave May }
7984502a2867SDave May 
7985531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */
7986531c7667SBarry Smith 
7987531c7667SBarry Smith /*
7988531c7667SBarry Smith     Converts the input vector to a ghosted vector and then calls the standard coloring code.
7989531c7667SBarry Smith     This has be a different function because it requires DM which is not defined in the Mat library
7990531c7667SBarry Smith */
7991531c7667SBarry Smith PetscErrorCode  MatFDColoringApply_AIJDM(Mat J,MatFDColoring coloring,Vec x1,void *sctx)
7992531c7667SBarry Smith {
7993531c7667SBarry Smith   PetscErrorCode ierr;
7994531c7667SBarry Smith 
7995531c7667SBarry Smith   PetscFunctionBegin;
7996531c7667SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
7997531c7667SBarry Smith     Vec x1local;
7998531c7667SBarry Smith     DM  dm;
7999531c7667SBarry Smith     ierr = MatGetDM(J,&dm);CHKERRQ(ierr);
8000531c7667SBarry Smith     if (!dm) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_INCOMP,"IS_COLORING_LOCAL requires a DM");
8001531c7667SBarry Smith     ierr = DMGetLocalVector(dm,&x1local);CHKERRQ(ierr);
8002531c7667SBarry Smith     ierr = DMGlobalToLocalBegin(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr);
8003531c7667SBarry Smith     ierr = DMGlobalToLocalEnd(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr);
8004531c7667SBarry Smith     x1   = x1local;
8005531c7667SBarry Smith   }
8006531c7667SBarry Smith   ierr = MatFDColoringApply_AIJ(J,coloring,x1,sctx);CHKERRQ(ierr);
8007531c7667SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
8008531c7667SBarry Smith     DM  dm;
8009531c7667SBarry Smith     ierr = MatGetDM(J,&dm);CHKERRQ(ierr);
8010531c7667SBarry Smith     ierr = DMRestoreLocalVector(dm,&x1);CHKERRQ(ierr);
8011531c7667SBarry Smith   }
8012531c7667SBarry Smith   PetscFunctionReturn(0);
8013531c7667SBarry Smith }
8014531c7667SBarry Smith 
8015531c7667SBarry Smith /*@
8016531c7667SBarry Smith     MatFDColoringUseDM - allows a MatFDColoring object to use the DM associated with the matrix to use a IS_COLORING_LOCAL coloring
8017531c7667SBarry Smith 
8018531c7667SBarry Smith     Input Parameter:
8019531c7667SBarry Smith .    coloring - the MatFDColoring object
8020531c7667SBarry Smith 
802195452b02SPatrick Sanan     Developer Notes:
802295452b02SPatrick Sanan     this routine exists because the PETSc Mat library does not know about the DM objects
8023531c7667SBarry Smith 
80241b266c99SBarry Smith     Level: advanced
80251b266c99SBarry Smith 
8026531c7667SBarry Smith .seealso: MatFDColoring, MatFDColoringCreate(), ISColoringType
8027531c7667SBarry Smith @*/
8028531c7667SBarry Smith PetscErrorCode  MatFDColoringUseDM(Mat coloring,MatFDColoring fdcoloring)
8029531c7667SBarry Smith {
8030531c7667SBarry Smith   PetscFunctionBegin;
8031531c7667SBarry Smith   coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM;
8032531c7667SBarry Smith   PetscFunctionReturn(0);
8033531c7667SBarry Smith }
80348320bc6fSPatrick Sanan 
80358320bc6fSPatrick Sanan /*@
80368320bc6fSPatrick Sanan     DMGetCompatibility - determine if two DMs are compatible
80378320bc6fSPatrick Sanan 
80388320bc6fSPatrick Sanan     Collective
80398320bc6fSPatrick Sanan 
80408320bc6fSPatrick Sanan     Input Parameters:
80418320bc6fSPatrick Sanan +    dm - the first DM
80428320bc6fSPatrick Sanan -    dm2 - the second DM
80438320bc6fSPatrick Sanan 
80448320bc6fSPatrick Sanan     Output Parameters:
80458320bc6fSPatrick Sanan +    compatible - whether or not the two DMs are compatible
80468320bc6fSPatrick Sanan -    set - whether or not the compatible value was set
80478320bc6fSPatrick Sanan 
80488320bc6fSPatrick Sanan     Notes:
80498320bc6fSPatrick Sanan     Two DMs are deemed compatible if they represent the same parallel decomposition
80503d862458SPatrick Sanan     of the same topology. This implies that the section (field data) on one
80518320bc6fSPatrick Sanan     "makes sense" with respect to the topology and parallel decomposition of the other.
80523d862458SPatrick Sanan     Loosely speaking, compatible DMs represent the same domain and parallel
80533d862458SPatrick Sanan     decomposition, but hold different data.
80548320bc6fSPatrick Sanan 
80558320bc6fSPatrick Sanan     Typically, one would confirm compatibility if intending to simultaneously iterate
80568320bc6fSPatrick Sanan     over a pair of vectors obtained from different DMs.
80578320bc6fSPatrick Sanan 
80588320bc6fSPatrick Sanan     For example, two DMDA objects are compatible if they have the same local
80598320bc6fSPatrick Sanan     and global sizes and the same stencil width. They can have different numbers
80608320bc6fSPatrick Sanan     of degrees of freedom per node. Thus, one could use the node numbering from
80618320bc6fSPatrick Sanan     either DM in bounds for a loop over vectors derived from either DM.
80628320bc6fSPatrick Sanan 
80638320bc6fSPatrick Sanan     Consider the operation of summing data living on a 2-dof DMDA to data living
80648320bc6fSPatrick Sanan     on a 1-dof DMDA, which should be compatible, as in the following snippet.
80658320bc6fSPatrick Sanan .vb
80668320bc6fSPatrick Sanan   ...
80678320bc6fSPatrick Sanan   ierr = DMGetCompatibility(da1,da2,&compatible,&set);CHKERRQ(ierr);
80688320bc6fSPatrick Sanan   if (set && compatible)  {
80698320bc6fSPatrick Sanan     ierr = DMDAVecGetArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr);
80708320bc6fSPatrick Sanan     ierr = DMDAVecGetArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr);
80713d862458SPatrick Sanan     ierr = DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL);CHKERRQ(ierr);
80728320bc6fSPatrick Sanan     for (j=y; j<y+n; ++j) {
80738320bc6fSPatrick Sanan       for (i=x; i<x+m, ++i) {
80748320bc6fSPatrick Sanan         arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1];
80758320bc6fSPatrick Sanan       }
80768320bc6fSPatrick Sanan     }
80778320bc6fSPatrick Sanan     ierr = DMDAVecRestoreArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr);
80788320bc6fSPatrick Sanan     ierr = DMDAVecRestoreArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr);
80798320bc6fSPatrick Sanan   } else {
80808320bc6fSPatrick Sanan     SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible");
80818320bc6fSPatrick Sanan   }
80828320bc6fSPatrick Sanan   ...
80838320bc6fSPatrick Sanan .ve
80848320bc6fSPatrick Sanan 
80858320bc6fSPatrick Sanan     Checking compatibility might be expensive for a given implementation of DM,
80868320bc6fSPatrick Sanan     or might be impossible to unambiguously confirm or deny. For this reason,
80878320bc6fSPatrick Sanan     this function may decline to determine compatibility, and hence users should
80888320bc6fSPatrick Sanan     always check the "set" output parameter.
80898320bc6fSPatrick Sanan 
80908320bc6fSPatrick Sanan     A DM is always compatible with itself.
80918320bc6fSPatrick Sanan 
80928320bc6fSPatrick Sanan     In the current implementation, DMs which live on "unequal" communicators
80938320bc6fSPatrick Sanan     (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed
80948320bc6fSPatrick Sanan     incompatible.
80958320bc6fSPatrick Sanan 
80968320bc6fSPatrick Sanan     This function is labeled "Collective," as information about all subdomains
80978320bc6fSPatrick Sanan     is required on each rank. However, in DM implementations which store all this
80988320bc6fSPatrick Sanan     information locally, this function may be merely "Logically Collective".
80998320bc6fSPatrick Sanan 
81008320bc6fSPatrick Sanan     Developer Notes:
81013d862458SPatrick Sanan     Compatibility is assumed to be a symmetric concept; DM A is compatible with DM B
81023d862458SPatrick Sanan     iff B is compatible with A. Thus, this function checks the implementations
81038320bc6fSPatrick Sanan     of both dm and dm2 (if they are of different types), attempting to determine
81048320bc6fSPatrick Sanan     compatibility. It is left to DM implementers to ensure that symmetry is
81058320bc6fSPatrick Sanan     preserved. The simplest way to do this is, when implementing type-specific
81063d862458SPatrick Sanan     logic for this function, is to check for existing logic in the implementation
81073d862458SPatrick Sanan     of other DM types and let *set = PETSC_FALSE if found.
81088320bc6fSPatrick Sanan 
81098320bc6fSPatrick Sanan     Level: advanced
81108320bc6fSPatrick Sanan 
81113d862458SPatrick Sanan .seealso: DM, DMDACreateCompatibleDMDA(), DMStagCreateCompatibleDMStag()
81128320bc6fSPatrick Sanan @*/
81138320bc6fSPatrick Sanan 
81148320bc6fSPatrick Sanan PetscErrorCode DMGetCompatibility(DM dm,DM dm2,PetscBool *compatible,PetscBool *set)
81158320bc6fSPatrick Sanan {
81168320bc6fSPatrick Sanan   PetscErrorCode ierr;
81178320bc6fSPatrick Sanan   PetscMPIInt    compareResult;
81188320bc6fSPatrick Sanan   DMType         type,type2;
81198320bc6fSPatrick Sanan   PetscBool      sameType;
81208320bc6fSPatrick Sanan 
81218320bc6fSPatrick Sanan   PetscFunctionBegin;
81228320bc6fSPatrick Sanan   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
81238320bc6fSPatrick Sanan   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
81248320bc6fSPatrick Sanan 
81258320bc6fSPatrick Sanan   /* Declare a DM compatible with itself */
81268320bc6fSPatrick Sanan   if (dm == dm2) {
81278320bc6fSPatrick Sanan     *set = PETSC_TRUE;
81288320bc6fSPatrick Sanan     *compatible = PETSC_TRUE;
81298320bc6fSPatrick Sanan     PetscFunctionReturn(0);
81308320bc6fSPatrick Sanan   }
81318320bc6fSPatrick Sanan 
81328320bc6fSPatrick Sanan   /* Declare a DM incompatible with a DM that lives on an "unequal"
81338320bc6fSPatrick Sanan      communicator. Note that this does not preclude compatibility with
81348320bc6fSPatrick Sanan      DMs living on "congruent" or "similar" communicators, but this must be
81358320bc6fSPatrick Sanan      determined by the implementation-specific logic */
81368320bc6fSPatrick Sanan   ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dm),PetscObjectComm((PetscObject)dm2),&compareResult);CHKERRQ(ierr);
81378320bc6fSPatrick Sanan   if (compareResult == MPI_UNEQUAL) {
81388320bc6fSPatrick Sanan     *set = PETSC_TRUE;
81398320bc6fSPatrick Sanan     *compatible = PETSC_FALSE;
81408320bc6fSPatrick Sanan     PetscFunctionReturn(0);
81418320bc6fSPatrick Sanan   }
81428320bc6fSPatrick Sanan 
81438320bc6fSPatrick Sanan   /* Pass to the implementation-specific routine, if one exists. */
81448320bc6fSPatrick Sanan   if (dm->ops->getcompatibility) {
81458320bc6fSPatrick Sanan     ierr = (*dm->ops->getcompatibility)(dm,dm2,compatible,set);CHKERRQ(ierr);
8146b9d85ea2SLisandro Dalcin     if (*set) PetscFunctionReturn(0);
81478320bc6fSPatrick Sanan   }
81488320bc6fSPatrick Sanan 
81498320bc6fSPatrick Sanan   /* If dm and dm2 are of different types, then attempt to check compatibility
81508320bc6fSPatrick Sanan      with an implementation of this function from dm2 */
81518320bc6fSPatrick Sanan   ierr = DMGetType(dm,&type);CHKERRQ(ierr);
81528320bc6fSPatrick Sanan   ierr = DMGetType(dm2,&type2);CHKERRQ(ierr);
81538320bc6fSPatrick Sanan   ierr = PetscStrcmp(type,type2,&sameType);CHKERRQ(ierr);
81548320bc6fSPatrick Sanan   if (!sameType && dm2->ops->getcompatibility) {
81558320bc6fSPatrick Sanan     ierr = (*dm2->ops->getcompatibility)(dm2,dm,compatible,set);CHKERRQ(ierr); /* Note argument order */
81568320bc6fSPatrick Sanan   } else {
81578320bc6fSPatrick Sanan     *set = PETSC_FALSE;
81588320bc6fSPatrick Sanan   }
81598320bc6fSPatrick Sanan   PetscFunctionReturn(0);
81608320bc6fSPatrick Sanan }
8161*c0f0dcc3SMatthew G. Knepley 
8162*c0f0dcc3SMatthew G. Knepley /*@C
8163*c0f0dcc3SMatthew G. Knepley   DMMonitorSet - Sets an ADDITIONAL function that is to be used after a solve to monitor discretization performance.
8164*c0f0dcc3SMatthew G. Knepley 
8165*c0f0dcc3SMatthew G. Knepley   Logically Collective on DM
8166*c0f0dcc3SMatthew G. Knepley 
8167*c0f0dcc3SMatthew G. Knepley   Input Parameters:
8168*c0f0dcc3SMatthew G. Knepley + DM - the DM
8169*c0f0dcc3SMatthew G. Knepley . f - the monitor function
8170*c0f0dcc3SMatthew G. Knepley . mctx - [optional] user-defined context for private data for the monitor routine (use NULL if no context is desired)
8171*c0f0dcc3SMatthew G. Knepley - monitordestroy - [optional] routine that frees monitor context (may be NULL)
8172*c0f0dcc3SMatthew G. Knepley 
8173*c0f0dcc3SMatthew G. Knepley   Options Database Keys:
8174*c0f0dcc3SMatthew G. Knepley - -dm_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to DMMonitorSet(), but
8175*c0f0dcc3SMatthew G. Knepley                             does not cancel those set via the options database.
8176*c0f0dcc3SMatthew G. Knepley 
8177*c0f0dcc3SMatthew G. Knepley   Notes:
8178*c0f0dcc3SMatthew G. Knepley   Several different monitoring routines may be set by calling
8179*c0f0dcc3SMatthew G. Knepley   DMMonitorSet() multiple times; all will be called in the
8180*c0f0dcc3SMatthew G. Knepley   order in which they were set.
8181*c0f0dcc3SMatthew G. Knepley 
8182*c0f0dcc3SMatthew G. Knepley   Fortran Notes:
8183*c0f0dcc3SMatthew G. Knepley   Only a single monitor function can be set for each DM object
8184*c0f0dcc3SMatthew G. Knepley 
8185*c0f0dcc3SMatthew G. Knepley   Level: intermediate
8186*c0f0dcc3SMatthew G. Knepley 
8187*c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorCancel()
8188*c0f0dcc3SMatthew G. Knepley @*/
8189*c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorSet(DM dm, PetscErrorCode (*f)(DM, void *), void *mctx, PetscErrorCode (*monitordestroy)(void**))
8190*c0f0dcc3SMatthew G. Knepley {
8191*c0f0dcc3SMatthew G. Knepley   PetscInt       m;
8192*c0f0dcc3SMatthew G. Knepley   PetscErrorCode ierr;
8193*c0f0dcc3SMatthew G. Knepley 
8194*c0f0dcc3SMatthew G. Knepley   PetscFunctionBegin;
8195*c0f0dcc3SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8196*c0f0dcc3SMatthew G. Knepley   for (m = 0; m < dm->numbermonitors; ++m) {
8197*c0f0dcc3SMatthew G. Knepley     PetscBool identical;
8198*c0f0dcc3SMatthew G. Knepley 
8199*c0f0dcc3SMatthew G. Knepley     ierr = PetscMonitorCompare((PetscErrorCode (*)(void)) f, mctx, monitordestroy, (PetscErrorCode (*)(void)) dm->monitor[m], dm->monitorcontext[m], dm->monitordestroy[m], &identical);CHKERRQ(ierr);
8200*c0f0dcc3SMatthew G. Knepley     if (identical) PetscFunctionReturn(0);
8201*c0f0dcc3SMatthew G. Knepley   }
8202*c0f0dcc3SMatthew G. Knepley   if (dm->numbermonitors >= MAXDMMONITORS) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set");
8203*c0f0dcc3SMatthew G. Knepley   dm->monitor[dm->numbermonitors]          = f;
8204*c0f0dcc3SMatthew G. Knepley   dm->monitordestroy[dm->numbermonitors]   = monitordestroy;
8205*c0f0dcc3SMatthew G. Knepley   dm->monitorcontext[dm->numbermonitors++] = (void *) mctx;
8206*c0f0dcc3SMatthew G. Knepley   PetscFunctionReturn(0);
8207*c0f0dcc3SMatthew G. Knepley }
8208*c0f0dcc3SMatthew G. Knepley 
8209*c0f0dcc3SMatthew G. Knepley /*@
8210*c0f0dcc3SMatthew G. Knepley   DMMonitorCancel - Clears all the monitor functions for a DM object.
8211*c0f0dcc3SMatthew G. Knepley 
8212*c0f0dcc3SMatthew G. Knepley   Logically Collective on DM
8213*c0f0dcc3SMatthew G. Knepley 
8214*c0f0dcc3SMatthew G. Knepley   Input Parameter:
8215*c0f0dcc3SMatthew G. Knepley . dm - the DM
8216*c0f0dcc3SMatthew G. Knepley 
8217*c0f0dcc3SMatthew G. Knepley   Options Database Key:
8218*c0f0dcc3SMatthew G. Knepley . -dm_monitor_cancel - cancels all monitors that have been hardwired
8219*c0f0dcc3SMatthew G. Knepley   into a code by calls to DMonitorSet(), but does not cancel those
8220*c0f0dcc3SMatthew G. Knepley   set via the options database
8221*c0f0dcc3SMatthew G. Knepley 
8222*c0f0dcc3SMatthew G. Knepley   Notes:
8223*c0f0dcc3SMatthew G. Knepley   There is no way to clear one specific monitor from a DM object.
8224*c0f0dcc3SMatthew G. Knepley 
8225*c0f0dcc3SMatthew G. Knepley   Level: intermediate
8226*c0f0dcc3SMatthew G. Knepley 
8227*c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorSet()
8228*c0f0dcc3SMatthew G. Knepley @*/
8229*c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorCancel(DM dm)
8230*c0f0dcc3SMatthew G. Knepley {
8231*c0f0dcc3SMatthew G. Knepley   PetscErrorCode ierr;
8232*c0f0dcc3SMatthew G. Knepley   PetscInt       m;
8233*c0f0dcc3SMatthew G. Knepley 
8234*c0f0dcc3SMatthew G. Knepley   PetscFunctionBegin;
8235*c0f0dcc3SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8236*c0f0dcc3SMatthew G. Knepley   for (m = 0; m < dm->numbermonitors; ++m) {
8237*c0f0dcc3SMatthew G. Knepley     if (dm->monitordestroy[m]) {ierr = (*dm->monitordestroy[m])(&dm->monitorcontext[m]);CHKERRQ(ierr);}
8238*c0f0dcc3SMatthew G. Knepley   }
8239*c0f0dcc3SMatthew G. Knepley   dm->numbermonitors = 0;
8240*c0f0dcc3SMatthew G. Knepley   PetscFunctionReturn(0);
8241*c0f0dcc3SMatthew G. Knepley }
8242*c0f0dcc3SMatthew G. Knepley 
8243*c0f0dcc3SMatthew G. Knepley /*@C
8244*c0f0dcc3SMatthew G. Knepley   DMMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
8245*c0f0dcc3SMatthew G. Knepley 
8246*c0f0dcc3SMatthew G. Knepley   Collective on DM
8247*c0f0dcc3SMatthew G. Knepley 
8248*c0f0dcc3SMatthew G. Knepley   Input Parameters:
8249*c0f0dcc3SMatthew G. Knepley + dm   - DM object you wish to monitor
8250*c0f0dcc3SMatthew G. Knepley . name - the monitor type one is seeking
8251*c0f0dcc3SMatthew G. Knepley . help - message indicating what monitoring is done
8252*c0f0dcc3SMatthew G. Knepley . manual - manual page for the monitor
8253*c0f0dcc3SMatthew G. Knepley . monitor - the monitor function
8254*c0f0dcc3SMatthew G. Knepley - monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the DM or PetscViewer objects
8255*c0f0dcc3SMatthew G. Knepley 
8256*c0f0dcc3SMatthew G. Knepley   Output Parameter:
8257*c0f0dcc3SMatthew G. Knepley . flg - Flag set if the monitor was created
8258*c0f0dcc3SMatthew G. Knepley 
8259*c0f0dcc3SMatthew G. Knepley   Level: developer
8260*c0f0dcc3SMatthew G. Knepley 
8261*c0f0dcc3SMatthew G. Knepley .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
8262*c0f0dcc3SMatthew G. Knepley           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
8263*c0f0dcc3SMatthew G. Knepley           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
8264*c0f0dcc3SMatthew G. Knepley           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
8265*c0f0dcc3SMatthew G. Knepley           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
8266*c0f0dcc3SMatthew G. Knepley           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
8267*c0f0dcc3SMatthew G. Knepley           PetscOptionsFList(), PetscOptionsEList()
8268*c0f0dcc3SMatthew G. Knepley @*/
8269*c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorSetFromOptions(DM dm, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(DM, void *), PetscErrorCode (*monitorsetup)(DM, PetscViewerAndFormat *), PetscBool *flg)
8270*c0f0dcc3SMatthew G. Knepley {
8271*c0f0dcc3SMatthew G. Knepley   PetscViewer       viewer;
8272*c0f0dcc3SMatthew G. Knepley   PetscViewerFormat format;
8273*c0f0dcc3SMatthew G. Knepley   PetscErrorCode    ierr;
8274*c0f0dcc3SMatthew G. Knepley 
8275*c0f0dcc3SMatthew G. Knepley   PetscFunctionBegin;
8276*c0f0dcc3SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8277*c0f0dcc3SMatthew G. Knepley   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) dm), ((PetscObject) dm)->options, ((PetscObject) dm)->prefix, name, &viewer, &format, flg);CHKERRQ(ierr);
8278*c0f0dcc3SMatthew G. Knepley   if (*flg) {
8279*c0f0dcc3SMatthew G. Knepley     PetscViewerAndFormat *vf;
8280*c0f0dcc3SMatthew G. Knepley 
8281*c0f0dcc3SMatthew G. Knepley     ierr = PetscViewerAndFormatCreate(viewer, format, &vf);CHKERRQ(ierr);
8282*c0f0dcc3SMatthew G. Knepley     ierr = PetscObjectDereference((PetscObject) viewer);CHKERRQ(ierr);
8283*c0f0dcc3SMatthew G. Knepley     if (monitorsetup) {ierr = (*monitorsetup)(dm, vf);CHKERRQ(ierr);}
8284*c0f0dcc3SMatthew G. Knepley     ierr = DMMonitorSet(dm,(PetscErrorCode (*)(DM, void *)) monitor, vf, (PetscErrorCode (*)(void **)) PetscViewerAndFormatDestroy);CHKERRQ(ierr);
8285*c0f0dcc3SMatthew G. Knepley   }
8286*c0f0dcc3SMatthew G. Knepley   PetscFunctionReturn(0);
8287*c0f0dcc3SMatthew G. Knepley }
8288*c0f0dcc3SMatthew G. Knepley 
8289*c0f0dcc3SMatthew G. Knepley /*@
8290*c0f0dcc3SMatthew G. Knepley    DMMonitor - runs the user provided monitor routines, if they exist
8291*c0f0dcc3SMatthew G. Knepley 
8292*c0f0dcc3SMatthew G. Knepley    Collective on DM
8293*c0f0dcc3SMatthew G. Knepley 
8294*c0f0dcc3SMatthew G. Knepley    Input Parameters:
8295*c0f0dcc3SMatthew G. Knepley .  dm - The DM
8296*c0f0dcc3SMatthew G. Knepley 
8297*c0f0dcc3SMatthew G. Knepley    Level: developer
8298*c0f0dcc3SMatthew G. Knepley 
8299*c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorSet()
8300*c0f0dcc3SMatthew G. Knepley @*/
8301*c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitor(DM dm)
8302*c0f0dcc3SMatthew G. Knepley {
8303*c0f0dcc3SMatthew G. Knepley   PetscInt       m;
8304*c0f0dcc3SMatthew G. Knepley   PetscErrorCode ierr;
8305*c0f0dcc3SMatthew G. Knepley 
8306*c0f0dcc3SMatthew G. Knepley   PetscFunctionBegin;
8307*c0f0dcc3SMatthew G. Knepley   if (!dm) PetscFunctionReturn(0);
8308*c0f0dcc3SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8309*c0f0dcc3SMatthew G. Knepley   for (m = 0; m < dm->numbermonitors; ++m) {
8310*c0f0dcc3SMatthew G. Knepley     ierr = (*dm->monitor[m])(dm, dm->monitorcontext[m]);CHKERRQ(ierr);
8311*c0f0dcc3SMatthew G. Knepley   }
8312*c0f0dcc3SMatthew G. Knepley   PetscFunctionReturn(0);
8313*c0f0dcc3SMatthew G. Knepley }
8314