xref: /petsc/src/dm/interface/dm.c (revision 92cfd99a522dd5f5e132443db7e958e78e49e2da)
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;
1158cd63d5SVaclav Hapla PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal, DM_LocalToLocal, DM_LocatePoints, DM_Coarsen, DM_Refine, DM_CreateInterpolation, DM_CreateRestriction, DM_CreateInjection, DM_CreateMatrix, DM_Load;
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 
105*92cfd99aSMartin Diehl .seealso: DMDestroy(), 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   }
767c0f0dcc3SMatthew 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);
375858cd63d5SVaclav Hapla   ierr = PetscLogEventBegin(DM_Load,viewer,0,0,0);CHKERRQ(ierr);
37599331c7a4SMatthew G. Knepley   if (isbinary) {
37609331c7a4SMatthew G. Knepley     PetscInt classid;
37619331c7a4SMatthew G. Knepley     char     type[256];
3762b859378eSBarry Smith 
3763060da220SMatthew G. Knepley     ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr);
37649200755eSBarry Smith     if (classid != DM_FILE_CLASSID) SETERRQ1(PetscObjectComm((PetscObject)newdm),PETSC_ERR_ARG_WRONG,"Not DM next in file, classid found %d",(int)classid);
3765060da220SMatthew G. Knepley     ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr);
376632c0f0efSBarry Smith     ierr = DMSetType(newdm, type);CHKERRQ(ierr);
37679331c7a4SMatthew G. Knepley     if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);}
37689331c7a4SMatthew G. Knepley   } else if (ishdf5) {
37699331c7a4SMatthew G. Knepley     if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);}
37709331c7a4SMatthew G. Knepley   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()");
377158cd63d5SVaclav Hapla   ierr = PetscLogEventEnd(DM_Load,viewer,0,0,0);CHKERRQ(ierr);
3772b859378eSBarry Smith   PetscFunctionReturn(0);
3773b859378eSBarry Smith }
3774b859378eSBarry Smith 
3775b2e4378dSMatthew G. Knepley /*@
3776b2e4378dSMatthew G. Knepley   DMGetLocalBoundingBox - Returns the bounding box for the piece of the DM on this process.
3777b2e4378dSMatthew G. Knepley 
3778b2e4378dSMatthew G. Knepley   Not collective
3779b2e4378dSMatthew G. Knepley 
3780b2e4378dSMatthew G. Knepley   Input Parameter:
3781b2e4378dSMatthew G. Knepley . dm - the DM
3782b2e4378dSMatthew G. Knepley 
3783b2e4378dSMatthew G. Knepley   Output Parameters:
3784b2e4378dSMatthew G. Knepley + lmin - local minimum coordinates (length coord dim, optional)
3785b2e4378dSMatthew G. Knepley - lmax - local maximim coordinates (length coord dim, optional)
3786b2e4378dSMatthew G. Knepley 
3787b2e4378dSMatthew G. Knepley   Level: beginner
3788b2e4378dSMatthew G. Knepley 
3789b2e4378dSMatthew G. Knepley   Note: If the DM is a DMDA and has no coordinates, the index bounds are returned instead.
3790b2e4378dSMatthew G. Knepley 
3791b2e4378dSMatthew G. Knepley 
3792b2e4378dSMatthew G. Knepley .seealso: DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetBoundingBox()
3793b2e4378dSMatthew G. Knepley @*/
3794b2e4378dSMatthew G. Knepley PetscErrorCode DMGetLocalBoundingBox(DM dm, PetscReal lmin[], PetscReal lmax[])
3795b2e4378dSMatthew G. Knepley {
3796b2e4378dSMatthew G. Knepley   Vec                coords = NULL;
3797b2e4378dSMatthew G. Knepley   PetscReal          min[3] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MAX_REAL};
3798b2e4378dSMatthew G. Knepley   PetscReal          max[3] = {PETSC_MIN_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL};
3799b2e4378dSMatthew G. Knepley   const PetscScalar *local_coords;
3800b2e4378dSMatthew G. Knepley   PetscInt           N, Ni;
3801b2e4378dSMatthew G. Knepley   PetscInt           cdim, i, j;
3802b2e4378dSMatthew G. Knepley   PetscErrorCode     ierr;
3803b2e4378dSMatthew G. Knepley 
3804b2e4378dSMatthew G. Knepley   PetscFunctionBegin;
3805b2e4378dSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3806b2e4378dSMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
3807b2e4378dSMatthew G. Knepley   ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr);
3808b2e4378dSMatthew G. Knepley   if (coords) {
3809b2e4378dSMatthew G. Knepley     ierr = VecGetArrayRead(coords, &local_coords);CHKERRQ(ierr);
3810b2e4378dSMatthew G. Knepley     ierr = VecGetLocalSize(coords, &N);CHKERRQ(ierr);
3811b2e4378dSMatthew G. Knepley     Ni   = N/cdim;
3812b2e4378dSMatthew G. Knepley     for (i = 0; i < Ni; ++i) {
3813b2e4378dSMatthew G. Knepley       for (j = 0; j < 3; ++j) {
3814b2e4378dSMatthew G. Knepley         min[j] = j < cdim ? PetscMin(min[j], PetscRealPart(local_coords[i*cdim+j])) : 0;
3815b2e4378dSMatthew G. Knepley         max[j] = j < cdim ? PetscMax(max[j], PetscRealPart(local_coords[i*cdim+j])) : 0;
3816b2e4378dSMatthew G. Knepley       }
3817b2e4378dSMatthew G. Knepley     }
3818b2e4378dSMatthew G. Knepley     ierr = VecRestoreArrayRead(coords, &local_coords);CHKERRQ(ierr);
3819b2e4378dSMatthew G. Knepley   } else {
3820b2e4378dSMatthew G. Knepley     PetscBool isda;
3821b2e4378dSMatthew G. Knepley 
3822b2e4378dSMatthew G. Knepley     ierr = PetscObjectTypeCompare((PetscObject) dm, DMDA, &isda);CHKERRQ(ierr);
3823b2e4378dSMatthew G. Knepley     if (isda) {ierr = DMGetLocalBoundingIndices_DMDA(dm, min, max);CHKERRQ(ierr);}
3824b2e4378dSMatthew G. Knepley   }
3825b2e4378dSMatthew G. Knepley   if (lmin) {ierr = PetscArraycpy(lmin, min, cdim);CHKERRQ(ierr);}
3826b2e4378dSMatthew G. Knepley   if (lmax) {ierr = PetscArraycpy(lmax, max, cdim);CHKERRQ(ierr);}
3827b2e4378dSMatthew G. Knepley   PetscFunctionReturn(0);
3828b2e4378dSMatthew G. Knepley }
3829b2e4378dSMatthew G. Knepley 
3830b2e4378dSMatthew G. Knepley /*@
3831b2e4378dSMatthew G. Knepley   DMGetBoundingBox - Returns the global bounding box for the DM.
3832b2e4378dSMatthew G. Knepley 
3833b2e4378dSMatthew G. Knepley   Collective
3834b2e4378dSMatthew G. Knepley 
3835b2e4378dSMatthew G. Knepley   Input Parameter:
3836b2e4378dSMatthew G. Knepley . dm - the DM
3837b2e4378dSMatthew G. Knepley 
3838b2e4378dSMatthew G. Knepley   Output Parameters:
3839b2e4378dSMatthew G. Knepley + gmin - global minimum coordinates (length coord dim, optional)
3840b2e4378dSMatthew G. Knepley - gmax - global maximim coordinates (length coord dim, optional)
3841b2e4378dSMatthew G. Knepley 
3842b2e4378dSMatthew G. Knepley   Level: beginner
3843b2e4378dSMatthew G. Knepley 
3844b2e4378dSMatthew G. Knepley .seealso: DMGetLocalBoundingBox(), DMGetCoordinates(), DMGetCoordinatesLocal()
3845b2e4378dSMatthew G. Knepley @*/
3846b2e4378dSMatthew G. Knepley PetscErrorCode DMGetBoundingBox(DM dm, PetscReal gmin[], PetscReal gmax[])
3847b2e4378dSMatthew G. Knepley {
3848b2e4378dSMatthew G. Knepley   PetscReal      lmin[3], lmax[3];
38496ce308c4SMatthew G. Knepley   PetscInt       cdim;
38506ce308c4SMatthew G. Knepley   PetscMPIInt    count;
3851b2e4378dSMatthew G. Knepley   PetscErrorCode ierr;
3852b2e4378dSMatthew G. Knepley 
3853b2e4378dSMatthew G. Knepley   PetscFunctionBegin;
3854b2e4378dSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3855b2e4378dSMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
3856b2e4378dSMatthew G. Knepley   ierr = PetscMPIIntCast(cdim, &count);CHKERRQ(ierr);
3857b2e4378dSMatthew G. Knepley   ierr = DMGetLocalBoundingBox(dm, lmin, lmax);CHKERRQ(ierr);
3858b2e4378dSMatthew G. Knepley   if (gmin) {ierr = MPIU_Allreduce(lmin, gmin, count, MPIU_REAL, MPIU_MIN, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);}
3859b2e4378dSMatthew G. Knepley   if (gmax) {ierr = MPIU_Allreduce(lmax, gmax, count, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);}
3860b2e4378dSMatthew G. Knepley   PetscFunctionReturn(0);
3861b2e4378dSMatthew G. Knepley }
3862b2e4378dSMatthew G. Knepley 
38637da65231SMatthew G Knepley /******************************** FEM Support **********************************/
38647da65231SMatthew G Knepley 
3865a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[])
3866a6dfd86eSKarl Rupp {
38671d47ebbbSSatish Balay   PetscInt       f;
38681b30c384SMatthew G Knepley   PetscErrorCode ierr;
38691b30c384SMatthew G Knepley 
38707da65231SMatthew G Knepley   PetscFunctionBegin;
387174778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
38721d47ebbbSSatish Balay   for (f = 0; f < len; ++f) {
387357622a8eSBarry Smith     ierr = PetscPrintf(PETSC_COMM_SELF, "  | %g |\n", (double)PetscRealPart(x[f]));CHKERRQ(ierr);
38747da65231SMatthew G Knepley   }
38757da65231SMatthew G Knepley   PetscFunctionReturn(0);
38767da65231SMatthew G Knepley }
38777da65231SMatthew G Knepley 
3878a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[])
3879a6dfd86eSKarl Rupp {
38801b30c384SMatthew G Knepley   PetscInt       f, g;
38817da65231SMatthew G Knepley   PetscErrorCode ierr;
38827da65231SMatthew G Knepley 
38837da65231SMatthew G Knepley   PetscFunctionBegin;
388474778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
38851d47ebbbSSatish Balay   for (f = 0; f < rows; ++f) {
388674778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  |");CHKERRQ(ierr);
38871d47ebbbSSatish Balay     for (g = 0; g < cols; ++g) {
3888e3556bceSMatthew G. Knepley       ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5g", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr);
38897da65231SMatthew G Knepley     }
389074778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr);
38917da65231SMatthew G Knepley   }
38927da65231SMatthew G Knepley   PetscFunctionReturn(0);
38937da65231SMatthew G Knepley }
3894e7c4fc90SDmitry Karpeev 
38956113b454SMatthew G. Knepley PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X)
3896e759306cSMatthew G. Knepley {
38970c5b8624SToby Isaac   PetscInt          localSize, bs;
38980c5b8624SToby Isaac   PetscMPIInt       size;
38990c5b8624SToby Isaac   Vec               x, xglob;
39000c5b8624SToby Isaac   const PetscScalar *xarray;
3901e759306cSMatthew G. Knepley   PetscErrorCode    ierr;
3902e759306cSMatthew G. Knepley 
3903e759306cSMatthew G. Knepley   PetscFunctionBegin;
39049852e123SBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm),&size);CHKERRQ(ierr);
3905e759306cSMatthew G. Knepley   ierr = VecDuplicate(X, &x);CHKERRQ(ierr);
3906e759306cSMatthew G. Knepley   ierr = VecCopy(X, x);CHKERRQ(ierr);
39076113b454SMatthew G. Knepley   ierr = VecChop(x, tol);CHKERRQ(ierr);
39080c5b8624SToby Isaac   ierr = PetscPrintf(PetscObjectComm((PetscObject) dm),"%s:\n",name);CHKERRQ(ierr);
39090c5b8624SToby Isaac   if (size > 1) {
39100c5b8624SToby Isaac     ierr = VecGetLocalSize(x,&localSize);CHKERRQ(ierr);
39110c5b8624SToby Isaac     ierr = VecGetArrayRead(x,&xarray);CHKERRQ(ierr);
39120c5b8624SToby Isaac     ierr = VecGetBlockSize(x,&bs);CHKERRQ(ierr);
39130c5b8624SToby Isaac     ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject) dm),bs,localSize,PETSC_DETERMINE,xarray,&xglob);CHKERRQ(ierr);
39140c5b8624SToby Isaac   } else {
39150c5b8624SToby Isaac     xglob = x;
39160c5b8624SToby Isaac   }
39170c5b8624SToby Isaac   ierr = VecView(xglob,PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject) dm)));CHKERRQ(ierr);
39180c5b8624SToby Isaac   if (size > 1) {
39190c5b8624SToby Isaac     ierr = VecDestroy(&xglob);CHKERRQ(ierr);
39200c5b8624SToby Isaac     ierr = VecRestoreArrayRead(x,&xarray);CHKERRQ(ierr);
39210c5b8624SToby Isaac   }
3922e759306cSMatthew G. Knepley   ierr = VecDestroy(&x);CHKERRQ(ierr);
3923e759306cSMatthew G. Knepley   PetscFunctionReturn(0);
3924e759306cSMatthew G. Knepley }
3925e759306cSMatthew G. Knepley 
392688ed4aceSMatthew G Knepley /*@
39271bb6d2a8SBarry Smith   DMGetSection - Get the PetscSection encoding the local data layout for the DM.   This is equivalent to DMGetLocalSection(). Deprecated in v3.12
3928061576a5SJed Brown 
3929061576a5SJed Brown   Input Parameter:
3930061576a5SJed Brown . dm - The DM
3931061576a5SJed Brown 
3932061576a5SJed Brown   Output Parameter:
3933061576a5SJed Brown . section - The PetscSection
3934061576a5SJed Brown 
3935061576a5SJed Brown   Options Database Keys:
3936061576a5SJed Brown . -dm_petscsection_view - View the Section created by the DM
3937061576a5SJed Brown 
3938061576a5SJed Brown   Level: advanced
3939061576a5SJed Brown 
3940061576a5SJed Brown   Notes:
3941061576a5SJed Brown   Use DMGetLocalSection() in new code.
3942061576a5SJed Brown 
3943061576a5SJed Brown   This gets a borrowed reference, so the user should not destroy this PetscSection.
3944061576a5SJed Brown 
3945061576a5SJed Brown .seealso: DMGetLocalSection(), DMSetLocalSection(), DMGetGlobalSection()
3946061576a5SJed Brown @*/
3947061576a5SJed Brown PetscErrorCode DMGetSection(DM dm, PetscSection *section)
3948061576a5SJed Brown {
3949061576a5SJed Brown   PetscErrorCode ierr;
3950061576a5SJed Brown 
3951061576a5SJed Brown   PetscFunctionBegin;
3952061576a5SJed Brown   ierr = DMGetLocalSection(dm,section);CHKERRQ(ierr);
3953061576a5SJed Brown   PetscFunctionReturn(0);
3954061576a5SJed Brown }
3955061576a5SJed Brown 
3956061576a5SJed Brown /*@
3957061576a5SJed Brown   DMGetLocalSection - Get the PetscSection encoding the local data layout for the DM.
395888ed4aceSMatthew G Knepley 
395988ed4aceSMatthew G Knepley   Input Parameter:
396088ed4aceSMatthew G Knepley . dm - The DM
396188ed4aceSMatthew G Knepley 
396288ed4aceSMatthew G Knepley   Output Parameter:
396388ed4aceSMatthew G Knepley . section - The PetscSection
396488ed4aceSMatthew G Knepley 
3965e5893cccSMatthew G. Knepley   Options Database Keys:
3966e5893cccSMatthew G. Knepley . -dm_petscsection_view - View the Section created by the DM
3967e5893cccSMatthew G. Knepley 
396888ed4aceSMatthew G Knepley   Level: intermediate
396988ed4aceSMatthew G Knepley 
397088ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
397188ed4aceSMatthew G Knepley 
3972061576a5SJed Brown .seealso: DMSetLocalSection(), DMGetGlobalSection()
397388ed4aceSMatthew G Knepley @*/
3974061576a5SJed Brown PetscErrorCode DMGetLocalSection(DM dm, PetscSection *section)
39750adebc6cSBarry Smith {
3976fd59a867SMatthew G. Knepley   PetscErrorCode ierr;
3977fd59a867SMatthew G. Knepley 
397888ed4aceSMatthew G Knepley   PetscFunctionBegin;
397988ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
398088ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
39811bb6d2a8SBarry Smith   if (!dm->localSection && dm->ops->createlocalsection) {
3982e5e52638SMatthew G. Knepley     PetscInt d;
3983e5e52638SMatthew G. Knepley 
3984e5e52638SMatthew G. Knepley     if (dm->setfromoptionscalled) for (d = 0; d < dm->Nds; ++d) {ierr = PetscDSSetFromOptions(dm->probs[d].ds);CHKERRQ(ierr);}
39851bb6d2a8SBarry Smith     ierr = (*dm->ops->createlocalsection)(dm);CHKERRQ(ierr);
39861bb6d2a8SBarry Smith     if (dm->localSection) {ierr = PetscObjectViewFromOptions((PetscObject) dm->localSection, NULL, "-dm_petscsection_view");CHKERRQ(ierr);}
39872f0f8703SMatthew G. Knepley   }
39881bb6d2a8SBarry Smith   *section = dm->localSection;
398988ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
399088ed4aceSMatthew G Knepley }
399188ed4aceSMatthew G Knepley 
399288ed4aceSMatthew G Knepley /*@
39931bb6d2a8SBarry Smith   DMSetSection - Set the PetscSection encoding the local data layout for the DM.  This is equivalent to DMSetLocalSection(). Deprecated in v3.12
3994061576a5SJed Brown 
3995061576a5SJed Brown   Input Parameters:
3996061576a5SJed Brown + dm - The DM
3997061576a5SJed Brown - section - The PetscSection
3998061576a5SJed Brown 
3999061576a5SJed Brown   Level: advanced
4000061576a5SJed Brown 
4001061576a5SJed Brown   Notes:
4002061576a5SJed Brown   Use DMSetLocalSection() in new code.
4003061576a5SJed Brown 
4004061576a5SJed Brown   Any existing Section will be destroyed
4005061576a5SJed Brown 
4006061576a5SJed Brown .seealso: DMSetLocalSection(), DMGetLocalSection(), DMSetGlobalSection()
4007061576a5SJed Brown @*/
4008061576a5SJed Brown PetscErrorCode DMSetSection(DM dm, PetscSection section)
4009061576a5SJed Brown {
4010061576a5SJed Brown   PetscErrorCode ierr;
4011061576a5SJed Brown 
4012061576a5SJed Brown   PetscFunctionBegin;
4013061576a5SJed Brown   ierr = DMSetLocalSection(dm,section);CHKERRQ(ierr);
4014061576a5SJed Brown   PetscFunctionReturn(0);
4015061576a5SJed Brown }
4016061576a5SJed Brown 
4017061576a5SJed Brown /*@
4018061576a5SJed Brown   DMSetLocalSection - Set the PetscSection encoding the local data layout for the DM.
401988ed4aceSMatthew G Knepley 
402088ed4aceSMatthew G Knepley   Input Parameters:
402188ed4aceSMatthew G Knepley + dm - The DM
402288ed4aceSMatthew G Knepley - section - The PetscSection
402388ed4aceSMatthew G Knepley 
402488ed4aceSMatthew G Knepley   Level: intermediate
402588ed4aceSMatthew G Knepley 
402688ed4aceSMatthew G Knepley   Note: Any existing Section will be destroyed
402788ed4aceSMatthew G Knepley 
4028061576a5SJed Brown .seealso: DMGetLocalSection(), DMSetGlobalSection()
402988ed4aceSMatthew G Knepley @*/
4030061576a5SJed Brown PetscErrorCode DMSetLocalSection(DM dm, PetscSection section)
40310adebc6cSBarry Smith {
4032c473ab19SMatthew G. Knepley   PetscInt       numFields = 0;
4033af122d2aSMatthew G Knepley   PetscInt       f;
403488ed4aceSMatthew G Knepley   PetscErrorCode ierr;
403588ed4aceSMatthew G Knepley 
403688ed4aceSMatthew G Knepley   PetscFunctionBegin;
403788ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4038b9d85ea2SLisandro Dalcin   if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
40391d799100SJed Brown   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
40401bb6d2a8SBarry Smith   ierr = PetscSectionDestroy(&dm->localSection);CHKERRQ(ierr);
40411bb6d2a8SBarry Smith   dm->localSection = section;
40421bb6d2a8SBarry Smith   if (section) {ierr = PetscSectionGetNumFields(dm->localSection, &numFields);CHKERRQ(ierr);}
4043af122d2aSMatthew G Knepley   if (numFields) {
4044af122d2aSMatthew G Knepley     ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr);
4045af122d2aSMatthew G Knepley     for (f = 0; f < numFields; ++f) {
40460f21e855SMatthew G. Knepley       PetscObject disc;
4047af122d2aSMatthew G Knepley       const char *name;
4048af122d2aSMatthew G Knepley 
40491bb6d2a8SBarry Smith       ierr = PetscSectionGetFieldName(dm->localSection, f, &name);CHKERRQ(ierr);
405044a7f3ddSMatthew G. Knepley       ierr = DMGetField(dm, f, NULL, &disc);CHKERRQ(ierr);
40510f21e855SMatthew G. Knepley       ierr = PetscObjectSetName(disc, name);CHKERRQ(ierr);
4052af122d2aSMatthew G Knepley     }
4053af122d2aSMatthew G Knepley   }
4054e87a4003SBarry Smith   /* The global section will be rebuilt in the next call to DMGetGlobalSection(). */
40551bb6d2a8SBarry Smith   ierr = PetscSectionDestroy(&dm->globalSection);CHKERRQ(ierr);
405688ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
405788ed4aceSMatthew G Knepley }
405888ed4aceSMatthew G Knepley 
40599435951eSToby Isaac /*@
4060b7385021SStefano Zampini   DMGetDefaultConstraints - Get the PetscSection and Mat that specify the local constraint interpolation. See DMSetDefaultConstraints() for a description of the purpose of constraint interpolation.
40619435951eSToby Isaac 
4062e228b242SToby Isaac   not collective
4063e228b242SToby Isaac 
40649435951eSToby Isaac   Input Parameter:
40659435951eSToby Isaac . dm - The DM
40669435951eSToby Isaac 
40679435951eSToby Isaac   Output Parameter:
40689435951eSToby 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.
40699435951eSToby 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.
40709435951eSToby Isaac 
40719435951eSToby Isaac   Level: advanced
40729435951eSToby Isaac 
40739435951eSToby Isaac   Note: This gets borrowed references, so the user should not destroy the PetscSection or the Mat.
40749435951eSToby Isaac 
40759435951eSToby Isaac .seealso: DMSetDefaultConstraints()
40769435951eSToby Isaac @*/
40779435951eSToby Isaac PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat)
40789435951eSToby Isaac {
40799435951eSToby Isaac   PetscErrorCode ierr;
40809435951eSToby Isaac 
40819435951eSToby Isaac   PetscFunctionBegin;
40829435951eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
40839435951eSToby Isaac   if (!dm->defaultConstraintSection && !dm->defaultConstraintMat && dm->ops->createdefaultconstraints) {ierr = (*dm->ops->createdefaultconstraints)(dm);CHKERRQ(ierr);}
408445a75d81SToby Isaac   if (section) {*section = dm->defaultConstraintSection;}
408545a75d81SToby Isaac   if (mat) {*mat = dm->defaultConstraintMat;}
40869435951eSToby Isaac   PetscFunctionReturn(0);
40879435951eSToby Isaac }
40889435951eSToby Isaac 
40899435951eSToby Isaac /*@
4090b7385021SStefano Zampini   DMSetDefaultConstraints - Set the PetscSection and Mat that specify the local constraint interpolation.
40919435951eSToby Isaac 
40929435951eSToby 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().
40939435951eSToby Isaac 
40949435951eSToby 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.
40959435951eSToby Isaac 
4096e228b242SToby Isaac   collective on dm
4097e228b242SToby Isaac 
40989435951eSToby Isaac   Input Parameters:
40999435951eSToby Isaac + dm - The DM
4100e228b242SToby 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).
4101e228b242SToby 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).
41029435951eSToby Isaac 
41039435951eSToby Isaac   Level: advanced
41049435951eSToby Isaac 
41059435951eSToby Isaac   Note: This increments the references of the PetscSection and the Mat, so they user can destroy them
41069435951eSToby Isaac 
41079435951eSToby Isaac .seealso: DMGetDefaultConstraints()
41089435951eSToby Isaac @*/
41099435951eSToby Isaac PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat)
41109435951eSToby Isaac {
4111e228b242SToby Isaac   PetscMPIInt result;
41129435951eSToby Isaac   PetscErrorCode ierr;
41139435951eSToby Isaac 
41149435951eSToby Isaac   PetscFunctionBegin;
41159435951eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4116e228b242SToby Isaac   if (section) {
4117e228b242SToby Isaac     PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
4118e228b242SToby Isaac     ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)section),&result);CHKERRQ(ierr);
4119f60917d2SBarry Smith     if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint section must have local communicator");
4120e228b242SToby Isaac   }
4121e228b242SToby Isaac   if (mat) {
4122e228b242SToby Isaac     PetscValidHeaderSpecific(mat,MAT_CLASSID,3);
4123e228b242SToby Isaac     ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)mat),&result);CHKERRQ(ierr);
4124f60917d2SBarry Smith     if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint matrix must have local communicator");
4125e228b242SToby Isaac   }
41269435951eSToby Isaac   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
41279435951eSToby Isaac   ierr = PetscSectionDestroy(&dm->defaultConstraintSection);CHKERRQ(ierr);
41289435951eSToby Isaac   dm->defaultConstraintSection = section;
41299435951eSToby Isaac   ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
41309435951eSToby Isaac   ierr = MatDestroy(&dm->defaultConstraintMat);CHKERRQ(ierr);
41319435951eSToby Isaac   dm->defaultConstraintMat = mat;
41329435951eSToby Isaac   PetscFunctionReturn(0);
41339435951eSToby Isaac }
41349435951eSToby Isaac 
4135497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG)
4136507e4973SMatthew G. Knepley /*
4137507e4973SMatthew G. Knepley   DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections.
4138507e4973SMatthew G. Knepley 
4139507e4973SMatthew G. Knepley   Input Parameters:
4140507e4973SMatthew G. Knepley + dm - The DM
4141507e4973SMatthew G. Knepley . localSection - PetscSection describing the local data layout
4142507e4973SMatthew G. Knepley - globalSection - PetscSection describing the global data layout
4143507e4973SMatthew G. Knepley 
4144507e4973SMatthew G. Knepley   Level: intermediate
4145507e4973SMatthew G. Knepley 
41461bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMSetSectionSF()
4147507e4973SMatthew G. Knepley */
4148f741bcd2SMatthew G. Knepley static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection)
4149507e4973SMatthew G. Knepley {
4150507e4973SMatthew G. Knepley   MPI_Comm        comm;
4151507e4973SMatthew G. Knepley   PetscLayout     layout;
4152507e4973SMatthew G. Knepley   const PetscInt *ranges;
4153507e4973SMatthew G. Knepley   PetscInt        pStart, pEnd, p, nroots;
4154507e4973SMatthew G. Knepley   PetscMPIInt     size, rank;
4155507e4973SMatthew G. Knepley   PetscBool       valid = PETSC_TRUE, gvalid;
4156507e4973SMatthew G. Knepley   PetscErrorCode  ierr;
4157507e4973SMatthew G. Knepley 
4158507e4973SMatthew G. Knepley   PetscFunctionBegin;
4159507e4973SMatthew G. Knepley   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
4160507e4973SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4161507e4973SMatthew G. Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
4162507e4973SMatthew G. Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
4163507e4973SMatthew G. Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
4164507e4973SMatthew G. Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
4165507e4973SMatthew G. Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
4166507e4973SMatthew G. Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
4167507e4973SMatthew G. Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
4168507e4973SMatthew G. Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
4169507e4973SMatthew G. Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
4170507e4973SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
4171f741bcd2SMatthew G. Knepley     PetscInt       dof, cdof, off, gdof, gcdof, goff, gsize, d;
4172507e4973SMatthew G. Knepley 
4173507e4973SMatthew G. Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
4174507e4973SMatthew G. Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
4175507e4973SMatthew G. Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
4176507e4973SMatthew G. Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
4177507e4973SMatthew G. Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
4178507e4973SMatthew G. Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
4179507e4973SMatthew G. Knepley     if (!gdof) continue; /* Censored point */
4180507e4973SMatthew 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;}
4181507e4973SMatthew 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;}
4182507e4973SMatthew G. Knepley     if (gdof < 0) {
4183507e4973SMatthew G. Knepley       gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
4184507e4973SMatthew G. Knepley       for (d = 0; d < gsize; ++d) {
4185507e4973SMatthew G. Knepley         PetscInt offset = -(goff+1) + d, r;
4186507e4973SMatthew G. Knepley 
4187507e4973SMatthew G. Knepley         ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr);
4188507e4973SMatthew G. Knepley         if (r < 0) r = -(r+2);
4189507e4973SMatthew 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;}
4190507e4973SMatthew G. Knepley       }
4191507e4973SMatthew G. Knepley     }
4192507e4973SMatthew G. Knepley   }
4193507e4973SMatthew G. Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
4194507e4973SMatthew G. Knepley   ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr);
4195b2566f29SBarry Smith   ierr = MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRQ(ierr);
4196507e4973SMatthew G. Knepley   if (!gvalid) {
4197507e4973SMatthew G. Knepley     ierr = DMView(dm, NULL);CHKERRQ(ierr);
4198507e4973SMatthew G. Knepley     SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections");
4199507e4973SMatthew G. Knepley   }
4200507e4973SMatthew G. Knepley   PetscFunctionReturn(0);
4201507e4973SMatthew G. Knepley }
4202f741bcd2SMatthew G. Knepley #endif
4203507e4973SMatthew G. Knepley 
420488ed4aceSMatthew G Knepley /*@
4205e87a4003SBarry Smith   DMGetGlobalSection - Get the PetscSection encoding the global data layout for the DM.
420688ed4aceSMatthew G Knepley 
4207d083f849SBarry Smith   Collective on dm
42088b1ab98fSJed Brown 
420988ed4aceSMatthew G Knepley   Input Parameter:
421088ed4aceSMatthew G Knepley . dm - The DM
421188ed4aceSMatthew G Knepley 
421288ed4aceSMatthew G Knepley   Output Parameter:
421388ed4aceSMatthew G Knepley . section - The PetscSection
421488ed4aceSMatthew G Knepley 
421588ed4aceSMatthew G Knepley   Level: intermediate
421688ed4aceSMatthew G Knepley 
421788ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
421888ed4aceSMatthew G Knepley 
421992fd8e1eSJed Brown .seealso: DMSetLocalSection(), DMGetLocalSection()
422088ed4aceSMatthew G Knepley @*/
4221e87a4003SBarry Smith PetscErrorCode DMGetGlobalSection(DM dm, PetscSection *section)
42220adebc6cSBarry Smith {
422388ed4aceSMatthew G Knepley   PetscErrorCode ierr;
422488ed4aceSMatthew G Knepley 
422588ed4aceSMatthew G Knepley   PetscFunctionBegin;
422688ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
422788ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
42281bb6d2a8SBarry Smith   if (!dm->globalSection) {
4229fd59a867SMatthew G. Knepley     PetscSection s;
4230fd59a867SMatthew G. Knepley 
423192fd8e1eSJed Brown     ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr);
4232fd59a867SMatthew 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");
423333907cc2SStefano 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");
42341bb6d2a8SBarry Smith     ierr = PetscSectionCreateGlobalSection(s, dm->sf, PETSC_FALSE, PETSC_FALSE, &dm->globalSection);CHKERRQ(ierr);
4235cf06b437SMatthew G. Knepley     ierr = PetscLayoutDestroy(&dm->map);CHKERRQ(ierr);
42361bb6d2a8SBarry Smith     ierr = PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->globalSection, &dm->map);CHKERRQ(ierr);
42371bb6d2a8SBarry Smith     ierr = PetscSectionViewFromOptions(dm->globalSection, NULL, "-global_section_view");CHKERRQ(ierr);
423888ed4aceSMatthew G Knepley   }
42391bb6d2a8SBarry Smith   *section = dm->globalSection;
424088ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
424188ed4aceSMatthew G Knepley }
424288ed4aceSMatthew G Knepley 
4243b21d0597SMatthew G Knepley /*@
4244e87a4003SBarry Smith   DMSetGlobalSection - Set the PetscSection encoding the global data layout for the DM.
4245b21d0597SMatthew G Knepley 
4246b21d0597SMatthew G Knepley   Input Parameters:
4247b21d0597SMatthew G Knepley + dm - The DM
42485080bbdbSMatthew G Knepley - section - The PetscSection, or NULL
4249b21d0597SMatthew G Knepley 
4250b21d0597SMatthew G Knepley   Level: intermediate
4251b21d0597SMatthew G Knepley 
4252b21d0597SMatthew G Knepley   Note: Any existing Section will be destroyed
4253b21d0597SMatthew G Knepley 
425492fd8e1eSJed Brown .seealso: DMGetGlobalSection(), DMSetLocalSection()
4255b21d0597SMatthew G Knepley @*/
4256e87a4003SBarry Smith PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section)
42570adebc6cSBarry Smith {
4258b21d0597SMatthew G Knepley   PetscErrorCode ierr;
4259b21d0597SMatthew G Knepley 
4260b21d0597SMatthew G Knepley   PetscFunctionBegin;
4261b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
42625080bbdbSMatthew G Knepley   if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
42631d799100SJed Brown   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
42641bb6d2a8SBarry Smith   ierr = PetscSectionDestroy(&dm->globalSection);CHKERRQ(ierr);
42651bb6d2a8SBarry Smith   dm->globalSection = section;
4266497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG)
42671bb6d2a8SBarry Smith   if (section) {ierr = DMDefaultSectionCheckConsistency_Internal(dm, dm->localSection, section);CHKERRQ(ierr);}
4268507e4973SMatthew G. Knepley #endif
4269b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
4270b21d0597SMatthew G Knepley }
4271b21d0597SMatthew G Knepley 
427288ed4aceSMatthew G Knepley /*@
42731bb6d2a8SBarry Smith   DMGetSectionSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set,
427488ed4aceSMatthew G Knepley   it is created from the default PetscSection layouts in the DM.
427588ed4aceSMatthew G Knepley 
427688ed4aceSMatthew G Knepley   Input Parameter:
427788ed4aceSMatthew G Knepley . dm - The DM
427888ed4aceSMatthew G Knepley 
427988ed4aceSMatthew G Knepley   Output Parameter:
428088ed4aceSMatthew G Knepley . sf - The PetscSF
428188ed4aceSMatthew G Knepley 
428288ed4aceSMatthew G Knepley   Level: intermediate
428388ed4aceSMatthew G Knepley 
428488ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
428588ed4aceSMatthew G Knepley 
42861bb6d2a8SBarry Smith .seealso: DMSetSectionSF(), DMCreateSectionSF()
428788ed4aceSMatthew G Knepley @*/
42881bb6d2a8SBarry Smith PetscErrorCode DMGetSectionSF(DM dm, PetscSF *sf)
42890adebc6cSBarry Smith {
429088ed4aceSMatthew G Knepley   PetscInt       nroots;
429188ed4aceSMatthew G Knepley   PetscErrorCode ierr;
429288ed4aceSMatthew G Knepley 
429388ed4aceSMatthew G Knepley   PetscFunctionBegin;
429488ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
429588ed4aceSMatthew G Knepley   PetscValidPointer(sf, 2);
42961bb6d2a8SBarry Smith   if (!dm->sectionSF) {
42971bb6d2a8SBarry Smith     ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm),&dm->sectionSF);CHKERRQ(ierr);
429833907cc2SStefano Zampini   }
42991bb6d2a8SBarry Smith   ierr = PetscSFGetGraph(dm->sectionSF, &nroots, NULL, NULL, NULL);CHKERRQ(ierr);
430088ed4aceSMatthew G Knepley   if (nroots < 0) {
430188ed4aceSMatthew G Knepley     PetscSection section, gSection;
430288ed4aceSMatthew G Knepley 
430392fd8e1eSJed Brown     ierr = DMGetLocalSection(dm, &section);CHKERRQ(ierr);
430431ea6d37SMatthew G Knepley     if (section) {
4305e87a4003SBarry Smith       ierr = DMGetGlobalSection(dm, &gSection);CHKERRQ(ierr);
43061bb6d2a8SBarry Smith       ierr = DMCreateSectionSF(dm, section, gSection);CHKERRQ(ierr);
430731ea6d37SMatthew G Knepley     } else {
43080298fd71SBarry Smith       *sf = NULL;
430931ea6d37SMatthew G Knepley       PetscFunctionReturn(0);
431031ea6d37SMatthew G Knepley     }
431188ed4aceSMatthew G Knepley   }
43121bb6d2a8SBarry Smith   *sf = dm->sectionSF;
431388ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
431488ed4aceSMatthew G Knepley }
431588ed4aceSMatthew G Knepley 
431688ed4aceSMatthew G Knepley /*@
43171bb6d2a8SBarry Smith   DMSetSectionSF - Set the PetscSF encoding the parallel dof overlap for the DM
431888ed4aceSMatthew G Knepley 
431988ed4aceSMatthew G Knepley   Input Parameters:
432088ed4aceSMatthew G Knepley + dm - The DM
432188ed4aceSMatthew G Knepley - sf - The PetscSF
432288ed4aceSMatthew G Knepley 
432388ed4aceSMatthew G Knepley   Level: intermediate
432488ed4aceSMatthew G Knepley 
432588ed4aceSMatthew G Knepley   Note: Any previous SF is destroyed
432688ed4aceSMatthew G Knepley 
43271bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMCreateSectionSF()
432888ed4aceSMatthew G Knepley @*/
43291bb6d2a8SBarry Smith PetscErrorCode DMSetSectionSF(DM dm, PetscSF sf)
43300adebc6cSBarry Smith {
433188ed4aceSMatthew G Knepley   PetscErrorCode ierr;
433288ed4aceSMatthew G Knepley 
433388ed4aceSMatthew G Knepley   PetscFunctionBegin;
433488ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4335b9d85ea2SLisandro Dalcin   if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
433633907cc2SStefano Zampini   ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr);
43371bb6d2a8SBarry Smith   ierr = PetscSFDestroy(&dm->sectionSF);CHKERRQ(ierr);
43381bb6d2a8SBarry Smith   dm->sectionSF = sf;
433988ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
434088ed4aceSMatthew G Knepley }
434188ed4aceSMatthew G Knepley 
434288ed4aceSMatthew G Knepley /*@C
43431bb6d2a8SBarry Smith   DMCreateSectionSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections
434488ed4aceSMatthew G Knepley   describing the data layout.
434588ed4aceSMatthew G Knepley 
434688ed4aceSMatthew G Knepley   Input Parameters:
434788ed4aceSMatthew G Knepley + dm - The DM
434888ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout
434988ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout
435088ed4aceSMatthew G Knepley 
43511bb6d2a8SBarry Smith   Notes: One usually uses DMGetSectionSF() to obtain the PetscSF
435288ed4aceSMatthew G Knepley 
43531bb6d2a8SBarry Smith   Level: developer
43541bb6d2a8SBarry Smith 
43551bb6d2a8SBarry Smith   Developer Note: Since this routine has for arguments the two sections from the DM and puts the resulting PetscSF
43561bb6d2a8SBarry Smith                   directly into the DM, perhaps this function should not take the local and global sections as
43571bb6d2a8SBarry Smith                   input and should just obtain them from the DM?
43581bb6d2a8SBarry Smith 
43591bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMSetSectionSF(), DMGetLocalSection(), DMGetGlobalSection()
436088ed4aceSMatthew G Knepley @*/
43611bb6d2a8SBarry Smith PetscErrorCode DMCreateSectionSF(DM dm, PetscSection localSection, PetscSection globalSection)
436288ed4aceSMatthew G Knepley {
436382f516ccSBarry Smith   MPI_Comm       comm;
436488ed4aceSMatthew G Knepley   PetscLayout    layout;
436588ed4aceSMatthew G Knepley   const PetscInt *ranges;
436688ed4aceSMatthew G Knepley   PetscInt       *local;
436788ed4aceSMatthew G Knepley   PetscSFNode    *remote;
4368ecd73843SMatthew G. Knepley   PetscInt       pStart, pEnd, p, nroots, nleaves = 0, l;
436988ed4aceSMatthew G Knepley   PetscMPIInt    size, rank;
437088ed4aceSMatthew G Knepley   PetscErrorCode ierr;
437188ed4aceSMatthew G Knepley 
437288ed4aceSMatthew G Knepley   PetscFunctionBegin;
437388ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4374367003a6SStefano Zampini   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
437588ed4aceSMatthew G Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
437688ed4aceSMatthew G Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
437788ed4aceSMatthew G Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
437888ed4aceSMatthew G Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
437988ed4aceSMatthew G Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
438088ed4aceSMatthew G Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
438188ed4aceSMatthew G Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
438288ed4aceSMatthew G Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
438388ed4aceSMatthew G Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
4384ecd73843SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
43856636e97aSMatthew G Knepley     PetscInt gdof, gcdof;
438688ed4aceSMatthew G Knepley 
43876636e97aSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
43886636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
4389235fbf56SMatthew 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));
43906636e97aSMatthew G Knepley     nleaves += gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
439188ed4aceSMatthew G Knepley   }
4392785e854fSJed Brown   ierr = PetscMalloc1(nleaves, &local);CHKERRQ(ierr);
4393785e854fSJed Brown   ierr = PetscMalloc1(nleaves, &remote);CHKERRQ(ierr);
439488ed4aceSMatthew G Knepley   for (p = pStart, l = 0; p < pEnd; ++p) {
43951f588964SMatthew G Knepley     const PetscInt *cind;
43966636e97aSMatthew G Knepley     PetscInt       dof, cdof, off, gdof, gcdof, goff, gsize, d, c;
439788ed4aceSMatthew G Knepley 
439888ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
439988ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
440088ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
440188ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr);
440288ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
44036636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
440488ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
44056636e97aSMatthew G Knepley     if (!gdof) continue; /* Censored point */
44066636e97aSMatthew G Knepley     gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
44076636e97aSMatthew G Knepley     if (gsize != dof-cdof) {
4408057b4bcdSMatthew 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);
44096636e97aSMatthew G Knepley       cdof = 0; /* Ignore constraints */
44106636e97aSMatthew G Knepley     }
441188ed4aceSMatthew G Knepley     for (d = 0, c = 0; d < dof; ++d) {
441288ed4aceSMatthew G Knepley       if ((c < cdof) && (cind[c] == d)) {++c; continue;}
441388ed4aceSMatthew G Knepley       local[l+d-c] = off+d;
441488ed4aceSMatthew G Knepley     }
441588ed4aceSMatthew G Knepley     if (gdof < 0) {
44166636e97aSMatthew G Knepley       for (d = 0; d < gsize; ++d, ++l) {
441788ed4aceSMatthew G Knepley         PetscInt offset = -(goff+1) + d, r;
441888ed4aceSMatthew G Knepley 
441905376888SMatthew G. Knepley         ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr);
442031d3f06eSJed Brown         if (r < 0) r = -(r+2);
442105376888SMatthew 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);
442288ed4aceSMatthew G Knepley         remote[l].rank  = r;
442388ed4aceSMatthew G Knepley         remote[l].index = offset - ranges[r];
442488ed4aceSMatthew G Knepley       }
442588ed4aceSMatthew G Knepley     } else {
44266636e97aSMatthew G Knepley       for (d = 0; d < gsize; ++d, ++l) {
442788ed4aceSMatthew G Knepley         remote[l].rank  = rank;
442888ed4aceSMatthew G Knepley         remote[l].index = goff+d - ranges[rank];
442988ed4aceSMatthew G Knepley       }
443088ed4aceSMatthew G Knepley     }
443188ed4aceSMatthew G Knepley   }
44326636e97aSMatthew G Knepley   if (l != nleaves) SETERRQ2(comm, PETSC_ERR_PLIB, "Iteration error, l %d != nleaves %d", l, nleaves);
443388ed4aceSMatthew G Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
44341bb6d2a8SBarry Smith   ierr = PetscSFSetGraph(dm->sectionSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr);
443588ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
443688ed4aceSMatthew G Knepley }
4437af122d2aSMatthew G Knepley 
4438b21d0597SMatthew G Knepley /*@
4439b21d0597SMatthew G Knepley   DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM.
4440b21d0597SMatthew G Knepley 
4441b21d0597SMatthew G Knepley   Input Parameter:
4442b21d0597SMatthew G Knepley . dm - The DM
4443b21d0597SMatthew G Knepley 
4444b21d0597SMatthew G Knepley   Output Parameter:
4445b21d0597SMatthew G Knepley . sf - The PetscSF
4446b21d0597SMatthew G Knepley 
4447b21d0597SMatthew G Knepley   Level: intermediate
4448b21d0597SMatthew G Knepley 
4449b21d0597SMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
4450b21d0597SMatthew G Knepley 
44511bb6d2a8SBarry Smith .seealso: DMSetPointSF(), DMGetSectionSF(), DMSetSectionSF(), DMCreateSectionSF()
4452b21d0597SMatthew G Knepley @*/
44530adebc6cSBarry Smith PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf)
44540adebc6cSBarry Smith {
4455b21d0597SMatthew G Knepley   PetscFunctionBegin;
4456b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4457b21d0597SMatthew G Knepley   PetscValidPointer(sf, 2);
4458b21d0597SMatthew G Knepley   *sf = dm->sf;
4459b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
4460b21d0597SMatthew G Knepley }
4461b21d0597SMatthew G Knepley 
4462057b4bcdSMatthew G Knepley /*@
4463057b4bcdSMatthew G Knepley   DMSetPointSF - Set the PetscSF encoding the parallel section point overlap for the DM.
4464057b4bcdSMatthew G Knepley 
4465057b4bcdSMatthew G Knepley   Input Parameters:
4466057b4bcdSMatthew G Knepley + dm - The DM
4467057b4bcdSMatthew G Knepley - sf - The PetscSF
4468057b4bcdSMatthew G Knepley 
4469057b4bcdSMatthew G Knepley   Level: intermediate
4470057b4bcdSMatthew G Knepley 
44711bb6d2a8SBarry Smith .seealso: DMGetPointSF(), DMGetSectionSF(), DMSetSectionSF(), DMCreateSectionSF()
4472057b4bcdSMatthew G Knepley @*/
44730adebc6cSBarry Smith PetscErrorCode DMSetPointSF(DM dm, PetscSF sf)
44740adebc6cSBarry Smith {
4475057b4bcdSMatthew G Knepley   PetscErrorCode ierr;
4476057b4bcdSMatthew G Knepley 
4477057b4bcdSMatthew G Knepley   PetscFunctionBegin;
4478057b4bcdSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4479b9d85ea2SLisandro Dalcin   if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
4480057b4bcdSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr);
448133907cc2SStefano Zampini   ierr = PetscSFDestroy(&dm->sf);CHKERRQ(ierr);
4482057b4bcdSMatthew G Knepley   dm->sf = sf;
4483057b4bcdSMatthew G Knepley   PetscFunctionReturn(0);
4484057b4bcdSMatthew G Knepley }
4485057b4bcdSMatthew G Knepley 
448634aa8a36SMatthew G. Knepley static PetscErrorCode DMSetDefaultAdjacency_Private(DM dm, PetscInt f, PetscObject disc)
448734aa8a36SMatthew G. Knepley {
448834aa8a36SMatthew G. Knepley   PetscClassId   id;
448934aa8a36SMatthew G. Knepley   PetscErrorCode ierr;
449034aa8a36SMatthew G. Knepley 
449134aa8a36SMatthew G. Knepley   PetscFunctionBegin;
449234aa8a36SMatthew G. Knepley   ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr);
449334aa8a36SMatthew G. Knepley   if (id == PETSCFE_CLASSID) {
449434aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr);
449534aa8a36SMatthew G. Knepley   } else if (id == PETSCFV_CLASSID) {
449634aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(dm, f, PETSC_TRUE, PETSC_FALSE);CHKERRQ(ierr);
449717c1d62eSMatthew G. Knepley   } else {
449817c1d62eSMatthew G. Knepley     ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr);
449934aa8a36SMatthew G. Knepley   }
450034aa8a36SMatthew G. Knepley   PetscFunctionReturn(0);
450134aa8a36SMatthew G. Knepley }
450234aa8a36SMatthew G. Knepley 
450344a7f3ddSMatthew G. Knepley static PetscErrorCode DMFieldEnlarge_Static(DM dm, PetscInt NfNew)
450444a7f3ddSMatthew G. Knepley {
450544a7f3ddSMatthew G. Knepley   RegionField   *tmpr;
450644a7f3ddSMatthew G. Knepley   PetscInt       Nf = dm->Nf, f;
450744a7f3ddSMatthew G. Knepley   PetscErrorCode ierr;
450844a7f3ddSMatthew G. Knepley 
450944a7f3ddSMatthew G. Knepley   PetscFunctionBegin;
451044a7f3ddSMatthew G. Knepley   if (Nf >= NfNew) PetscFunctionReturn(0);
451144a7f3ddSMatthew G. Knepley   ierr = PetscMalloc1(NfNew, &tmpr);CHKERRQ(ierr);
451244a7f3ddSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpr[f] = dm->fields[f];
451344a7f3ddSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) {tmpr[f].disc = NULL; tmpr[f].label = NULL;}
451444a7f3ddSMatthew G. Knepley   ierr = PetscFree(dm->fields);CHKERRQ(ierr);
451544a7f3ddSMatthew G. Knepley   dm->Nf     = NfNew;
451644a7f3ddSMatthew G. Knepley   dm->fields = tmpr;
451744a7f3ddSMatthew G. Knepley   PetscFunctionReturn(0);
451844a7f3ddSMatthew G. Knepley }
451944a7f3ddSMatthew G. Knepley 
452044a7f3ddSMatthew G. Knepley /*@
452144a7f3ddSMatthew G. Knepley   DMClearFields - Remove all fields from the DM
452244a7f3ddSMatthew G. Knepley 
4523d083f849SBarry Smith   Logically collective on dm
452444a7f3ddSMatthew G. Knepley 
452544a7f3ddSMatthew G. Knepley   Input Parameter:
452644a7f3ddSMatthew G. Knepley . dm - The DM
452744a7f3ddSMatthew G. Knepley 
452844a7f3ddSMatthew G. Knepley   Level: intermediate
452944a7f3ddSMatthew G. Knepley 
453044a7f3ddSMatthew G. Knepley .seealso: DMGetNumFields(), DMSetNumFields(), DMSetField()
453144a7f3ddSMatthew G. Knepley @*/
453244a7f3ddSMatthew G. Knepley PetscErrorCode DMClearFields(DM dm)
453344a7f3ddSMatthew G. Knepley {
453444a7f3ddSMatthew G. Knepley   PetscInt       f;
453544a7f3ddSMatthew G. Knepley   PetscErrorCode ierr;
453644a7f3ddSMatthew G. Knepley 
453744a7f3ddSMatthew G. Knepley   PetscFunctionBegin;
453844a7f3ddSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
453944a7f3ddSMatthew G. Knepley   for (f = 0; f < dm->Nf; ++f) {
454044a7f3ddSMatthew G. Knepley     ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr);
454144a7f3ddSMatthew G. Knepley     ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr);
454244a7f3ddSMatthew G. Knepley   }
454344a7f3ddSMatthew G. Knepley   ierr = PetscFree(dm->fields);CHKERRQ(ierr);
454444a7f3ddSMatthew G. Knepley   dm->fields = NULL;
454544a7f3ddSMatthew G. Knepley   dm->Nf     = 0;
454644a7f3ddSMatthew G. Knepley   PetscFunctionReturn(0);
454744a7f3ddSMatthew G. Knepley }
454844a7f3ddSMatthew G. Knepley 
4549689b5837SMatthew G. Knepley /*@
4550689b5837SMatthew G. Knepley   DMGetNumFields - Get the number of fields in the DM
4551689b5837SMatthew G. Knepley 
4552689b5837SMatthew G. Knepley   Not collective
4553689b5837SMatthew G. Knepley 
4554689b5837SMatthew G. Knepley   Input Parameter:
4555689b5837SMatthew G. Knepley . dm - The DM
4556689b5837SMatthew G. Knepley 
4557689b5837SMatthew G. Knepley   Output Parameter:
4558689b5837SMatthew G. Knepley . Nf - The number of fields
4559689b5837SMatthew G. Knepley 
4560689b5837SMatthew G. Knepley   Level: intermediate
4561689b5837SMatthew G. Knepley 
4562689b5837SMatthew G. Knepley .seealso: DMSetNumFields(), DMSetField()
4563689b5837SMatthew G. Knepley @*/
45640f21e855SMatthew G. Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields)
45650f21e855SMatthew G. Knepley {
45660f21e855SMatthew G. Knepley   PetscFunctionBegin;
45670f21e855SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4568534a8f05SLisandro Dalcin   PetscValidIntPointer(numFields, 2);
456944a7f3ddSMatthew G. Knepley   *numFields = dm->Nf;
4570af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
4571af122d2aSMatthew G Knepley }
4572af122d2aSMatthew G Knepley 
4573689b5837SMatthew G. Knepley /*@
4574689b5837SMatthew G. Knepley   DMSetNumFields - Set the number of fields in the DM
4575689b5837SMatthew G. Knepley 
4576d083f849SBarry Smith   Logically collective on dm
4577689b5837SMatthew G. Knepley 
4578689b5837SMatthew G. Knepley   Input Parameters:
4579689b5837SMatthew G. Knepley + dm - The DM
4580689b5837SMatthew G. Knepley - Nf - The number of fields
4581689b5837SMatthew G. Knepley 
4582689b5837SMatthew G. Knepley   Level: intermediate
4583689b5837SMatthew G. Knepley 
4584689b5837SMatthew G. Knepley .seealso: DMGetNumFields(), DMSetField()
4585689b5837SMatthew G. Knepley @*/
4586af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields)
4587af122d2aSMatthew G Knepley {
45880f21e855SMatthew G. Knepley   PetscInt       Nf, f;
4589af122d2aSMatthew G Knepley   PetscErrorCode ierr;
4590af122d2aSMatthew G Knepley 
4591af122d2aSMatthew G Knepley   PetscFunctionBegin;
4592af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
459344a7f3ddSMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
45940f21e855SMatthew G. Knepley   for (f = Nf; f < numFields; ++f) {
45950f21e855SMatthew G. Knepley     PetscContainer obj;
45960f21e855SMatthew G. Knepley 
45970f21e855SMatthew G. Knepley     ierr = PetscContainerCreate(PetscObjectComm((PetscObject) dm), &obj);CHKERRQ(ierr);
459844a7f3ddSMatthew G. Knepley     ierr = DMAddField(dm, NULL, (PetscObject) obj);CHKERRQ(ierr);
45990f21e855SMatthew G. Knepley     ierr = PetscContainerDestroy(&obj);CHKERRQ(ierr);
4600af122d2aSMatthew G Knepley   }
4601af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
4602af122d2aSMatthew G Knepley }
4603af122d2aSMatthew G Knepley 
4604c1929be8SMatthew G. Knepley /*@
4605c1929be8SMatthew G. Knepley   DMGetField - Return the discretization object for a given DM field
4606c1929be8SMatthew G. Knepley 
4607c1929be8SMatthew G. Knepley   Not collective
4608c1929be8SMatthew G. Knepley 
4609c1929be8SMatthew G. Knepley   Input Parameters:
4610c1929be8SMatthew G. Knepley + dm - The DM
4611c1929be8SMatthew G. Knepley - f  - The field number
4612c1929be8SMatthew G. Knepley 
461344a7f3ddSMatthew G. Knepley   Output Parameters:
461444a7f3ddSMatthew G. Knepley + label - The label indicating the support of the field, or NULL for the entire mesh
461544a7f3ddSMatthew G. Knepley - field - The discretization object
4616c1929be8SMatthew G. Knepley 
461744a7f3ddSMatthew G. Knepley   Level: intermediate
4618c1929be8SMatthew G. Knepley 
461944a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMSetField()
4620c1929be8SMatthew G. Knepley @*/
462144a7f3ddSMatthew G. Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, DMLabel *label, PetscObject *field)
4622af122d2aSMatthew G Knepley {
4623af122d2aSMatthew G Knepley   PetscFunctionBegin;
4624af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
462544a7f3ddSMatthew G. Knepley   PetscValidPointer(field, 3);
462644a7f3ddSMatthew 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);
462744a7f3ddSMatthew G. Knepley   if (label) *label = dm->fields[f].label;
462844a7f3ddSMatthew G. Knepley   if (field) *field = dm->fields[f].disc;
4629decb47aaSMatthew G. Knepley   PetscFunctionReturn(0);
4630decb47aaSMatthew G. Knepley }
4631decb47aaSMatthew G. Knepley 
4632c1929be8SMatthew G. Knepley /*@
4633c1929be8SMatthew G. Knepley   DMSetField - Set the discretization object for a given DM field
4634c1929be8SMatthew G. Knepley 
4635d083f849SBarry Smith   Logically collective on dm
4636c1929be8SMatthew G. Knepley 
4637c1929be8SMatthew G. Knepley   Input Parameters:
4638c1929be8SMatthew G. Knepley + dm    - The DM
4639c1929be8SMatthew G. Knepley . f     - The field number
464044a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh
4641c1929be8SMatthew G. Knepley - field - The discretization object
4642c1929be8SMatthew G. Knepley 
464344a7f3ddSMatthew G. Knepley   Level: intermediate
4644c1929be8SMatthew G. Knepley 
464544a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMGetField()
4646c1929be8SMatthew G. Knepley @*/
464744a7f3ddSMatthew G. Knepley PetscErrorCode DMSetField(DM dm, PetscInt f, DMLabel label, PetscObject field)
4648decb47aaSMatthew G. Knepley {
4649decb47aaSMatthew G. Knepley   PetscErrorCode ierr;
4650decb47aaSMatthew G. Knepley 
4651decb47aaSMatthew G. Knepley   PetscFunctionBegin;
4652decb47aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4653e5e52638SMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3);
465444a7f3ddSMatthew G. Knepley   PetscValidHeader(field, 4);
4655e5e52638SMatthew G. Knepley   if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
465644a7f3ddSMatthew G. Knepley   ierr = DMFieldEnlarge_Static(dm, f+1);CHKERRQ(ierr);
465744a7f3ddSMatthew G. Knepley   ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr);
465844a7f3ddSMatthew G. Knepley   ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr);
465944a7f3ddSMatthew G. Knepley   dm->fields[f].label = label;
466044a7f3ddSMatthew G. Knepley   dm->fields[f].disc  = field;
466144a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
466244a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr);
466334aa8a36SMatthew G. Knepley   ierr = DMSetDefaultAdjacency_Private(dm, f, field);CHKERRQ(ierr);
46642df9ee95SMatthew G. Knepley   ierr = DMClearDS(dm);CHKERRQ(ierr);
466544a7f3ddSMatthew G. Knepley   PetscFunctionReturn(0);
466644a7f3ddSMatthew G. Knepley }
466744a7f3ddSMatthew G. Knepley 
466844a7f3ddSMatthew G. Knepley /*@
466944a7f3ddSMatthew G. Knepley   DMAddField - Add the discretization object for the given DM field
467044a7f3ddSMatthew G. Knepley 
4671d083f849SBarry Smith   Logically collective on dm
467244a7f3ddSMatthew G. Knepley 
467344a7f3ddSMatthew G. Knepley   Input Parameters:
467444a7f3ddSMatthew G. Knepley + dm    - The DM
467544a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh
467644a7f3ddSMatthew G. Knepley - field - The discretization object
467744a7f3ddSMatthew G. Knepley 
467844a7f3ddSMatthew G. Knepley   Level: intermediate
467944a7f3ddSMatthew G. Knepley 
468044a7f3ddSMatthew G. Knepley .seealso: DMSetField(), DMGetField()
468144a7f3ddSMatthew G. Knepley @*/
468244a7f3ddSMatthew G. Knepley PetscErrorCode DMAddField(DM dm, DMLabel label, PetscObject field)
468344a7f3ddSMatthew G. Knepley {
468444a7f3ddSMatthew G. Knepley   PetscInt       Nf = dm->Nf;
468544a7f3ddSMatthew G. Knepley   PetscErrorCode ierr;
468644a7f3ddSMatthew G. Knepley 
468744a7f3ddSMatthew G. Knepley   PetscFunctionBegin;
468844a7f3ddSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
468944a7f3ddSMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3);
469044a7f3ddSMatthew G. Knepley   PetscValidHeader(field, 3);
469144a7f3ddSMatthew G. Knepley   ierr = DMFieldEnlarge_Static(dm, Nf+1);CHKERRQ(ierr);
469244a7f3ddSMatthew G. Knepley   dm->fields[Nf].label = label;
469344a7f3ddSMatthew G. Knepley   dm->fields[Nf].disc  = field;
469444a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
469544a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr);
469634aa8a36SMatthew G. Knepley   ierr = DMSetDefaultAdjacency_Private(dm, Nf, field);CHKERRQ(ierr);
46972df9ee95SMatthew G. Knepley   ierr = DMClearDS(dm);CHKERRQ(ierr);
4698af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
4699af122d2aSMatthew G Knepley }
47006636e97aSMatthew G Knepley 
4701e5e52638SMatthew G. Knepley /*@
4702e5e52638SMatthew G. Knepley   DMCopyFields - Copy the discretizations for the DM into another DM
4703e5e52638SMatthew G. Knepley 
4704d083f849SBarry Smith   Collective on dm
4705e5e52638SMatthew G. Knepley 
4706e5e52638SMatthew G. Knepley   Input Parameter:
4707e5e52638SMatthew G. Knepley . dm - The DM
4708e5e52638SMatthew G. Knepley 
4709e5e52638SMatthew G. Knepley   Output Parameter:
4710e5e52638SMatthew G. Knepley . newdm - The DM
4711e5e52638SMatthew G. Knepley 
4712e5e52638SMatthew G. Knepley   Level: advanced
4713e5e52638SMatthew G. Knepley 
4714e5e52638SMatthew G. Knepley .seealso: DMGetField(), DMSetField(), DMAddField(), DMCopyDS(), DMGetDS(), DMGetCellDS()
4715e5e52638SMatthew G. Knepley @*/
4716e5e52638SMatthew G. Knepley PetscErrorCode DMCopyFields(DM dm, DM newdm)
4717e5e52638SMatthew G. Knepley {
4718e5e52638SMatthew G. Knepley   PetscInt       Nf, f;
4719e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4720e5e52638SMatthew G. Knepley 
4721e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4722e5e52638SMatthew G. Knepley   if (dm == newdm) PetscFunctionReturn(0);
4723e5e52638SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4724e5e52638SMatthew G. Knepley   ierr = DMClearFields(newdm);CHKERRQ(ierr);
4725e5e52638SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
4726e5e52638SMatthew G. Knepley     DMLabel     label;
4727e5e52638SMatthew G. Knepley     PetscObject field;
472834aa8a36SMatthew G. Knepley     PetscBool   useCone, useClosure;
4729e5e52638SMatthew G. Knepley 
4730e5e52638SMatthew G. Knepley     ierr = DMGetField(dm, f, &label, &field);CHKERRQ(ierr);
4731e5e52638SMatthew G. Knepley     ierr = DMSetField(newdm, f, label, field);CHKERRQ(ierr);
473234aa8a36SMatthew G. Knepley     ierr = DMGetAdjacency(dm, f, &useCone, &useClosure);CHKERRQ(ierr);
473334aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(newdm, f, useCone, useClosure);CHKERRQ(ierr);
473434aa8a36SMatthew G. Knepley   }
473534aa8a36SMatthew G. Knepley   PetscFunctionReturn(0);
473634aa8a36SMatthew G. Knepley }
473734aa8a36SMatthew G. Knepley 
473834aa8a36SMatthew G. Knepley /*@
473934aa8a36SMatthew G. Knepley   DMGetAdjacency - Returns the flags for determining variable influence
474034aa8a36SMatthew G. Knepley 
474134aa8a36SMatthew G. Knepley   Not collective
474234aa8a36SMatthew G. Knepley 
474334aa8a36SMatthew G. Knepley   Input Parameters:
474434aa8a36SMatthew G. Knepley + dm - The DM object
474534aa8a36SMatthew G. Knepley - f  - The field number, or PETSC_DEFAULT for the default adjacency
474634aa8a36SMatthew G. Knepley 
474734aa8a36SMatthew G. Knepley   Output Parameter:
474834aa8a36SMatthew G. Knepley + useCone    - Flag for variable influence starting with the cone operation
474934aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
475034aa8a36SMatthew G. Knepley 
475134aa8a36SMatthew G. Knepley   Notes:
475234aa8a36SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
475334aa8a36SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
475434aa8a36SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4755979e053dSMatthew G. Knepley   Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another.
475634aa8a36SMatthew G. Knepley 
475734aa8a36SMatthew G. Knepley   Level: developer
475834aa8a36SMatthew G. Knepley 
475934aa8a36SMatthew G. Knepley .seealso: DMSetAdjacency(), DMGetField(), DMSetField()
476034aa8a36SMatthew G. Knepley @*/
476134aa8a36SMatthew G. Knepley PetscErrorCode DMGetAdjacency(DM dm, PetscInt f, PetscBool *useCone, PetscBool *useClosure)
476234aa8a36SMatthew G. Knepley {
476334aa8a36SMatthew G. Knepley   PetscFunctionBegin;
476434aa8a36SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4765534a8f05SLisandro Dalcin   if (useCone)    PetscValidBoolPointer(useCone, 3);
4766534a8f05SLisandro Dalcin   if (useClosure) PetscValidBoolPointer(useClosure, 4);
476734aa8a36SMatthew G. Knepley   if (f < 0) {
476834aa8a36SMatthew G. Knepley     if (useCone)    *useCone    = dm->adjacency[0];
476934aa8a36SMatthew G. Knepley     if (useClosure) *useClosure = dm->adjacency[1];
477034aa8a36SMatthew G. Knepley   } else {
477134aa8a36SMatthew G. Knepley     PetscInt       Nf;
477234aa8a36SMatthew G. Knepley     PetscErrorCode ierr;
477334aa8a36SMatthew G. Knepley 
477434aa8a36SMatthew G. Knepley     ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
477534aa8a36SMatthew G. Knepley     if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf);
477634aa8a36SMatthew G. Knepley     if (useCone)    *useCone    = dm->fields[f].adjacency[0];
477734aa8a36SMatthew G. Knepley     if (useClosure) *useClosure = dm->fields[f].adjacency[1];
477834aa8a36SMatthew G. Knepley   }
477934aa8a36SMatthew G. Knepley   PetscFunctionReturn(0);
478034aa8a36SMatthew G. Knepley }
478134aa8a36SMatthew G. Knepley 
478234aa8a36SMatthew G. Knepley /*@
478334aa8a36SMatthew G. Knepley   DMSetAdjacency - Set the flags for determining variable influence
478434aa8a36SMatthew G. Knepley 
478534aa8a36SMatthew G. Knepley   Not collective
478634aa8a36SMatthew G. Knepley 
478734aa8a36SMatthew G. Knepley   Input Parameters:
478834aa8a36SMatthew G. Knepley + dm         - The DM object
478934aa8a36SMatthew G. Knepley . f          - The field number
479034aa8a36SMatthew G. Knepley . useCone    - Flag for variable influence starting with the cone operation
479134aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
479234aa8a36SMatthew G. Knepley 
479334aa8a36SMatthew G. Knepley   Notes:
479434aa8a36SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
479534aa8a36SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
479634aa8a36SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4797979e053dSMatthew G. Knepley   Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another.
479834aa8a36SMatthew G. Knepley 
479934aa8a36SMatthew G. Knepley   Level: developer
480034aa8a36SMatthew G. Knepley 
480134aa8a36SMatthew G. Knepley .seealso: DMGetAdjacency(), DMGetField(), DMSetField()
480234aa8a36SMatthew G. Knepley @*/
480334aa8a36SMatthew G. Knepley PetscErrorCode DMSetAdjacency(DM dm, PetscInt f, PetscBool useCone, PetscBool useClosure)
480434aa8a36SMatthew G. Knepley {
480534aa8a36SMatthew G. Knepley   PetscFunctionBegin;
480634aa8a36SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
480734aa8a36SMatthew G. Knepley   if (f < 0) {
480834aa8a36SMatthew G. Knepley     dm->adjacency[0] = useCone;
480934aa8a36SMatthew G. Knepley     dm->adjacency[1] = useClosure;
481034aa8a36SMatthew G. Knepley   } else {
481134aa8a36SMatthew G. Knepley     PetscInt       Nf;
481234aa8a36SMatthew G. Knepley     PetscErrorCode ierr;
481334aa8a36SMatthew G. Knepley 
481434aa8a36SMatthew G. Knepley     ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
481534aa8a36SMatthew G. Knepley     if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf);
481634aa8a36SMatthew G. Knepley     dm->fields[f].adjacency[0] = useCone;
481734aa8a36SMatthew G. Knepley     dm->fields[f].adjacency[1] = useClosure;
4818e5e52638SMatthew G. Knepley   }
4819e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4820e5e52638SMatthew G. Knepley }
4821e5e52638SMatthew G. Knepley 
4822b0441da4SMatthew G. Knepley /*@
4823b0441da4SMatthew G. Knepley   DMGetBasicAdjacency - Returns the flags for determining variable influence, using either the default or field 0 if it is defined
4824b0441da4SMatthew G. Knepley 
4825b0441da4SMatthew G. Knepley   Not collective
4826b0441da4SMatthew G. Knepley 
4827b0441da4SMatthew G. Knepley   Input Parameters:
4828b0441da4SMatthew G. Knepley . dm - The DM object
4829b0441da4SMatthew G. Knepley 
4830b0441da4SMatthew G. Knepley   Output Parameter:
4831b0441da4SMatthew G. Knepley + useCone    - Flag for variable influence starting with the cone operation
4832b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
4833b0441da4SMatthew G. Knepley 
4834b0441da4SMatthew G. Knepley   Notes:
4835b0441da4SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
4836b0441da4SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
4837b0441da4SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4838b0441da4SMatthew G. Knepley 
4839b0441da4SMatthew G. Knepley   Level: developer
4840b0441da4SMatthew G. Knepley 
4841b0441da4SMatthew G. Knepley .seealso: DMSetBasicAdjacency(), DMGetField(), DMSetField()
4842b0441da4SMatthew G. Knepley @*/
4843b0441da4SMatthew G. Knepley PetscErrorCode DMGetBasicAdjacency(DM dm, PetscBool *useCone, PetscBool *useClosure)
4844b0441da4SMatthew G. Knepley {
4845b0441da4SMatthew G. Knepley   PetscInt       Nf;
4846b0441da4SMatthew G. Knepley   PetscErrorCode ierr;
4847b0441da4SMatthew G. Knepley 
4848b0441da4SMatthew G. Knepley   PetscFunctionBegin;
4849b0441da4SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4850534a8f05SLisandro Dalcin   if (useCone)    PetscValidBoolPointer(useCone, 3);
4851534a8f05SLisandro Dalcin   if (useClosure) PetscValidBoolPointer(useClosure, 4);
4852b0441da4SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4853b0441da4SMatthew G. Knepley   if (!Nf) {
4854b0441da4SMatthew G. Knepley     ierr = DMGetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr);
4855b0441da4SMatthew G. Knepley   } else {
4856b0441da4SMatthew G. Knepley     ierr = DMGetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr);
4857b0441da4SMatthew G. Knepley   }
4858b0441da4SMatthew G. Knepley   PetscFunctionReturn(0);
4859b0441da4SMatthew G. Knepley }
4860b0441da4SMatthew G. Knepley 
4861b0441da4SMatthew G. Knepley /*@
4862b0441da4SMatthew G. Knepley   DMSetBasicAdjacency - Set the flags for determining variable influence, using either the default or field 0 if it is defined
4863b0441da4SMatthew G. Knepley 
4864b0441da4SMatthew G. Knepley   Not collective
4865b0441da4SMatthew G. Knepley 
4866b0441da4SMatthew G. Knepley   Input Parameters:
4867b0441da4SMatthew G. Knepley + dm         - The DM object
4868b0441da4SMatthew G. Knepley . useCone    - Flag for variable influence starting with the cone operation
4869b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
4870b0441da4SMatthew G. Knepley 
4871b0441da4SMatthew G. Knepley   Notes:
4872b0441da4SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
4873b0441da4SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
4874b0441da4SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4875b0441da4SMatthew G. Knepley 
4876b0441da4SMatthew G. Knepley   Level: developer
4877b0441da4SMatthew G. Knepley 
4878b0441da4SMatthew G. Knepley .seealso: DMGetBasicAdjacency(), DMGetField(), DMSetField()
4879b0441da4SMatthew G. Knepley @*/
4880b0441da4SMatthew G. Knepley PetscErrorCode DMSetBasicAdjacency(DM dm, PetscBool useCone, PetscBool useClosure)
4881b0441da4SMatthew G. Knepley {
4882b0441da4SMatthew G. Knepley   PetscInt       Nf;
4883b0441da4SMatthew G. Knepley   PetscErrorCode ierr;
4884b0441da4SMatthew G. Knepley 
4885b0441da4SMatthew G. Knepley   PetscFunctionBegin;
4886b0441da4SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4887b0441da4SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4888b0441da4SMatthew G. Knepley   if (!Nf) {
4889b0441da4SMatthew G. Knepley     ierr = DMSetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr);
4890b0441da4SMatthew G. Knepley   } else {
4891b0441da4SMatthew G. Knepley     ierr = DMSetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr);
4892e5e52638SMatthew G. Knepley   }
4893e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4894e5e52638SMatthew G. Knepley }
4895e5e52638SMatthew G. Knepley 
4896e5e52638SMatthew G. Knepley static PetscErrorCode DMDSEnlarge_Static(DM dm, PetscInt NdsNew)
4897e5e52638SMatthew G. Knepley {
4898e5e52638SMatthew G. Knepley   DMSpace       *tmpd;
4899e5e52638SMatthew G. Knepley   PetscInt       Nds = dm->Nds, s;
4900e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4901e5e52638SMatthew G. Knepley 
4902e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4903e5e52638SMatthew G. Knepley   if (Nds >= NdsNew) PetscFunctionReturn(0);
4904e5e52638SMatthew G. Knepley   ierr = PetscMalloc1(NdsNew, &tmpd);CHKERRQ(ierr);
4905e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) tmpd[s] = dm->probs[s];
4906b3cf3223SMatthew G. Knepley   for (s = Nds; s < NdsNew; ++s) {tmpd[s].ds = NULL; tmpd[s].label = NULL; tmpd[s].fields = NULL;}
4907e5e52638SMatthew G. Knepley   ierr = PetscFree(dm->probs);CHKERRQ(ierr);
4908e5e52638SMatthew G. Knepley   dm->Nds   = NdsNew;
4909e5e52638SMatthew G. Knepley   dm->probs = tmpd;
4910e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4911e5e52638SMatthew G. Knepley }
4912e5e52638SMatthew G. Knepley 
4913e5e52638SMatthew G. Knepley /*@
4914e5e52638SMatthew G. Knepley   DMGetNumDS - Get the number of discrete systems in the DM
4915e5e52638SMatthew G. Knepley 
4916e5e52638SMatthew G. Knepley   Not collective
4917e5e52638SMatthew G. Knepley 
4918e5e52638SMatthew G. Knepley   Input Parameter:
4919e5e52638SMatthew G. Knepley . dm - The DM
4920e5e52638SMatthew G. Knepley 
4921e5e52638SMatthew G. Knepley   Output Parameter:
4922e5e52638SMatthew G. Knepley . Nds - The number of PetscDS objects
4923e5e52638SMatthew G. Knepley 
4924e5e52638SMatthew G. Knepley   Level: intermediate
4925e5e52638SMatthew G. Knepley 
4926e5e52638SMatthew G. Knepley .seealso: DMGetDS(), DMGetCellDS()
4927e5e52638SMatthew G. Knepley @*/
4928e5e52638SMatthew G. Knepley PetscErrorCode DMGetNumDS(DM dm, PetscInt *Nds)
4929e5e52638SMatthew G. Knepley {
4930e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4931e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4932534a8f05SLisandro Dalcin   PetscValidIntPointer(Nds, 2);
4933e5e52638SMatthew G. Knepley   *Nds = dm->Nds;
4934e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4935e5e52638SMatthew G. Knepley }
4936e5e52638SMatthew G. Knepley 
4937e5e52638SMatthew G. Knepley /*@
4938e5e52638SMatthew G. Knepley   DMClearDS - Remove all discrete systems from the DM
4939e5e52638SMatthew G. Knepley 
4940d083f849SBarry Smith   Logically collective on dm
4941e5e52638SMatthew G. Knepley 
4942e5e52638SMatthew G. Knepley   Input Parameter:
4943e5e52638SMatthew G. Knepley . dm - The DM
4944e5e52638SMatthew G. Knepley 
4945e5e52638SMatthew G. Knepley   Level: intermediate
4946e5e52638SMatthew G. Knepley 
4947e5e52638SMatthew G. Knepley .seealso: DMGetNumDS(), DMGetDS(), DMSetField()
4948e5e52638SMatthew G. Knepley @*/
4949e5e52638SMatthew G. Knepley PetscErrorCode DMClearDS(DM dm)
4950e5e52638SMatthew G. Knepley {
4951e5e52638SMatthew G. Knepley   PetscInt       s;
4952e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4953e5e52638SMatthew G. Knepley 
4954e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4955e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4956e5e52638SMatthew G. Knepley   for (s = 0; s < dm->Nds; ++s) {
4957e5e52638SMatthew G. Knepley     ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr);
4958e5e52638SMatthew G. Knepley     ierr = DMLabelDestroy(&dm->probs[s].label);CHKERRQ(ierr);
4959b3cf3223SMatthew G. Knepley     ierr = ISDestroy(&dm->probs[s].fields);CHKERRQ(ierr);
4960e5e52638SMatthew G. Knepley   }
4961e5e52638SMatthew G. Knepley   ierr = PetscFree(dm->probs);CHKERRQ(ierr);
4962e5e52638SMatthew G. Knepley   dm->probs = NULL;
4963e5e52638SMatthew G. Knepley   dm->Nds   = 0;
4964e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4965e5e52638SMatthew G. Knepley }
4966e5e52638SMatthew G. Knepley 
4967e5e52638SMatthew G. Knepley /*@
4968e5e52638SMatthew G. Knepley   DMGetDS - Get the default PetscDS
4969e5e52638SMatthew G. Knepley 
4970e5e52638SMatthew G. Knepley   Not collective
4971e5e52638SMatthew G. Knepley 
4972e5e52638SMatthew G. Knepley   Input Parameter:
4973e5e52638SMatthew G. Knepley . dm    - The DM
4974e5e52638SMatthew G. Knepley 
4975e5e52638SMatthew G. Knepley   Output Parameter:
4976e5e52638SMatthew G. Knepley . prob - The default PetscDS
4977e5e52638SMatthew G. Knepley 
4978e5e52638SMatthew G. Knepley   Level: intermediate
4979e5e52638SMatthew G. Knepley 
4980e5e52638SMatthew G. Knepley .seealso: DMGetCellDS(), DMGetRegionDS()
4981e5e52638SMatthew G. Knepley @*/
4982e5e52638SMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *prob)
4983e5e52638SMatthew G. Knepley {
4984b0143b4dSMatthew G. Knepley   PetscErrorCode ierr;
4985b0143b4dSMatthew G. Knepley 
4986e5e52638SMatthew G. Knepley   PetscFunctionBeginHot;
4987e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4988e5e52638SMatthew G. Knepley   PetscValidPointer(prob, 2);
4989b0143b4dSMatthew G. Knepley   if (dm->Nds <= 0) {
4990b0143b4dSMatthew G. Knepley     PetscDS ds;
4991b0143b4dSMatthew G. Knepley 
4992b0143b4dSMatthew G. Knepley     ierr = PetscDSCreate(PetscObjectComm((PetscObject) dm), &ds);CHKERRQ(ierr);
4993b3cf3223SMatthew G. Knepley     ierr = DMSetRegionDS(dm, NULL, NULL, ds);CHKERRQ(ierr);
4994b0143b4dSMatthew G. Knepley     ierr = PetscDSDestroy(&ds);CHKERRQ(ierr);
4995b0143b4dSMatthew G. Knepley   }
4996b0143b4dSMatthew G. Knepley   *prob = dm->probs[0].ds;
4997e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4998e5e52638SMatthew G. Knepley }
4999e5e52638SMatthew G. Knepley 
5000e5e52638SMatthew G. Knepley /*@
5001e5e52638SMatthew G. Knepley   DMGetCellDS - Get the PetscDS defined on a given cell
5002e5e52638SMatthew G. Knepley 
5003e5e52638SMatthew G. Knepley   Not collective
5004e5e52638SMatthew G. Knepley 
5005e5e52638SMatthew G. Knepley   Input Parameters:
5006e5e52638SMatthew G. Knepley + dm    - The DM
5007e5e52638SMatthew G. Knepley - point - Cell for the DS
5008e5e52638SMatthew G. Knepley 
5009e5e52638SMatthew G. Knepley   Output Parameter:
5010e5e52638SMatthew G. Knepley . prob - The PetscDS defined on the given cell
5011e5e52638SMatthew G. Knepley 
5012e5e52638SMatthew G. Knepley   Level: developer
5013e5e52638SMatthew G. Knepley 
5014b0143b4dSMatthew G. Knepley .seealso: DMGetDS(), DMSetRegionDS()
5015e5e52638SMatthew G. Knepley @*/
5016e5e52638SMatthew G. Knepley PetscErrorCode DMGetCellDS(DM dm, PetscInt point, PetscDS *prob)
5017e5e52638SMatthew G. Knepley {
5018e5e52638SMatthew G. Knepley   PetscDS        probDef = NULL;
5019e5e52638SMatthew G. Knepley   PetscInt       s;
5020e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5021e5e52638SMatthew G. Knepley 
5022e5e52638SMatthew G. Knepley   PetscFunctionBeginHot;
5023e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5024e5e52638SMatthew G. Knepley   PetscValidPointer(prob, 3);
5025e5e52638SMatthew G. Knepley   *prob = NULL;
5026e5e52638SMatthew G. Knepley   for (s = 0; s < dm->Nds; ++s) {
5027e5e52638SMatthew G. Knepley     PetscInt val;
5028e5e52638SMatthew G. Knepley 
5029e5e52638SMatthew G. Knepley     if (!dm->probs[s].label) {probDef = dm->probs[s].ds;}
5030e5e52638SMatthew G. Knepley     else {
5031e5e52638SMatthew G. Knepley       ierr = DMLabelGetValue(dm->probs[s].label, point, &val);CHKERRQ(ierr);
5032e5e52638SMatthew G. Knepley       if (val >= 0) {*prob = dm->probs[s].ds; break;}
5033e5e52638SMatthew G. Knepley     }
5034e5e52638SMatthew G. Knepley   }
5035e5e52638SMatthew G. Knepley   if (!*prob) *prob = probDef;
5036e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5037e5e52638SMatthew G. Knepley }
5038e5e52638SMatthew G. Knepley 
5039e5e52638SMatthew G. Knepley /*@
5040e5e52638SMatthew G. Knepley   DMGetRegionDS - Get the PetscDS for a given mesh region, defined by a DMLabel
5041e5e52638SMatthew G. Knepley 
5042e5e52638SMatthew G. Knepley   Not collective
5043e5e52638SMatthew G. Knepley 
5044e5e52638SMatthew G. Knepley   Input Parameters:
5045e5e52638SMatthew G. Knepley + dm    - The DM
5046e5e52638SMatthew G. Knepley - label - The DMLabel defining the mesh region, or NULL for the entire mesh
5047e5e52638SMatthew G. Knepley 
5048b3cf3223SMatthew G. Knepley   Output Parameters:
5049b3cf3223SMatthew G. Knepley + fields - The IS containing the DM field numbers for the fields in this DS, or NULL
5050b3cf3223SMatthew G. Knepley - prob - The PetscDS defined on the given region, or NULL
5051e5e52638SMatthew G. Knepley 
5052e5e52638SMatthew G. Knepley   Note: If the label is missing, this function returns an error
5053e5e52638SMatthew G. Knepley 
5054e5e52638SMatthew G. Knepley   Level: advanced
5055e5e52638SMatthew G. Knepley 
5056e5e52638SMatthew G. Knepley .seealso: DMGetRegionNumDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS()
5057e5e52638SMatthew G. Knepley @*/
5058b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionDS(DM dm, DMLabel label, IS *fields, PetscDS *ds)
5059e5e52638SMatthew G. Knepley {
5060e5e52638SMatthew G. Knepley   PetscInt Nds = dm->Nds, s;
5061e5e52638SMatthew G. Knepley 
5062e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5063e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5064e5e52638SMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2);
5065b3cf3223SMatthew G. Knepley   if (fields) {PetscValidPointer(fields, 3); *fields = NULL;}
5066b3cf3223SMatthew G. Knepley   if (ds)     {PetscValidPointer(ds, 4);     *ds     = NULL;}
5067e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
5068b3cf3223SMatthew G. Knepley     if (dm->probs[s].label == label) {
5069b3cf3223SMatthew G. Knepley       if (fields) *fields = dm->probs[s].fields;
5070b3cf3223SMatthew G. Knepley       if (ds)     *ds     = dm->probs[s].ds;
5071b3cf3223SMatthew G. Knepley       PetscFunctionReturn(0);
5072b3cf3223SMatthew G. Knepley     }
5073e5e52638SMatthew G. Knepley   }
50742df9ee95SMatthew G. Knepley   PetscFunctionReturn(0);
5075e5e52638SMatthew G. Knepley }
5076e5e52638SMatthew G. Knepley 
5077e5e52638SMatthew G. Knepley /*@
5078e5e52638SMatthew G. Knepley   DMGetRegionNumDS - Get the PetscDS for a given mesh region, defined by the region number
5079e5e52638SMatthew G. Knepley 
5080e5e52638SMatthew G. Knepley   Not collective
5081e5e52638SMatthew G. Knepley 
5082e5e52638SMatthew G. Knepley   Input Parameters:
5083e5e52638SMatthew G. Knepley + dm  - The DM
5084e5e52638SMatthew G. Knepley - num - The region number, in [0, Nds)
5085e5e52638SMatthew G. Knepley 
5086e5e52638SMatthew G. Knepley   Output Parameters:
5087b3cf3223SMatthew G. Knepley + label  - The region label, or NULL
5088b3cf3223SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL
5089b3cf3223SMatthew G. Knepley - prob   - The PetscDS defined on the given region, or NULL
5090e5e52638SMatthew G. Knepley 
5091e5e52638SMatthew G. Knepley   Level: advanced
5092e5e52638SMatthew G. Knepley 
5093e5e52638SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS()
5094e5e52638SMatthew G. Knepley @*/
5095b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionNumDS(DM dm, PetscInt num, DMLabel *label, IS *fields, PetscDS *ds)
5096e5e52638SMatthew G. Knepley {
5097e5e52638SMatthew G. Knepley   PetscInt       Nds;
5098e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5099e5e52638SMatthew G. Knepley 
5100e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5101e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5102e5e52638SMatthew G. Knepley   ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr);
5103e5e52638SMatthew 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);
5104e5e52638SMatthew G. Knepley   if (label) {
5105e5e52638SMatthew G. Knepley     PetscValidPointer(label, 3);
5106e5e52638SMatthew G. Knepley     *label = dm->probs[num].label;
5107e5e52638SMatthew G. Knepley   }
5108b3cf3223SMatthew G. Knepley   if (fields) {
5109b3cf3223SMatthew G. Knepley     PetscValidPointer(fields, 4);
5110b3cf3223SMatthew G. Knepley     *fields = dm->probs[num].fields;
5111b3cf3223SMatthew G. Knepley   }
5112e5e52638SMatthew G. Knepley   if (ds) {
5113b3cf3223SMatthew G. Knepley     PetscValidPointer(ds, 5);
5114e5e52638SMatthew G. Knepley     *ds = dm->probs[num].ds;
5115e5e52638SMatthew G. Knepley   }
5116e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5117e5e52638SMatthew G. Knepley }
5118e5e52638SMatthew G. Knepley 
5119e5e52638SMatthew G. Knepley /*@
5120e5e52638SMatthew G. Knepley   DMSetRegionDS - Set the PetscDS for a given mesh region, defined by a DMLabel
5121e5e52638SMatthew G. Knepley 
5122d083f849SBarry Smith   Collective on dm
5123e5e52638SMatthew G. Knepley 
5124e5e52638SMatthew G. Knepley   Input Parameters:
5125e5e52638SMatthew G. Knepley + dm     - The DM
5126e5e52638SMatthew G. Knepley . label  - The DMLabel defining the mesh region, or NULL for the entire mesh
5127b3cf3223SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL for all fields
5128e5e52638SMatthew G. Knepley - prob   - The PetscDS defined on the given cell
5129e5e52638SMatthew G. Knepley 
5130b3cf3223SMatthew 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,
5131b3cf3223SMatthew G. Knepley   the fields argument is ignored.
5132e5e52638SMatthew G. Knepley 
5133e5e52638SMatthew G. Knepley   Level: advanced
5134e5e52638SMatthew G. Knepley 
5135e5e52638SMatthew G. Knepley .seealso: DMGetRegionDS(), DMGetDS(), DMGetCellDS()
5136e5e52638SMatthew G. Knepley @*/
5137b3cf3223SMatthew G. Knepley PetscErrorCode DMSetRegionDS(DM dm, DMLabel label, IS fields, PetscDS ds)
5138e5e52638SMatthew G. Knepley {
5139e5e52638SMatthew G. Knepley   PetscInt       Nds = dm->Nds, s;
5140e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5141e5e52638SMatthew G. Knepley 
5142e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5143e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5144e5e52638SMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2);
5145e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 3);
5146e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
5147e5e52638SMatthew G. Knepley     if (dm->probs[s].label == label) {
5148b3cf3223SMatthew G. Knepley       ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr);
5149e5e52638SMatthew G. Knepley       dm->probs[s].ds = ds;
5150e5e52638SMatthew G. Knepley       PetscFunctionReturn(0);
5151e5e52638SMatthew G. Knepley     }
5152e5e52638SMatthew G. Knepley   }
51531b5e6740SSatish Balay   ierr = DMDSEnlarge_Static(dm, Nds+1);CHKERRQ(ierr);
5154e5e52638SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
5155b3cf3223SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) fields);CHKERRQ(ierr);
5156e5e52638SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) ds);CHKERRQ(ierr);
5157e5e52638SMatthew G. Knepley   if (!label) {
5158e5e52638SMatthew G. Knepley     /* Put the NULL label at the front, so it is returned as the default */
5159e5e52638SMatthew G. Knepley     for (s = Nds-1; s >=0; --s) dm->probs[s+1] = dm->probs[s];
5160e5e52638SMatthew G. Knepley     Nds = 0;
5161e5e52638SMatthew G. Knepley   }
5162e5e52638SMatthew G. Knepley   dm->probs[Nds].label  = label;
5163b3cf3223SMatthew G. Knepley   dm->probs[Nds].fields = fields;
5164e5e52638SMatthew G. Knepley   dm->probs[Nds].ds     = ds;
5165e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5166e5e52638SMatthew G. Knepley }
5167e5e52638SMatthew G. Knepley 
5168e5e52638SMatthew G. Knepley /*@
5169e5e52638SMatthew G. Knepley   DMCreateDS - Create the discrete systems for the DM based upon the fields added to the DM
5170e5e52638SMatthew G. Knepley 
5171d083f849SBarry Smith   Collective on dm
5172e5e52638SMatthew G. Knepley 
5173e5e52638SMatthew G. Knepley   Input Parameter:
5174e5e52638SMatthew G. Knepley . dm - The DM
5175e5e52638SMatthew G. Knepley 
5176e5e52638SMatthew G. Knepley   Note: If the label has a DS defined, it will be replaced. Otherwise, it will be added to the DM.
5177e5e52638SMatthew G. Knepley 
5178e5e52638SMatthew G. Knepley   Level: intermediate
5179e5e52638SMatthew G. Knepley 
5180e5e52638SMatthew G. Knepley .seealso: DMSetField, DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS()
5181e5e52638SMatthew G. Knepley @*/
5182e5e52638SMatthew G. Knepley PetscErrorCode DMCreateDS(DM dm)
5183e5e52638SMatthew G. Knepley {
5184e5e52638SMatthew G. Knepley   MPI_Comm       comm;
5185e5e52638SMatthew G. Knepley   PetscDS        prob, probh = NULL;
5186b3cf3223SMatthew G. Knepley   PetscInt       dimEmbed, Nf = dm->Nf, f, s, field = 0, fieldh = 0;
5187e5e52638SMatthew G. Knepley   PetscBool      doSetup = PETSC_TRUE;
5188e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5189e5e52638SMatthew G. Knepley 
5190e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5191e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5192e5e52638SMatthew G. Knepley   if (!dm->fields) PetscFunctionReturn(0);
5193e5e52638SMatthew G. Knepley   /* Can only handle two label cases right now:
5194e5e52638SMatthew G. Knepley    1) NULL
5195e5e52638SMatthew G. Knepley    2) Hybrid cells
5196e5e52638SMatthew G. Knepley   */
5197e5e52638SMatthew G. Knepley   ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr);
5198e5e52638SMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr);
5199e5e52638SMatthew G. Knepley   /* Create default DS */
5200b3cf3223SMatthew G. Knepley   ierr = DMGetRegionDS(dm, NULL, NULL, &prob);CHKERRQ(ierr);
52012df9ee95SMatthew G. Knepley   if (!prob) {
5202b3cf3223SMatthew G. Knepley     IS        fields;
5203b3cf3223SMatthew G. Knepley     PetscInt *fld, nf;
5204b3cf3223SMatthew G. Knepley 
5205b3cf3223SMatthew G. Knepley     for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) ++nf;
5206b3cf3223SMatthew G. Knepley     ierr = PetscMalloc1(nf, &fld);CHKERRQ(ierr);
5207b3cf3223SMatthew G. Knepley     for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) fld[nf++] = f;
520888f0c812SMatthew G. Knepley     ierr = ISCreate(PETSC_COMM_SELF, &fields);CHKERRQ(ierr);
520988f0c812SMatthew G. Knepley     ierr = PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_");CHKERRQ(ierr);
521088f0c812SMatthew G. Knepley     ierr = ISSetType(fields, ISGENERAL);CHKERRQ(ierr);
521188f0c812SMatthew G. Knepley     ierr = ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER);CHKERRQ(ierr);
521288f0c812SMatthew G. Knepley 
52132df9ee95SMatthew G. Knepley     ierr = PetscDSCreate(comm, &prob);CHKERRQ(ierr);
5214b3cf3223SMatthew G. Knepley     ierr = DMSetRegionDS(dm, NULL, fields, prob);CHKERRQ(ierr);
52152df9ee95SMatthew G. Knepley     ierr = PetscDSDestroy(&prob);CHKERRQ(ierr);
5216b3cf3223SMatthew G. Knepley     ierr = ISDestroy(&fields);CHKERRQ(ierr);
5217b3cf3223SMatthew G. Knepley     ierr = DMGetRegionDS(dm, NULL, NULL, &prob);CHKERRQ(ierr);
52182df9ee95SMatthew G. Knepley   }
5219e5e52638SMatthew G. Knepley   ierr = PetscDSSetCoordinateDimension(prob, dimEmbed);CHKERRQ(ierr);
5220e5e52638SMatthew G. Knepley   /* Optionally create hybrid DS */
5221b3cf3223SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
5222e5e52638SMatthew G. Knepley     DMLabel  label = dm->fields[f].label;
5223e5e52638SMatthew G. Knepley     PetscInt lStart, lEnd;
5224e5e52638SMatthew G. Knepley 
5225e5e52638SMatthew G. Knepley     if (label) {
52260122748bSMatthew G. Knepley       DM        plex;
5227a2d47024SMatthew G. Knepley       IS        fields;
5228a2d47024SMatthew G. Knepley       PetscInt *fld;
52290122748bSMatthew G. Knepley       PetscInt  depth, pMax[4];
52300122748bSMatthew G. Knepley 
52310122748bSMatthew G. Knepley       ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr);
52320122748bSMatthew G. Knepley       ierr = DMPlexGetDepth(plex, &depth);CHKERRQ(ierr);
52330122748bSMatthew 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);
52340122748bSMatthew G. Knepley       ierr = DMDestroy(&plex);CHKERRQ(ierr);
52350122748bSMatthew G. Knepley 
5236e5e52638SMatthew G. Knepley       ierr = DMLabelGetBounds(label, &lStart, &lEnd);CHKERRQ(ierr);
5237e5e52638SMatthew G. Knepley       if (lStart < pMax[depth]) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only support labels over hybrid cells right now");
5238e5e52638SMatthew G. Knepley       ierr = PetscDSCreate(comm, &probh);CHKERRQ(ierr);
5239a2d47024SMatthew G. Knepley       ierr = PetscMalloc1(1, &fld);CHKERRQ(ierr);
5240a2d47024SMatthew G. Knepley       fld[0] = f;
5241a2d47024SMatthew G. Knepley       ierr = ISCreate(PETSC_COMM_SELF, &fields);CHKERRQ(ierr);
5242a2d47024SMatthew G. Knepley       ierr = PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_");CHKERRQ(ierr);
5243a2d47024SMatthew G. Knepley       ierr = ISSetType(fields, ISGENERAL);CHKERRQ(ierr);
5244a2d47024SMatthew G. Knepley       ierr = ISGeneralSetIndices(fields, 1, fld, PETSC_OWN_POINTER);CHKERRQ(ierr);
5245a2d47024SMatthew G. Knepley       ierr = DMSetRegionDS(dm, label, fields, probh);CHKERRQ(ierr);
5246a2d47024SMatthew G. Knepley       ierr = ISDestroy(&fields);CHKERRQ(ierr);
5247e5e52638SMatthew G. Knepley       ierr = PetscDSSetHybrid(probh, PETSC_TRUE);CHKERRQ(ierr);
5248e5e52638SMatthew G. Knepley       ierr = PetscDSSetCoordinateDimension(probh, dimEmbed);CHKERRQ(ierr);
5249e5e52638SMatthew G. Knepley       break;
5250e5e52638SMatthew G. Knepley     }
5251e5e52638SMatthew G. Knepley   }
5252e5e52638SMatthew G. Knepley   /* Set fields in DSes */
5253b3cf3223SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
5254e5e52638SMatthew G. Knepley     DMLabel     label = dm->fields[f].label;
5255e5e52638SMatthew G. Knepley     PetscObject disc  = dm->fields[f].disc;
5256e5e52638SMatthew G. Knepley 
5257e5e52638SMatthew G. Knepley     if (!label) {
5258e5e52638SMatthew G. Knepley       ierr = PetscDSSetDiscretization(prob,  field++,  disc);CHKERRQ(ierr);
5259e5e52638SMatthew G. Knepley       if (probh) {
5260e5e52638SMatthew G. Knepley         PetscFE subfe;
5261e5e52638SMatthew G. Knepley 
5262e5e52638SMatthew G. Knepley         ierr = PetscFEGetHeightSubspace((PetscFE) disc, 1, &subfe);CHKERRQ(ierr);
5263e5e52638SMatthew G. Knepley         ierr = PetscDSSetDiscretization(probh, fieldh++, (PetscObject) subfe);CHKERRQ(ierr);
5264e5e52638SMatthew G. Knepley       }
5265e5e52638SMatthew G. Knepley     } else {
5266e5e52638SMatthew G. Knepley       ierr = PetscDSSetDiscretization(probh, fieldh++, disc);CHKERRQ(ierr);
5267e5e52638SMatthew G. Knepley     }
5268e5e52638SMatthew G. Knepley     /* We allow people to have placeholder fields and construct the Section by hand */
5269e5e52638SMatthew G. Knepley     {
5270e5e52638SMatthew G. Knepley       PetscClassId id;
5271e5e52638SMatthew G. Knepley 
5272e5e52638SMatthew G. Knepley       ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr);
5273e5e52638SMatthew G. Knepley       if ((id != PETSCFE_CLASSID) && (id != PETSCFV_CLASSID)) doSetup = PETSC_FALSE;
5274e5e52638SMatthew G. Knepley     }
5275e5e52638SMatthew G. Knepley   }
5276e5e52638SMatthew G. Knepley   ierr = PetscDSDestroy(&probh);CHKERRQ(ierr);
5277e5e52638SMatthew G. Knepley   /* Setup DSes */
5278e5e52638SMatthew G. Knepley   if (doSetup) {
5279e5e52638SMatthew G. Knepley     for (s = 0; s < dm->Nds; ++s) {ierr = PetscDSSetUp(dm->probs[s].ds);CHKERRQ(ierr);}
5280e5e52638SMatthew G. Knepley   }
5281e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5282e5e52638SMatthew G. Knepley }
5283e5e52638SMatthew G. Knepley 
5284e5e52638SMatthew G. Knepley /*@
5285e5e52638SMatthew G. Knepley   DMCopyDS - Copy the discrete systems for the DM into another DM
5286e5e52638SMatthew G. Knepley 
5287d083f849SBarry Smith   Collective on dm
5288e5e52638SMatthew G. Knepley 
5289e5e52638SMatthew G. Knepley   Input Parameter:
5290e5e52638SMatthew G. Knepley . dm - The DM
5291e5e52638SMatthew G. Knepley 
5292e5e52638SMatthew G. Knepley   Output Parameter:
5293e5e52638SMatthew G. Knepley . newdm - The DM
5294e5e52638SMatthew G. Knepley 
5295e5e52638SMatthew G. Knepley   Level: advanced
5296e5e52638SMatthew G. Knepley 
5297e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS()
5298e5e52638SMatthew G. Knepley @*/
5299e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDS(DM dm, DM newdm)
5300e5e52638SMatthew G. Knepley {
5301e5e52638SMatthew G. Knepley   PetscInt       Nds, s;
5302e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5303e5e52638SMatthew G. Knepley 
5304e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5305e5e52638SMatthew G. Knepley   if (dm == newdm) PetscFunctionReturn(0);
5306e5e52638SMatthew G. Knepley   ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr);
5307e5e52638SMatthew G. Knepley   ierr = DMClearDS(newdm);CHKERRQ(ierr);
5308e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
5309e5e52638SMatthew G. Knepley     DMLabel label;
5310b3cf3223SMatthew G. Knepley     IS      fields;
5311e5e52638SMatthew G. Knepley     PetscDS ds;
5312e5e52638SMatthew G. Knepley 
5313b3cf3223SMatthew G. Knepley     ierr = DMGetRegionNumDS(dm, s, &label, &fields, &ds);CHKERRQ(ierr);
5314b3cf3223SMatthew G. Knepley     ierr = DMSetRegionDS(newdm, label, fields, ds);CHKERRQ(ierr);
5315e5e52638SMatthew G. Knepley   }
5316e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5317e5e52638SMatthew G. Knepley }
5318e5e52638SMatthew G. Knepley 
5319e5e52638SMatthew G. Knepley /*@
5320e5e52638SMatthew G. Knepley   DMCopyDisc - Copy the fields and discrete systems for the DM into another DM
5321e5e52638SMatthew G. Knepley 
5322d083f849SBarry Smith   Collective on dm
5323e5e52638SMatthew G. Knepley 
5324e5e52638SMatthew G. Knepley   Input Parameter:
5325e5e52638SMatthew G. Knepley . dm - The DM
5326e5e52638SMatthew G. Knepley 
5327e5e52638SMatthew G. Knepley   Output Parameter:
5328e5e52638SMatthew G. Knepley . newdm - The DM
5329e5e52638SMatthew G. Knepley 
5330e5e52638SMatthew G. Knepley   Level: advanced
5331e5e52638SMatthew G. Knepley 
5332e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMCopyDS()
5333e5e52638SMatthew G. Knepley @*/
5334e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDisc(DM dm, DM newdm)
5335e5e52638SMatthew G. Knepley {
5336e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5337e5e52638SMatthew G. Knepley 
5338e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5339e5e52638SMatthew G. Knepley   if (dm == newdm) PetscFunctionReturn(0);
5340e5e52638SMatthew G. Knepley   ierr = DMCopyFields(dm, newdm);CHKERRQ(ierr);
5341e5e52638SMatthew G. Knepley   ierr = DMCopyDS(dm, newdm);CHKERRQ(ierr);
5342e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5343e5e52638SMatthew G. Knepley }
5344e5e52638SMatthew G. Knepley 
5345b64e0483SPeter Brune PetscErrorCode DMRestrictHook_Coordinates(DM dm,DM dmc,void *ctx)
5346b64e0483SPeter Brune {
5347b64e0483SPeter Brune   DM dm_coord,dmc_coord;
5348b64e0483SPeter Brune   PetscErrorCode ierr;
5349b64e0483SPeter Brune   Vec coords,ccoords;
53506dbf9973SLawrence Mitchell   Mat inject;
5351b64e0483SPeter Brune   PetscFunctionBegin;
5352b64e0483SPeter Brune   ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr);
5353b64e0483SPeter Brune   ierr = DMGetCoordinateDM(dmc,&dmc_coord);CHKERRQ(ierr);
5354b64e0483SPeter Brune   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
5355b64e0483SPeter Brune   ierr = DMGetCoordinates(dmc,&ccoords);CHKERRQ(ierr);
5356b64e0483SPeter Brune   if (coords && !ccoords) {
5357b64e0483SPeter Brune     ierr = DMCreateGlobalVector(dmc_coord,&ccoords);CHKERRQ(ierr);
53586668ed41SLisandro Dalcin     ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr);
53596dbf9973SLawrence Mitchell     ierr = DMCreateInjection(dmc_coord,dm_coord,&inject);CHKERRQ(ierr);
53602adcf181SLawrence Mitchell     ierr = MatRestrict(inject,coords,ccoords);CHKERRQ(ierr);
53616dbf9973SLawrence Mitchell     ierr = MatDestroy(&inject);CHKERRQ(ierr);
5362b64e0483SPeter Brune     ierr = DMSetCoordinates(dmc,ccoords);CHKERRQ(ierr);
5363b64e0483SPeter Brune     ierr = VecDestroy(&ccoords);CHKERRQ(ierr);
5364b64e0483SPeter Brune   }
5365b64e0483SPeter Brune   PetscFunctionReturn(0);
5366b64e0483SPeter Brune }
5367b64e0483SPeter Brune 
536803dadc2fSPeter Brune static PetscErrorCode DMSubDomainHook_Coordinates(DM dm,DM subdm,void *ctx)
536903dadc2fSPeter Brune {
537003dadc2fSPeter Brune   DM dm_coord,subdm_coord;
537103dadc2fSPeter Brune   PetscErrorCode ierr;
537203dadc2fSPeter Brune   Vec coords,ccoords,clcoords;
537303dadc2fSPeter Brune   VecScatter *scat_i,*scat_g;
537403dadc2fSPeter Brune   PetscFunctionBegin;
537503dadc2fSPeter Brune   ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr);
537603dadc2fSPeter Brune   ierr = DMGetCoordinateDM(subdm,&subdm_coord);CHKERRQ(ierr);
537703dadc2fSPeter Brune   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
537803dadc2fSPeter Brune   ierr = DMGetCoordinates(subdm,&ccoords);CHKERRQ(ierr);
537903dadc2fSPeter Brune   if (coords && !ccoords) {
538003dadc2fSPeter Brune     ierr = DMCreateGlobalVector(subdm_coord,&ccoords);CHKERRQ(ierr);
53816668ed41SLisandro Dalcin     ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr);
538203dadc2fSPeter Brune     ierr = DMCreateLocalVector(subdm_coord,&clcoords);CHKERRQ(ierr);
538324640c55SToby Isaac     ierr = PetscObjectSetName((PetscObject)clcoords,"coordinates");CHKERRQ(ierr);
538403dadc2fSPeter Brune     ierr = DMCreateDomainDecompositionScatters(dm_coord,1,&subdm_coord,NULL,&scat_i,&scat_g);CHKERRQ(ierr);
538503dadc2fSPeter Brune     ierr = VecScatterBegin(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
538603dadc2fSPeter Brune     ierr = VecScatterEnd(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
53871ed9ada7SJunchao Zhang     ierr = VecScatterBegin(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
538803dadc2fSPeter Brune     ierr = VecScatterEnd(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
538903dadc2fSPeter Brune     ierr = DMSetCoordinates(subdm,ccoords);CHKERRQ(ierr);
539003dadc2fSPeter Brune     ierr = DMSetCoordinatesLocal(subdm,clcoords);CHKERRQ(ierr);
539103dadc2fSPeter Brune     ierr = VecScatterDestroy(&scat_i[0]);CHKERRQ(ierr);
539203dadc2fSPeter Brune     ierr = VecScatterDestroy(&scat_g[0]);CHKERRQ(ierr);
539303dadc2fSPeter Brune     ierr = VecDestroy(&ccoords);CHKERRQ(ierr);
539403dadc2fSPeter Brune     ierr = VecDestroy(&clcoords);CHKERRQ(ierr);
539503dadc2fSPeter Brune     ierr = PetscFree(scat_i);CHKERRQ(ierr);
539603dadc2fSPeter Brune     ierr = PetscFree(scat_g);CHKERRQ(ierr);
539703dadc2fSPeter Brune   }
539803dadc2fSPeter Brune   PetscFunctionReturn(0);
539903dadc2fSPeter Brune }
540003dadc2fSPeter Brune 
5401c73cfb54SMatthew G. Knepley /*@
5402c73cfb54SMatthew G. Knepley   DMGetDimension - Return the topological dimension of the DM
5403c73cfb54SMatthew G. Knepley 
5404c73cfb54SMatthew G. Knepley   Not collective
5405c73cfb54SMatthew G. Knepley 
5406c73cfb54SMatthew G. Knepley   Input Parameter:
5407c73cfb54SMatthew G. Knepley . dm - The DM
5408c73cfb54SMatthew G. Knepley 
5409c73cfb54SMatthew G. Knepley   Output Parameter:
5410c73cfb54SMatthew G. Knepley . dim - The topological dimension
5411c73cfb54SMatthew G. Knepley 
5412c73cfb54SMatthew G. Knepley   Level: beginner
5413c73cfb54SMatthew G. Knepley 
5414c73cfb54SMatthew G. Knepley .seealso: DMSetDimension(), DMCreate()
5415c73cfb54SMatthew G. Knepley @*/
5416c73cfb54SMatthew G. Knepley PetscErrorCode DMGetDimension(DM dm, PetscInt *dim)
5417c73cfb54SMatthew G. Knepley {
5418c73cfb54SMatthew G. Knepley   PetscFunctionBegin;
5419c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5420534a8f05SLisandro Dalcin   PetscValidIntPointer(dim, 2);
5421c73cfb54SMatthew G. Knepley   *dim = dm->dim;
5422c73cfb54SMatthew G. Knepley   PetscFunctionReturn(0);
5423c73cfb54SMatthew G. Knepley }
5424c73cfb54SMatthew G. Knepley 
5425c73cfb54SMatthew G. Knepley /*@
5426c73cfb54SMatthew G. Knepley   DMSetDimension - Set the topological dimension of the DM
5427c73cfb54SMatthew G. Knepley 
5428c73cfb54SMatthew G. Knepley   Collective on dm
5429c73cfb54SMatthew G. Knepley 
5430c73cfb54SMatthew G. Knepley   Input Parameters:
5431c73cfb54SMatthew G. Knepley + dm - The DM
5432c73cfb54SMatthew G. Knepley - dim - The topological dimension
5433c73cfb54SMatthew G. Knepley 
5434c73cfb54SMatthew G. Knepley   Level: beginner
5435c73cfb54SMatthew G. Knepley 
5436c73cfb54SMatthew G. Knepley .seealso: DMGetDimension(), DMCreate()
5437c73cfb54SMatthew G. Knepley @*/
5438c73cfb54SMatthew G. Knepley PetscErrorCode DMSetDimension(DM dm, PetscInt dim)
5439c73cfb54SMatthew G. Knepley {
5440e5e52638SMatthew G. Knepley   PetscDS        ds;
5441f17e8794SMatthew G. Knepley   PetscErrorCode ierr;
5442f17e8794SMatthew G. Knepley 
5443c73cfb54SMatthew G. Knepley   PetscFunctionBegin;
5444c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5445c73cfb54SMatthew G. Knepley   PetscValidLogicalCollectiveInt(dm, dim, 2);
5446c73cfb54SMatthew G. Knepley   dm->dim = dim;
5447e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
5448e5e52638SMatthew G. Knepley   if (ds->dimEmbed < 0) {ierr = PetscDSSetCoordinateDimension(ds, dm->dim);CHKERRQ(ierr);}
5449c73cfb54SMatthew G. Knepley   PetscFunctionReturn(0);
5450c73cfb54SMatthew G. Knepley }
5451c73cfb54SMatthew G. Knepley 
5452793f3fe5SMatthew G. Knepley /*@
5453793f3fe5SMatthew G. Knepley   DMGetDimPoints - Get the half-open interval for all points of a given dimension
5454793f3fe5SMatthew G. Knepley 
5455d083f849SBarry Smith   Collective on dm
5456793f3fe5SMatthew G. Knepley 
5457793f3fe5SMatthew G. Knepley   Input Parameters:
5458793f3fe5SMatthew G. Knepley + dm - the DM
5459793f3fe5SMatthew G. Knepley - dim - the dimension
5460793f3fe5SMatthew G. Knepley 
5461793f3fe5SMatthew G. Knepley   Output Parameters:
5462793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension
5463aa049354SPatrick Sanan - pEnd - The first point following points of the given dimension
5464793f3fe5SMatthew G. Knepley 
5465793f3fe5SMatthew G. Knepley   Note:
5466793f3fe5SMatthew G. Knepley   The points are vertices in the Hasse diagram encoding the topology. This is explained in
5467a8d69d7bSBarry Smith   https://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme,
5468793f3fe5SMatthew G. Knepley   then the interval is empty.
5469793f3fe5SMatthew G. Knepley 
5470793f3fe5SMatthew G. Knepley   Level: intermediate
5471793f3fe5SMatthew G. Knepley 
5472793f3fe5SMatthew G. Knepley .seealso: DMPLEX, DMPlexGetDepthStratum(), DMPlexGetHeightStratum()
5473793f3fe5SMatthew G. Knepley @*/
5474793f3fe5SMatthew G. Knepley PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd)
5475793f3fe5SMatthew G. Knepley {
5476793f3fe5SMatthew G. Knepley   PetscInt       d;
5477793f3fe5SMatthew G. Knepley   PetscErrorCode ierr;
5478793f3fe5SMatthew G. Knepley 
5479793f3fe5SMatthew G. Knepley   PetscFunctionBegin;
5480793f3fe5SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5481793f3fe5SMatthew G. Knepley   ierr = DMGetDimension(dm, &d);CHKERRQ(ierr);
5482793f3fe5SMatthew G. Knepley   if ((dim < 0) || (dim > d)) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %d 1", dim, d);
5483b9d85ea2SLisandro Dalcin   if (!dm->ops->getdimpoints) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "DM type %s does not implement DMGetDimPoints",((PetscObject)dm)->type_name);
5484793f3fe5SMatthew G. Knepley   ierr = (*dm->ops->getdimpoints)(dm, dim, pStart, pEnd);CHKERRQ(ierr);
5485793f3fe5SMatthew G. Knepley   PetscFunctionReturn(0);
5486793f3fe5SMatthew G. Knepley }
5487793f3fe5SMatthew G. Knepley 
54886636e97aSMatthew G Knepley /*@
54896636e97aSMatthew G Knepley   DMSetCoordinates - Sets into the DM a global vector that holds the coordinates
54906636e97aSMatthew G Knepley 
5491d083f849SBarry Smith   Collective on dm
54926636e97aSMatthew G Knepley 
54936636e97aSMatthew G Knepley   Input Parameters:
54946636e97aSMatthew G Knepley + dm - the DM
54956636e97aSMatthew G Knepley - c - coordinate vector
54966636e97aSMatthew G Knepley 
54972dd40e9bSPatrick Sanan   Notes:
54982dd40e9bSPatrick Sanan   The coordinates do include those for ghost points, which are in the local vector.
54992dd40e9bSPatrick Sanan 
55002dd40e9bSPatrick Sanan   The vector c should be destroyed by the caller.
55016636e97aSMatthew G Knepley 
55026636e97aSMatthew G Knepley   Level: intermediate
55036636e97aSMatthew G Knepley 
55042dd40e9bSPatrick Sanan .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
55056636e97aSMatthew G Knepley @*/
55066636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c)
55076636e97aSMatthew G Knepley {
55086636e97aSMatthew G Knepley   PetscErrorCode ierr;
55096636e97aSMatthew G Knepley 
55106636e97aSMatthew G Knepley   PetscFunctionBegin;
55116636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
55126636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
55136636e97aSMatthew G Knepley   ierr            = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
55146636e97aSMatthew G Knepley   ierr            = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
55156636e97aSMatthew G Knepley   dm->coordinates = c;
55166636e97aSMatthew G Knepley   ierr            = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
5517b64e0483SPeter Brune   ierr            = DMCoarsenHookAdd(dm,DMRestrictHook_Coordinates,NULL,NULL);CHKERRQ(ierr);
551803dadc2fSPeter Brune   ierr            = DMSubDomainHookAdd(dm,DMSubDomainHook_Coordinates,NULL,NULL);CHKERRQ(ierr);
55196636e97aSMatthew G Knepley   PetscFunctionReturn(0);
55206636e97aSMatthew G Knepley }
55216636e97aSMatthew G Knepley 
55226636e97aSMatthew G Knepley /*@
55236636e97aSMatthew G Knepley   DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates
55246636e97aSMatthew G Knepley 
55257058e716SVaclav Hapla   Not collective
55266636e97aSMatthew G Knepley 
55276636e97aSMatthew G Knepley    Input Parameters:
55286636e97aSMatthew G Knepley +  dm - the DM
55296636e97aSMatthew G Knepley -  c - coordinate vector
55306636e97aSMatthew G Knepley 
55312dd40e9bSPatrick Sanan   Notes:
55326636e97aSMatthew G Knepley   The coordinates of ghost points can be set using DMSetCoordinates()
55336636e97aSMatthew G Knepley   followed by DMGetCoordinatesLocal(). This is intended to enable the
55346636e97aSMatthew G Knepley   setting of ghost coordinates outside of the domain.
55356636e97aSMatthew G Knepley 
55362dd40e9bSPatrick Sanan   The vector c should be destroyed by the caller.
55372dd40e9bSPatrick Sanan 
55386636e97aSMatthew G Knepley   Level: intermediate
55396636e97aSMatthew G Knepley 
55406636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM()
55416636e97aSMatthew G Knepley @*/
55426636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c)
55436636e97aSMatthew G Knepley {
55446636e97aSMatthew G Knepley   PetscErrorCode ierr;
55456636e97aSMatthew G Knepley 
55466636e97aSMatthew G Knepley   PetscFunctionBegin;
55476636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
55486636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
55496636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
55506636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
55518865f1eaSKarl Rupp 
55526636e97aSMatthew G Knepley   dm->coordinatesLocal = c;
55538865f1eaSKarl Rupp 
55546636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
55556636e97aSMatthew G Knepley   PetscFunctionReturn(0);
55566636e97aSMatthew G Knepley }
55576636e97aSMatthew G Knepley 
55586636e97aSMatthew G Knepley /*@
55596636e97aSMatthew G Knepley   DMGetCoordinates - Gets a global vector with the coordinates associated with the DM.
55606636e97aSMatthew G Knepley 
5561d083f849SBarry Smith   Collective on dm
55626636e97aSMatthew G Knepley 
55636636e97aSMatthew G Knepley   Input Parameter:
55646636e97aSMatthew G Knepley . dm - the DM
55656636e97aSMatthew G Knepley 
55666636e97aSMatthew G Knepley   Output Parameter:
55676636e97aSMatthew G Knepley . c - global coordinate vector
55686636e97aSMatthew G Knepley 
55696636e97aSMatthew G Knepley   Note:
55706636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
55716636e97aSMatthew G Knepley 
55726636e97aSMatthew G Knepley   Each process has only the local coordinates (does NOT have the ghost coordinates).
55736636e97aSMatthew G Knepley 
55746636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
55756636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
55766636e97aSMatthew G Knepley 
55776636e97aSMatthew G Knepley   Level: intermediate
55786636e97aSMatthew G Knepley 
55796636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
55806636e97aSMatthew G Knepley @*/
55816636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c)
55826636e97aSMatthew G Knepley {
55836636e97aSMatthew G Knepley   PetscErrorCode ierr;
55846636e97aSMatthew G Knepley 
55856636e97aSMatthew G Knepley   PetscFunctionBegin;
55866636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
55876636e97aSMatthew G Knepley   PetscValidPointer(c,2);
55881f588964SMatthew G Knepley   if (!dm->coordinates && dm->coordinatesLocal) {
55890298fd71SBarry Smith     DM        cdm = NULL;
55901970a576SMatthew G. Knepley     PetscBool localized;
55916636e97aSMatthew G Knepley 
55926636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
55936636e97aSMatthew G Knepley     ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr);
55941970a576SMatthew G. Knepley     ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
55951970a576SMatthew G. Knepley     /* Block size is not correctly set by CreateGlobalVector() if coordinates are localized */
55961970a576SMatthew G. Knepley     if (localized) {
55971970a576SMatthew G. Knepley       PetscInt cdim;
55981970a576SMatthew G. Knepley 
55991970a576SMatthew G. Knepley       ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
56001970a576SMatthew G. Knepley       ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr);
56011970a576SMatthew G. Knepley     }
56026636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr);
56036636e97aSMatthew G Knepley     ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
56046636e97aSMatthew G Knepley     ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
56056636e97aSMatthew G Knepley   }
56066636e97aSMatthew G Knepley   *c = dm->coordinates;
56076636e97aSMatthew G Knepley   PetscFunctionReturn(0);
56086636e97aSMatthew G Knepley }
56096636e97aSMatthew G Knepley 
56106636e97aSMatthew G Knepley /*@
561181e9a530SVaclav Hapla   DMGetCoordinatesLocalSetUp - Prepares a local vector of coordinates, so that DMGetCoordinatesLocalNoncollective() can be used as non-collective afterwards.
561281e9a530SVaclav Hapla 
5613d083f849SBarry Smith   Collective on dm
561481e9a530SVaclav Hapla 
561581e9a530SVaclav Hapla   Input Parameter:
561681e9a530SVaclav Hapla . dm - the DM
561781e9a530SVaclav Hapla 
561881e9a530SVaclav Hapla   Level: advanced
561981e9a530SVaclav Hapla 
562081e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalNoncollective()
562181e9a530SVaclav Hapla @*/
562281e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalSetUp(DM dm)
562381e9a530SVaclav Hapla {
562481e9a530SVaclav Hapla   PetscErrorCode ierr;
562581e9a530SVaclav Hapla 
562681e9a530SVaclav Hapla   PetscFunctionBegin;
562781e9a530SVaclav Hapla   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
562881e9a530SVaclav Hapla   if (!dm->coordinatesLocal && dm->coordinates) {
56291970a576SMatthew G. Knepley     DM        cdm = NULL;
56301970a576SMatthew G. Knepley     PetscBool localized;
56311970a576SMatthew G. Knepley 
563281e9a530SVaclav Hapla     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
563381e9a530SVaclav Hapla     ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr);
56341970a576SMatthew G. Knepley     ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
56351970a576SMatthew G. Knepley     /* Block size is not correctly set by CreateLocalVector() if coordinates are localized */
56361970a576SMatthew G. Knepley     if (localized) {
56371970a576SMatthew G. Knepley       PetscInt cdim;
56381970a576SMatthew G. Knepley 
56391970a576SMatthew G. Knepley       ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
56401970a576SMatthew G. Knepley       ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr);
56411970a576SMatthew G. Knepley     }
564281e9a530SVaclav Hapla     ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr);
564381e9a530SVaclav Hapla     ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
564481e9a530SVaclav Hapla     ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
564581e9a530SVaclav Hapla   }
564681e9a530SVaclav Hapla   PetscFunctionReturn(0);
564781e9a530SVaclav Hapla }
564881e9a530SVaclav Hapla 
564981e9a530SVaclav Hapla /*@
56506636e97aSMatthew G Knepley   DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM.
56516636e97aSMatthew G Knepley 
5652d083f849SBarry Smith   Collective on dm
56536636e97aSMatthew G Knepley 
56546636e97aSMatthew G Knepley   Input Parameter:
56556636e97aSMatthew G Knepley . dm - the DM
56566636e97aSMatthew G Knepley 
56576636e97aSMatthew G Knepley   Output Parameter:
56586636e97aSMatthew G Knepley . c - coordinate vector
56596636e97aSMatthew G Knepley 
56606636e97aSMatthew G Knepley   Note:
56616636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
56626636e97aSMatthew G Knepley 
56636636e97aSMatthew G Knepley   Each process has the local and ghost coordinates
56646636e97aSMatthew G Knepley 
56656636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
56666636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
56676636e97aSMatthew G Knepley 
56686636e97aSMatthew G Knepley   Level: intermediate
56696636e97aSMatthew G Knepley 
567081e9a530SVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM(), DMGetCoordinatesLocalNoncollective()
56716636e97aSMatthew G Knepley @*/
56726636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c)
56736636e97aSMatthew G Knepley {
56746636e97aSMatthew G Knepley   PetscErrorCode ierr;
56756636e97aSMatthew G Knepley 
56766636e97aSMatthew G Knepley   PetscFunctionBegin;
56776636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
56786636e97aSMatthew G Knepley   PetscValidPointer(c,2);
567981e9a530SVaclav Hapla   ierr = DMGetCoordinatesLocalSetUp(dm);CHKERRQ(ierr);
56806636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
56816636e97aSMatthew G Knepley   PetscFunctionReturn(0);
56826636e97aSMatthew G Knepley }
56836636e97aSMatthew G Knepley 
568481e9a530SVaclav Hapla /*@
568581e9a530SVaclav Hapla   DMGetCoordinatesLocalNoncollective - Non-collective version of DMGetCoordinatesLocal(). Fails if global coordinates have been set and DMGetCoordinatesLocalSetUp() not called.
568681e9a530SVaclav Hapla 
568781e9a530SVaclav Hapla   Not collective
568881e9a530SVaclav Hapla 
568981e9a530SVaclav Hapla   Input Parameter:
569081e9a530SVaclav Hapla . dm - the DM
569181e9a530SVaclav Hapla 
569281e9a530SVaclav Hapla   Output Parameter:
569381e9a530SVaclav Hapla . c - coordinate vector
569481e9a530SVaclav Hapla 
569581e9a530SVaclav Hapla   Level: advanced
569681e9a530SVaclav Hapla 
569781e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalSetUp(), DMGetCoordinatesLocal(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
569881e9a530SVaclav Hapla @*/
569981e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalNoncollective(DM dm, Vec *c)
570081e9a530SVaclav Hapla {
570181e9a530SVaclav Hapla   PetscFunctionBegin;
570281e9a530SVaclav Hapla   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
570381e9a530SVaclav Hapla   PetscValidPointer(c,2);
570481e9a530SVaclav Hapla   if (!dm->coordinatesLocal && dm->coordinates) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called");
57056636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
57066636e97aSMatthew G Knepley   PetscFunctionReturn(0);
57076636e97aSMatthew G Knepley }
57086636e97aSMatthew G Knepley 
57092db98f8dSVaclav Hapla /*@
57102db98f8dSVaclav Hapla   DMGetCoordinatesLocalTuple - Gets a local vector with the coordinates of specified points and section describing its layout.
57112db98f8dSVaclav Hapla 
57122db98f8dSVaclav Hapla   Not collective
57132db98f8dSVaclav Hapla 
57142db98f8dSVaclav Hapla   Input Parameter:
57152db98f8dSVaclav Hapla + dm - the DM
57162db98f8dSVaclav Hapla - p - the IS of points whose coordinates will be returned
57172db98f8dSVaclav Hapla 
57182db98f8dSVaclav Hapla   Output Parameter:
57192db98f8dSVaclav Hapla + pCoordSection - the PetscSection describing the layout of pCoord, i.e. each point corresponds to one point in p, and DOFs correspond to coordinates
57202db98f8dSVaclav Hapla - pCoord - the Vec with coordinates of points in p
57212db98f8dSVaclav Hapla 
57222db98f8dSVaclav Hapla   Note:
57232db98f8dSVaclav Hapla   DMGetCoordinatesLocalSetUp() must be called first. This function employs DMGetCoordinatesLocalNoncollective() so it is not collective.
57242db98f8dSVaclav Hapla 
57252db98f8dSVaclav Hapla   This creates a new vector, so the user SHOULD destroy this vector
57262db98f8dSVaclav Hapla 
57272db98f8dSVaclav Hapla   Each process has the local and ghost coordinates
57282db98f8dSVaclav Hapla 
57292db98f8dSVaclav Hapla   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
57302db98f8dSVaclav Hapla   and (x_0,y_0,z_0,x_1,y_1,z_1...)
57312db98f8dSVaclav Hapla 
57322db98f8dSVaclav Hapla   Level: advanced
57332db98f8dSVaclav Hapla 
57342db98f8dSVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinatesLocal(), DMGetCoordinatesLocalNoncollective(), DMGetCoordinatesLocalSetUp(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
57352db98f8dSVaclav Hapla @*/
57362db98f8dSVaclav Hapla PetscErrorCode DMGetCoordinatesLocalTuple(DM dm, IS p, PetscSection *pCoordSection, Vec *pCoord)
57372db98f8dSVaclav Hapla {
57382db98f8dSVaclav Hapla   PetscSection        cs, newcs;
57392db98f8dSVaclav Hapla   Vec                 coords;
57402db98f8dSVaclav Hapla   const PetscScalar   *arr;
57412db98f8dSVaclav Hapla   PetscScalar         *newarr=NULL;
57422db98f8dSVaclav Hapla   PetscInt            n;
57432db98f8dSVaclav Hapla   PetscErrorCode      ierr;
57442db98f8dSVaclav Hapla 
57452db98f8dSVaclav Hapla   PetscFunctionBegin;
57462db98f8dSVaclav Hapla   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
57472db98f8dSVaclav Hapla   PetscValidHeaderSpecific(p, IS_CLASSID, 2);
57482db98f8dSVaclav Hapla   if (pCoordSection) PetscValidPointer(pCoordSection, 3);
57492db98f8dSVaclav Hapla   if (pCoord) PetscValidPointer(pCoord, 4);
57502db98f8dSVaclav Hapla   if (!dm->coordinatesLocal) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called or coordinates not set");
57511bb6d2a8SBarry Smith   if (!dm->coordinateDM || !dm->coordinateDM->localSection) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM not supported");
57521bb6d2a8SBarry Smith   cs = dm->coordinateDM->localSection;
57532db98f8dSVaclav Hapla   coords = dm->coordinatesLocal;
57542db98f8dSVaclav Hapla   ierr = VecGetArrayRead(coords, &arr);CHKERRQ(ierr);
57552db98f8dSVaclav Hapla   ierr = PetscSectionExtractDofsFromArray(cs, MPIU_SCALAR, arr, p, &newcs, pCoord ? ((void**)&newarr) : NULL);CHKERRQ(ierr);
57562db98f8dSVaclav Hapla   ierr = VecRestoreArrayRead(coords, &arr);CHKERRQ(ierr);
57572db98f8dSVaclav Hapla   if (pCoord) {
57582db98f8dSVaclav Hapla     ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr);
57592db98f8dSVaclav Hapla     /* set array in two steps to mimic PETSC_OWN_POINTER */
57602db98f8dSVaclav Hapla     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)p), 1, n, NULL, pCoord);CHKERRQ(ierr);
57612db98f8dSVaclav Hapla     ierr = VecReplaceArray(*pCoord, newarr);CHKERRQ(ierr);
5762ad9ac99dSVaclav Hapla   } else {
5763ad9ac99dSVaclav Hapla     ierr = PetscFree(newarr);CHKERRQ(ierr);
57642db98f8dSVaclav Hapla   }
5765ad9ac99dSVaclav Hapla   if (pCoordSection) {*pCoordSection = newcs;}
5766ad9ac99dSVaclav Hapla   else               {ierr = PetscSectionDestroy(&newcs);CHKERRQ(ierr);}
57672db98f8dSVaclav Hapla   PetscFunctionReturn(0);
57682db98f8dSVaclav Hapla }
57692db98f8dSVaclav Hapla 
5770f19dbd58SToby Isaac PetscErrorCode DMGetCoordinateField(DM dm, DMField *field)
5771f19dbd58SToby Isaac {
5772f19dbd58SToby Isaac   PetscErrorCode ierr;
5773f19dbd58SToby Isaac 
5774f19dbd58SToby Isaac   PetscFunctionBegin;
5775f19dbd58SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5776f19dbd58SToby Isaac   PetscValidPointer(field,2);
5777f19dbd58SToby Isaac   if (!dm->coordinateField) {
5778f19dbd58SToby Isaac     if (dm->ops->createcoordinatefield) {
5779f19dbd58SToby Isaac       ierr = (*dm->ops->createcoordinatefield)(dm,&dm->coordinateField);CHKERRQ(ierr);
5780f19dbd58SToby Isaac     }
5781f19dbd58SToby Isaac   }
5782f19dbd58SToby Isaac   *field = dm->coordinateField;
5783f19dbd58SToby Isaac   PetscFunctionReturn(0);
5784f19dbd58SToby Isaac }
5785f19dbd58SToby Isaac 
5786f19dbd58SToby Isaac PetscErrorCode DMSetCoordinateField(DM dm, DMField field)
5787f19dbd58SToby Isaac {
5788f19dbd58SToby Isaac   PetscErrorCode ierr;
5789f19dbd58SToby Isaac 
5790f19dbd58SToby Isaac   PetscFunctionBegin;
5791f19dbd58SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5792f19dbd58SToby Isaac   if (field) PetscValidHeaderSpecific(field,DMFIELD_CLASSID,2);
5793c4e6da2cSBarry Smith   ierr = PetscObjectReference((PetscObject)field);CHKERRQ(ierr);
5794f19dbd58SToby Isaac   ierr = DMFieldDestroy(&dm->coordinateField);CHKERRQ(ierr);
5795f19dbd58SToby Isaac   dm->coordinateField = field;
5796f19dbd58SToby Isaac   PetscFunctionReturn(0);
5797f19dbd58SToby Isaac }
5798f19dbd58SToby Isaac 
57996636e97aSMatthew G Knepley /*@
58001cfe2091SMatthew G. Knepley   DMGetCoordinateDM - Gets the DM that prescribes coordinate layout and scatters between global and local coordinates
58016636e97aSMatthew G Knepley 
5802d083f849SBarry Smith   Collective on dm
58036636e97aSMatthew G Knepley 
58046636e97aSMatthew G Knepley   Input Parameter:
58056636e97aSMatthew G Knepley . dm - the DM
58066636e97aSMatthew G Knepley 
58076636e97aSMatthew G Knepley   Output Parameter:
58086636e97aSMatthew G Knepley . cdm - coordinate DM
58096636e97aSMatthew G Knepley 
58106636e97aSMatthew G Knepley   Level: intermediate
58116636e97aSMatthew G Knepley 
58121cfe2091SMatthew G. Knepley .seealso: DMSetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
58136636e97aSMatthew G Knepley @*/
58146636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm)
58156636e97aSMatthew G Knepley {
58166636e97aSMatthew G Knepley   PetscErrorCode ierr;
58176636e97aSMatthew G Knepley 
58186636e97aSMatthew G Knepley   PetscFunctionBegin;
58196636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
58206636e97aSMatthew G Knepley   PetscValidPointer(cdm,2);
58216636e97aSMatthew G Knepley   if (!dm->coordinateDM) {
5822308f8a94SToby Isaac     DM cdm;
5823308f8a94SToby Isaac 
582482f516ccSBarry Smith     if (!dm->ops->createcoordinatedm) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unable to create coordinates for this DM");
5825308f8a94SToby Isaac     ierr = (*dm->ops->createcoordinatedm)(dm, &cdm);CHKERRQ(ierr);
5826308f8a94SToby Isaac     /* Just in case the DM sets the coordinate DM when creating it (DMP4est can do this, because it may not setup
5827308f8a94SToby Isaac      * until the call to CreateCoordinateDM) */
5828308f8a94SToby Isaac     ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr);
5829308f8a94SToby Isaac     dm->coordinateDM = cdm;
58306636e97aSMatthew G Knepley   }
58316636e97aSMatthew G Knepley   *cdm = dm->coordinateDM;
58326636e97aSMatthew G Knepley   PetscFunctionReturn(0);
58336636e97aSMatthew G Knepley }
5834e87bb0d3SMatthew G Knepley 
58351cfe2091SMatthew G. Knepley /*@
58361cfe2091SMatthew G. Knepley   DMSetCoordinateDM - Sets the DM that prescribes coordinate layout and scatters between global and local coordinates
58371cfe2091SMatthew G. Knepley 
5838d083f849SBarry Smith   Logically Collective on dm
58391cfe2091SMatthew G. Knepley 
58401cfe2091SMatthew G. Knepley   Input Parameters:
58411cfe2091SMatthew G. Knepley + dm - the DM
58421cfe2091SMatthew G. Knepley - cdm - coordinate DM
58431cfe2091SMatthew G. Knepley 
58441cfe2091SMatthew G. Knepley   Level: intermediate
58451cfe2091SMatthew G. Knepley 
58461cfe2091SMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
58471cfe2091SMatthew G. Knepley @*/
58481cfe2091SMatthew G. Knepley PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm)
58491cfe2091SMatthew G. Knepley {
58501cfe2091SMatthew G. Knepley   PetscErrorCode ierr;
58511cfe2091SMatthew G. Knepley 
58521cfe2091SMatthew G. Knepley   PetscFunctionBegin;
58531cfe2091SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
58541cfe2091SMatthew G. Knepley   PetscValidHeaderSpecific(cdm,DM_CLASSID,2);
5855f26b38b9SToby Isaac   ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr);
58561cfe2091SMatthew G. Knepley   ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr);
58571cfe2091SMatthew G. Knepley   dm->coordinateDM = cdm;
58581cfe2091SMatthew G. Knepley   PetscFunctionReturn(0);
58591cfe2091SMatthew G. Knepley }
58601cfe2091SMatthew G. Knepley 
586146e270d4SMatthew G. Knepley /*@
586246e270d4SMatthew G. Knepley   DMGetCoordinateDim - Retrieve the dimension of embedding space for coordinate values.
586346e270d4SMatthew G. Knepley 
586446e270d4SMatthew G. Knepley   Not Collective
586546e270d4SMatthew G. Knepley 
586646e270d4SMatthew G. Knepley   Input Parameter:
586746e270d4SMatthew G. Knepley . dm - The DM object
586846e270d4SMatthew G. Knepley 
586946e270d4SMatthew G. Knepley   Output Parameter:
587046e270d4SMatthew G. Knepley . dim - The embedding dimension
587146e270d4SMatthew G. Knepley 
587246e270d4SMatthew G. Knepley   Level: intermediate
587346e270d4SMatthew G. Knepley 
587492fd8e1eSJed Brown .seealso: DMSetCoordinateDim(), DMGetCoordinateSection(), DMGetCoordinateDM(), DMGetLocalSection(), DMSetLocalSection()
587546e270d4SMatthew G. Knepley @*/
587646e270d4SMatthew G. Knepley PetscErrorCode DMGetCoordinateDim(DM dm, PetscInt *dim)
587746e270d4SMatthew G. Knepley {
587846e270d4SMatthew G. Knepley   PetscFunctionBegin;
587946e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5880534a8f05SLisandro Dalcin   PetscValidIntPointer(dim, 2);
58819a9a41abSToby Isaac   if (dm->dimEmbed == PETSC_DEFAULT) {
58829a9a41abSToby Isaac     dm->dimEmbed = dm->dim;
58839a9a41abSToby Isaac   }
588446e270d4SMatthew G. Knepley   *dim = dm->dimEmbed;
588546e270d4SMatthew G. Knepley   PetscFunctionReturn(0);
588646e270d4SMatthew G. Knepley }
588746e270d4SMatthew G. Knepley 
588846e270d4SMatthew G. Knepley /*@
588946e270d4SMatthew G. Knepley   DMSetCoordinateDim - Set the dimension of the embedding space for coordinate values.
589046e270d4SMatthew G. Knepley 
589146e270d4SMatthew G. Knepley   Not Collective
589246e270d4SMatthew G. Knepley 
589346e270d4SMatthew G. Knepley   Input Parameters:
589446e270d4SMatthew G. Knepley + dm  - The DM object
589546e270d4SMatthew G. Knepley - dim - The embedding dimension
589646e270d4SMatthew G. Knepley 
589746e270d4SMatthew G. Knepley   Level: intermediate
589846e270d4SMatthew G. Knepley 
589992fd8e1eSJed Brown .seealso: DMGetCoordinateDim(), DMSetCoordinateSection(), DMGetCoordinateSection(), DMGetLocalSection(), DMSetLocalSection()
590046e270d4SMatthew G. Knepley @*/
590146e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateDim(DM dm, PetscInt dim)
590246e270d4SMatthew G. Knepley {
5903e5e52638SMatthew G. Knepley   PetscDS        ds;
5904f17e8794SMatthew G. Knepley   PetscErrorCode ierr;
5905f17e8794SMatthew G. Knepley 
590646e270d4SMatthew G. Knepley   PetscFunctionBegin;
590746e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
590846e270d4SMatthew G. Knepley   dm->dimEmbed = dim;
5909e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
5910e5e52638SMatthew G. Knepley   ierr = PetscDSSetCoordinateDimension(ds, dim);CHKERRQ(ierr);
591146e270d4SMatthew G. Knepley   PetscFunctionReturn(0);
591246e270d4SMatthew G. Knepley }
591346e270d4SMatthew G. Knepley 
5914e8abe2deSMatthew G. Knepley /*@
5915e8abe2deSMatthew G. Knepley   DMGetCoordinateSection - Retrieve the layout of coordinate values over the mesh.
5916e8abe2deSMatthew G. Knepley 
5917d083f849SBarry Smith   Collective on dm
5918e8abe2deSMatthew G. Knepley 
5919e8abe2deSMatthew G. Knepley   Input Parameter:
5920e8abe2deSMatthew G. Knepley . dm - The DM object
5921e8abe2deSMatthew G. Knepley 
5922e8abe2deSMatthew G. Knepley   Output Parameter:
5923e8abe2deSMatthew G. Knepley . section - The PetscSection object
5924e8abe2deSMatthew G. Knepley 
5925e8abe2deSMatthew G. Knepley   Level: intermediate
5926e8abe2deSMatthew G. Knepley 
592792fd8e1eSJed Brown .seealso: DMGetCoordinateDM(), DMGetLocalSection(), DMSetLocalSection()
5928e8abe2deSMatthew G. Knepley @*/
5929e8abe2deSMatthew G. Knepley PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section)
5930e8abe2deSMatthew G. Knepley {
5931e8abe2deSMatthew G. Knepley   DM             cdm;
5932e8abe2deSMatthew G. Knepley   PetscErrorCode ierr;
5933e8abe2deSMatthew G. Knepley 
5934e8abe2deSMatthew G. Knepley   PetscFunctionBegin;
5935e8abe2deSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5936e8abe2deSMatthew G. Knepley   PetscValidPointer(section, 2);
5937e8abe2deSMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
593892fd8e1eSJed Brown   ierr = DMGetLocalSection(cdm, section);CHKERRQ(ierr);
5939e8abe2deSMatthew G. Knepley   PetscFunctionReturn(0);
5940e8abe2deSMatthew G. Knepley }
5941e8abe2deSMatthew G. Knepley 
5942e8abe2deSMatthew G. Knepley /*@
5943e8abe2deSMatthew G. Knepley   DMSetCoordinateSection - Set the layout of coordinate values over the mesh.
5944e8abe2deSMatthew G. Knepley 
5945e8abe2deSMatthew G. Knepley   Not Collective
5946e8abe2deSMatthew G. Knepley 
5947e8abe2deSMatthew G. Knepley   Input Parameters:
5948e8abe2deSMatthew G. Knepley + dm      - The DM object
594946e270d4SMatthew G. Knepley . dim     - The embedding dimension, or PETSC_DETERMINE
5950e8abe2deSMatthew G. Knepley - section - The PetscSection object
5951e8abe2deSMatthew G. Knepley 
5952e8abe2deSMatthew G. Knepley   Level: intermediate
5953e8abe2deSMatthew G. Knepley 
595492fd8e1eSJed Brown .seealso: DMGetCoordinateSection(), DMGetLocalSection(), DMSetLocalSection()
5955e8abe2deSMatthew G. Knepley @*/
595646e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateSection(DM dm, PetscInt dim, PetscSection section)
5957e8abe2deSMatthew G. Knepley {
5958e8abe2deSMatthew G. Knepley   DM             cdm;
5959e8abe2deSMatthew G. Knepley   PetscErrorCode ierr;
5960e8abe2deSMatthew G. Knepley 
5961e8abe2deSMatthew G. Knepley   PetscFunctionBegin;
5962e8abe2deSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
596346e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,3);
5964e8abe2deSMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
596592fd8e1eSJed Brown   ierr = DMSetLocalSection(cdm, section);CHKERRQ(ierr);
596646e270d4SMatthew G. Knepley   if (dim == PETSC_DETERMINE) {
59674c1069a6SMatthew G. Knepley     PetscInt d = PETSC_DEFAULT;
596846e270d4SMatthew G. Knepley     PetscInt pStart, pEnd, vStart, vEnd, v, dd;
596946e270d4SMatthew G. Knepley 
597046e270d4SMatthew G. Knepley     ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
597146e270d4SMatthew G. Knepley     ierr = DMGetDimPoints(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
597246e270d4SMatthew G. Knepley     pStart = PetscMax(vStart, pStart);
597346e270d4SMatthew G. Knepley     pEnd   = PetscMin(vEnd, pEnd);
597446e270d4SMatthew G. Knepley     for (v = pStart; v < pEnd; ++v) {
597546e270d4SMatthew G. Knepley       ierr = PetscSectionGetDof(section, v, &dd);CHKERRQ(ierr);
597646e270d4SMatthew G. Knepley       if (dd) {d = dd; break;}
597746e270d4SMatthew G. Knepley     }
5978ebfe4b0dSMatthew G. Knepley     if (d >= 0) {ierr = DMSetCoordinateDim(dm, d);CHKERRQ(ierr);}
597946e270d4SMatthew G. Knepley   }
5980e8abe2deSMatthew G. Knepley   PetscFunctionReturn(0);
5981e8abe2deSMatthew G. Knepley }
5982e8abe2deSMatthew G. Knepley 
59835dc8c3f7SMatthew G. Knepley /*@C
598490b157c4SStefano Zampini   DMGetPeriodicity - Get the description of mesh periodicity
59855dc8c3f7SMatthew G. Knepley 
59865dc8c3f7SMatthew G. Knepley   Input Parameters:
598790b157c4SStefano Zampini . dm      - The DM object
598890b157c4SStefano Zampini 
598990b157c4SStefano Zampini   Output Parameters:
599090b157c4SStefano Zampini + per     - Whether the DM is periodic or not
59915dc8c3f7SMatthew 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
59925dc8c3f7SMatthew G. Knepley . L       - If we assume the mesh is a torus, this is the length of each coordinate
59935dc8c3f7SMatthew G. Knepley - bd      - This describes the type of periodicity in each topological dimension
59945dc8c3f7SMatthew G. Knepley 
59955dc8c3f7SMatthew G. Knepley   Level: developer
59965dc8c3f7SMatthew G. Knepley 
59975dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity()
59985dc8c3f7SMatthew G. Knepley @*/
599990b157c4SStefano Zampini PetscErrorCode DMGetPeriodicity(DM dm, PetscBool *per, const PetscReal **maxCell, const PetscReal **L, const DMBoundaryType **bd)
6000c6b900c6SMatthew G. Knepley {
6001c6b900c6SMatthew G. Knepley   PetscFunctionBegin;
6002c6b900c6SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
600390b157c4SStefano Zampini   if (per)     *per     = dm->periodic;
6004c6b900c6SMatthew G. Knepley   if (L)       *L       = dm->L;
6005c6b900c6SMatthew G. Knepley   if (maxCell) *maxCell = dm->maxCell;
60065dc8c3f7SMatthew G. Knepley   if (bd)      *bd      = dm->bdtype;
6007c6b900c6SMatthew G. Knepley   PetscFunctionReturn(0);
6008c6b900c6SMatthew G. Knepley }
6009c6b900c6SMatthew G. Knepley 
60105dc8c3f7SMatthew G. Knepley /*@C
60115dc8c3f7SMatthew G. Knepley   DMSetPeriodicity - Set the description of mesh periodicity
60125dc8c3f7SMatthew G. Knepley 
60135dc8c3f7SMatthew G. Knepley   Input Parameters:
60145dc8c3f7SMatthew G. Knepley + dm      - The DM object
601590b157c4SStefano Zampini . per     - Whether the DM is periodic or not. If maxCell is not provided, coordinates need to be localized
60165dc8c3f7SMatthew 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
60175dc8c3f7SMatthew G. Knepley . L       - If we assume the mesh is a torus, this is the length of each coordinate
60185dc8c3f7SMatthew G. Knepley - bd      - This describes the type of periodicity in each topological dimension
60195dc8c3f7SMatthew G. Knepley 
60205dc8c3f7SMatthew G. Knepley   Level: developer
60215dc8c3f7SMatthew G. Knepley 
60225dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity()
60235dc8c3f7SMatthew G. Knepley @*/
602490b157c4SStefano Zampini PetscErrorCode DMSetPeriodicity(DM dm, PetscBool per, const PetscReal maxCell[], const PetscReal L[], const DMBoundaryType bd[])
6025c6b900c6SMatthew G. Knepley {
6026c6b900c6SMatthew G. Knepley   PetscInt       dim, d;
6027c6b900c6SMatthew G. Knepley   PetscErrorCode ierr;
6028c6b900c6SMatthew G. Knepley 
6029c6b900c6SMatthew G. Knepley   PetscFunctionBegin;
6030c6b900c6SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
603190b157c4SStefano Zampini   PetscValidLogicalCollectiveBool(dm,per,2);
603290b157c4SStefano Zampini   if (maxCell) {
6033534a8f05SLisandro Dalcin     PetscValidRealPointer(maxCell,3);
6034534a8f05SLisandro Dalcin     PetscValidRealPointer(L,4);
603590b157c4SStefano Zampini     PetscValidPointer(bd,5);
603690b157c4SStefano Zampini   }
60375dc8c3f7SMatthew G. Knepley   ierr = PetscFree3(dm->L,dm->maxCell,dm->bdtype);CHKERRQ(ierr);
60385dc8c3f7SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
603990b157c4SStefano Zampini   if (maxCell) {
60405dc8c3f7SMatthew G. Knepley     ierr = PetscMalloc3(dim,&dm->L,dim,&dm->maxCell,dim,&dm->bdtype);CHKERRQ(ierr);
60415dc8c3f7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {dm->L[d] = L[d]; dm->maxCell[d] = maxCell[d]; dm->bdtype[d] = bd[d];}
604290b157c4SStefano Zampini   }
6043072d7d67SStefano Zampini   dm->periodic = per;
6044c6b900c6SMatthew G. Knepley   PetscFunctionReturn(0);
6045c6b900c6SMatthew G. Knepley }
6046c6b900c6SMatthew G. Knepley 
60472e17dfb7SMatthew G. Knepley /*@
60482e17dfb7SMatthew 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.
60492e17dfb7SMatthew G. Knepley 
60502e17dfb7SMatthew G. Knepley   Input Parameters:
60512e17dfb7SMatthew G. Knepley + dm     - The DM
605265da65dcSMatthew G. Knepley . in     - The input coordinate point (dim numbers)
605365da65dcSMatthew G. Knepley - endpoint - Include the endpoint L_i
60542e17dfb7SMatthew G. Knepley 
60552e17dfb7SMatthew G. Knepley   Output Parameter:
60562e17dfb7SMatthew G. Knepley . out - The localized coordinate point
60572e17dfb7SMatthew G. Knepley 
60582e17dfb7SMatthew G. Knepley   Level: developer
60592e17dfb7SMatthew G. Knepley 
60602e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate()
60612e17dfb7SMatthew G. Knepley @*/
606265da65dcSMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate(DM dm, const PetscScalar in[], PetscBool endpoint, PetscScalar out[])
60632e17dfb7SMatthew G. Knepley {
60642e17dfb7SMatthew G. Knepley   PetscInt       dim, d;
60652e17dfb7SMatthew G. Knepley   PetscErrorCode ierr;
60662e17dfb7SMatthew G. Knepley 
60672e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
60682e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr);
60692e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
60702e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] = in[d];
60712e17dfb7SMatthew G. Knepley   } else {
607265da65dcSMatthew G. Knepley     if (endpoint) {
607365da65dcSMatthew G. Knepley       for (d = 0; d < dim; ++d) {
6074da3333bfSMatthew 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)) {
6075da3333bfSMatthew G. Knepley           out[d] = in[d] - dm->L[d]*(PetscFloorReal(PetscRealPart(in[d])/dm->L[d]) - 1);
607665da65dcSMatthew G. Knepley         } else {
6077da3333bfSMatthew G. Knepley           out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]);
607865da65dcSMatthew G. Knepley         }
607965da65dcSMatthew G. Knepley       }
608065da65dcSMatthew G. Knepley     } else {
60812e17dfb7SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
60821118d4bcSLisandro Dalcin         out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]);
60832e17dfb7SMatthew G. Knepley       }
60842e17dfb7SMatthew G. Knepley     }
608565da65dcSMatthew G. Knepley   }
60862e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
60872e17dfb7SMatthew G. Knepley }
60882e17dfb7SMatthew G. Knepley 
60892e17dfb7SMatthew G. Knepley /*
60902e17dfb7SMatthew 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.
60912e17dfb7SMatthew G. Knepley 
60922e17dfb7SMatthew G. Knepley   Input Parameters:
60932e17dfb7SMatthew G. Knepley + dm     - The DM
60942e17dfb7SMatthew G. Knepley . dim    - The spatial dimension
60952e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it
60962e17dfb7SMatthew G. Knepley - in     - The input coordinate point (dim numbers)
60972e17dfb7SMatthew G. Knepley 
60982e17dfb7SMatthew G. Knepley   Output Parameter:
60992e17dfb7SMatthew G. Knepley . out - The localized coordinate point
61002e17dfb7SMatthew G. Knepley 
61012e17dfb7SMatthew G. Knepley   Level: developer
61022e17dfb7SMatthew G. Knepley 
61032e17dfb7SMatthew 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
61042e17dfb7SMatthew G. Knepley 
61052e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate()
61062e17dfb7SMatthew G. Knepley */
61072e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[])
61082e17dfb7SMatthew G. Knepley {
61092e17dfb7SMatthew G. Knepley   PetscInt d;
61102e17dfb7SMatthew G. Knepley 
61112e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
61122e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
61132e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] = in[d];
61142e17dfb7SMatthew G. Knepley   } else {
61152e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
6116908eca10SMatthew G. Knepley       if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) {
61172e17dfb7SMatthew G. Knepley         out[d] = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d];
61182e17dfb7SMatthew G. Knepley       } else {
61192e17dfb7SMatthew G. Knepley         out[d] = in[d];
61202e17dfb7SMatthew G. Knepley       }
61212e17dfb7SMatthew G. Knepley     }
61222e17dfb7SMatthew G. Knepley   }
61232e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
61242e17dfb7SMatthew G. Knepley }
61252e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinateReal_Internal(DM dm, PetscInt dim, const PetscReal anchor[], const PetscReal in[], PetscReal out[])
61262e17dfb7SMatthew G. Knepley {
61272e17dfb7SMatthew G. Knepley   PetscInt d;
61282e17dfb7SMatthew G. Knepley 
61292e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
61302e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
61312e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] = in[d];
61322e17dfb7SMatthew G. Knepley   } else {
61332e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
6134908eca10SMatthew G. Knepley       if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsReal(anchor[d] - in[d]) > dm->maxCell[d])) {
61352e17dfb7SMatthew G. Knepley         out[d] = anchor[d] > in[d] ? dm->L[d] + in[d] : in[d] - dm->L[d];
61362e17dfb7SMatthew G. Knepley       } else {
61372e17dfb7SMatthew G. Knepley         out[d] = in[d];
61382e17dfb7SMatthew G. Knepley       }
61392e17dfb7SMatthew G. Knepley     }
61402e17dfb7SMatthew G. Knepley   }
61412e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
61422e17dfb7SMatthew G. Knepley }
61432e17dfb7SMatthew G. Knepley 
61442e17dfb7SMatthew G. Knepley /*
61452e17dfb7SMatthew 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.
61462e17dfb7SMatthew G. Knepley 
61472e17dfb7SMatthew G. Knepley   Input Parameters:
61482e17dfb7SMatthew G. Knepley + dm     - The DM
61492e17dfb7SMatthew G. Knepley . dim    - The spatial dimension
61502e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it
61512e17dfb7SMatthew G. Knepley . in     - The input coordinate delta (dim numbers)
61522e17dfb7SMatthew G. Knepley - out    - The input coordinate point (dim numbers)
61532e17dfb7SMatthew G. Knepley 
61542e17dfb7SMatthew G. Knepley   Output Parameter:
61552e17dfb7SMatthew G. Knepley . out    - The localized coordinate in + out
61562e17dfb7SMatthew G. Knepley 
61572e17dfb7SMatthew G. Knepley   Level: developer
61582e17dfb7SMatthew G. Knepley 
61592e17dfb7SMatthew 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
61602e17dfb7SMatthew G. Knepley 
61612e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeCoordinate()
61622e17dfb7SMatthew G. Knepley */
61632e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeAddCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[])
61642e17dfb7SMatthew G. Knepley {
61652e17dfb7SMatthew G. Knepley   PetscInt d;
61662e17dfb7SMatthew G. Knepley 
61672e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
61682e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
61692e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] += in[d];
61702e17dfb7SMatthew G. Knepley   } else {
61712e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
6172908eca10SMatthew G. Knepley       if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) {
61732e17dfb7SMatthew G. Knepley         out[d] += PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d];
61742e17dfb7SMatthew G. Knepley       } else {
61752e17dfb7SMatthew G. Knepley         out[d] += in[d];
61762e17dfb7SMatthew G. Knepley       }
61772e17dfb7SMatthew G. Knepley     }
61782e17dfb7SMatthew G. Knepley   }
61792e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
61802e17dfb7SMatthew G. Knepley }
61812e17dfb7SMatthew G. Knepley 
618236447a5eSToby Isaac /*@
61838f700142SStefano Zampini   DMGetCoordinatesLocalizedLocal - Check if the DM coordinates have been localized for cells on this process
61848f700142SStefano Zampini 
61858f700142SStefano Zampini   Not collective
618636447a5eSToby Isaac 
618736447a5eSToby Isaac   Input Parameter:
618836447a5eSToby Isaac . dm - The DM
618936447a5eSToby Isaac 
619036447a5eSToby Isaac   Output Parameter:
619136447a5eSToby Isaac   areLocalized - True if localized
619236447a5eSToby Isaac 
619336447a5eSToby Isaac   Level: developer
619436447a5eSToby Isaac 
61958f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMGetCoordinatesLocalized(), DMSetPeriodicity()
619636447a5eSToby Isaac @*/
61978f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalizedLocal(DM dm,PetscBool *areLocalized)
619836447a5eSToby Isaac {
619936447a5eSToby Isaac   DM             cdm;
620036447a5eSToby Isaac   PetscSection   coordSection;
620146a3a80fSLisandro Dalcin   PetscInt       cStart, cEnd, sStart, sEnd, c, dof;
620246a3a80fSLisandro Dalcin   PetscBool      isPlex, alreadyLocalized;
620336447a5eSToby Isaac   PetscErrorCode ierr;
620436447a5eSToby Isaac 
620536447a5eSToby Isaac   PetscFunctionBegin;
620636447a5eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6207534a8f05SLisandro Dalcin   PetscValidBoolPointer(areLocalized, 2);
62088b09590cSToby Isaac   *areLocalized = PETSC_FALSE;
620946a3a80fSLisandro Dalcin 
621036447a5eSToby Isaac   /* We need some generic way of refering to cells/vertices */
621136447a5eSToby Isaac   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
621246a3a80fSLisandro Dalcin   ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isPlex);CHKERRQ(ierr);
62139f7230bfSMatthew G. Knepley   if (!isPlex) PetscFunctionReturn(0);
621446a3a80fSLisandro Dalcin 
62159f7230bfSMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
621646a3a80fSLisandro Dalcin   ierr = DMPlexGetHeightStratum(cdm, 0, &cStart, &cEnd);CHKERRQ(ierr);
621736447a5eSToby Isaac   ierr = PetscSectionGetChart(coordSection, &sStart, &sEnd);CHKERRQ(ierr);
621836447a5eSToby Isaac   alreadyLocalized = PETSC_FALSE;
621946a3a80fSLisandro Dalcin   for (c = cStart; c < cEnd; ++c) {
622046a3a80fSLisandro Dalcin     if (c < sStart || c >= sEnd) continue;
622136447a5eSToby Isaac     ierr = PetscSectionGetDof(coordSection, c, &dof);CHKERRQ(ierr);
622246a3a80fSLisandro Dalcin     if (dof) { alreadyLocalized = PETSC_TRUE; break; }
622336447a5eSToby Isaac   }
62248f700142SStefano Zampini   *areLocalized = alreadyLocalized;
622536447a5eSToby Isaac   PetscFunctionReturn(0);
622636447a5eSToby Isaac }
622736447a5eSToby Isaac 
62288f700142SStefano Zampini /*@
62298f700142SStefano Zampini   DMGetCoordinatesLocalized - Check if the DM coordinates have been localized for cells
62308f700142SStefano Zampini 
62318f700142SStefano Zampini   Collective on dm
62328f700142SStefano Zampini 
62338f700142SStefano Zampini   Input Parameter:
62348f700142SStefano Zampini . dm - The DM
62358f700142SStefano Zampini 
62368f700142SStefano Zampini   Output Parameter:
62378f700142SStefano Zampini   areLocalized - True if localized
62388f700142SStefano Zampini 
62398f700142SStefano Zampini   Level: developer
62408f700142SStefano Zampini 
62418f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMSetPeriodicity(), DMGetCoordinatesLocalizedLocal()
62428f700142SStefano Zampini @*/
62438f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalized(DM dm,PetscBool *areLocalized)
62448f700142SStefano Zampini {
62458f700142SStefano Zampini   PetscBool      localized;
62468f700142SStefano Zampini   PetscErrorCode ierr;
62478f700142SStefano Zampini 
62488f700142SStefano Zampini   PetscFunctionBegin;
62498f700142SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6250534a8f05SLisandro Dalcin   PetscValidBoolPointer(areLocalized, 2);
62518f700142SStefano Zampini   ierr = DMGetCoordinatesLocalizedLocal(dm,&localized);CHKERRQ(ierr);
62528f700142SStefano Zampini   ierr = MPIU_Allreduce(&localized,areLocalized,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
62538f700142SStefano Zampini   PetscFunctionReturn(0);
62548f700142SStefano Zampini }
625536447a5eSToby Isaac 
62562e17dfb7SMatthew G. Knepley /*@
6257492b8470SStefano Zampini   DMLocalizeCoordinates - If a mesh is periodic, create local coordinates for cells having periodic faces
62582e17dfb7SMatthew G. Knepley 
62598f700142SStefano Zampini   Collective on dm
62608f700142SStefano Zampini 
62612e17dfb7SMatthew G. Knepley   Input Parameter:
62622e17dfb7SMatthew G. Knepley . dm - The DM
62632e17dfb7SMatthew G. Knepley 
62642e17dfb7SMatthew G. Knepley   Level: developer
62652e17dfb7SMatthew G. Knepley 
62668f700142SStefano Zampini .seealso: DMSetPeriodicity(), DMLocalizeCoordinate(), DMLocalizeAddCoordinate()
62672e17dfb7SMatthew G. Knepley @*/
62682e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinates(DM dm)
62692e17dfb7SMatthew G. Knepley {
62702e17dfb7SMatthew G. Knepley   DM             cdm;
62712e17dfb7SMatthew G. Knepley   PetscSection   coordSection, cSection;
62722e17dfb7SMatthew G. Knepley   Vec            coordinates,  cVec;
62733e922f36SToby Isaac   PetscScalar   *coords, *coords2, *anchor, *localized;
62743e922f36SToby Isaac   PetscInt       Nc, vStart, vEnd, v, sStart, sEnd, newStart = PETSC_MAX_INT, newEnd = PETSC_MIN_INT, dof, d, off, off2, bs, coordSize;
6275e0ae35bbSToby Isaac   PetscBool      alreadyLocalized, alreadyLocalizedGlobal;
62763e922f36SToby Isaac   PetscInt       maxHeight = 0, h;
62773e922f36SToby Isaac   PetscInt       *pStart = NULL, *pEnd = NULL;
62782e17dfb7SMatthew G. Knepley   PetscErrorCode ierr;
62792e17dfb7SMatthew G. Knepley 
62802e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
62812e17dfb7SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
628292c9c85fSStefano Zampini   if (!dm->periodic) PetscFunctionReturn(0);
6283f7cbd40bSStefano Zampini   ierr = DMGetCoordinatesLocalized(dm, &alreadyLocalized);CHKERRQ(ierr);
6284f7cbd40bSStefano Zampini   if (alreadyLocalized) PetscFunctionReturn(0);
6285f7cbd40bSStefano Zampini 
62862e17dfb7SMatthew G. Knepley   /* We need some generic way of refering to cells/vertices */
62872e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
62882e17dfb7SMatthew G. Knepley   {
62892e17dfb7SMatthew G. Knepley     PetscBool isplex;
62902e17dfb7SMatthew G. Knepley 
62912e17dfb7SMatthew G. Knepley     ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isplex);CHKERRQ(ierr);
62922e17dfb7SMatthew G. Knepley     if (isplex) {
62932e17dfb7SMatthew G. Knepley       ierr = DMPlexGetDepthStratum(cdm, 0, &vStart, &vEnd);CHKERRQ(ierr);
62943e922f36SToby Isaac       ierr = DMPlexGetMaxProjectionHeight(cdm,&maxHeight);CHKERRQ(ierr);
629569291d52SBarry Smith       ierr = DMGetWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr);
62963e922f36SToby Isaac       pEnd = &pStart[maxHeight + 1];
62973e922f36SToby Isaac       newStart = vStart;
62983e922f36SToby Isaac       newEnd   = vEnd;
62993e922f36SToby Isaac       for (h = 0; h <= maxHeight; h++) {
63003e922f36SToby Isaac         ierr = DMPlexGetHeightStratum(cdm, h, &pStart[h], &pEnd[h]);CHKERRQ(ierr);
63013e922f36SToby Isaac         newStart = PetscMin(newStart,pStart[h]);
63023e922f36SToby Isaac         newEnd   = PetscMax(newEnd,pEnd[h]);
63033e922f36SToby Isaac       }
63042e17dfb7SMatthew G. Knepley     } else SETERRQ(PetscObjectComm((PetscObject) cdm), PETSC_ERR_ARG_WRONG, "Coordinate localization requires a DMPLEX coordinate DM");
63052e17dfb7SMatthew G. Knepley   }
63062e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
630743eeeb2dSStefano Zampini   if (!coordinates) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Missing local coordinates vector");
63082e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
63093e922f36SToby Isaac   ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr);
6310e0ae35bbSToby Isaac   ierr = PetscSectionGetChart(coordSection,&sStart,&sEnd);CHKERRQ(ierr);
63113e922f36SToby Isaac 
63122e17dfb7SMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &cSection);CHKERRQ(ierr);
63132e17dfb7SMatthew G. Knepley   ierr = PetscSectionSetNumFields(cSection, 1);CHKERRQ(ierr);
63142e17dfb7SMatthew G. Knepley   ierr = PetscSectionGetFieldComponents(coordSection, 0, &Nc);CHKERRQ(ierr);
63152e17dfb7SMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(cSection, 0, Nc);CHKERRQ(ierr);
63163e922f36SToby Isaac   ierr = PetscSectionSetChart(cSection, newStart, newEnd);CHKERRQ(ierr);
63173e922f36SToby Isaac 
631869291d52SBarry Smith   ierr = DMGetWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr);
63193e922f36SToby Isaac   localized = &anchor[bs];
63203e922f36SToby Isaac   alreadyLocalized = alreadyLocalizedGlobal = PETSC_TRUE;
63213e922f36SToby Isaac   for (h = 0; h <= maxHeight; h++) {
63223e922f36SToby Isaac     PetscInt cStart = pStart[h], cEnd = pEnd[h], c;
63233e922f36SToby Isaac 
63243e922f36SToby Isaac     for (c = cStart; c < cEnd; ++c) {
63253e922f36SToby Isaac       PetscScalar *cellCoords = NULL;
63263e922f36SToby Isaac       PetscInt     b;
63273e922f36SToby Isaac 
63283e922f36SToby Isaac       if (c < sStart || c >= sEnd) alreadyLocalized = PETSC_FALSE;
63293e922f36SToby Isaac       ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
63303e922f36SToby Isaac       for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b];
63313e922f36SToby Isaac       for (d = 0; d < dof/bs; ++d) {
63323e922f36SToby Isaac         ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], localized);CHKERRQ(ierr);
63333e922f36SToby Isaac         for (b = 0; b < bs; b++) {
63343e922f36SToby Isaac           if (cellCoords[d*bs + b] != localized[b]) break;
63353e922f36SToby Isaac         }
63363e922f36SToby Isaac         if (b < bs) break;
63373e922f36SToby Isaac       }
63383e922f36SToby Isaac       if (d < dof/bs) {
63393e922f36SToby Isaac         if (c >= sStart && c < sEnd) {
63403e922f36SToby Isaac           PetscInt cdof;
63413e922f36SToby Isaac 
63423e922f36SToby Isaac           ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr);
63433e922f36SToby Isaac           if (cdof != dof) alreadyLocalized = PETSC_FALSE;
63443e922f36SToby Isaac         }
63453e922f36SToby Isaac         ierr = PetscSectionSetDof(cSection, c, dof);CHKERRQ(ierr);
63463e922f36SToby Isaac         ierr = PetscSectionSetFieldDof(cSection, c, 0, dof);CHKERRQ(ierr);
63473e922f36SToby Isaac       }
63483e922f36SToby Isaac       ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
63493e922f36SToby Isaac     }
63503e922f36SToby Isaac   }
63513e922f36SToby Isaac   ierr = MPI_Allreduce(&alreadyLocalized,&alreadyLocalizedGlobal,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
63523e922f36SToby Isaac   if (alreadyLocalizedGlobal) {
635369291d52SBarry Smith     ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr);
63543e922f36SToby Isaac     ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr);
635569291d52SBarry Smith     ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr);
63563e922f36SToby Isaac     PetscFunctionReturn(0);
63573e922f36SToby Isaac   }
63582e17dfb7SMatthew G. Knepley   for (v = vStart; v < vEnd; ++v) {
63592e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr);
63602e17dfb7SMatthew G. Knepley     ierr = PetscSectionSetDof(cSection, v, dof);CHKERRQ(ierr);
63612e17dfb7SMatthew G. Knepley     ierr = PetscSectionSetFieldDof(cSection, v, 0, dof);CHKERRQ(ierr);
63622e17dfb7SMatthew G. Knepley   }
63632e17dfb7SMatthew G. Knepley   ierr = PetscSectionSetUp(cSection);CHKERRQ(ierr);
63642e17dfb7SMatthew G. Knepley   ierr = PetscSectionGetStorageSize(cSection, &coordSize);CHKERRQ(ierr);
6365c2be7e5eSLisandro Dalcin   ierr = VecCreate(PETSC_COMM_SELF, &cVec);CHKERRQ(ierr);
63662e17dfb7SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject)cVec,"coordinates");CHKERRQ(ierr);
63672e17dfb7SMatthew G. Knepley   ierr = VecSetBlockSize(cVec, bs);CHKERRQ(ierr);
63682e17dfb7SMatthew G. Knepley   ierr = VecSetSizes(cVec, coordSize, PETSC_DETERMINE);CHKERRQ(ierr);
63692e17dfb7SMatthew G. Knepley   ierr = VecSetType(cVec, VECSTANDARD);CHKERRQ(ierr);
6370c2be7e5eSLisandro Dalcin   ierr = VecGetArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr);
63712e17dfb7SMatthew G. Knepley   ierr = VecGetArray(cVec, &coords2);CHKERRQ(ierr);
63722e17dfb7SMatthew G. Knepley   for (v = vStart; v < vEnd; ++v) {
63732e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr);
63742e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
63752e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetOffset(cSection,     v, &off2);CHKERRQ(ierr);
63762e17dfb7SMatthew G. Knepley     for (d = 0; d < dof; ++d) coords2[off2+d] = coords[off+d];
63772e17dfb7SMatthew G. Knepley   }
63783e922f36SToby Isaac   for (h = 0; h <= maxHeight; h++) {
63793e922f36SToby Isaac     PetscInt cStart = pStart[h], cEnd = pEnd[h], c;
63803e922f36SToby Isaac 
63812e17dfb7SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
63822e17dfb7SMatthew G. Knepley       PetscScalar *cellCoords = NULL;
63833e922f36SToby Isaac       PetscInt     b, cdof;
63842e17dfb7SMatthew G. Knepley 
63853e922f36SToby Isaac       ierr = PetscSectionGetDof(cSection,c,&cdof);CHKERRQ(ierr);
63863e922f36SToby Isaac       if (!cdof) continue;
63872e17dfb7SMatthew G. Knepley       ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
63882e17dfb7SMatthew G. Knepley       ierr = PetscSectionGetOffset(cSection, c, &off2);CHKERRQ(ierr);
63892e17dfb7SMatthew G. Knepley       for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b];
63902e17dfb7SMatthew G. Knepley       for (d = 0; d < dof/bs; ++d) {ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], &coords2[off2+d*bs]);CHKERRQ(ierr);}
63912e17dfb7SMatthew G. Knepley       ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
63922e17dfb7SMatthew G. Knepley     }
63933e922f36SToby Isaac   }
639469291d52SBarry Smith   ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr);
639569291d52SBarry Smith   ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr);
6396c2be7e5eSLisandro Dalcin   ierr = VecRestoreArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr);
63972e17dfb7SMatthew G. Knepley   ierr = VecRestoreArray(cVec, &coords2);CHKERRQ(ierr);
63982e17dfb7SMatthew G. Knepley   ierr = DMSetCoordinateSection(dm, PETSC_DETERMINE, cSection);CHKERRQ(ierr);
63992e17dfb7SMatthew G. Knepley   ierr = DMSetCoordinatesLocal(dm, cVec);CHKERRQ(ierr);
64002e17dfb7SMatthew G. Knepley   ierr = VecDestroy(&cVec);CHKERRQ(ierr);
64012e17dfb7SMatthew G. Knepley   ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr);
64022e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
64032e17dfb7SMatthew G. Knepley }
64042e17dfb7SMatthew G. Knepley 
6405e87bb0d3SMatthew G Knepley /*@
64063a93e3b7SToby Isaac   DMLocatePoints - Locate the points in v in the mesh and return a PetscSF of the containing cells
6407e87bb0d3SMatthew G Knepley 
6408d083f849SBarry Smith   Collective on v (see explanation below)
6409e87bb0d3SMatthew G Knepley 
6410e87bb0d3SMatthew G Knepley   Input Parameters:
6411e87bb0d3SMatthew G Knepley + dm - The DM
64123a93e3b7SToby Isaac . v - The Vec of points
641362a38674SMatthew G. Knepley . ltype - The type of point location, e.g. DM_POINTLOCATION_NONE or DM_POINTLOCATION_NEAREST
64143a93e3b7SToby Isaac - cells - Points to either NULL, or a PetscSF with guesses for which cells contain each point.
6415e87bb0d3SMatthew G Knepley 
641661e3bb9bSMatthew G Knepley   Output Parameter:
641762a38674SMatthew G. Knepley + v - The Vec of points, which now contains the nearest mesh points to the given points if DM_POINTLOCATION_NEAREST is used
641862a38674SMatthew G. Knepley - cells - The PetscSF containing the ranks and local indices of the containing points.
64193a93e3b7SToby Isaac 
6420e87bb0d3SMatthew G Knepley 
6421e87bb0d3SMatthew G Knepley   Level: developer
642261e3bb9bSMatthew G Knepley 
642362a38674SMatthew G. Knepley   Notes:
64243a93e3b7SToby Isaac   To do a search of the local cells of the mesh, v should have PETSC_COMM_SELF as its communicator.
642562a38674SMatthew G. Knepley   To do a search of all the cells in the distributed mesh, v should have the same communicator as dm.
64263a93e3b7SToby Isaac 
64273a93e3b7SToby Isaac   If *cellSF is NULL on input, a PetscSF will be created.
642862a38674SMatthew G. Knepley   If *cellSF is not NULL on input, it should point to an existing PetscSF, whose graph will be used as initial guesses.
64293a93e3b7SToby Isaac 
64303a93e3b7SToby Isaac   An array that maps each point to its containing cell can be obtained with
64313a93e3b7SToby Isaac 
643262a38674SMatthew G. Knepley $    const PetscSFNode *cells;
643362a38674SMatthew G. Knepley $    PetscInt           nFound;
6434a6216909SToby Isaac $    const PetscInt    *found;
643562a38674SMatthew G. Knepley $
6436a6216909SToby Isaac $    PetscSFGetGraph(cellSF,NULL,&nFound,&found,&cells);
64373a93e3b7SToby Isaac 
64383a93e3b7SToby 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
64393a93e3b7SToby Isaac   the index of the cell in its rank's local numbering.
64403a93e3b7SToby Isaac 
644162a38674SMatthew G. Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMPointLocationType
644261e3bb9bSMatthew G Knepley @*/
644362a38674SMatthew G. Knepley PetscErrorCode DMLocatePoints(DM dm, Vec v, DMPointLocationType ltype, PetscSF *cellSF)
6444e87bb0d3SMatthew G Knepley {
6445735aa83eSMatthew G Knepley   PetscErrorCode ierr;
6446735aa83eSMatthew G Knepley 
6447e87bb0d3SMatthew G Knepley   PetscFunctionBegin;
6448e87bb0d3SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6449e87bb0d3SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
6450e0fc9d1bSMatthew G. Knepley   PetscValidPointer(cellSF,4);
64513a93e3b7SToby Isaac   if (*cellSF) {
64523a93e3b7SToby Isaac     PetscMPIInt result;
64533a93e3b7SToby Isaac 
6454e0fc9d1bSMatthew G. Knepley     PetscValidHeaderSpecific(*cellSF,PETSCSF_CLASSID,4);
6455a4f09dd6SDave May     ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)v),PetscObjectComm((PetscObject)*cellSF),&result);CHKERRQ(ierr);
64563a93e3b7SToby 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");
6457e0fc9d1bSMatthew G. Knepley   } else {
64583a93e3b7SToby Isaac     ierr = PetscSFCreate(PetscObjectComm((PetscObject)v),cellSF);CHKERRQ(ierr);
64593a93e3b7SToby Isaac   }
6460b9d85ea2SLisandro Dalcin   if (!dm->ops->locatepoints) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Point location not available for this DM");
646147a35634SPatrick Farrell   ierr = PetscLogEventBegin(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr);
646262a38674SMatthew G. Knepley   ierr = (*dm->ops->locatepoints)(dm,v,ltype,*cellSF);CHKERRQ(ierr);
646347a35634SPatrick Farrell   ierr = PetscLogEventEnd(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr);
6464e87bb0d3SMatthew G Knepley   PetscFunctionReturn(0);
6465e87bb0d3SMatthew G Knepley }
646614f150ffSMatthew G. Knepley 
6467f4d763aaSMatthew G. Knepley /*@
6468f4d763aaSMatthew G. Knepley   DMGetOutputDM - Retrieve the DM associated with the layout for output
6469f4d763aaSMatthew G. Knepley 
64708f700142SStefano Zampini   Collective on dm
64718f700142SStefano Zampini 
6472f4d763aaSMatthew G. Knepley   Input Parameter:
6473f4d763aaSMatthew G. Knepley . dm - The original DM
6474f4d763aaSMatthew G. Knepley 
6475f4d763aaSMatthew G. Knepley   Output Parameter:
6476f4d763aaSMatthew G. Knepley . odm - The DM which provides the layout for output
6477f4d763aaSMatthew G. Knepley 
6478f4d763aaSMatthew G. Knepley   Level: intermediate
6479f4d763aaSMatthew G. Knepley 
6480e87a4003SBarry Smith .seealso: VecView(), DMGetGlobalSection()
6481f4d763aaSMatthew G. Knepley @*/
648214f150ffSMatthew G. Knepley PetscErrorCode DMGetOutputDM(DM dm, DM *odm)
648314f150ffSMatthew G. Knepley {
6484c26acbdeSMatthew G. Knepley   PetscSection   section;
64852d4e4a49SMatthew G. Knepley   PetscBool      hasConstraints, ghasConstraints;
648614f150ffSMatthew G. Knepley   PetscErrorCode ierr;
648714f150ffSMatthew G. Knepley 
648814f150ffSMatthew G. Knepley   PetscFunctionBegin;
648914f150ffSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
649014f150ffSMatthew G. Knepley   PetscValidPointer(odm,2);
649192fd8e1eSJed Brown   ierr = DMGetLocalSection(dm, &section);CHKERRQ(ierr);
6492c26acbdeSMatthew G. Knepley   ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr);
6493127fe6b9SMatthew G. Knepley   ierr = MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);
64942d4e4a49SMatthew G. Knepley   if (!ghasConstraints) {
6495c26acbdeSMatthew G. Knepley     *odm = dm;
6496c26acbdeSMatthew G. Knepley     PetscFunctionReturn(0);
6497c26acbdeSMatthew G. Knepley   }
649814f150ffSMatthew G. Knepley   if (!dm->dmBC) {
6499c26acbdeSMatthew G. Knepley     PetscSection newSection, gsection;
650014f150ffSMatthew G. Knepley     PetscSF      sf;
650114f150ffSMatthew G. Knepley 
650214f150ffSMatthew G. Knepley     ierr = DMClone(dm, &dm->dmBC);CHKERRQ(ierr);
6503e5e52638SMatthew G. Knepley     ierr = DMCopyDisc(dm, dm->dmBC);CHKERRQ(ierr);
650414f150ffSMatthew G. Knepley     ierr = PetscSectionClone(section, &newSection);CHKERRQ(ierr);
650592fd8e1eSJed Brown     ierr = DMSetLocalSection(dm->dmBC, newSection);CHKERRQ(ierr);
650614f150ffSMatthew G. Knepley     ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr);
650714f150ffSMatthew G. Knepley     ierr = DMGetPointSF(dm->dmBC, &sf);CHKERRQ(ierr);
650815b58121SMatthew G. Knepley     ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr);
6509e87a4003SBarry Smith     ierr = DMSetGlobalSection(dm->dmBC, gsection);CHKERRQ(ierr);
651014f150ffSMatthew G. Knepley     ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr);
651114f150ffSMatthew G. Knepley   }
651214f150ffSMatthew G. Knepley   *odm = dm->dmBC;
651314f150ffSMatthew G. Knepley   PetscFunctionReturn(0);
651414f150ffSMatthew G. Knepley }
6515f4d763aaSMatthew G. Knepley 
6516f4d763aaSMatthew G. Knepley /*@
6517cdb7a50dSMatthew G. Knepley   DMGetOutputSequenceNumber - Retrieve the sequence number/value for output
6518f4d763aaSMatthew G. Knepley 
6519f4d763aaSMatthew G. Knepley   Input Parameter:
6520f4d763aaSMatthew G. Knepley . dm - The original DM
6521f4d763aaSMatthew G. Knepley 
6522cdb7a50dSMatthew G. Knepley   Output Parameters:
6523cdb7a50dSMatthew G. Knepley + num - The output sequence number
6524cdb7a50dSMatthew G. Knepley - val - The output sequence value
6525f4d763aaSMatthew G. Knepley 
6526f4d763aaSMatthew G. Knepley   Level: intermediate
6527f4d763aaSMatthew G. Knepley 
6528f4d763aaSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
6529f4d763aaSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
6530f4d763aaSMatthew G. Knepley 
6531f4d763aaSMatthew G. Knepley .seealso: VecView()
6532f4d763aaSMatthew G. Knepley @*/
6533cdb7a50dSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val)
6534f4d763aaSMatthew G. Knepley {
6535f4d763aaSMatthew G. Knepley   PetscFunctionBegin;
6536f4d763aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6537534a8f05SLisandro Dalcin   if (num) {PetscValidIntPointer(num,2); *num = dm->outputSequenceNum;}
6538534a8f05SLisandro Dalcin   if (val) {PetscValidRealPointer(val,3);*val = dm->outputSequenceVal;}
6539f4d763aaSMatthew G. Knepley   PetscFunctionReturn(0);
6540f4d763aaSMatthew G. Knepley }
6541f4d763aaSMatthew G. Knepley 
6542f4d763aaSMatthew G. Knepley /*@
6543cdb7a50dSMatthew G. Knepley   DMSetOutputSequenceNumber - Set the sequence number/value for output
6544f4d763aaSMatthew G. Knepley 
6545f4d763aaSMatthew G. Knepley   Input Parameters:
6546f4d763aaSMatthew G. Knepley + dm - The original DM
6547cdb7a50dSMatthew G. Knepley . num - The output sequence number
6548cdb7a50dSMatthew G. Knepley - val - The output sequence value
6549f4d763aaSMatthew G. Knepley 
6550f4d763aaSMatthew G. Knepley   Level: intermediate
6551f4d763aaSMatthew G. Knepley 
6552f4d763aaSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
6553f4d763aaSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
6554f4d763aaSMatthew G. Knepley 
6555f4d763aaSMatthew G. Knepley .seealso: VecView()
6556f4d763aaSMatthew G. Knepley @*/
6557cdb7a50dSMatthew G. Knepley PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val)
6558f4d763aaSMatthew G. Knepley {
6559f4d763aaSMatthew G. Knepley   PetscFunctionBegin;
6560f4d763aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6561f4d763aaSMatthew G. Knepley   dm->outputSequenceNum = num;
6562cdb7a50dSMatthew G. Knepley   dm->outputSequenceVal = val;
6563cdb7a50dSMatthew G. Knepley   PetscFunctionReturn(0);
6564cdb7a50dSMatthew G. Knepley }
6565cdb7a50dSMatthew G. Knepley 
6566cdb7a50dSMatthew G. Knepley /*@C
6567cdb7a50dSMatthew G. Knepley   DMOutputSequenceLoad - Retrieve the sequence value from a Viewer
6568cdb7a50dSMatthew G. Knepley 
6569cdb7a50dSMatthew G. Knepley   Input Parameters:
6570cdb7a50dSMatthew G. Knepley + dm   - The original DM
6571cdb7a50dSMatthew G. Knepley . name - The sequence name
6572cdb7a50dSMatthew G. Knepley - num  - The output sequence number
6573cdb7a50dSMatthew G. Knepley 
6574cdb7a50dSMatthew G. Knepley   Output Parameter:
6575cdb7a50dSMatthew G. Knepley . val  - The output sequence value
6576cdb7a50dSMatthew G. Knepley 
6577cdb7a50dSMatthew G. Knepley   Level: intermediate
6578cdb7a50dSMatthew G. Knepley 
6579cdb7a50dSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
6580cdb7a50dSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
6581cdb7a50dSMatthew G. Knepley 
6582cdb7a50dSMatthew G. Knepley .seealso: DMGetOutputSequenceNumber(), DMSetOutputSequenceNumber(), VecView()
6583cdb7a50dSMatthew G. Knepley @*/
6584cdb7a50dSMatthew G. Knepley PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val)
6585cdb7a50dSMatthew G. Knepley {
6586cdb7a50dSMatthew G. Knepley   PetscBool      ishdf5;
6587cdb7a50dSMatthew G. Knepley   PetscErrorCode ierr;
6588cdb7a50dSMatthew G. Knepley 
6589cdb7a50dSMatthew G. Knepley   PetscFunctionBegin;
6590cdb7a50dSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6591cdb7a50dSMatthew G. Knepley   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
6592534a8f05SLisandro Dalcin   PetscValidRealPointer(val,4);
6593cdb7a50dSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr);
6594cdb7a50dSMatthew G. Knepley   if (ishdf5) {
6595cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5)
6596cdb7a50dSMatthew G. Knepley     PetscScalar value;
6597cdb7a50dSMatthew G. Knepley 
659839d25373SMatthew G. Knepley     ierr = DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer);CHKERRQ(ierr);
65994aeb217fSMatthew G. Knepley     *val = PetscRealPart(value);
6600cdb7a50dSMatthew G. Knepley #endif
6601cdb7a50dSMatthew G. Knepley   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()");
6602f4d763aaSMatthew G. Knepley   PetscFunctionReturn(0);
6603f4d763aaSMatthew G. Knepley }
66048e4ac7eaSMatthew G. Knepley 
66058e4ac7eaSMatthew G. Knepley /*@
66068e4ac7eaSMatthew G. Knepley   DMGetUseNatural - Get the flag for creating a mapping to the natural order on distribution
66078e4ac7eaSMatthew G. Knepley 
66088e4ac7eaSMatthew G. Knepley   Not collective
66098e4ac7eaSMatthew G. Knepley 
66108e4ac7eaSMatthew G. Knepley   Input Parameter:
66118e4ac7eaSMatthew G. Knepley . dm - The DM
66128e4ac7eaSMatthew G. Knepley 
66138e4ac7eaSMatthew G. Knepley   Output Parameter:
66148e4ac7eaSMatthew G. Knepley . useNatural - The flag to build the mapping to a natural order during distribution
66158e4ac7eaSMatthew G. Knepley 
66168e4ac7eaSMatthew G. Knepley   Level: beginner
66178e4ac7eaSMatthew G. Knepley 
66188e4ac7eaSMatthew G. Knepley .seealso: DMSetUseNatural(), DMCreate()
66198e4ac7eaSMatthew G. Knepley @*/
66208e4ac7eaSMatthew G. Knepley PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural)
66218e4ac7eaSMatthew G. Knepley {
66228e4ac7eaSMatthew G. Knepley   PetscFunctionBegin;
66238e4ac7eaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6624534a8f05SLisandro Dalcin   PetscValidBoolPointer(useNatural, 2);
66258e4ac7eaSMatthew G. Knepley   *useNatural = dm->useNatural;
66268e4ac7eaSMatthew G. Knepley   PetscFunctionReturn(0);
66278e4ac7eaSMatthew G. Knepley }
66288e4ac7eaSMatthew G. Knepley 
66298e4ac7eaSMatthew G. Knepley /*@
66305d3b26e6SMatthew G. Knepley   DMSetUseNatural - Set the flag for creating a mapping to the natural order after distribution
66318e4ac7eaSMatthew G. Knepley 
66328e4ac7eaSMatthew G. Knepley   Collective on dm
66338e4ac7eaSMatthew G. Knepley 
66348e4ac7eaSMatthew G. Knepley   Input Parameters:
66358e4ac7eaSMatthew G. Knepley + dm - The DM
66368e4ac7eaSMatthew G. Knepley - useNatural - The flag to build the mapping to a natural order during distribution
66378e4ac7eaSMatthew G. Knepley 
66385d3b26e6SMatthew G. Knepley   Note: This also causes the map to be build after DMCreateSubDM() and DMCreateSuperDM()
66395d3b26e6SMatthew G. Knepley 
66408e4ac7eaSMatthew G. Knepley   Level: beginner
66418e4ac7eaSMatthew G. Knepley 
66425d3b26e6SMatthew G. Knepley .seealso: DMGetUseNatural(), DMCreate(), DMPlexDistribute(), DMCreateSubDM(), DMCreateSuperDM()
66438e4ac7eaSMatthew G. Knepley @*/
66448e4ac7eaSMatthew G. Knepley PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural)
66458e4ac7eaSMatthew G. Knepley {
66468e4ac7eaSMatthew G. Knepley   PetscFunctionBegin;
66478e4ac7eaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
66488833efb5SBlaise Bourdin   PetscValidLogicalCollectiveBool(dm, useNatural, 2);
66498e4ac7eaSMatthew G. Knepley   dm->useNatural = useNatural;
66508e4ac7eaSMatthew G. Knepley   PetscFunctionReturn(0);
66518e4ac7eaSMatthew G. Knepley }
6652c58f1c22SToby Isaac 
6653c58f1c22SToby Isaac 
6654c58f1c22SToby Isaac /*@C
6655c58f1c22SToby Isaac   DMCreateLabel - Create a label of the given name if it does not already exist
6656c58f1c22SToby Isaac 
6657c58f1c22SToby Isaac   Not Collective
6658c58f1c22SToby Isaac 
6659c58f1c22SToby Isaac   Input Parameters:
6660c58f1c22SToby Isaac + dm   - The DM object
6661c58f1c22SToby Isaac - name - The label name
6662c58f1c22SToby Isaac 
6663c58f1c22SToby Isaac   Level: intermediate
6664c58f1c22SToby Isaac 
6665c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6666c58f1c22SToby Isaac @*/
6667c58f1c22SToby Isaac PetscErrorCode DMCreateLabel(DM dm, const char name[])
6668c58f1c22SToby Isaac {
66695d80c0bfSVaclav Hapla   PetscBool      flg;
66705d80c0bfSVaclav Hapla   DMLabel        label;
6671c58f1c22SToby Isaac   PetscErrorCode ierr;
6672c58f1c22SToby Isaac 
6673c58f1c22SToby Isaac   PetscFunctionBegin;
6674c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6675c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
66765d80c0bfSVaclav Hapla   ierr = DMHasLabel(dm, name, &flg);CHKERRQ(ierr);
6677c58f1c22SToby Isaac   if (!flg) {
66785d80c0bfSVaclav Hapla     ierr = DMLabelCreate(PETSC_COMM_SELF, name, &label);CHKERRQ(ierr);
66795d80c0bfSVaclav Hapla     ierr = DMAddLabel(dm, label);CHKERRQ(ierr);
66805d80c0bfSVaclav Hapla     ierr = DMLabelDestroy(&label);CHKERRQ(ierr);
6681c58f1c22SToby Isaac   }
6682c58f1c22SToby Isaac   PetscFunctionReturn(0);
6683c58f1c22SToby Isaac }
6684c58f1c22SToby Isaac 
6685c58f1c22SToby Isaac /*@C
6686c58f1c22SToby Isaac   DMGetLabelValue - Get the value in a Sieve Label for the given point, with 0 as the default
6687c58f1c22SToby Isaac 
6688c58f1c22SToby Isaac   Not Collective
6689c58f1c22SToby Isaac 
6690c58f1c22SToby Isaac   Input Parameters:
6691c58f1c22SToby Isaac + dm   - The DM object
6692c58f1c22SToby Isaac . name - The label name
6693c58f1c22SToby Isaac - point - The mesh point
6694c58f1c22SToby Isaac 
6695c58f1c22SToby Isaac   Output Parameter:
6696c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label
6697c58f1c22SToby Isaac 
6698c58f1c22SToby Isaac   Level: beginner
6699c58f1c22SToby Isaac 
6700c58f1c22SToby Isaac .seealso: DMLabelGetValue(), DMSetLabelValue(), DMGetStratumIS()
6701c58f1c22SToby Isaac @*/
6702c58f1c22SToby Isaac PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value)
6703c58f1c22SToby Isaac {
6704c58f1c22SToby Isaac   DMLabel        label;
6705c58f1c22SToby Isaac   PetscErrorCode ierr;
6706c58f1c22SToby Isaac 
6707c58f1c22SToby Isaac   PetscFunctionBegin;
6708c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6709c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6710c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
671113903a91SSatish Balay   if (!label) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name);
6712c58f1c22SToby Isaac   ierr = DMLabelGetValue(label, point, value);CHKERRQ(ierr);
6713c58f1c22SToby Isaac   PetscFunctionReturn(0);
6714c58f1c22SToby Isaac }
6715c58f1c22SToby Isaac 
6716c58f1c22SToby Isaac /*@C
6717c58f1c22SToby Isaac   DMSetLabelValue - Add a point to a Sieve Label with given value
6718c58f1c22SToby Isaac 
6719c58f1c22SToby Isaac   Not Collective
6720c58f1c22SToby Isaac 
6721c58f1c22SToby Isaac   Input Parameters:
6722c58f1c22SToby Isaac + dm   - The DM object
6723c58f1c22SToby Isaac . name - The label name
6724c58f1c22SToby Isaac . point - The mesh point
6725c58f1c22SToby Isaac - value - The label value for this point
6726c58f1c22SToby Isaac 
6727c58f1c22SToby Isaac   Output Parameter:
6728c58f1c22SToby Isaac 
6729c58f1c22SToby Isaac   Level: beginner
6730c58f1c22SToby Isaac 
6731c58f1c22SToby Isaac .seealso: DMLabelSetValue(), DMGetStratumIS(), DMClearLabelValue()
6732c58f1c22SToby Isaac @*/
6733c58f1c22SToby Isaac PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value)
6734c58f1c22SToby Isaac {
6735c58f1c22SToby Isaac   DMLabel        label;
6736c58f1c22SToby Isaac   PetscErrorCode ierr;
6737c58f1c22SToby Isaac 
6738c58f1c22SToby Isaac   PetscFunctionBegin;
6739c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6740c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6741c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6742c58f1c22SToby Isaac   if (!label) {
6743c58f1c22SToby Isaac     ierr = DMCreateLabel(dm, name);CHKERRQ(ierr);
6744c58f1c22SToby Isaac     ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6745c58f1c22SToby Isaac   }
6746c58f1c22SToby Isaac   ierr = DMLabelSetValue(label, point, value);CHKERRQ(ierr);
6747c58f1c22SToby Isaac   PetscFunctionReturn(0);
6748c58f1c22SToby Isaac }
6749c58f1c22SToby Isaac 
6750c58f1c22SToby Isaac /*@C
6751c58f1c22SToby Isaac   DMClearLabelValue - Remove a point from a Sieve Label with given value
6752c58f1c22SToby Isaac 
6753c58f1c22SToby Isaac   Not Collective
6754c58f1c22SToby Isaac 
6755c58f1c22SToby Isaac   Input Parameters:
6756c58f1c22SToby Isaac + dm   - The DM object
6757c58f1c22SToby Isaac . name - The label name
6758c58f1c22SToby Isaac . point - The mesh point
6759c58f1c22SToby Isaac - value - The label value for this point
6760c58f1c22SToby Isaac 
6761c58f1c22SToby Isaac   Output Parameter:
6762c58f1c22SToby Isaac 
6763c58f1c22SToby Isaac   Level: beginner
6764c58f1c22SToby Isaac 
6765c58f1c22SToby Isaac .seealso: DMLabelClearValue(), DMSetLabelValue(), DMGetStratumIS()
6766c58f1c22SToby Isaac @*/
6767c58f1c22SToby Isaac PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value)
6768c58f1c22SToby Isaac {
6769c58f1c22SToby Isaac   DMLabel        label;
6770c58f1c22SToby Isaac   PetscErrorCode ierr;
6771c58f1c22SToby Isaac 
6772c58f1c22SToby Isaac   PetscFunctionBegin;
6773c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6774c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6775c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6776c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6777c58f1c22SToby Isaac   ierr = DMLabelClearValue(label, point, value);CHKERRQ(ierr);
6778c58f1c22SToby Isaac   PetscFunctionReturn(0);
6779c58f1c22SToby Isaac }
6780c58f1c22SToby Isaac 
6781c58f1c22SToby Isaac /*@C
6782c58f1c22SToby Isaac   DMGetLabelSize - Get the number of different integer ids in a Label
6783c58f1c22SToby Isaac 
6784c58f1c22SToby Isaac   Not Collective
6785c58f1c22SToby Isaac 
6786c58f1c22SToby Isaac   Input Parameters:
6787c58f1c22SToby Isaac + dm   - The DM object
6788c58f1c22SToby Isaac - name - The label name
6789c58f1c22SToby Isaac 
6790c58f1c22SToby Isaac   Output Parameter:
6791c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist
6792c58f1c22SToby Isaac 
6793c58f1c22SToby Isaac   Level: beginner
6794c58f1c22SToby Isaac 
6795df813f42SMatthew G. Knepley .seealso: DMLabelGetNumValues(), DMSetLabelValue()
6796c58f1c22SToby Isaac @*/
6797c58f1c22SToby Isaac PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size)
6798c58f1c22SToby Isaac {
6799c58f1c22SToby Isaac   DMLabel        label;
6800c58f1c22SToby Isaac   PetscErrorCode ierr;
6801c58f1c22SToby Isaac 
6802c58f1c22SToby Isaac   PetscFunctionBegin;
6803c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6804c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6805534a8f05SLisandro Dalcin   PetscValidIntPointer(size, 3);
6806c58f1c22SToby Isaac   ierr  = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6807c58f1c22SToby Isaac   *size = 0;
6808c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6809c58f1c22SToby Isaac   ierr = DMLabelGetNumValues(label, size);CHKERRQ(ierr);
6810c58f1c22SToby Isaac   PetscFunctionReturn(0);
6811c58f1c22SToby Isaac }
6812c58f1c22SToby Isaac 
6813c58f1c22SToby Isaac /*@C
6814c58f1c22SToby Isaac   DMGetLabelIdIS - Get the integer ids in a label
6815c58f1c22SToby Isaac 
6816c58f1c22SToby Isaac   Not Collective
6817c58f1c22SToby Isaac 
6818c58f1c22SToby Isaac   Input Parameters:
6819c58f1c22SToby Isaac + mesh - The DM object
6820c58f1c22SToby Isaac - name - The label name
6821c58f1c22SToby Isaac 
6822c58f1c22SToby Isaac   Output Parameter:
6823c58f1c22SToby Isaac . ids - The integer ids, or NULL if the label does not exist
6824c58f1c22SToby Isaac 
6825c58f1c22SToby Isaac   Level: beginner
6826c58f1c22SToby Isaac 
6827c58f1c22SToby Isaac .seealso: DMLabelGetValueIS(), DMGetLabelSize()
6828c58f1c22SToby Isaac @*/
6829c58f1c22SToby Isaac PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids)
6830c58f1c22SToby Isaac {
6831c58f1c22SToby Isaac   DMLabel        label;
6832c58f1c22SToby Isaac   PetscErrorCode ierr;
6833c58f1c22SToby Isaac 
6834c58f1c22SToby Isaac   PetscFunctionBegin;
6835c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6836c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6837c58f1c22SToby Isaac   PetscValidPointer(ids, 3);
6838c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6839c58f1c22SToby Isaac   *ids = NULL;
6840dab2e251SBlaise Bourdin  if (label) {
6841c58f1c22SToby Isaac     ierr = DMLabelGetValueIS(label, ids);CHKERRQ(ierr);
6842dab2e251SBlaise Bourdin   } else {
6843dab2e251SBlaise Bourdin     /* returning an empty IS */
6844dab2e251SBlaise Bourdin     ierr = ISCreateGeneral(PETSC_COMM_SELF,0,NULL,PETSC_USE_POINTER,ids);CHKERRQ(ierr);
6845dab2e251SBlaise Bourdin   }
6846c58f1c22SToby Isaac   PetscFunctionReturn(0);
6847c58f1c22SToby Isaac }
6848c58f1c22SToby Isaac 
6849c58f1c22SToby Isaac /*@C
6850c58f1c22SToby Isaac   DMGetStratumSize - Get the number of points in a label stratum
6851c58f1c22SToby Isaac 
6852c58f1c22SToby Isaac   Not Collective
6853c58f1c22SToby Isaac 
6854c58f1c22SToby Isaac   Input Parameters:
6855c58f1c22SToby Isaac + dm - The DM object
6856c58f1c22SToby Isaac . name - The label name
6857c58f1c22SToby Isaac - value - The stratum value
6858c58f1c22SToby Isaac 
6859c58f1c22SToby Isaac   Output Parameter:
6860c58f1c22SToby Isaac . size - The stratum size
6861c58f1c22SToby Isaac 
6862c58f1c22SToby Isaac   Level: beginner
6863c58f1c22SToby Isaac 
6864c58f1c22SToby Isaac .seealso: DMLabelGetStratumSize(), DMGetLabelSize(), DMGetLabelIds()
6865c58f1c22SToby Isaac @*/
6866c58f1c22SToby Isaac PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size)
6867c58f1c22SToby Isaac {
6868c58f1c22SToby Isaac   DMLabel        label;
6869c58f1c22SToby Isaac   PetscErrorCode ierr;
6870c58f1c22SToby Isaac 
6871c58f1c22SToby Isaac   PetscFunctionBegin;
6872c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6873c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6874534a8f05SLisandro Dalcin   PetscValidIntPointer(size, 4);
6875c58f1c22SToby Isaac   ierr  = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6876c58f1c22SToby Isaac   *size = 0;
6877c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6878c58f1c22SToby Isaac   ierr = DMLabelGetStratumSize(label, value, size);CHKERRQ(ierr);
6879c58f1c22SToby Isaac   PetscFunctionReturn(0);
6880c58f1c22SToby Isaac }
6881c58f1c22SToby Isaac 
6882c58f1c22SToby Isaac /*@C
6883c58f1c22SToby Isaac   DMGetStratumIS - Get the points in a label stratum
6884c58f1c22SToby Isaac 
6885c58f1c22SToby Isaac   Not Collective
6886c58f1c22SToby Isaac 
6887c58f1c22SToby Isaac   Input Parameters:
6888c58f1c22SToby Isaac + dm - The DM object
6889c58f1c22SToby Isaac . name - The label name
6890c58f1c22SToby Isaac - value - The stratum value
6891c58f1c22SToby Isaac 
6892c58f1c22SToby Isaac   Output Parameter:
6893c58f1c22SToby Isaac . points - The stratum points, or NULL if the label does not exist or does not have that value
6894c58f1c22SToby Isaac 
6895c58f1c22SToby Isaac   Level: beginner
6896c58f1c22SToby Isaac 
6897c58f1c22SToby Isaac .seealso: DMLabelGetStratumIS(), DMGetStratumSize()
6898c58f1c22SToby Isaac @*/
6899c58f1c22SToby Isaac PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points)
6900c58f1c22SToby Isaac {
6901c58f1c22SToby Isaac   DMLabel        label;
6902c58f1c22SToby Isaac   PetscErrorCode ierr;
6903c58f1c22SToby Isaac 
6904c58f1c22SToby Isaac   PetscFunctionBegin;
6905c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6906c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6907c58f1c22SToby Isaac   PetscValidPointer(points, 4);
6908c58f1c22SToby Isaac   ierr    = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6909c58f1c22SToby Isaac   *points = NULL;
6910c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6911c58f1c22SToby Isaac   ierr = DMLabelGetStratumIS(label, value, points);CHKERRQ(ierr);
6912c58f1c22SToby Isaac   PetscFunctionReturn(0);
6913c58f1c22SToby Isaac }
6914c58f1c22SToby Isaac 
69154de306b1SToby Isaac /*@C
69169044fa66SMatthew G. Knepley   DMSetStratumIS - Set the points in a label stratum
69174de306b1SToby Isaac 
69184de306b1SToby Isaac   Not Collective
69194de306b1SToby Isaac 
69204de306b1SToby Isaac   Input Parameters:
69214de306b1SToby Isaac + dm - The DM object
69224de306b1SToby Isaac . name - The label name
69234de306b1SToby Isaac . value - The stratum value
69244de306b1SToby Isaac - points - The stratum points
69254de306b1SToby Isaac 
69264de306b1SToby Isaac   Level: beginner
69274de306b1SToby Isaac 
69284de306b1SToby Isaac .seealso: DMLabelSetStratumIS(), DMGetStratumSize()
69294de306b1SToby Isaac @*/
69304de306b1SToby Isaac PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points)
69314de306b1SToby Isaac {
69324de306b1SToby Isaac   DMLabel        label;
69334de306b1SToby Isaac   PetscErrorCode ierr;
69344de306b1SToby Isaac 
69354de306b1SToby Isaac   PetscFunctionBegin;
69364de306b1SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
69374de306b1SToby Isaac   PetscValidCharPointer(name, 2);
69384de306b1SToby Isaac   PetscValidPointer(points, 4);
69394de306b1SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
69404de306b1SToby Isaac   if (!label) PetscFunctionReturn(0);
69414de306b1SToby Isaac   ierr = DMLabelSetStratumIS(label, value, points);CHKERRQ(ierr);
69424de306b1SToby Isaac   PetscFunctionReturn(0);
69434de306b1SToby Isaac }
69444de306b1SToby Isaac 
6945c58f1c22SToby Isaac /*@C
6946c58f1c22SToby Isaac   DMClearLabelStratum - Remove all points from a stratum from a Sieve Label
6947c58f1c22SToby Isaac 
6948c58f1c22SToby Isaac   Not Collective
6949c58f1c22SToby Isaac 
6950c58f1c22SToby Isaac   Input Parameters:
6951c58f1c22SToby Isaac + dm   - The DM object
6952c58f1c22SToby Isaac . name - The label name
6953c58f1c22SToby Isaac - value - The label value for this point
6954c58f1c22SToby Isaac 
6955c58f1c22SToby Isaac   Output Parameter:
6956c58f1c22SToby Isaac 
6957c58f1c22SToby Isaac   Level: beginner
6958c58f1c22SToby Isaac 
6959c58f1c22SToby Isaac .seealso: DMLabelClearStratum(), DMSetLabelValue(), DMGetStratumIS(), DMClearLabelValue()
6960c58f1c22SToby Isaac @*/
6961c58f1c22SToby Isaac PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value)
6962c58f1c22SToby Isaac {
6963c58f1c22SToby Isaac   DMLabel        label;
6964c58f1c22SToby Isaac   PetscErrorCode ierr;
6965c58f1c22SToby Isaac 
6966c58f1c22SToby Isaac   PetscFunctionBegin;
6967c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6968c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6969c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6970c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6971c58f1c22SToby Isaac   ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr);
6972c58f1c22SToby Isaac   PetscFunctionReturn(0);
6973c58f1c22SToby Isaac }
6974c58f1c22SToby Isaac 
6975c58f1c22SToby Isaac /*@
6976c58f1c22SToby Isaac   DMGetNumLabels - Return the number of labels defined by the mesh
6977c58f1c22SToby Isaac 
6978c58f1c22SToby Isaac   Not Collective
6979c58f1c22SToby Isaac 
6980c58f1c22SToby Isaac   Input Parameter:
6981c58f1c22SToby Isaac . dm   - The DM object
6982c58f1c22SToby Isaac 
6983c58f1c22SToby Isaac   Output Parameter:
6984c58f1c22SToby Isaac . numLabels - the number of Labels
6985c58f1c22SToby Isaac 
6986c58f1c22SToby Isaac   Level: intermediate
6987c58f1c22SToby Isaac 
6988c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6989c58f1c22SToby Isaac @*/
6990c58f1c22SToby Isaac PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels)
6991c58f1c22SToby Isaac {
69925d80c0bfSVaclav Hapla   DMLabelLink next = dm->labels;
6993c58f1c22SToby Isaac   PetscInt  n    = 0;
6994c58f1c22SToby Isaac 
6995c58f1c22SToby Isaac   PetscFunctionBegin;
6996c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6997534a8f05SLisandro Dalcin   PetscValidIntPointer(numLabels, 2);
6998c58f1c22SToby Isaac   while (next) {++n; next = next->next;}
6999c58f1c22SToby Isaac   *numLabels = n;
7000c58f1c22SToby Isaac   PetscFunctionReturn(0);
7001c58f1c22SToby Isaac }
7002c58f1c22SToby Isaac 
7003c58f1c22SToby Isaac /*@C
7004c58f1c22SToby Isaac   DMGetLabelName - Return the name of nth label
7005c58f1c22SToby Isaac 
7006c58f1c22SToby Isaac   Not Collective
7007c58f1c22SToby Isaac 
7008c58f1c22SToby Isaac   Input Parameters:
7009c58f1c22SToby Isaac + dm - The DM object
7010c58f1c22SToby Isaac - n  - the label number
7011c58f1c22SToby Isaac 
7012c58f1c22SToby Isaac   Output Parameter:
7013c58f1c22SToby Isaac . name - the label name
7014c58f1c22SToby Isaac 
7015c58f1c22SToby Isaac   Level: intermediate
7016c58f1c22SToby Isaac 
7017c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7018c58f1c22SToby Isaac @*/
7019c58f1c22SToby Isaac PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name)
7020c58f1c22SToby Isaac {
70215d80c0bfSVaclav Hapla   DMLabelLink    next = dm->labels;
7022c58f1c22SToby Isaac   PetscInt       l    = 0;
7023d67d17b1SMatthew G. Knepley   PetscErrorCode ierr;
7024c58f1c22SToby Isaac 
7025c58f1c22SToby Isaac   PetscFunctionBegin;
7026c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7027c58f1c22SToby Isaac   PetscValidPointer(name, 3);
7028c58f1c22SToby Isaac   while (next) {
7029c58f1c22SToby Isaac     if (l == n) {
7030d67d17b1SMatthew G. Knepley       ierr = PetscObjectGetName((PetscObject) next->label, name);CHKERRQ(ierr);
7031c58f1c22SToby Isaac       PetscFunctionReturn(0);
7032c58f1c22SToby Isaac     }
7033c58f1c22SToby Isaac     ++l;
7034c58f1c22SToby Isaac     next = next->next;
7035c58f1c22SToby Isaac   }
7036c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n);
7037c58f1c22SToby Isaac }
7038c58f1c22SToby Isaac 
7039c58f1c22SToby Isaac /*@C
7040c58f1c22SToby Isaac   DMHasLabel - Determine whether the mesh has a label of a given name
7041c58f1c22SToby Isaac 
7042c58f1c22SToby Isaac   Not Collective
7043c58f1c22SToby Isaac 
7044c58f1c22SToby Isaac   Input Parameters:
7045c58f1c22SToby Isaac + dm   - The DM object
7046c58f1c22SToby Isaac - name - The label name
7047c58f1c22SToby Isaac 
7048c58f1c22SToby Isaac   Output Parameter:
7049c58f1c22SToby Isaac . hasLabel - PETSC_TRUE if the label is present
7050c58f1c22SToby Isaac 
7051c58f1c22SToby Isaac   Level: intermediate
7052c58f1c22SToby Isaac 
7053c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7054c58f1c22SToby Isaac @*/
7055c58f1c22SToby Isaac PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel)
7056c58f1c22SToby Isaac {
70575d80c0bfSVaclav Hapla   DMLabelLink    next = dm->labels;
7058d67d17b1SMatthew G. Knepley   const char    *lname;
7059c58f1c22SToby Isaac   PetscErrorCode ierr;
7060c58f1c22SToby Isaac 
7061c58f1c22SToby Isaac   PetscFunctionBegin;
7062c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7063c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
7064534a8f05SLisandro Dalcin   PetscValidBoolPointer(hasLabel, 3);
7065c58f1c22SToby Isaac   *hasLabel = PETSC_FALSE;
7066c58f1c22SToby Isaac   while (next) {
7067d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
7068d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, hasLabel);CHKERRQ(ierr);
7069c58f1c22SToby Isaac     if (*hasLabel) break;
7070c58f1c22SToby Isaac     next = next->next;
7071c58f1c22SToby Isaac   }
7072c58f1c22SToby Isaac   PetscFunctionReturn(0);
7073c58f1c22SToby Isaac }
7074c58f1c22SToby Isaac 
7075c58f1c22SToby Isaac /*@C
7076c58f1c22SToby Isaac   DMGetLabel - Return the label of a given name, or NULL
7077c58f1c22SToby Isaac 
7078c58f1c22SToby Isaac   Not Collective
7079c58f1c22SToby Isaac 
7080c58f1c22SToby Isaac   Input Parameters:
7081c58f1c22SToby Isaac + dm   - The DM object
7082c58f1c22SToby Isaac - name - The label name
7083c58f1c22SToby Isaac 
7084c58f1c22SToby Isaac   Output Parameter:
7085c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent
7086c58f1c22SToby Isaac 
7087c58f1c22SToby Isaac   Level: intermediate
7088c58f1c22SToby Isaac 
7089c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7090c58f1c22SToby Isaac @*/
7091c58f1c22SToby Isaac PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label)
7092c58f1c22SToby Isaac {
70935d80c0bfSVaclav Hapla   DMLabelLink    next = dm->labels;
7094c58f1c22SToby Isaac   PetscBool      hasLabel;
7095d67d17b1SMatthew G. Knepley   const char    *lname;
7096c58f1c22SToby Isaac   PetscErrorCode ierr;
7097c58f1c22SToby Isaac 
7098c58f1c22SToby Isaac   PetscFunctionBegin;
7099c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7100c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
7101c58f1c22SToby Isaac   PetscValidPointer(label, 3);
7102c58f1c22SToby Isaac   *label = NULL;
7103c58f1c22SToby Isaac   while (next) {
7104d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
7105d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr);
7106c58f1c22SToby Isaac     if (hasLabel) {
7107c58f1c22SToby Isaac       *label = next->label;
7108c58f1c22SToby Isaac       break;
7109c58f1c22SToby Isaac     }
7110c58f1c22SToby Isaac     next = next->next;
7111c58f1c22SToby Isaac   }
7112c58f1c22SToby Isaac   PetscFunctionReturn(0);
7113c58f1c22SToby Isaac }
7114c58f1c22SToby Isaac 
7115c58f1c22SToby Isaac /*@C
7116c58f1c22SToby Isaac   DMGetLabelByNum - Return the nth label
7117c58f1c22SToby Isaac 
7118c58f1c22SToby Isaac   Not Collective
7119c58f1c22SToby Isaac 
7120c58f1c22SToby Isaac   Input Parameters:
7121c58f1c22SToby Isaac + dm - The DM object
7122c58f1c22SToby Isaac - n  - the label number
7123c58f1c22SToby Isaac 
7124c58f1c22SToby Isaac   Output Parameter:
7125c58f1c22SToby Isaac . label - the label
7126c58f1c22SToby Isaac 
7127c58f1c22SToby Isaac   Level: intermediate
7128c58f1c22SToby Isaac 
7129c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7130c58f1c22SToby Isaac @*/
7131c58f1c22SToby Isaac PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label)
7132c58f1c22SToby Isaac {
71335d80c0bfSVaclav Hapla   DMLabelLink next = dm->labels;
7134c58f1c22SToby Isaac   PetscInt    l    = 0;
7135c58f1c22SToby Isaac 
7136c58f1c22SToby Isaac   PetscFunctionBegin;
7137c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7138c58f1c22SToby Isaac   PetscValidPointer(label, 3);
7139c58f1c22SToby Isaac   while (next) {
7140c58f1c22SToby Isaac     if (l == n) {
7141c58f1c22SToby Isaac       *label = next->label;
7142c58f1c22SToby Isaac       PetscFunctionReturn(0);
7143c58f1c22SToby Isaac     }
7144c58f1c22SToby Isaac     ++l;
7145c58f1c22SToby Isaac     next = next->next;
7146c58f1c22SToby Isaac   }
7147c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n);
7148c58f1c22SToby Isaac }
7149c58f1c22SToby Isaac 
7150c58f1c22SToby Isaac /*@C
7151c58f1c22SToby Isaac   DMAddLabel - Add the label to this mesh
7152c58f1c22SToby Isaac 
7153c58f1c22SToby Isaac   Not Collective
7154c58f1c22SToby Isaac 
7155c58f1c22SToby Isaac   Input Parameters:
7156c58f1c22SToby Isaac + dm   - The DM object
7157c58f1c22SToby Isaac - label - The DMLabel
7158c58f1c22SToby Isaac 
7159c58f1c22SToby Isaac   Level: developer
7160c58f1c22SToby Isaac 
7161c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7162c58f1c22SToby Isaac @*/
7163c58f1c22SToby Isaac PetscErrorCode DMAddLabel(DM dm, DMLabel label)
7164c58f1c22SToby Isaac {
71655d80c0bfSVaclav Hapla   DMLabelLink    l, *p, tmpLabel;
7166c58f1c22SToby Isaac   PetscBool      hasLabel;
7167d67d17b1SMatthew G. Knepley   const char    *lname;
71685d80c0bfSVaclav Hapla   PetscBool      flg;
7169c58f1c22SToby Isaac   PetscErrorCode ierr;
7170c58f1c22SToby Isaac 
7171c58f1c22SToby Isaac   PetscFunctionBegin;
7172c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7173d67d17b1SMatthew G. Knepley   ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr);
7174d67d17b1SMatthew G. Knepley   ierr = DMHasLabel(dm, lname, &hasLabel);CHKERRQ(ierr);
7175d67d17b1SMatthew G. Knepley   if (hasLabel) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname);
7176c58f1c22SToby Isaac   ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr);
7177c58f1c22SToby Isaac   tmpLabel->label  = label;
7178c58f1c22SToby Isaac   tmpLabel->output = PETSC_TRUE;
71795d80c0bfSVaclav Hapla   for (p=&dm->labels; (l=*p); p=&l->next) {}
71805d80c0bfSVaclav Hapla   *p = tmpLabel;
718108f633c4SVaclav Hapla   ierr = PetscObjectReference((PetscObject)label);CHKERRQ(ierr);
71825d80c0bfSVaclav Hapla   ierr = PetscStrcmp(lname, "depth", &flg);CHKERRQ(ierr);
71835d80c0bfSVaclav Hapla   if (flg) dm->depthLabel = label;
7184c58f1c22SToby Isaac   PetscFunctionReturn(0);
7185c58f1c22SToby Isaac }
7186c58f1c22SToby Isaac 
7187c58f1c22SToby Isaac /*@C
7188e5472504SVaclav Hapla   DMRemoveLabel - Remove the label given by name from this mesh
7189c58f1c22SToby Isaac 
7190c58f1c22SToby Isaac   Not Collective
7191c58f1c22SToby Isaac 
7192c58f1c22SToby Isaac   Input Parameters:
7193c58f1c22SToby Isaac + dm   - The DM object
7194c58f1c22SToby Isaac - name - The label name
7195c58f1c22SToby Isaac 
7196c58f1c22SToby Isaac   Output Parameter:
7197c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent
7198c58f1c22SToby Isaac 
7199c58f1c22SToby Isaac   Level: developer
7200c58f1c22SToby Isaac 
7201e5472504SVaclav Hapla   Notes:
7202e5472504SVaclav Hapla   DMRemoveLabel(dm,name,NULL) removes the label from dm and calls
7203e5472504SVaclav Hapla   DMLabelDestroy() on the label.
7204e5472504SVaclav Hapla 
7205e5472504SVaclav Hapla   DMRemoveLabel(dm,name,&label) removes the label from dm, but it DOES NOT
7206e5472504SVaclav Hapla   call DMLabelDestroy(). Instead, the label is returned and the user is
7207e5472504SVaclav Hapla   responsible of calling DMLabelDestroy() at some point.
7208e5472504SVaclav Hapla 
7209e5472504SVaclav Hapla .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabel(), DMGetLabelValue(), DMSetLabelValue(), DMLabelDestroy(), DMRemoveLabelBySelf()
7210c58f1c22SToby Isaac @*/
7211c58f1c22SToby Isaac PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label)
7212c58f1c22SToby Isaac {
721395d578d6SVaclav Hapla   DMLabelLink    link, *pnext;
7214c58f1c22SToby Isaac   PetscBool      hasLabel;
7215d67d17b1SMatthew G. Knepley   const char    *lname;
7216c58f1c22SToby Isaac   PetscErrorCode ierr;
7217c58f1c22SToby Isaac 
7218c58f1c22SToby Isaac   PetscFunctionBegin;
7219c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7220e5472504SVaclav Hapla   PetscValidCharPointer(name, 2);
7221e5472504SVaclav Hapla   if (label) {
7222e5472504SVaclav Hapla     PetscValidPointer(label, 3);
7223c58f1c22SToby Isaac     *label = NULL;
7224e5472504SVaclav Hapla   }
72255d80c0bfSVaclav Hapla   for (pnext=&dm->labels; (link=*pnext); pnext=&link->next) {
722695d578d6SVaclav Hapla     ierr = PetscObjectGetName((PetscObject) link->label, &lname);CHKERRQ(ierr);
7227d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr);
7228c58f1c22SToby Isaac     if (hasLabel) {
722995d578d6SVaclav Hapla       *pnext = link->next; /* Remove from list */
7230c58f1c22SToby Isaac       ierr = PetscStrcmp(name, "depth", &hasLabel);CHKERRQ(ierr);
723195d578d6SVaclav Hapla       if (hasLabel) dm->depthLabel = NULL;
723295d578d6SVaclav Hapla       if (label) *label = link->label;
723395d578d6SVaclav Hapla       else       {ierr = DMLabelDestroy(&link->label);CHKERRQ(ierr);}
723495d578d6SVaclav Hapla       ierr = PetscFree(link);CHKERRQ(ierr);
7235c58f1c22SToby Isaac       break;
7236c58f1c22SToby Isaac     }
7237c58f1c22SToby Isaac   }
7238c58f1c22SToby Isaac   PetscFunctionReturn(0);
7239c58f1c22SToby Isaac }
7240c58f1c22SToby Isaac 
7241306894acSVaclav Hapla /*@
7242306894acSVaclav Hapla   DMRemoveLabelBySelf - Remove the label from this mesh
7243306894acSVaclav Hapla 
7244306894acSVaclav Hapla   Not Collective
7245306894acSVaclav Hapla 
7246306894acSVaclav Hapla   Input Parameters:
7247306894acSVaclav Hapla + dm   - The DM object
7248306894acSVaclav Hapla . label - (Optional) The DMLabel to be removed from the DM
7249306894acSVaclav Hapla - failNotFound - Should it fail if the label is not found in the DM?
7250306894acSVaclav Hapla 
7251306894acSVaclav Hapla   Level: developer
7252306894acSVaclav Hapla 
7253306894acSVaclav Hapla   Notes:
7254306894acSVaclav Hapla   Only exactly the same instance is removed if found, name match is ignored.
7255306894acSVaclav Hapla   If the DM has an exclusive reference to the label, it gets destroyed and
7256306894acSVaclav Hapla   *label nullified.
7257306894acSVaclav Hapla 
7258306894acSVaclav Hapla .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabel() DMGetLabelValue(), DMSetLabelValue(), DMLabelDestroy(), DMRemoveLabel()
7259306894acSVaclav Hapla @*/
7260306894acSVaclav Hapla PetscErrorCode DMRemoveLabelBySelf(DM dm, DMLabel *label, PetscBool failNotFound)
7261306894acSVaclav Hapla {
726243e45a93SVaclav Hapla   DMLabelLink    link, *pnext;
7263306894acSVaclav Hapla   PetscBool      hasLabel = PETSC_FALSE;
7264306894acSVaclav Hapla   PetscErrorCode ierr;
7265306894acSVaclav Hapla 
7266306894acSVaclav Hapla   PetscFunctionBegin;
7267306894acSVaclav Hapla   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7268306894acSVaclav Hapla   PetscValidPointer(label, 2);
7269f39a9ae0SVaclav Hapla   if (!*label && !failNotFound) PetscFunctionReturn(0);
7270306894acSVaclav Hapla   PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 2);
7271306894acSVaclav Hapla   PetscValidLogicalCollectiveBool(dm,failNotFound,3);
72725d80c0bfSVaclav Hapla   for (pnext=&dm->labels; (link=*pnext); pnext=&link->next) {
727343e45a93SVaclav Hapla     if (*label == link->label) {
7274306894acSVaclav Hapla       hasLabel = PETSC_TRUE;
727543e45a93SVaclav Hapla       *pnext = link->next; /* Remove from list */
7276306894acSVaclav Hapla       if (*label == dm->depthLabel) dm->depthLabel = NULL;
727743e45a93SVaclav Hapla       if (((PetscObject) link->label)->refct < 2) *label = NULL; /* nullify if exclusive reference */
727843e45a93SVaclav Hapla       ierr = DMLabelDestroy(&link->label);CHKERRQ(ierr);
727943e45a93SVaclav Hapla       ierr = PetscFree(link);CHKERRQ(ierr);
7280306894acSVaclav Hapla       break;
7281306894acSVaclav Hapla     }
7282306894acSVaclav Hapla   }
7283306894acSVaclav Hapla   if (!hasLabel && failNotFound) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Given label not found in DM");
7284306894acSVaclav Hapla   PetscFunctionReturn(0);
7285306894acSVaclav Hapla }
7286306894acSVaclav Hapla 
7287c58f1c22SToby Isaac /*@C
7288c58f1c22SToby Isaac   DMGetLabelOutput - Get the output flag for a given label
7289c58f1c22SToby Isaac 
7290c58f1c22SToby Isaac   Not Collective
7291c58f1c22SToby Isaac 
7292c58f1c22SToby Isaac   Input Parameters:
7293c58f1c22SToby Isaac + dm   - The DM object
7294c58f1c22SToby Isaac - name - The label name
7295c58f1c22SToby Isaac 
7296c58f1c22SToby Isaac   Output Parameter:
7297c58f1c22SToby Isaac . output - The flag for output
7298c58f1c22SToby Isaac 
7299c58f1c22SToby Isaac   Level: developer
7300c58f1c22SToby Isaac 
7301c58f1c22SToby Isaac .seealso: DMSetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7302c58f1c22SToby Isaac @*/
7303c58f1c22SToby Isaac PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output)
7304c58f1c22SToby Isaac {
73055d80c0bfSVaclav Hapla   DMLabelLink    next = dm->labels;
7306d67d17b1SMatthew G. Knepley   const char    *lname;
7307c58f1c22SToby Isaac   PetscErrorCode ierr;
7308c58f1c22SToby Isaac 
7309c58f1c22SToby Isaac   PetscFunctionBegin;
7310c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7311c58f1c22SToby Isaac   PetscValidPointer(name, 2);
7312c58f1c22SToby Isaac   PetscValidPointer(output, 3);
7313c58f1c22SToby Isaac   while (next) {
7314c58f1c22SToby Isaac     PetscBool flg;
7315c58f1c22SToby Isaac 
7316d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
7317d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr);
7318c58f1c22SToby Isaac     if (flg) {*output = next->output; PetscFunctionReturn(0);}
7319c58f1c22SToby Isaac     next = next->next;
7320c58f1c22SToby Isaac   }
7321c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name);
7322c58f1c22SToby Isaac }
7323c58f1c22SToby Isaac 
7324c58f1c22SToby Isaac /*@C
7325c58f1c22SToby Isaac   DMSetLabelOutput - Set the output flag for a given label
7326c58f1c22SToby Isaac 
7327c58f1c22SToby Isaac   Not Collective
7328c58f1c22SToby Isaac 
7329c58f1c22SToby Isaac   Input Parameters:
7330c58f1c22SToby Isaac + dm     - The DM object
7331c58f1c22SToby Isaac . name   - The label name
7332c58f1c22SToby Isaac - output - The flag for output
7333c58f1c22SToby Isaac 
7334c58f1c22SToby Isaac   Level: developer
7335c58f1c22SToby Isaac 
7336c58f1c22SToby Isaac .seealso: DMGetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7337c58f1c22SToby Isaac @*/
7338c58f1c22SToby Isaac PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output)
7339c58f1c22SToby Isaac {
73405d80c0bfSVaclav Hapla   DMLabelLink    next = dm->labels;
7341d67d17b1SMatthew G. Knepley   const char    *lname;
7342c58f1c22SToby Isaac   PetscErrorCode ierr;
7343c58f1c22SToby Isaac 
7344c58f1c22SToby Isaac   PetscFunctionBegin;
7345c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7346534a8f05SLisandro Dalcin   PetscValidCharPointer(name, 2);
7347c58f1c22SToby Isaac   while (next) {
7348c58f1c22SToby Isaac     PetscBool flg;
7349c58f1c22SToby Isaac 
7350d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
7351d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr);
7352c58f1c22SToby Isaac     if (flg) {next->output = output; PetscFunctionReturn(0);}
7353c58f1c22SToby Isaac     next = next->next;
7354c58f1c22SToby Isaac   }
7355c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name);
7356c58f1c22SToby Isaac }
7357c58f1c22SToby Isaac 
7358c58f1c22SToby Isaac /*@
7359c58f1c22SToby Isaac   DMCopyLabels - Copy labels from one mesh to another with a superset of the points
7360c58f1c22SToby Isaac 
7361d083f849SBarry Smith   Collective on dmA
7362c58f1c22SToby Isaac 
7363c58f1c22SToby Isaac   Input Parameter:
73645d80c0bfSVaclav Hapla + dmA - The DM object with initial labels
73652e17dfb7SMatthew G. Knepley . dmB - The DM object with copied labels
73665d80c0bfSVaclav Hapla . mode - Copy labels by pointers (PETSC_OWN_POINTER) or duplicate them (PETSC_COPY_VALUES)
73675d80c0bfSVaclav Hapla - all  - Copy all labels including "depth" and "dim" (PETSC_TRUE) which are otherwise ignored (PETSC_FALSE)
7368c58f1c22SToby Isaac 
7369c58f1c22SToby Isaac   Level: intermediate
7370c58f1c22SToby Isaac 
7371c58f1c22SToby Isaac   Note: This is typically used when interpolating or otherwise adding to a mesh
7372c58f1c22SToby Isaac 
73735d80c0bfSVaclav Hapla .seealso: DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMGetCoordinateSection(), DMShareLabels()
7374c58f1c22SToby Isaac @*/
73755d80c0bfSVaclav Hapla PetscErrorCode DMCopyLabels(DM dmA, DM dmB, PetscCopyMode mode, PetscBool all)
7376c58f1c22SToby Isaac {
7377c58f1c22SToby Isaac   DMLabel        label, labelNew;
7378c58f1c22SToby Isaac   const char    *name;
7379c58f1c22SToby Isaac   PetscBool      flg;
73805d80c0bfSVaclav Hapla   DMLabelLink    link;
73815d80c0bfSVaclav Hapla   PetscErrorCode ierr;
7382c58f1c22SToby Isaac 
73835d80c0bfSVaclav Hapla   PetscFunctionBegin;
73845d80c0bfSVaclav Hapla   PetscValidHeaderSpecific(dmA, DM_CLASSID, 1);
73855d80c0bfSVaclav Hapla   PetscValidHeaderSpecific(dmB, DM_CLASSID, 2);
73865d80c0bfSVaclav Hapla   PetscValidLogicalCollectiveEnum(dmA, mode,3);
73875d80c0bfSVaclav Hapla   PetscValidLogicalCollectiveBool(dmA, all, 4);
73885d80c0bfSVaclav Hapla   if (mode==PETSC_USE_POINTER) SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_SUP, "PETSC_USE_POINTER not supported for objects");
73895d80c0bfSVaclav Hapla   if (dmA == dmB) PetscFunctionReturn(0);
73905d80c0bfSVaclav Hapla   for (link=dmA->labels; link; link=link->next) {
73915d80c0bfSVaclav Hapla     label=link->label;
73925d80c0bfSVaclav Hapla     ierr = PetscObjectGetName((PetscObject)label, &name);CHKERRQ(ierr);
73935d80c0bfSVaclav Hapla     if (!all) {
7394c58f1c22SToby Isaac       ierr = PetscStrcmp(name, "depth", &flg);CHKERRQ(ierr);
7395c58f1c22SToby Isaac       if (flg) continue;
73967d5acc75SStefano Zampini       ierr = PetscStrcmp(name, "dim", &flg);CHKERRQ(ierr);
73977d5acc75SStefano Zampini       if (flg) continue;
73985d80c0bfSVaclav Hapla     } else {
73995d80c0bfSVaclav Hapla       dmB->depthLabel = dmA->depthLabel;
74005d80c0bfSVaclav Hapla     }
74015d80c0bfSVaclav Hapla     if (mode==PETSC_COPY_VALUES) {
7402c58f1c22SToby Isaac       ierr = DMLabelDuplicate(label, &labelNew);CHKERRQ(ierr);
74035d80c0bfSVaclav Hapla     } else {
74045d80c0bfSVaclav Hapla       labelNew = label;
74055d80c0bfSVaclav Hapla     }
7406c58f1c22SToby Isaac     ierr = DMAddLabel(dmB, labelNew);CHKERRQ(ierr);
74075d80c0bfSVaclav Hapla     if (mode==PETSC_COPY_VALUES) {ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr);}
7408c58f1c22SToby Isaac   }
7409c58f1c22SToby Isaac   PetscFunctionReturn(0);
7410c58f1c22SToby Isaac }
7411a8fb8f29SToby Isaac 
7412a8fb8f29SToby Isaac /*@
7413a8fb8f29SToby Isaac   DMGetCoarseDM - Get the coarse mesh from which this was obtained by refinement
7414a8fb8f29SToby Isaac 
7415a8fb8f29SToby Isaac   Input Parameter:
7416a8fb8f29SToby Isaac . dm - The DM object
7417a8fb8f29SToby Isaac 
7418a8fb8f29SToby Isaac   Output Parameter:
7419a8fb8f29SToby Isaac . cdm - The coarse DM
7420a8fb8f29SToby Isaac 
7421a8fb8f29SToby Isaac   Level: intermediate
7422a8fb8f29SToby Isaac 
7423a8fb8f29SToby Isaac .seealso: DMSetCoarseDM()
7424a8fb8f29SToby Isaac @*/
7425a8fb8f29SToby Isaac PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm)
7426a8fb8f29SToby Isaac {
7427a8fb8f29SToby Isaac   PetscFunctionBegin;
7428a8fb8f29SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7429a8fb8f29SToby Isaac   PetscValidPointer(cdm, 2);
7430a8fb8f29SToby Isaac   *cdm = dm->coarseMesh;
7431a8fb8f29SToby Isaac   PetscFunctionReturn(0);
7432a8fb8f29SToby Isaac }
7433a8fb8f29SToby Isaac 
7434a8fb8f29SToby Isaac /*@
7435a8fb8f29SToby Isaac   DMSetCoarseDM - Set the coarse mesh from which this was obtained by refinement
7436a8fb8f29SToby Isaac 
7437a8fb8f29SToby Isaac   Input Parameters:
7438a8fb8f29SToby Isaac + dm - The DM object
7439a8fb8f29SToby Isaac - cdm - The coarse DM
7440a8fb8f29SToby Isaac 
7441a8fb8f29SToby Isaac   Level: intermediate
7442a8fb8f29SToby Isaac 
7443a8fb8f29SToby Isaac .seealso: DMGetCoarseDM()
7444a8fb8f29SToby Isaac @*/
7445a8fb8f29SToby Isaac PetscErrorCode DMSetCoarseDM(DM dm, DM cdm)
7446a8fb8f29SToby Isaac {
7447a8fb8f29SToby Isaac   PetscErrorCode ierr;
7448a8fb8f29SToby Isaac 
7449a8fb8f29SToby Isaac   PetscFunctionBegin;
7450a8fb8f29SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7451a8fb8f29SToby Isaac   if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2);
7452a8fb8f29SToby Isaac   ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr);
7453a8fb8f29SToby Isaac   ierr = DMDestroy(&dm->coarseMesh);CHKERRQ(ierr);
7454a8fb8f29SToby Isaac   dm->coarseMesh = cdm;
7455a8fb8f29SToby Isaac   PetscFunctionReturn(0);
7456a8fb8f29SToby Isaac }
7457a8fb8f29SToby Isaac 
745888bdff64SToby Isaac /*@
745988bdff64SToby Isaac   DMGetFineDM - Get the fine mesh from which this was obtained by refinement
746088bdff64SToby Isaac 
746188bdff64SToby Isaac   Input Parameter:
746288bdff64SToby Isaac . dm - The DM object
746388bdff64SToby Isaac 
746488bdff64SToby Isaac   Output Parameter:
746588bdff64SToby Isaac . fdm - The fine DM
746688bdff64SToby Isaac 
746788bdff64SToby Isaac   Level: intermediate
746888bdff64SToby Isaac 
746988bdff64SToby Isaac .seealso: DMSetFineDM()
747088bdff64SToby Isaac @*/
747188bdff64SToby Isaac PetscErrorCode DMGetFineDM(DM dm, DM *fdm)
747288bdff64SToby Isaac {
747388bdff64SToby Isaac   PetscFunctionBegin;
747488bdff64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
747588bdff64SToby Isaac   PetscValidPointer(fdm, 2);
747688bdff64SToby Isaac   *fdm = dm->fineMesh;
747788bdff64SToby Isaac   PetscFunctionReturn(0);
747888bdff64SToby Isaac }
747988bdff64SToby Isaac 
748088bdff64SToby Isaac /*@
748188bdff64SToby Isaac   DMSetFineDM - Set the fine mesh from which this was obtained by refinement
748288bdff64SToby Isaac 
748388bdff64SToby Isaac   Input Parameters:
748488bdff64SToby Isaac + dm - The DM object
748588bdff64SToby Isaac - fdm - The fine DM
748688bdff64SToby Isaac 
748788bdff64SToby Isaac   Level: intermediate
748888bdff64SToby Isaac 
748988bdff64SToby Isaac .seealso: DMGetFineDM()
749088bdff64SToby Isaac @*/
749188bdff64SToby Isaac PetscErrorCode DMSetFineDM(DM dm, DM fdm)
749288bdff64SToby Isaac {
749388bdff64SToby Isaac   PetscErrorCode ierr;
749488bdff64SToby Isaac 
749588bdff64SToby Isaac   PetscFunctionBegin;
749688bdff64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
749788bdff64SToby Isaac   if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2);
749888bdff64SToby Isaac   ierr = PetscObjectReference((PetscObject)fdm);CHKERRQ(ierr);
749988bdff64SToby Isaac   ierr = DMDestroy(&dm->fineMesh);CHKERRQ(ierr);
750088bdff64SToby Isaac   dm->fineMesh = fdm;
750188bdff64SToby Isaac   PetscFunctionReturn(0);
750288bdff64SToby Isaac }
750388bdff64SToby Isaac 
7504a6ba4734SToby Isaac /*=== DMBoundary code ===*/
7505a6ba4734SToby Isaac 
7506a6ba4734SToby Isaac PetscErrorCode DMCopyBoundary(DM dm, DM dmNew)
7507a6ba4734SToby Isaac {
7508e5e52638SMatthew G. Knepley   PetscInt       d;
7509a6ba4734SToby Isaac   PetscErrorCode ierr;
7510a6ba4734SToby Isaac 
7511a6ba4734SToby Isaac   PetscFunctionBegin;
7512e5e52638SMatthew G. Knepley   for (d = 0; d < dm->Nds; ++d) {
7513e5e52638SMatthew G. Knepley     ierr = PetscDSCopyBoundary(dm->probs[d].ds, dmNew->probs[d].ds);CHKERRQ(ierr);
7514e5e52638SMatthew G. Knepley   }
7515a6ba4734SToby Isaac   PetscFunctionReturn(0);
7516a6ba4734SToby Isaac }
7517a6ba4734SToby Isaac 
7518a6ba4734SToby Isaac /*@C
7519a6ba4734SToby Isaac   DMAddBoundary - Add a boundary condition to the model
7520a6ba4734SToby Isaac 
7521a6ba4734SToby Isaac   Input Parameters:
75224c258f51SMatthew G. Knepley + dm          - The DM, with a PetscDS that matches the problem being constrained
7523f971fd6bSMatthew G. Knepley . type        - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
7524a6ba4734SToby Isaac . name        - The BC name
7525a6ba4734SToby Isaac . labelname   - The label defining constrained points
7526a6ba4734SToby Isaac . field       - The field to constrain
7527e8ecbf3fSStefano Zampini . numcomps    - The number of constrained field components (0 will constrain all fields)
7528a6ba4734SToby Isaac . comps       - An array of constrained component numbers
7529a6ba4734SToby Isaac . bcFunc      - A pointwise function giving boundary values
7530a6ba4734SToby Isaac . numids      - The number of DMLabel ids for constrained points
7531a6ba4734SToby Isaac . ids         - An array of ids for constrained points
7532a6ba4734SToby Isaac - ctx         - An optional user context for bcFunc
7533a6ba4734SToby Isaac 
7534a6ba4734SToby Isaac   Options Database Keys:
7535a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
7536a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
7537a6ba4734SToby Isaac 
7538a6ba4734SToby Isaac   Level: developer
7539a6ba4734SToby Isaac 
7540a6ba4734SToby Isaac .seealso: DMGetBoundary()
7541a6ba4734SToby Isaac @*/
7542a30ec4eaSSatish 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)
7543a6ba4734SToby Isaac {
7544e5e52638SMatthew G. Knepley   PetscDS        ds;
7545a6ba4734SToby Isaac   PetscErrorCode ierr;
7546a6ba4734SToby Isaac 
7547a6ba4734SToby Isaac   PetscFunctionBegin;
7548a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7549e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7550e5e52638SMatthew G. Knepley   ierr = PetscDSAddBoundary(ds, type,name, labelname, field, numcomps, comps, bcFunc, numids, ids, ctx);CHKERRQ(ierr);
7551a6ba4734SToby Isaac   PetscFunctionReturn(0);
7552a6ba4734SToby Isaac }
7553a6ba4734SToby Isaac 
7554a6ba4734SToby Isaac /*@
7555a6ba4734SToby Isaac   DMGetNumBoundary - Get the number of registered BC
7556a6ba4734SToby Isaac 
7557a6ba4734SToby Isaac   Input Parameters:
7558a6ba4734SToby Isaac . dm - The mesh object
7559a6ba4734SToby Isaac 
7560a6ba4734SToby Isaac   Output Parameters:
7561a6ba4734SToby Isaac . numBd - The number of BC
7562a6ba4734SToby Isaac 
7563a6ba4734SToby Isaac   Level: intermediate
7564a6ba4734SToby Isaac 
7565a6ba4734SToby Isaac .seealso: DMAddBoundary(), DMGetBoundary()
7566a6ba4734SToby Isaac @*/
7567a6ba4734SToby Isaac PetscErrorCode DMGetNumBoundary(DM dm, PetscInt *numBd)
7568a6ba4734SToby Isaac {
7569e5e52638SMatthew G. Knepley   PetscDS        ds;
757058ebd649SToby Isaac   PetscErrorCode ierr;
7571a6ba4734SToby Isaac 
7572a6ba4734SToby Isaac   PetscFunctionBegin;
7573a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7574e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7575e5e52638SMatthew G. Knepley   ierr = PetscDSGetNumBoundary(ds, numBd);CHKERRQ(ierr);
7576a6ba4734SToby Isaac   PetscFunctionReturn(0);
7577a6ba4734SToby Isaac }
7578a6ba4734SToby Isaac 
7579a6ba4734SToby Isaac /*@C
75801c531cf8SMatthew G. Knepley   DMGetBoundary - Get a model boundary condition
7581a6ba4734SToby Isaac 
7582a6ba4734SToby Isaac   Input Parameters:
7583a6ba4734SToby Isaac + dm          - The mesh object
7584a6ba4734SToby Isaac - bd          - The BC number
7585a6ba4734SToby Isaac 
7586a6ba4734SToby Isaac   Output Parameters:
7587f971fd6bSMatthew G. Knepley + type        - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
7588a6ba4734SToby Isaac . name        - The BC name
7589a6ba4734SToby Isaac . labelname   - The label defining constrained points
7590a6ba4734SToby Isaac . field       - The field to constrain
7591a6ba4734SToby Isaac . numcomps    - The number of constrained field components
7592a6ba4734SToby Isaac . comps       - An array of constrained component numbers
7593a6ba4734SToby Isaac . bcFunc      - A pointwise function giving boundary values
7594a6ba4734SToby Isaac . numids      - The number of DMLabel ids for constrained points
7595a6ba4734SToby Isaac . ids         - An array of ids for constrained points
7596a6ba4734SToby Isaac - ctx         - An optional user context for bcFunc
7597a6ba4734SToby Isaac 
7598a6ba4734SToby Isaac   Options Database Keys:
7599a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
7600a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
7601a6ba4734SToby Isaac 
7602a6ba4734SToby Isaac   Level: developer
7603a6ba4734SToby Isaac 
7604a6ba4734SToby Isaac .seealso: DMAddBoundary()
7605a6ba4734SToby Isaac @*/
7606a30ec4eaSSatish 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)
7607a6ba4734SToby Isaac {
7608e5e52638SMatthew G. Knepley   PetscDS        ds;
760958ebd649SToby Isaac   PetscErrorCode ierr;
7610a6ba4734SToby Isaac 
7611a6ba4734SToby Isaac   PetscFunctionBegin;
7612a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7613e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7614e5e52638SMatthew G. Knepley   ierr = PetscDSGetBoundary(ds, bd, type, name, labelname, field, numcomps, comps, func, numids, ids, ctx);CHKERRQ(ierr);
7615a6ba4734SToby Isaac   PetscFunctionReturn(0);
7616a6ba4734SToby Isaac }
7617a6ba4734SToby Isaac 
7618e6f8dbb6SToby Isaac static PetscErrorCode DMPopulateBoundary(DM dm)
7619e6f8dbb6SToby Isaac {
7620e5e52638SMatthew G. Knepley   PetscDS        ds;
7621dff059c6SToby Isaac   DMBoundary    *lastnext;
7622e6f8dbb6SToby Isaac   DSBoundary     dsbound;
7623e6f8dbb6SToby Isaac   PetscErrorCode ierr;
7624e6f8dbb6SToby Isaac 
7625e6f8dbb6SToby Isaac   PetscFunctionBegin;
7626e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7627e5e52638SMatthew G. Knepley   dsbound = ds->boundary;
762847a1f5adSToby Isaac   if (dm->boundary) {
762947a1f5adSToby Isaac     DMBoundary next = dm->boundary;
763047a1f5adSToby Isaac 
763147a1f5adSToby Isaac     /* quick check to see if the PetscDS has changed */
763247a1f5adSToby Isaac     if (next->dsboundary == dsbound) PetscFunctionReturn(0);
763347a1f5adSToby Isaac     /* the PetscDS has changed: tear down and rebuild */
763447a1f5adSToby Isaac     while (next) {
763547a1f5adSToby Isaac       DMBoundary b = next;
763647a1f5adSToby Isaac 
763747a1f5adSToby Isaac       next = b->next;
763847a1f5adSToby Isaac       ierr = PetscFree(b);CHKERRQ(ierr);
7639a6ba4734SToby Isaac     }
764047a1f5adSToby Isaac     dm->boundary = NULL;
7641a6ba4734SToby Isaac   }
764247a1f5adSToby Isaac 
7643dff059c6SToby Isaac   lastnext = &(dm->boundary);
7644e6f8dbb6SToby Isaac   while (dsbound) {
7645e6f8dbb6SToby Isaac     DMBoundary dmbound;
7646e6f8dbb6SToby Isaac 
7647e6f8dbb6SToby Isaac     ierr = PetscNew(&dmbound);CHKERRQ(ierr);
7648e6f8dbb6SToby Isaac     dmbound->dsboundary = dsbound;
7649e6f8dbb6SToby Isaac     ierr = DMGetLabel(dm, dsbound->labelname, &(dmbound->label));CHKERRQ(ierr);
7650994fe344SLisandro 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);}
765147a1f5adSToby Isaac     /* push on the back instead of the front so that it is in the same order as in the PetscDS */
7652dff059c6SToby Isaac     *lastnext = dmbound;
7653dff059c6SToby Isaac     lastnext = &(dmbound->next);
7654dff059c6SToby Isaac     dsbound = dsbound->next;
7655a6ba4734SToby Isaac   }
7656a6ba4734SToby Isaac   PetscFunctionReturn(0);
7657a6ba4734SToby Isaac }
7658a6ba4734SToby Isaac 
7659a6ba4734SToby Isaac PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd)
7660a6ba4734SToby Isaac {
7661b95f2879SToby Isaac   DMBoundary     b;
7662a6ba4734SToby Isaac   PetscErrorCode ierr;
7663a6ba4734SToby Isaac 
7664a6ba4734SToby Isaac   PetscFunctionBegin;
7665a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7666534a8f05SLisandro Dalcin   PetscValidBoolPointer(isBd, 3);
7667a6ba4734SToby Isaac   *isBd = PETSC_FALSE;
7668e6f8dbb6SToby Isaac   ierr = DMPopulateBoundary(dm);CHKERRQ(ierr);
7669b95f2879SToby Isaac   b = dm->boundary;
7670a6ba4734SToby Isaac   while (b && !(*isBd)) {
7671e6f8dbb6SToby Isaac     DMLabel    label = b->label;
7672e6f8dbb6SToby Isaac     DSBoundary dsb = b->dsboundary;
76733424c85cSToby Isaac 
76743424c85cSToby Isaac     if (label) {
7675a6ba4734SToby Isaac       PetscInt i;
7676a6ba4734SToby Isaac 
7677e6f8dbb6SToby Isaac       for (i = 0; i < dsb->numids && !(*isBd); ++i) {
7678e6f8dbb6SToby Isaac         ierr = DMLabelStratumHasPoint(label, dsb->ids[i], point, isBd);CHKERRQ(ierr);
7679a6ba4734SToby Isaac       }
7680a6ba4734SToby Isaac     }
7681a6ba4734SToby Isaac     b = b->next;
7682a6ba4734SToby Isaac   }
7683a6ba4734SToby Isaac   PetscFunctionReturn(0);
7684a6ba4734SToby Isaac }
76854d6f44ffSToby Isaac 
76864d6f44ffSToby Isaac /*@C
76874d6f44ffSToby Isaac   DMProjectFunction - This projects the given function into the function space provided.
76884d6f44ffSToby Isaac 
76894d6f44ffSToby Isaac   Input Parameters:
76904d6f44ffSToby Isaac + dm      - The DM
76910709b2feSToby Isaac . time    - The time
76924d6f44ffSToby Isaac . funcs   - The coordinate functions to evaluate, one per field
76934d6f44ffSToby Isaac . ctxs    - Optional array of contexts to pass to each coordinate function.  ctxs itself may be null.
76944d6f44ffSToby Isaac - mode    - The insertion mode for values
76954d6f44ffSToby Isaac 
76964d6f44ffSToby Isaac   Output Parameter:
76974d6f44ffSToby Isaac . X - vector
76984d6f44ffSToby Isaac 
76994d6f44ffSToby Isaac    Calling sequence of func:
77000709b2feSToby Isaac $    func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx);
77014d6f44ffSToby Isaac 
77024d6f44ffSToby Isaac +  dim - The spatial dimension
77034d6f44ffSToby Isaac .  x   - The coordinates
77044d6f44ffSToby Isaac .  Nf  - The number of fields
77054d6f44ffSToby Isaac .  u   - The output field values
77064d6f44ffSToby Isaac -  ctx - optional user-defined function context
77074d6f44ffSToby Isaac 
77084d6f44ffSToby Isaac   Level: developer
77094d6f44ffSToby Isaac 
77102716604bSToby Isaac .seealso: DMComputeL2Diff()
77114d6f44ffSToby Isaac @*/
77120709b2feSToby Isaac PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X)
77134d6f44ffSToby Isaac {
77144d6f44ffSToby Isaac   Vec            localX;
77154d6f44ffSToby Isaac   PetscErrorCode ierr;
77164d6f44ffSToby Isaac 
77174d6f44ffSToby Isaac   PetscFunctionBegin;
77184d6f44ffSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
77194d6f44ffSToby Isaac   ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr);
77200709b2feSToby Isaac   ierr = DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr);
77214d6f44ffSToby Isaac   ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr);
77224d6f44ffSToby Isaac   ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr);
77234d6f44ffSToby Isaac   ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr);
77244d6f44ffSToby Isaac   PetscFunctionReturn(0);
77254d6f44ffSToby Isaac }
77264d6f44ffSToby Isaac 
77270709b2feSToby Isaac PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX)
77284d6f44ffSToby Isaac {
77294d6f44ffSToby Isaac   PetscErrorCode ierr;
77304d6f44ffSToby Isaac 
77314d6f44ffSToby Isaac   PetscFunctionBegin;
77324d6f44ffSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
77334d6f44ffSToby Isaac   PetscValidHeaderSpecific(localX,VEC_CLASSID,5);
77340918c465SMatthew G. Knepley   if (!dm->ops->projectfunctionlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLocal",((PetscObject)dm)->type_name);
77350709b2feSToby Isaac   ierr = (dm->ops->projectfunctionlocal) (dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr);
77364d6f44ffSToby Isaac   PetscFunctionReturn(0);
77374d6f44ffSToby Isaac }
77384d6f44ffSToby Isaac 
77392c53366bSMatthew 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)
77402c53366bSMatthew G. Knepley {
77412c53366bSMatthew G. Knepley   Vec            localX;
77422c53366bSMatthew G. Knepley   PetscErrorCode ierr;
77432c53366bSMatthew G. Knepley 
77442c53366bSMatthew G. Knepley   PetscFunctionBegin;
77452c53366bSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
77462c53366bSMatthew G. Knepley   ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr);
77472c53366bSMatthew G. Knepley   ierr = DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr);
77482c53366bSMatthew G. Knepley   ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr);
77492c53366bSMatthew G. Knepley   ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr);
77502c53366bSMatthew G. Knepley   ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr);
77512c53366bSMatthew G. Knepley   PetscFunctionReturn(0);
77522c53366bSMatthew G. Knepley }
77532c53366bSMatthew G. Knepley 
77541c531cf8SMatthew 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)
77554d6f44ffSToby Isaac {
77564d6f44ffSToby Isaac   PetscErrorCode ierr;
77574d6f44ffSToby Isaac 
77584d6f44ffSToby Isaac   PetscFunctionBegin;
77594d6f44ffSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
77604d6f44ffSToby Isaac   PetscValidHeaderSpecific(localX,VEC_CLASSID,5);
77610918c465SMatthew G. Knepley   if (!dm->ops->projectfunctionlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLabelLocal",((PetscObject)dm)->type_name);
77621c531cf8SMatthew G. Knepley   ierr = (dm->ops->projectfunctionlabellocal) (dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr);
77634d6f44ffSToby Isaac   PetscFunctionReturn(0);
77644d6f44ffSToby Isaac }
77652716604bSToby Isaac 
77668c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal(DM dm, PetscReal time, Vec localU,
77678c6c5593SMatthew G. Knepley                                    void (**funcs)(PetscInt, PetscInt, PetscInt,
77688c6c5593SMatthew G. Knepley                                                   const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
77698c6c5593SMatthew G. Knepley                                                   const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
7770191494d9SMatthew G. Knepley                                                   PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]),
77718c6c5593SMatthew G. Knepley                                    InsertMode mode, Vec localX)
77728c6c5593SMatthew G. Knepley {
77738c6c5593SMatthew G. Knepley   PetscErrorCode ierr;
77748c6c5593SMatthew G. Knepley 
77758c6c5593SMatthew G. Knepley   PetscFunctionBegin;
77768c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
77778c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localU,VEC_CLASSID,3);
77788c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localX,VEC_CLASSID,6);
77790918c465SMatthew G. Knepley   if (!dm->ops->projectfieldlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name);
77808c6c5593SMatthew G. Knepley   ierr = (dm->ops->projectfieldlocal) (dm, time, localU, funcs, mode, localX);CHKERRQ(ierr);
77818c6c5593SMatthew G. Knepley   PetscFunctionReturn(0);
77828c6c5593SMatthew G. Knepley }
77838c6c5593SMatthew G. Knepley 
77841c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU,
77858c6c5593SMatthew G. Knepley                                         void (**funcs)(PetscInt, PetscInt, PetscInt,
77868c6c5593SMatthew G. Knepley                                                        const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
77878c6c5593SMatthew G. Knepley                                                        const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
7788191494d9SMatthew G. Knepley                                                        PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]),
77898c6c5593SMatthew G. Knepley                                         InsertMode mode, Vec localX)
77908c6c5593SMatthew G. Knepley {
77918c6c5593SMatthew G. Knepley   PetscErrorCode ierr;
77928c6c5593SMatthew G. Knepley 
77938c6c5593SMatthew G. Knepley   PetscFunctionBegin;
77948c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
77958c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localU,VEC_CLASSID,6);
77968c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localX,VEC_CLASSID,9);
77970918c465SMatthew G. Knepley   if (!dm->ops->projectfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name);
77981c531cf8SMatthew G. Knepley   ierr = (dm->ops->projectfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX);CHKERRQ(ierr);
77998c6c5593SMatthew G. Knepley   PetscFunctionReturn(0);
78008c6c5593SMatthew G. Knepley }
78018c6c5593SMatthew G. Knepley 
78022716604bSToby Isaac /*@C
78032716604bSToby Isaac   DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h.
78042716604bSToby Isaac 
78052716604bSToby Isaac   Input Parameters:
78062716604bSToby Isaac + dm    - The DM
78070709b2feSToby Isaac . time  - The time
78082716604bSToby Isaac . funcs - The functions to evaluate for each field component
78092716604bSToby Isaac . ctxs  - Optional array of contexts to pass to each function, or NULL.
7810574a98acSMatthew G. Knepley - X     - The coefficient vector u_h, a global vector
78112716604bSToby Isaac 
78122716604bSToby Isaac   Output Parameter:
78132716604bSToby Isaac . diff - The diff ||u - u_h||_2
78142716604bSToby Isaac 
78152716604bSToby Isaac   Level: developer
78162716604bSToby Isaac 
78171189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff()
78182716604bSToby Isaac @*/
78190709b2feSToby Isaac PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff)
78202716604bSToby Isaac {
78212716604bSToby Isaac   PetscErrorCode ierr;
78222716604bSToby Isaac 
78232716604bSToby Isaac   PetscFunctionBegin;
78242716604bSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7825b698f381SToby Isaac   PetscValidHeaderSpecific(X,VEC_CLASSID,5);
78260918c465SMatthew G. Knepley   if (!dm->ops->computel2diff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2Diff",((PetscObject)dm)->type_name);
78270709b2feSToby Isaac   ierr = (dm->ops->computel2diff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr);
78282716604bSToby Isaac   PetscFunctionReturn(0);
78292716604bSToby Isaac }
7830b698f381SToby Isaac 
7831b698f381SToby Isaac /*@C
7832b698f381SToby Isaac   DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h.
7833b698f381SToby Isaac 
7834d083f849SBarry Smith   Collective on dm
7835d083f849SBarry Smith 
7836b698f381SToby Isaac   Input Parameters:
7837b698f381SToby Isaac + dm    - The DM
7838b698f381SToby Isaac , time  - The time
7839b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component
7840b698f381SToby Isaac . ctxs  - Optional array of contexts to pass to each function, or NULL.
7841574a98acSMatthew G. Knepley . X     - The coefficient vector u_h, a global vector
7842b698f381SToby Isaac - n     - The vector to project along
7843b698f381SToby Isaac 
7844b698f381SToby Isaac   Output Parameter:
7845b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2
7846b698f381SToby Isaac 
7847b698f381SToby Isaac   Level: developer
7848b698f381SToby Isaac 
7849b698f381SToby Isaac .seealso: DMProjectFunction(), DMComputeL2Diff()
7850b698f381SToby Isaac @*/
7851b698f381SToby 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)
7852b698f381SToby Isaac {
7853b698f381SToby Isaac   PetscErrorCode ierr;
7854b698f381SToby Isaac 
7855b698f381SToby Isaac   PetscFunctionBegin;
7856b698f381SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7857b698f381SToby Isaac   PetscValidHeaderSpecific(X,VEC_CLASSID,5);
7858b698f381SToby Isaac   if (!dm->ops->computel2gradientdiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2GradientDiff",((PetscObject)dm)->type_name);
7859b698f381SToby Isaac   ierr = (dm->ops->computel2gradientdiff)(dm,time,funcs,ctxs,X,n,diff);CHKERRQ(ierr);
7860b698f381SToby Isaac   PetscFunctionReturn(0);
7861b698f381SToby Isaac }
7862b698f381SToby Isaac 
78632a16baeaSToby Isaac /*@C
78642a16baeaSToby Isaac   DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components.
78652a16baeaSToby Isaac 
7866d083f849SBarry Smith   Collective on dm
7867d083f849SBarry Smith 
78682a16baeaSToby Isaac   Input Parameters:
78692a16baeaSToby Isaac + dm    - The DM
78702a16baeaSToby Isaac . time  - The time
78712a16baeaSToby Isaac . funcs - The functions to evaluate for each field component
78722a16baeaSToby Isaac . ctxs  - Optional array of contexts to pass to each function, or NULL.
7873574a98acSMatthew G. Knepley - X     - The coefficient vector u_h, a global vector
78742a16baeaSToby Isaac 
78752a16baeaSToby Isaac   Output Parameter:
78762a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2
78772a16baeaSToby Isaac 
78782a16baeaSToby Isaac   Level: developer
78792a16baeaSToby Isaac 
78801189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff()
78812a16baeaSToby Isaac @*/
78821189c1efSToby Isaac PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[])
78832a16baeaSToby Isaac {
78842a16baeaSToby Isaac   PetscErrorCode ierr;
78852a16baeaSToby Isaac 
78862a16baeaSToby Isaac   PetscFunctionBegin;
78872a16baeaSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
78882a16baeaSToby Isaac   PetscValidHeaderSpecific(X,VEC_CLASSID,5);
78890918c465SMatthew G. Knepley   if (!dm->ops->computel2fielddiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2FieldDiff",((PetscObject)dm)->type_name);
78902a16baeaSToby Isaac   ierr = (dm->ops->computel2fielddiff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr);
78912a16baeaSToby Isaac   PetscFunctionReturn(0);
78922a16baeaSToby Isaac }
78932a16baeaSToby Isaac 
7894df0b854cSToby Isaac /*@C
7895df0b854cSToby Isaac   DMAdaptLabel - Adapt a dm based on a label with values interpreted as coarsening and refining flags.  Specific implementations of DM maybe have
7896cd3c525cSToby Isaac                  specialized flags, but all implementations should accept flag values DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN.
7897df0b854cSToby Isaac 
7898df0b854cSToby Isaac   Collective on dm
7899df0b854cSToby Isaac 
7900df0b854cSToby Isaac   Input parameters:
7901df0b854cSToby Isaac + dm - the pre-adaptation DM object
7902a1b0c543SToby Isaac - label - label with the flags
7903df0b854cSToby Isaac 
7904df0b854cSToby Isaac   Output parameters:
79050d1cd5e0SMatthew G. Knepley . dmAdapt - the adapted DM object: may be NULL if an adapted DM could not be produced.
7906df0b854cSToby Isaac 
7907df0b854cSToby Isaac   Level: intermediate
79080d1cd5e0SMatthew G. Knepley 
79090d1cd5e0SMatthew G. Knepley .seealso: DMAdaptMetric(), DMCoarsen(), DMRefine()
7910df0b854cSToby Isaac @*/
79110d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptLabel(DM dm, DMLabel label, DM *dmAdapt)
7912df0b854cSToby Isaac {
7913df0b854cSToby Isaac   PetscErrorCode ierr;
7914df0b854cSToby Isaac 
7915df0b854cSToby Isaac   PetscFunctionBegin;
7916df0b854cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7917a1b0c543SToby Isaac   PetscValidPointer(label,2);
79180d1cd5e0SMatthew G. Knepley   PetscValidPointer(dmAdapt,3);
79190d1cd5e0SMatthew G. Knepley   *dmAdapt = NULL;
79206f25b0d8SLisandro Dalcin   if (!dm->ops->adaptlabel) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptLabel",((PetscObject)dm)->type_name);
79210d1cd5e0SMatthew G. Knepley   ierr = (dm->ops->adaptlabel)(dm, label, dmAdapt);CHKERRQ(ierr);
79220d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
79230d1cd5e0SMatthew G. Knepley }
79240d1cd5e0SMatthew G. Knepley 
79250d1cd5e0SMatthew G. Knepley /*@C
79260d1cd5e0SMatthew G. Knepley   DMAdaptMetric - Generates a mesh adapted to the specified metric field using the pragmatic library.
79270d1cd5e0SMatthew G. Knepley 
79280d1cd5e0SMatthew G. Knepley   Input Parameters:
79290d1cd5e0SMatthew G. Knepley + dm - The DM object
79300d1cd5e0SMatthew G. Knepley . metric - The metric to which the mesh is adapted, defined vertex-wise.
79316f25b0d8SLisandro 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_".
79320d1cd5e0SMatthew G. Knepley 
79330d1cd5e0SMatthew G. Knepley   Output Parameter:
79340d1cd5e0SMatthew G. Knepley . dmAdapt  - Pointer to the DM object containing the adapted mesh
79350d1cd5e0SMatthew G. Knepley 
79360d1cd5e0SMatthew G. Knepley   Note: The label in the adapted mesh will be registered under the name of the input DMLabel object
79370d1cd5e0SMatthew G. Knepley 
79380d1cd5e0SMatthew G. Knepley   Level: advanced
79390d1cd5e0SMatthew G. Knepley 
79400d1cd5e0SMatthew G. Knepley .seealso: DMAdaptLabel(), DMCoarsen(), DMRefine()
79410d1cd5e0SMatthew G. Knepley @*/
79420d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptMetric(DM dm, Vec metric, DMLabel bdLabel, DM *dmAdapt)
79430d1cd5e0SMatthew G. Knepley {
79440d1cd5e0SMatthew G. Knepley   PetscErrorCode ierr;
79450d1cd5e0SMatthew G. Knepley 
79460d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
79470d1cd5e0SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
79480d1cd5e0SMatthew G. Knepley   PetscValidHeaderSpecific(metric, VEC_CLASSID, 2);
79490d1cd5e0SMatthew G. Knepley   if (bdLabel) PetscValidPointer(bdLabel, 3);
79500d1cd5e0SMatthew G. Knepley   PetscValidPointer(dmAdapt, 4);
79516f25b0d8SLisandro Dalcin   *dmAdapt = NULL;
79526f25b0d8SLisandro Dalcin   if (!dm->ops->adaptmetric) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptMetric",((PetscObject)dm)->type_name);
79530d1cd5e0SMatthew G. Knepley   ierr = (dm->ops->adaptmetric)(dm, metric, bdLabel, dmAdapt);CHKERRQ(ierr);
7954df0b854cSToby Isaac   PetscFunctionReturn(0);
7955df0b854cSToby Isaac }
7956c4088d22SMatthew G. Knepley 
7957502a2867SDave May /*@C
7958502a2867SDave May  DMGetNeighbors - Gets an array containing the MPI rank of all the processes neighbors
7959502a2867SDave May 
7960502a2867SDave May  Not Collective
7961502a2867SDave May 
7962502a2867SDave May  Input Parameter:
7963502a2867SDave May  . dm    - The DM
7964502a2867SDave May 
7965502a2867SDave May  Output Parameter:
7966502a2867SDave May  . nranks - the number of neighbours
7967502a2867SDave May  . ranks - the neighbors ranks
7968502a2867SDave May 
7969502a2867SDave May  Notes:
7970502a2867SDave May  Do not free the array, it is freed when the DM is destroyed.
7971502a2867SDave May 
7972502a2867SDave May  Level: beginner
7973502a2867SDave May 
7974dec1416fSJunchao Zhang  .seealso: DMDAGetNeighbors(), PetscSFGetRootRanks()
7975502a2867SDave May @*/
7976502a2867SDave May PetscErrorCode DMGetNeighbors(DM dm,PetscInt *nranks,const PetscMPIInt *ranks[])
7977502a2867SDave May {
7978502a2867SDave May   PetscErrorCode ierr;
7979502a2867SDave May 
7980502a2867SDave May   PetscFunctionBegin;
7981502a2867SDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
79820918c465SMatthew G. Knepley   if (!dm->ops->getneighbors) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMGetNeighbors",((PetscObject)dm)->type_name);
7983502a2867SDave May   ierr = (dm->ops->getneighbors)(dm,nranks,ranks);CHKERRQ(ierr);
7984502a2867SDave May   PetscFunctionReturn(0);
7985502a2867SDave May }
7986502a2867SDave May 
7987531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */
7988531c7667SBarry Smith 
7989531c7667SBarry Smith /*
7990531c7667SBarry Smith     Converts the input vector to a ghosted vector and then calls the standard coloring code.
7991531c7667SBarry Smith     This has be a different function because it requires DM which is not defined in the Mat library
7992531c7667SBarry Smith */
7993531c7667SBarry Smith PetscErrorCode  MatFDColoringApply_AIJDM(Mat J,MatFDColoring coloring,Vec x1,void *sctx)
7994531c7667SBarry Smith {
7995531c7667SBarry Smith   PetscErrorCode ierr;
7996531c7667SBarry Smith 
7997531c7667SBarry Smith   PetscFunctionBegin;
7998531c7667SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
7999531c7667SBarry Smith     Vec x1local;
8000531c7667SBarry Smith     DM  dm;
8001531c7667SBarry Smith     ierr = MatGetDM(J,&dm);CHKERRQ(ierr);
8002531c7667SBarry Smith     if (!dm) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_INCOMP,"IS_COLORING_LOCAL requires a DM");
8003531c7667SBarry Smith     ierr = DMGetLocalVector(dm,&x1local);CHKERRQ(ierr);
8004531c7667SBarry Smith     ierr = DMGlobalToLocalBegin(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr);
8005531c7667SBarry Smith     ierr = DMGlobalToLocalEnd(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr);
8006531c7667SBarry Smith     x1   = x1local;
8007531c7667SBarry Smith   }
8008531c7667SBarry Smith   ierr = MatFDColoringApply_AIJ(J,coloring,x1,sctx);CHKERRQ(ierr);
8009531c7667SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
8010531c7667SBarry Smith     DM  dm;
8011531c7667SBarry Smith     ierr = MatGetDM(J,&dm);CHKERRQ(ierr);
8012531c7667SBarry Smith     ierr = DMRestoreLocalVector(dm,&x1);CHKERRQ(ierr);
8013531c7667SBarry Smith   }
8014531c7667SBarry Smith   PetscFunctionReturn(0);
8015531c7667SBarry Smith }
8016531c7667SBarry Smith 
8017531c7667SBarry Smith /*@
8018531c7667SBarry Smith     MatFDColoringUseDM - allows a MatFDColoring object to use the DM associated with the matrix to use a IS_COLORING_LOCAL coloring
8019531c7667SBarry Smith 
8020531c7667SBarry Smith     Input Parameter:
8021531c7667SBarry Smith .    coloring - the MatFDColoring object
8022531c7667SBarry Smith 
802395452b02SPatrick Sanan     Developer Notes:
802495452b02SPatrick Sanan     this routine exists because the PETSc Mat library does not know about the DM objects
8025531c7667SBarry Smith 
80261b266c99SBarry Smith     Level: advanced
80271b266c99SBarry Smith 
8028531c7667SBarry Smith .seealso: MatFDColoring, MatFDColoringCreate(), ISColoringType
8029531c7667SBarry Smith @*/
8030531c7667SBarry Smith PetscErrorCode  MatFDColoringUseDM(Mat coloring,MatFDColoring fdcoloring)
8031531c7667SBarry Smith {
8032531c7667SBarry Smith   PetscFunctionBegin;
8033531c7667SBarry Smith   coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM;
8034531c7667SBarry Smith   PetscFunctionReturn(0);
8035531c7667SBarry Smith }
80368320bc6fSPatrick Sanan 
80378320bc6fSPatrick Sanan /*@
80388320bc6fSPatrick Sanan     DMGetCompatibility - determine if two DMs are compatible
80398320bc6fSPatrick Sanan 
80408320bc6fSPatrick Sanan     Collective
80418320bc6fSPatrick Sanan 
80428320bc6fSPatrick Sanan     Input Parameters:
80438320bc6fSPatrick Sanan +    dm - the first DM
80448320bc6fSPatrick Sanan -    dm2 - the second DM
80458320bc6fSPatrick Sanan 
80468320bc6fSPatrick Sanan     Output Parameters:
80478320bc6fSPatrick Sanan +    compatible - whether or not the two DMs are compatible
80488320bc6fSPatrick Sanan -    set - whether or not the compatible value was set
80498320bc6fSPatrick Sanan 
80508320bc6fSPatrick Sanan     Notes:
80518320bc6fSPatrick Sanan     Two DMs are deemed compatible if they represent the same parallel decomposition
80523d862458SPatrick Sanan     of the same topology. This implies that the section (field data) on one
80538320bc6fSPatrick Sanan     "makes sense" with respect to the topology and parallel decomposition of the other.
80543d862458SPatrick Sanan     Loosely speaking, compatible DMs represent the same domain and parallel
80553d862458SPatrick Sanan     decomposition, but hold different data.
80568320bc6fSPatrick Sanan 
80578320bc6fSPatrick Sanan     Typically, one would confirm compatibility if intending to simultaneously iterate
80588320bc6fSPatrick Sanan     over a pair of vectors obtained from different DMs.
80598320bc6fSPatrick Sanan 
80608320bc6fSPatrick Sanan     For example, two DMDA objects are compatible if they have the same local
80618320bc6fSPatrick Sanan     and global sizes and the same stencil width. They can have different numbers
80628320bc6fSPatrick Sanan     of degrees of freedom per node. Thus, one could use the node numbering from
80638320bc6fSPatrick Sanan     either DM in bounds for a loop over vectors derived from either DM.
80648320bc6fSPatrick Sanan 
80658320bc6fSPatrick Sanan     Consider the operation of summing data living on a 2-dof DMDA to data living
80668320bc6fSPatrick Sanan     on a 1-dof DMDA, which should be compatible, as in the following snippet.
80678320bc6fSPatrick Sanan .vb
80688320bc6fSPatrick Sanan   ...
80698320bc6fSPatrick Sanan   ierr = DMGetCompatibility(da1,da2,&compatible,&set);CHKERRQ(ierr);
80708320bc6fSPatrick Sanan   if (set && compatible)  {
80718320bc6fSPatrick Sanan     ierr = DMDAVecGetArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr);
80728320bc6fSPatrick Sanan     ierr = DMDAVecGetArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr);
80733d862458SPatrick Sanan     ierr = DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL);CHKERRQ(ierr);
80748320bc6fSPatrick Sanan     for (j=y; j<y+n; ++j) {
80758320bc6fSPatrick Sanan       for (i=x; i<x+m, ++i) {
80768320bc6fSPatrick Sanan         arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1];
80778320bc6fSPatrick Sanan       }
80788320bc6fSPatrick Sanan     }
80798320bc6fSPatrick Sanan     ierr = DMDAVecRestoreArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr);
80808320bc6fSPatrick Sanan     ierr = DMDAVecRestoreArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr);
80818320bc6fSPatrick Sanan   } else {
80828320bc6fSPatrick Sanan     SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible");
80838320bc6fSPatrick Sanan   }
80848320bc6fSPatrick Sanan   ...
80858320bc6fSPatrick Sanan .ve
80868320bc6fSPatrick Sanan 
80878320bc6fSPatrick Sanan     Checking compatibility might be expensive for a given implementation of DM,
80888320bc6fSPatrick Sanan     or might be impossible to unambiguously confirm or deny. For this reason,
80898320bc6fSPatrick Sanan     this function may decline to determine compatibility, and hence users should
80908320bc6fSPatrick Sanan     always check the "set" output parameter.
80918320bc6fSPatrick Sanan 
80928320bc6fSPatrick Sanan     A DM is always compatible with itself.
80938320bc6fSPatrick Sanan 
80948320bc6fSPatrick Sanan     In the current implementation, DMs which live on "unequal" communicators
80958320bc6fSPatrick Sanan     (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed
80968320bc6fSPatrick Sanan     incompatible.
80978320bc6fSPatrick Sanan 
80988320bc6fSPatrick Sanan     This function is labeled "Collective," as information about all subdomains
80998320bc6fSPatrick Sanan     is required on each rank. However, in DM implementations which store all this
81008320bc6fSPatrick Sanan     information locally, this function may be merely "Logically Collective".
81018320bc6fSPatrick Sanan 
81028320bc6fSPatrick Sanan     Developer Notes:
81033d862458SPatrick Sanan     Compatibility is assumed to be a symmetric concept; DM A is compatible with DM B
81043d862458SPatrick Sanan     iff B is compatible with A. Thus, this function checks the implementations
81058320bc6fSPatrick Sanan     of both dm and dm2 (if they are of different types), attempting to determine
81068320bc6fSPatrick Sanan     compatibility. It is left to DM implementers to ensure that symmetry is
81078320bc6fSPatrick Sanan     preserved. The simplest way to do this is, when implementing type-specific
81083d862458SPatrick Sanan     logic for this function, is to check for existing logic in the implementation
81093d862458SPatrick Sanan     of other DM types and let *set = PETSC_FALSE if found.
81108320bc6fSPatrick Sanan 
81118320bc6fSPatrick Sanan     Level: advanced
81128320bc6fSPatrick Sanan 
81133d862458SPatrick Sanan .seealso: DM, DMDACreateCompatibleDMDA(), DMStagCreateCompatibleDMStag()
81148320bc6fSPatrick Sanan @*/
81158320bc6fSPatrick Sanan 
81168320bc6fSPatrick Sanan PetscErrorCode DMGetCompatibility(DM dm,DM dm2,PetscBool *compatible,PetscBool *set)
81178320bc6fSPatrick Sanan {
81188320bc6fSPatrick Sanan   PetscErrorCode ierr;
81198320bc6fSPatrick Sanan   PetscMPIInt    compareResult;
81208320bc6fSPatrick Sanan   DMType         type,type2;
81218320bc6fSPatrick Sanan   PetscBool      sameType;
81228320bc6fSPatrick Sanan 
81238320bc6fSPatrick Sanan   PetscFunctionBegin;
81248320bc6fSPatrick Sanan   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
81258320bc6fSPatrick Sanan   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
81268320bc6fSPatrick Sanan 
81278320bc6fSPatrick Sanan   /* Declare a DM compatible with itself */
81288320bc6fSPatrick Sanan   if (dm == dm2) {
81298320bc6fSPatrick Sanan     *set = PETSC_TRUE;
81308320bc6fSPatrick Sanan     *compatible = PETSC_TRUE;
81318320bc6fSPatrick Sanan     PetscFunctionReturn(0);
81328320bc6fSPatrick Sanan   }
81338320bc6fSPatrick Sanan 
81348320bc6fSPatrick Sanan   /* Declare a DM incompatible with a DM that lives on an "unequal"
81358320bc6fSPatrick Sanan      communicator. Note that this does not preclude compatibility with
81368320bc6fSPatrick Sanan      DMs living on "congruent" or "similar" communicators, but this must be
81378320bc6fSPatrick Sanan      determined by the implementation-specific logic */
81388320bc6fSPatrick Sanan   ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dm),PetscObjectComm((PetscObject)dm2),&compareResult);CHKERRQ(ierr);
81398320bc6fSPatrick Sanan   if (compareResult == MPI_UNEQUAL) {
81408320bc6fSPatrick Sanan     *set = PETSC_TRUE;
81418320bc6fSPatrick Sanan     *compatible = PETSC_FALSE;
81428320bc6fSPatrick Sanan     PetscFunctionReturn(0);
81438320bc6fSPatrick Sanan   }
81448320bc6fSPatrick Sanan 
81458320bc6fSPatrick Sanan   /* Pass to the implementation-specific routine, if one exists. */
81468320bc6fSPatrick Sanan   if (dm->ops->getcompatibility) {
81478320bc6fSPatrick Sanan     ierr = (*dm->ops->getcompatibility)(dm,dm2,compatible,set);CHKERRQ(ierr);
8148b9d85ea2SLisandro Dalcin     if (*set) PetscFunctionReturn(0);
81498320bc6fSPatrick Sanan   }
81508320bc6fSPatrick Sanan 
81518320bc6fSPatrick Sanan   /* If dm and dm2 are of different types, then attempt to check compatibility
81528320bc6fSPatrick Sanan      with an implementation of this function from dm2 */
81538320bc6fSPatrick Sanan   ierr = DMGetType(dm,&type);CHKERRQ(ierr);
81548320bc6fSPatrick Sanan   ierr = DMGetType(dm2,&type2);CHKERRQ(ierr);
81558320bc6fSPatrick Sanan   ierr = PetscStrcmp(type,type2,&sameType);CHKERRQ(ierr);
81568320bc6fSPatrick Sanan   if (!sameType && dm2->ops->getcompatibility) {
81578320bc6fSPatrick Sanan     ierr = (*dm2->ops->getcompatibility)(dm2,dm,compatible,set);CHKERRQ(ierr); /* Note argument order */
81588320bc6fSPatrick Sanan   } else {
81598320bc6fSPatrick Sanan     *set = PETSC_FALSE;
81608320bc6fSPatrick Sanan   }
81618320bc6fSPatrick Sanan   PetscFunctionReturn(0);
81628320bc6fSPatrick Sanan }
8163c0f0dcc3SMatthew G. Knepley 
8164c0f0dcc3SMatthew G. Knepley /*@C
8165c0f0dcc3SMatthew G. Knepley   DMMonitorSet - Sets an ADDITIONAL function that is to be used after a solve to monitor discretization performance.
8166c0f0dcc3SMatthew G. Knepley 
8167c0f0dcc3SMatthew G. Knepley   Logically Collective on DM
8168c0f0dcc3SMatthew G. Knepley 
8169c0f0dcc3SMatthew G. Knepley   Input Parameters:
8170c0f0dcc3SMatthew G. Knepley + DM - the DM
8171c0f0dcc3SMatthew G. Knepley . f - the monitor function
8172c0f0dcc3SMatthew G. Knepley . mctx - [optional] user-defined context for private data for the monitor routine (use NULL if no context is desired)
8173c0f0dcc3SMatthew G. Knepley - monitordestroy - [optional] routine that frees monitor context (may be NULL)
8174c0f0dcc3SMatthew G. Knepley 
8175c0f0dcc3SMatthew G. Knepley   Options Database Keys:
8176c0f0dcc3SMatthew G. Knepley - -dm_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to DMMonitorSet(), but
8177c0f0dcc3SMatthew G. Knepley                             does not cancel those set via the options database.
8178c0f0dcc3SMatthew G. Knepley 
8179c0f0dcc3SMatthew G. Knepley   Notes:
8180c0f0dcc3SMatthew G. Knepley   Several different monitoring routines may be set by calling
8181c0f0dcc3SMatthew G. Knepley   DMMonitorSet() multiple times; all will be called in the
8182c0f0dcc3SMatthew G. Knepley   order in which they were set.
8183c0f0dcc3SMatthew G. Knepley 
8184c0f0dcc3SMatthew G. Knepley   Fortran Notes:
8185c0f0dcc3SMatthew G. Knepley   Only a single monitor function can be set for each DM object
8186c0f0dcc3SMatthew G. Knepley 
8187c0f0dcc3SMatthew G. Knepley   Level: intermediate
8188c0f0dcc3SMatthew G. Knepley 
8189c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorCancel()
8190c0f0dcc3SMatthew G. Knepley @*/
8191c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorSet(DM dm, PetscErrorCode (*f)(DM, void *), void *mctx, PetscErrorCode (*monitordestroy)(void**))
8192c0f0dcc3SMatthew G. Knepley {
8193c0f0dcc3SMatthew G. Knepley   PetscInt       m;
8194c0f0dcc3SMatthew G. Knepley   PetscErrorCode ierr;
8195c0f0dcc3SMatthew G. Knepley 
8196c0f0dcc3SMatthew G. Knepley   PetscFunctionBegin;
8197c0f0dcc3SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8198c0f0dcc3SMatthew G. Knepley   for (m = 0; m < dm->numbermonitors; ++m) {
8199c0f0dcc3SMatthew G. Knepley     PetscBool identical;
8200c0f0dcc3SMatthew G. Knepley 
8201c0f0dcc3SMatthew G. Knepley     ierr = PetscMonitorCompare((PetscErrorCode (*)(void)) f, mctx, monitordestroy, (PetscErrorCode (*)(void)) dm->monitor[m], dm->monitorcontext[m], dm->monitordestroy[m], &identical);CHKERRQ(ierr);
8202c0f0dcc3SMatthew G. Knepley     if (identical) PetscFunctionReturn(0);
8203c0f0dcc3SMatthew G. Knepley   }
8204c0f0dcc3SMatthew G. Knepley   if (dm->numbermonitors >= MAXDMMONITORS) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set");
8205c0f0dcc3SMatthew G. Knepley   dm->monitor[dm->numbermonitors]          = f;
8206c0f0dcc3SMatthew G. Knepley   dm->monitordestroy[dm->numbermonitors]   = monitordestroy;
8207c0f0dcc3SMatthew G. Knepley   dm->monitorcontext[dm->numbermonitors++] = (void *) mctx;
8208c0f0dcc3SMatthew G. Knepley   PetscFunctionReturn(0);
8209c0f0dcc3SMatthew G. Knepley }
8210c0f0dcc3SMatthew G. Knepley 
8211c0f0dcc3SMatthew G. Knepley /*@
8212c0f0dcc3SMatthew G. Knepley   DMMonitorCancel - Clears all the monitor functions for a DM object.
8213c0f0dcc3SMatthew G. Knepley 
8214c0f0dcc3SMatthew G. Knepley   Logically Collective on DM
8215c0f0dcc3SMatthew G. Knepley 
8216c0f0dcc3SMatthew G. Knepley   Input Parameter:
8217c0f0dcc3SMatthew G. Knepley . dm - the DM
8218c0f0dcc3SMatthew G. Knepley 
8219c0f0dcc3SMatthew G. Knepley   Options Database Key:
8220c0f0dcc3SMatthew G. Knepley . -dm_monitor_cancel - cancels all monitors that have been hardwired
8221c0f0dcc3SMatthew G. Knepley   into a code by calls to DMonitorSet(), but does not cancel those
8222c0f0dcc3SMatthew G. Knepley   set via the options database
8223c0f0dcc3SMatthew G. Knepley 
8224c0f0dcc3SMatthew G. Knepley   Notes:
8225c0f0dcc3SMatthew G. Knepley   There is no way to clear one specific monitor from a DM object.
8226c0f0dcc3SMatthew G. Knepley 
8227c0f0dcc3SMatthew G. Knepley   Level: intermediate
8228c0f0dcc3SMatthew G. Knepley 
8229c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorSet()
8230c0f0dcc3SMatthew G. Knepley @*/
8231c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorCancel(DM dm)
8232c0f0dcc3SMatthew G. Knepley {
8233c0f0dcc3SMatthew G. Knepley   PetscErrorCode ierr;
8234c0f0dcc3SMatthew G. Knepley   PetscInt       m;
8235c0f0dcc3SMatthew G. Knepley 
8236c0f0dcc3SMatthew G. Knepley   PetscFunctionBegin;
8237c0f0dcc3SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8238c0f0dcc3SMatthew G. Knepley   for (m = 0; m < dm->numbermonitors; ++m) {
8239c0f0dcc3SMatthew G. Knepley     if (dm->monitordestroy[m]) {ierr = (*dm->monitordestroy[m])(&dm->monitorcontext[m]);CHKERRQ(ierr);}
8240c0f0dcc3SMatthew G. Knepley   }
8241c0f0dcc3SMatthew G. Knepley   dm->numbermonitors = 0;
8242c0f0dcc3SMatthew G. Knepley   PetscFunctionReturn(0);
8243c0f0dcc3SMatthew G. Knepley }
8244c0f0dcc3SMatthew G. Knepley 
8245c0f0dcc3SMatthew G. Knepley /*@C
8246c0f0dcc3SMatthew G. Knepley   DMMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
8247c0f0dcc3SMatthew G. Knepley 
8248c0f0dcc3SMatthew G. Knepley   Collective on DM
8249c0f0dcc3SMatthew G. Knepley 
8250c0f0dcc3SMatthew G. Knepley   Input Parameters:
8251c0f0dcc3SMatthew G. Knepley + dm   - DM object you wish to monitor
8252c0f0dcc3SMatthew G. Knepley . name - the monitor type one is seeking
8253c0f0dcc3SMatthew G. Knepley . help - message indicating what monitoring is done
8254c0f0dcc3SMatthew G. Knepley . manual - manual page for the monitor
8255c0f0dcc3SMatthew G. Knepley . monitor - the monitor function
8256c0f0dcc3SMatthew 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
8257c0f0dcc3SMatthew G. Knepley 
8258c0f0dcc3SMatthew G. Knepley   Output Parameter:
8259c0f0dcc3SMatthew G. Knepley . flg - Flag set if the monitor was created
8260c0f0dcc3SMatthew G. Knepley 
8261c0f0dcc3SMatthew G. Knepley   Level: developer
8262c0f0dcc3SMatthew G. Knepley 
8263c0f0dcc3SMatthew G. Knepley .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
8264c0f0dcc3SMatthew G. Knepley           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
8265c0f0dcc3SMatthew G. Knepley           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
8266c0f0dcc3SMatthew G. Knepley           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
8267c0f0dcc3SMatthew G. Knepley           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
8268c0f0dcc3SMatthew G. Knepley           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
8269c0f0dcc3SMatthew G. Knepley           PetscOptionsFList(), PetscOptionsEList()
8270c0f0dcc3SMatthew G. Knepley @*/
8271c0f0dcc3SMatthew 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)
8272c0f0dcc3SMatthew G. Knepley {
8273c0f0dcc3SMatthew G. Knepley   PetscViewer       viewer;
8274c0f0dcc3SMatthew G. Knepley   PetscViewerFormat format;
8275c0f0dcc3SMatthew G. Knepley   PetscErrorCode    ierr;
8276c0f0dcc3SMatthew G. Knepley 
8277c0f0dcc3SMatthew G. Knepley   PetscFunctionBegin;
8278c0f0dcc3SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8279c0f0dcc3SMatthew G. Knepley   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) dm), ((PetscObject) dm)->options, ((PetscObject) dm)->prefix, name, &viewer, &format, flg);CHKERRQ(ierr);
8280c0f0dcc3SMatthew G. Knepley   if (*flg) {
8281c0f0dcc3SMatthew G. Knepley     PetscViewerAndFormat *vf;
8282c0f0dcc3SMatthew G. Knepley 
8283c0f0dcc3SMatthew G. Knepley     ierr = PetscViewerAndFormatCreate(viewer, format, &vf);CHKERRQ(ierr);
8284c0f0dcc3SMatthew G. Knepley     ierr = PetscObjectDereference((PetscObject) viewer);CHKERRQ(ierr);
8285c0f0dcc3SMatthew G. Knepley     if (monitorsetup) {ierr = (*monitorsetup)(dm, vf);CHKERRQ(ierr);}
8286c0f0dcc3SMatthew G. Knepley     ierr = DMMonitorSet(dm,(PetscErrorCode (*)(DM, void *)) monitor, vf, (PetscErrorCode (*)(void **)) PetscViewerAndFormatDestroy);CHKERRQ(ierr);
8287c0f0dcc3SMatthew G. Knepley   }
8288c0f0dcc3SMatthew G. Knepley   PetscFunctionReturn(0);
8289c0f0dcc3SMatthew G. Knepley }
8290c0f0dcc3SMatthew G. Knepley 
8291c0f0dcc3SMatthew G. Knepley /*@
8292c0f0dcc3SMatthew G. Knepley    DMMonitor - runs the user provided monitor routines, if they exist
8293c0f0dcc3SMatthew G. Knepley 
8294c0f0dcc3SMatthew G. Knepley    Collective on DM
8295c0f0dcc3SMatthew G. Knepley 
8296c0f0dcc3SMatthew G. Knepley    Input Parameters:
8297c0f0dcc3SMatthew G. Knepley .  dm - The DM
8298c0f0dcc3SMatthew G. Knepley 
8299c0f0dcc3SMatthew G. Knepley    Level: developer
8300c0f0dcc3SMatthew G. Knepley 
8301c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorSet()
8302c0f0dcc3SMatthew G. Knepley @*/
8303c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitor(DM dm)
8304c0f0dcc3SMatthew G. Knepley {
8305c0f0dcc3SMatthew G. Knepley   PetscInt       m;
8306c0f0dcc3SMatthew G. Knepley   PetscErrorCode ierr;
8307c0f0dcc3SMatthew G. Knepley 
8308c0f0dcc3SMatthew G. Knepley   PetscFunctionBegin;
8309c0f0dcc3SMatthew G. Knepley   if (!dm) PetscFunctionReturn(0);
8310c0f0dcc3SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8311c0f0dcc3SMatthew G. Knepley   for (m = 0; m < dm->numbermonitors; ++m) {
8312c0f0dcc3SMatthew G. Knepley     ierr = (*dm->monitor[m])(dm, dm->monitorcontext[m]);CHKERRQ(ierr);
8313c0f0dcc3SMatthew G. Knepley   }
8314c0f0dcc3SMatthew G. Knepley   PetscFunctionReturn(0);
8315c0f0dcc3SMatthew G. Knepley }
8316