xref: /petsc/src/dm/impls/da/dageometry.c (revision aa1993de6e046ca787fc06fba2a1b90268ee3353)
157459e9aSMatthew G Knepley #include <petsc-private/daimpl.h>     /*I  "petscdmda.h"   I*/
257459e9aSMatthew G Knepley 
357459e9aSMatthew G Knepley #undef __FUNCT__
457459e9aSMatthew G Knepley #define __FUNCT__ "FillClosureArray_Private"
557459e9aSMatthew G Knepley PETSC_STATIC_INLINE PetscErrorCode FillClosureArray_Private(DM dm, PetscSection section, PetscInt nP, const PetscInt points[], PetscScalar *vArray, const PetscScalar **array)
657459e9aSMatthew G Knepley {
757459e9aSMatthew G Knepley   PetscScalar   *a;
857459e9aSMatthew G Knepley   PetscInt       size = 0, dof, off, d, k, i;
957459e9aSMatthew G Knepley   PetscErrorCode ierr;
1057459e9aSMatthew G Knepley 
1157459e9aSMatthew G Knepley   PetscFunctionBegin;
1257459e9aSMatthew G Knepley   for(i = 0; i < nP; ++i) {
1357459e9aSMatthew G Knepley     ierr = PetscSectionGetDof(section, points[i], &dof);CHKERRQ(ierr);
1457459e9aSMatthew G Knepley     size += dof;
1557459e9aSMatthew G Knepley   }
16*aa1993deSMatthew G Knepley   ierr = DMGetWorkArray(dm, size, PETSC_SCALAR, &a);CHKERRQ(ierr);
1757459e9aSMatthew G Knepley   for(i = 0, k = 0; i < nP; ++i) {
1857459e9aSMatthew G Knepley     ierr = PetscSectionGetDof(section, points[i], &dof);CHKERRQ(ierr);
1957459e9aSMatthew G Knepley     ierr = PetscSectionGetOffset(section, points[i], &off);CHKERRQ(ierr);
2057459e9aSMatthew G Knepley 
2157459e9aSMatthew G Knepley     for(d = 0; d < dof; ++d, ++k) {
2257459e9aSMatthew G Knepley       a[k] = vArray[off+d];
2357459e9aSMatthew G Knepley     }
2457459e9aSMatthew G Knepley   }
2557459e9aSMatthew G Knepley   *array = a;
2657459e9aSMatthew G Knepley   PetscFunctionReturn(0);
2757459e9aSMatthew G Knepley }
2857459e9aSMatthew G Knepley 
2957459e9aSMatthew G Knepley #undef __FUNCT__
3057459e9aSMatthew G Knepley #define __FUNCT__ "FillClosureVec_Private"
3157459e9aSMatthew G Knepley PETSC_STATIC_INLINE PetscErrorCode FillClosureVec_Private(DM dm, PetscSection section, PetscInt nP, const PetscInt points[], PetscScalar *vArray, const PetscScalar *array, InsertMode mode)
3257459e9aSMatthew G Knepley {
3357459e9aSMatthew G Knepley   PetscInt       dof, off, d, k, i;
3457459e9aSMatthew G Knepley   PetscErrorCode ierr;
3557459e9aSMatthew G Knepley 
3657459e9aSMatthew G Knepley   PetscFunctionBegin;
3757459e9aSMatthew G Knepley   if ((mode == INSERT_VALUES) || (mode == INSERT_ALL_VALUES)) {
3857459e9aSMatthew G Knepley     for(i = 0, k = 0; i < nP; ++i) {
3957459e9aSMatthew G Knepley       ierr = PetscSectionGetDof(section, points[i], &dof);CHKERRQ(ierr);
4057459e9aSMatthew G Knepley       ierr = PetscSectionGetOffset(section, points[i], &off);CHKERRQ(ierr);
4157459e9aSMatthew G Knepley 
4257459e9aSMatthew G Knepley       for(d = 0; d < dof; ++d, ++k) {
4357459e9aSMatthew G Knepley         vArray[off+d] = array[k];
4457459e9aSMatthew G Knepley       }
4557459e9aSMatthew G Knepley     }
4657459e9aSMatthew G Knepley   } else {
4757459e9aSMatthew G Knepley     for(i = 0, k = 0; i < nP; ++i) {
4857459e9aSMatthew G Knepley       ierr = PetscSectionGetDof(section, points[i], &dof);CHKERRQ(ierr);
4957459e9aSMatthew G Knepley       ierr = PetscSectionGetOffset(section, points[i], &off);CHKERRQ(ierr);
5057459e9aSMatthew G Knepley 
5157459e9aSMatthew G Knepley       for(d = 0; d < dof; ++d, ++k) {
5257459e9aSMatthew G Knepley         vArray[off+d] += array[k];
5357459e9aSMatthew G Knepley       }
5457459e9aSMatthew G Knepley     }
5557459e9aSMatthew G Knepley   }
5657459e9aSMatthew G Knepley   PetscFunctionReturn(0);
5757459e9aSMatthew G Knepley }
5857459e9aSMatthew G Knepley 
5957459e9aSMatthew G Knepley #undef __FUNCT__
60*aa1993deSMatthew G Knepley #define __FUNCT__ "GetPointArray_Private"
61*aa1993deSMatthew G Knepley PETSC_STATIC_INLINE PetscErrorCode GetPointArray_Private(DM dm,PetscInt n,PetscInt *points,PetscInt *rn,const PetscInt **rpoints)
62*aa1993deSMatthew G Knepley {
63*aa1993deSMatthew G Knepley   PetscErrorCode ierr;
64*aa1993deSMatthew G Knepley   PetscInt *work;
65*aa1993deSMatthew G Knepley 
66*aa1993deSMatthew G Knepley   PetscFunctionBegin;
67*aa1993deSMatthew G Knepley   if (rn) *rn = n;
68*aa1993deSMatthew G Knepley   if (rpoints) {
69*aa1993deSMatthew G Knepley     ierr = DMGetWorkArray(dm,n,PETSC_INT,&work);CHKERRQ(ierr);
70*aa1993deSMatthew G Knepley     ierr = PetscMemcpy(work,points,n*sizeof(PetscInt));CHKERRQ(ierr);
71*aa1993deSMatthew G Knepley     *rpoints = work;
72*aa1993deSMatthew G Knepley   }
73*aa1993deSMatthew G Knepley   PetscFunctionReturn(0);
74*aa1993deSMatthew G Knepley }
75*aa1993deSMatthew G Knepley 
76*aa1993deSMatthew G Knepley #undef __FUNCT__
77*aa1993deSMatthew G Knepley #define __FUNCT__ "RestorePointArray_Private"
78*aa1993deSMatthew G Knepley PETSC_STATIC_INLINE PetscErrorCode RestorePointArray_Private(DM dm,PetscInt *rn,const PetscInt **rpoints)
79*aa1993deSMatthew G Knepley {
80*aa1993deSMatthew G Knepley   PetscErrorCode ierr;
81*aa1993deSMatthew G Knepley 
82*aa1993deSMatthew G Knepley   PetscFunctionBegin;
83*aa1993deSMatthew G Knepley   if (rn) *rn = 0;
84*aa1993deSMatthew G Knepley   if (rpoints) {ierr = DMRestoreWorkArray(dm,*rn,PETSC_INT,rpoints);CHKERRQ(ierr);}
85*aa1993deSMatthew G Knepley   PetscFunctionReturn(0);
86*aa1993deSMatthew G Knepley }
87*aa1993deSMatthew G Knepley 
88*aa1993deSMatthew G Knepley #undef __FUNCT__
89*aa1993deSMatthew G Knepley #define __FUNCT__ "DMDAGetClosure"
90*aa1993deSMatthew G Knepley PetscErrorCode DMDAGetClosure(DM dm, PetscSection section, PetscInt p,PetscInt *n,const PetscInt **closure)
9157459e9aSMatthew G Knepley {
9257459e9aSMatthew G Knepley   DM_DA         *da  = (DM_DA *) dm->data;
9357459e9aSMatthew G Knepley   PetscInt       dim = da->dim;
94*aa1993deSMatthew G Knepley   PetscInt       nVx, nVy, nxF, nXF, nyF, nYF, nzF, nZF;
95*aa1993deSMatthew G Knepley   PetscInt       pStart, pEnd, cStart, cEnd, vStart, vEnd, fStart, fEnd, xfStart, xfEnd, yfStart;
96*aa1993deSMatthew G Knepley   PetscErrorCode ierr;
97*aa1993deSMatthew G Knepley 
98*aa1993deSMatthew G Knepley   PetscFunctionBegin;
99*aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
100*aa1993deSMatthew G Knepley   if (n) PetscValidIntPointer(n,4);
101*aa1993deSMatthew G Knepley   if (closure) PetscValidPointer(closure, 5);
102*aa1993deSMatthew G Knepley   if (!section) {ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);}
103*aa1993deSMatthew G Knepley   if (!section) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_ARG_WRONG, "This DM has not default PetscSection");
104*aa1993deSMatthew G Knepley   ierr = DMDAGetHeightStratum(dm, -1,  &pStart, &pEnd);CHKERRQ(ierr);
105*aa1993deSMatthew G Knepley   ierr = DMDAGetHeightStratum(dm, 0,   &cStart, &cEnd);CHKERRQ(ierr);
106*aa1993deSMatthew G Knepley   ierr = DMDAGetHeightStratum(dm, 1,   &fStart, &fEnd);CHKERRQ(ierr);
107*aa1993deSMatthew G Knepley   ierr = DMDAGetHeightStratum(dm, dim, &vStart, &vEnd);CHKERRQ(ierr);
108*aa1993deSMatthew G Knepley   ierr = DMDAGetNumVertices(dm, &nVx, &nVy, PETSC_NULL, PETSC_NULL);CHKERRQ(ierr);
109*aa1993deSMatthew G Knepley   ierr = DMDAGetNumFaces(dm, &nxF, &nXF, &nyF, &nYF, &nzF, &nZF);CHKERRQ(ierr);
110*aa1993deSMatthew G Knepley   xfStart = fStart; xfEnd = xfStart+nXF;
111*aa1993deSMatthew G Knepley   yfStart = xfEnd;
112*aa1993deSMatthew G Knepley   if ((p < pStart) || (p >= pEnd)) SETERRQ3(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid point %d should be in [%d, %d)", p, pStart, pEnd);
113*aa1993deSMatthew G Knepley   if ((p >= cStart) || (p < cEnd)) {
114*aa1993deSMatthew G Knepley     /* Cell */
115*aa1993deSMatthew G Knepley     if (dim == 1) {
116*aa1993deSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Not implemented");
117*aa1993deSMatthew G Knepley     } else if (dim == 2) {
118*aa1993deSMatthew G Knepley       /* 4 faces, 4 vertices
119*aa1993deSMatthew G Knepley          Bottom-left vertex follows same order as cells
120*aa1993deSMatthew G Knepley          Bottom y-face same order as cells
121*aa1993deSMatthew G Knepley          Left x-face follows same order as cells
122*aa1993deSMatthew G Knepley          We number the quad:
123*aa1993deSMatthew G Knepley 
124*aa1993deSMatthew G Knepley            8--3--7
125*aa1993deSMatthew G Knepley            |     |
126*aa1993deSMatthew G Knepley            4  0  2
127*aa1993deSMatthew G Knepley            |     |
128*aa1993deSMatthew G Knepley            5--1--6
129*aa1993deSMatthew G Knepley       */
130*aa1993deSMatthew G Knepley       PetscInt c         = p - cStart, cx = c % (nVx-1), cy = c / (nVx-1);
131*aa1993deSMatthew G Knepley       PetscInt v         = cy*nVx + cx +  vStart;
132*aa1993deSMatthew G Knepley       PetscInt xf        = cy*nxF + cx + xfStart;
133*aa1993deSMatthew G Knepley       PetscInt yf        = c + yfStart;
134*aa1993deSMatthew G Knepley       PetscInt points[9] = {p, yf, xf+1, yf+nyF, xf+0, v+0, v+1, v+nVx+1, v+nVx+0};
135*aa1993deSMatthew G Knepley 
136*aa1993deSMatthew G Knepley       ierr = GetPointArray_Private(dm,9,points,n,closure);CHKERRQ(ierr);
137*aa1993deSMatthew G Knepley     } else {
138*aa1993deSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Not implemented");
139*aa1993deSMatthew G Knepley     }
140*aa1993deSMatthew G Knepley   } else if ((p >= vStart) || (p < vEnd)) {
141*aa1993deSMatthew G Knepley     /* Vertex */
142*aa1993deSMatthew G Knepley     ierr = GetPointArray_Private(dm,1,&p,n,closure);CHKERRQ(ierr);
143*aa1993deSMatthew G Knepley   } else if ((p >= fStart) || (p < fStart + nXF)) {
144*aa1993deSMatthew G Knepley     /* X Face */
145*aa1993deSMatthew G Knepley     if (dim == 1) {
146*aa1993deSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "There are no faces in 1D");
147*aa1993deSMatthew G Knepley     } else if (dim == 2) {
148*aa1993deSMatthew G Knepley       /* 2 vertices: The bottom vertex has the same numbering as the face */
149*aa1993deSMatthew G Knepley       PetscInt f         = p - xfStart;
150*aa1993deSMatthew G Knepley       PetscInt points[3] = {p, f, f+nVx};
151*aa1993deSMatthew G Knepley 
152*aa1993deSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Broken");
153*aa1993deSMatthew G Knepley       ierr = GetPointArray_Private(dm,3,points,n,closure);CHKERRQ(ierr);
154*aa1993deSMatthew G Knepley     } else if (dim == 3) {
155*aa1993deSMatthew G Knepley       /* 4 vertices */
156*aa1993deSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Not implemented");
157*aa1993deSMatthew G Knepley     }
158*aa1993deSMatthew G Knepley   } else if ((p >= fStart + nXF) || (p < fStart + nXF + nYF)) {
159*aa1993deSMatthew G Knepley     /* Y Face */
160*aa1993deSMatthew G Knepley     if (dim == 1) {
161*aa1993deSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "There are no faces in 1D");
162*aa1993deSMatthew G Knepley     } else if (dim == 2) {
163*aa1993deSMatthew G Knepley       /* 2 vertices: The left vertex has the same numbering as the face */
164*aa1993deSMatthew G Knepley       PetscInt f         = p - yfStart;
165*aa1993deSMatthew G Knepley       PetscInt points[3] = {p, f, f+1};
166*aa1993deSMatthew G Knepley 
167*aa1993deSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Broken");
168*aa1993deSMatthew G Knepley       ierr = GetPointArray_Private(dm, 3, points, n, closure);CHKERRQ(ierr);
169*aa1993deSMatthew G Knepley     } else if (dim == 3) {
170*aa1993deSMatthew G Knepley       /* 4 vertices */
171*aa1993deSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Not implemented");
172*aa1993deSMatthew G Knepley     }
173*aa1993deSMatthew G Knepley   } else {
174*aa1993deSMatthew G Knepley     /* Z Face */
175*aa1993deSMatthew G Knepley     if (dim == 1) {
176*aa1993deSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "There are no faces in 1D");
177*aa1993deSMatthew G Knepley     } else if (dim == 2) {
178*aa1993deSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "There are no z-faces in 2D");
179*aa1993deSMatthew G Knepley     } else if (dim == 3) {
180*aa1993deSMatthew G Knepley       /* 4 vertices */
181*aa1993deSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Not implemented");
182*aa1993deSMatthew G Knepley     }
183*aa1993deSMatthew G Knepley   }
184*aa1993deSMatthew G Knepley   PetscFunctionReturn(0);
185*aa1993deSMatthew G Knepley }
186*aa1993deSMatthew G Knepley 
187*aa1993deSMatthew G Knepley #undef __FUNCT__
188*aa1993deSMatthew G Knepley #define __FUNCT__ "DMDARestoreClosure"
189*aa1993deSMatthew G Knepley PetscErrorCode DMDARestoreClosure(DM dm, PetscSection section, PetscInt p,PetscInt *n,const PetscInt **closure)
190*aa1993deSMatthew G Knepley {
191*aa1993deSMatthew G Knepley   PetscErrorCode ierr;
192*aa1993deSMatthew G Knepley 
193*aa1993deSMatthew G Knepley   PetscFunctionBegin;
194*aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
195*aa1993deSMatthew G Knepley   PetscValidIntPointer(n,4);
196*aa1993deSMatthew G Knepley   PetscValidPointer(closure, 5);
197*aa1993deSMatthew G Knepley   ierr = RestorePointArray_Private(dm,n,closure);CHKERRQ(ierr);
198*aa1993deSMatthew G Knepley   PetscFunctionReturn(0);
199*aa1993deSMatthew G Knepley }
200*aa1993deSMatthew G Knepley 
201*aa1993deSMatthew G Knepley #undef __FUNCT__
202*aa1993deSMatthew G Knepley #define __FUNCT__ "DMDAGetClosureScalar"
203*aa1993deSMatthew G Knepley /* If you did not pass PETSC_NULL for 'values', you must call DMDARestoreClosureScalar() */
204*aa1993deSMatthew G Knepley PetscErrorCode DMDAGetClosureScalar(DM dm, PetscSection section,PetscInt p,PetscScalar *vArray,const PetscScalar **values)
205*aa1993deSMatthew G Knepley {
206*aa1993deSMatthew G Knepley   DM_DA         *da  = (DM_DA *) dm->data;
207*aa1993deSMatthew G Knepley   PetscInt       dim = da->dim;
20857459e9aSMatthew G Knepley   PetscInt       nVx, nVy, nxF, nXF, nyF, nYF, nzF, nZF;
20995babc02SJed Brown   PetscInt       pStart, pEnd, cStart, cEnd, vStart, vEnd, fStart, fEnd, xfStart, xfEnd, yfStart, yfEnd, zfStart;
21057459e9aSMatthew G Knepley   PetscErrorCode ierr;
21157459e9aSMatthew G Knepley 
21257459e9aSMatthew G Knepley   PetscFunctionBegin;
21357459e9aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
214*aa1993deSMatthew G Knepley   PetscValidScalarPointer(vArray, 4);
21557459e9aSMatthew G Knepley   PetscValidPointer(values, 5);
21657459e9aSMatthew G Knepley   if (!section) {ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);}
21757459e9aSMatthew G Knepley   if (!section) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_ARG_WRONG, "This DM has not default PetscSection");
21857459e9aSMatthew G Knepley   ierr = DMDAGetHeightStratum(dm, -1,  &pStart, &pEnd);CHKERRQ(ierr);
21957459e9aSMatthew G Knepley   ierr = DMDAGetHeightStratum(dm, 0,   &cStart, &cEnd);CHKERRQ(ierr);
22057459e9aSMatthew G Knepley   ierr = DMDAGetHeightStratum(dm, 1,   &fStart, &fEnd);CHKERRQ(ierr);
22157459e9aSMatthew G Knepley   ierr = DMDAGetHeightStratum(dm, dim, &vStart, &vEnd);CHKERRQ(ierr);
22257459e9aSMatthew G Knepley   ierr = DMDAGetNumVertices(dm, &nVx, &nVy, PETSC_NULL, PETSC_NULL);CHKERRQ(ierr);
22357459e9aSMatthew G Knepley   ierr = DMDAGetNumFaces(dm, &nxF, &nXF, &nyF, &nYF, &nzF, &nZF);CHKERRQ(ierr);
22457459e9aSMatthew G Knepley   xfStart = fStart; xfEnd = xfStart+nXF;
22557459e9aSMatthew G Knepley   yfStart = xfEnd;  yfEnd = yfStart+nYF;
22695babc02SJed Brown   zfStart = yfEnd;
22757459e9aSMatthew G Knepley   if ((p < pStart) || (p >= pEnd)) SETERRQ3(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid point %d should be in [%d, %d)", p, pStart, pEnd);
22857459e9aSMatthew G Knepley   if ((p >= cStart) || (p < cEnd)) {
22957459e9aSMatthew G Knepley     /* Cell */
23057459e9aSMatthew G Knepley     if (dim == 1) {
23157459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Not implemented");
23257459e9aSMatthew G Knepley     } else if (dim == 2) {
23357459e9aSMatthew G Knepley       /* 4 faces, 4 vertices
23457459e9aSMatthew G Knepley          Bottom-left vertex follows same order as cells
23557459e9aSMatthew G Knepley          Bottom y-face same order as cells
23657459e9aSMatthew G Knepley          Left x-face follows same order as cells
23757459e9aSMatthew G Knepley          We number the quad:
23857459e9aSMatthew G Knepley 
23957459e9aSMatthew G Knepley            8--3--7
24057459e9aSMatthew G Knepley            |     |
24157459e9aSMatthew G Knepley            4  0  2
24257459e9aSMatthew G Knepley            |     |
24357459e9aSMatthew G Knepley            5--1--6
24457459e9aSMatthew G Knepley       */
24557459e9aSMatthew G Knepley       PetscInt c         = p - cStart, cx = c % (nVx-1), cy = c / (nVx-1);
24657459e9aSMatthew G Knepley       PetscInt v         = cy*nVx + cx +  vStart;
24757459e9aSMatthew G Knepley       PetscInt xf        = cy*nxF + cx + xfStart;
24857459e9aSMatthew G Knepley       PetscInt yf        = c + yfStart;
24957459e9aSMatthew G Knepley       PetscInt points[9] = {p, yf, xf+1, yf+nyF, xf+0, v+0, v+1, v+nVx+1, v+nVx+0};
25057459e9aSMatthew G Knepley 
25157459e9aSMatthew G Knepley       ierr = FillClosureArray_Private(dm, section, 9, points, vArray, values);CHKERRQ(ierr);
25257459e9aSMatthew G Knepley     } else {
25357459e9aSMatthew G Knepley       /* 6 faces, 8 vertices
25457459e9aSMatthew G Knepley          Bottom-left-back vertex follows same order as cells
25557459e9aSMatthew G Knepley          Back z-face follows same order as cells
25657459e9aSMatthew G Knepley          Bottom y-face follows same order as cells
25757459e9aSMatthew G Knepley          Left x-face follows same order as cells
25857459e9aSMatthew G Knepley 
25957459e9aSMatthew G Knepley               14-----13
26057459e9aSMatthew G Knepley               /|    /|
26157459e9aSMatthew G Knepley              / | 2 / |
26257459e9aSMatthew G Knepley             / 5|  /  |
26357459e9aSMatthew G Knepley           10-----9  4|
26457459e9aSMatthew G Knepley            |  11-|---12
26557459e9aSMatthew G Knepley            |6 /  |  /
26657459e9aSMatthew G Knepley            | /1 3| /
26757459e9aSMatthew G Knepley            |/    |/
26857459e9aSMatthew G Knepley            7-----8
26957459e9aSMatthew G Knepley       */
27057459e9aSMatthew G Knepley       PetscInt c          = p - cStart;
27157459e9aSMatthew G Knepley       PetscInt points[15] = {p, c+zfStart, c+zfStart+nzF, c+yfStart, c+xfStart+nxF, c+yfStart+nyF, c+xfStart,
27257459e9aSMatthew G Knepley                              c+vStart+0, c+vStart+1, c+vStart+nVx+1, c+vStart+nVx+0, c+vStart+nVx*nVy+0, c+vStart+nVx*nVy+1, c+vStart+nVx*nVy+nVx+1, c+vStart+nVx*nVy+nVx+0};
27357459e9aSMatthew G Knepley 
27457459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Broken");
27557459e9aSMatthew G Knepley       ierr = FillClosureArray_Private(dm, section, 15, points, vArray, values);CHKERRQ(ierr);
27657459e9aSMatthew G Knepley     }
27757459e9aSMatthew G Knepley   } else if ((p >= vStart) || (p < vEnd)) {
27857459e9aSMatthew G Knepley     /* Vertex */
27957459e9aSMatthew G Knepley     ierr = FillClosureArray_Private(dm, section, 1, &p, vArray, values);CHKERRQ(ierr);
28057459e9aSMatthew G Knepley   } else if ((p >= fStart) || (p < fStart + nXF)) {
28157459e9aSMatthew G Knepley     /* X Face */
28257459e9aSMatthew G Knepley     if (dim == 1) {
28357459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "There are no faces in 1D");
28457459e9aSMatthew G Knepley     } else if (dim == 2) {
28557459e9aSMatthew G Knepley       /* 2 vertices: The bottom vertex has the same numbering as the face */
28657459e9aSMatthew G Knepley       PetscInt f         = p - xfStart;
28757459e9aSMatthew G Knepley       PetscInt points[3] = {p, f, f+nVx};
28857459e9aSMatthew G Knepley 
28957459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Broken");
29057459e9aSMatthew G Knepley       ierr = FillClosureArray_Private(dm, section, 3, points, vArray, values);CHKERRQ(ierr);
29157459e9aSMatthew G Knepley     } else if (dim == 3) {
29257459e9aSMatthew G Knepley       /* 4 vertices */
29357459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Not implemented");
29457459e9aSMatthew G Knepley     }
29557459e9aSMatthew G Knepley   } else if ((p >= fStart + nXF) || (p < fStart + nXF + nYF)) {
29657459e9aSMatthew G Knepley     /* Y Face */
29757459e9aSMatthew G Knepley     if (dim == 1) {
29857459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "There are no faces in 1D");
29957459e9aSMatthew G Knepley     } else if (dim == 2) {
30057459e9aSMatthew G Knepley       /* 2 vertices: The left vertex has the same numbering as the face */
30157459e9aSMatthew G Knepley       PetscInt f         = p - yfStart;
30257459e9aSMatthew G Knepley       PetscInt points[3] = {p, f, f+1};
30357459e9aSMatthew G Knepley 
30457459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Broken");
30557459e9aSMatthew G Knepley       ierr = FillClosureArray_Private(dm, section, 3, points, vArray, values);CHKERRQ(ierr);
30657459e9aSMatthew G Knepley     } else if (dim == 3) {
30757459e9aSMatthew G Knepley       /* 4 vertices */
30857459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Not implemented");
30957459e9aSMatthew G Knepley     }
31057459e9aSMatthew G Knepley   } else {
31157459e9aSMatthew G Knepley     /* Z Face */
31257459e9aSMatthew G Knepley     if (dim == 1) {
31357459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "There are no faces in 1D");
31457459e9aSMatthew G Knepley     } else if (dim == 2) {
31557459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "There are no z-faces in 2D");
31657459e9aSMatthew G Knepley     } else if (dim == 3) {
31757459e9aSMatthew G Knepley       /* 4 vertices */
31857459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Not implemented");
31957459e9aSMatthew G Knepley     }
32057459e9aSMatthew G Knepley   }
321*aa1993deSMatthew G Knepley   PetscFunctionReturn(0);
322*aa1993deSMatthew G Knepley }
323*aa1993deSMatthew G Knepley 
324*aa1993deSMatthew G Knepley #undef __FUNCT__
325*aa1993deSMatthew G Knepley #define __FUNCT__ "DMDAVecGetClosure"
326*aa1993deSMatthew G Knepley PetscErrorCode DMDAVecGetClosure(DM dm, PetscSection section, Vec v, PetscInt p, const PetscScalar **values)
327*aa1993deSMatthew G Knepley {
328*aa1993deSMatthew G Knepley   PetscScalar *vArray;
329*aa1993deSMatthew G Knepley   PetscErrorCode ierr;
330*aa1993deSMatthew G Knepley 
331*aa1993deSMatthew G Knepley   PetscFunctionBegin;
332*aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
333*aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(v, VEC_CLASSID, 3);
334*aa1993deSMatthew G Knepley   PetscValidPointer(values, 5);
335*aa1993deSMatthew G Knepley   ierr = VecGetArray(v,&vArray);CHKERRQ(ierr);
336*aa1993deSMatthew G Knepley   ierr = DMDAGetClosureScalar(dm,section,p,vArray,values);CHKERRQ(ierr);
33757459e9aSMatthew G Knepley   ierr = VecRestoreArray(v,&vArray);CHKERRQ(ierr);
33857459e9aSMatthew G Knepley   PetscFunctionReturn(0);
33957459e9aSMatthew G Knepley }
34057459e9aSMatthew G Knepley 
34157459e9aSMatthew G Knepley #undef __FUNCT__
342*aa1993deSMatthew G Knepley #define __FUNCT__ "DMDARestoreClosureScalar"
343*aa1993deSMatthew G Knepley PetscErrorCode DMDARestoreClosureScalar(DM dm, PetscSection section,PetscInt p,PetscScalar *vArray,const PetscScalar **values)
344*aa1993deSMatthew G Knepley {
345*aa1993deSMatthew G Knepley   PetscErrorCode ierr;
346*aa1993deSMatthew G Knepley   PetscInt count;
347*aa1993deSMatthew G Knepley 
348*aa1993deSMatthew G Knepley   PetscFunctionBegin;
349*aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
350*aa1993deSMatthew G Knepley   PetscValidPointer(values, 5);
351*aa1993deSMatthew G Knepley   count = 0;                    /* We are lying about the count */
352*aa1993deSMatthew G Knepley   ierr = DMRestoreWorkArray(dm,count,PETSC_SCALAR,values);CHKERRQ(ierr);
353*aa1993deSMatthew G Knepley   PetscFunctionReturn(0);
354*aa1993deSMatthew G Knepley }
355*aa1993deSMatthew G Knepley 
356*aa1993deSMatthew G Knepley #undef __FUNCT__
357*aa1993deSMatthew G Knepley #define __FUNCT__ "DMDAVecRestoreClosure"
358*aa1993deSMatthew G Knepley PetscErrorCode DMDAVecRestoreClosure(DM dm, PetscSection section, Vec v, PetscInt p, const PetscScalar **values)
359*aa1993deSMatthew G Knepley {
360*aa1993deSMatthew G Knepley   PetscErrorCode ierr;
361*aa1993deSMatthew G Knepley 
362*aa1993deSMatthew G Knepley   PetscFunctionBegin;
363*aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
364*aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(v, VEC_CLASSID, 3);
365*aa1993deSMatthew G Knepley   PetscValidPointer(values, 5);
366*aa1993deSMatthew G Knepley   ierr = DMDARestoreClosureScalar(dm,section,p,PETSC_NULL,values);CHKERRQ(ierr);
367*aa1993deSMatthew G Knepley   PetscFunctionReturn(0);
368*aa1993deSMatthew G Knepley }
369*aa1993deSMatthew G Knepley 
370*aa1993deSMatthew G Knepley #undef __FUNCT__
371*aa1993deSMatthew G Knepley #define __FUNCT__ "DMDASetClosureScalar"
372*aa1993deSMatthew G Knepley PetscErrorCode DMDASetClosureScalar(DM dm, PetscSection section, PetscInt p,PetscScalar *vArray, const PetscScalar *values, InsertMode mode)
37357459e9aSMatthew G Knepley {
37457459e9aSMatthew G Knepley   DM_DA         *da  = (DM_DA *) dm->data;
37557459e9aSMatthew G Knepley   PetscInt       dim = da->dim;
37657459e9aSMatthew G Knepley   PetscInt       nVx, nVy, nxF, nXF, nyF, nYF, nzF, nZF;
37795babc02SJed Brown   PetscInt       pStart, pEnd, cStart, cEnd, vStart, vEnd, fStart, fEnd, xfStart, xfEnd, yfStart, yfEnd, zfStart;
37857459e9aSMatthew G Knepley   PetscErrorCode ierr;
37957459e9aSMatthew G Knepley 
38057459e9aSMatthew G Knepley   PetscFunctionBegin;
38157459e9aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
382*aa1993deSMatthew G Knepley   PetscValidScalarPointer(values, 4);
38357459e9aSMatthew G Knepley   PetscValidPointer(values, 5);
38457459e9aSMatthew G Knepley   if (!section) {ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);}
38557459e9aSMatthew G Knepley   if (!section) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_ARG_WRONG, "This DM has not default PetscSection");
38657459e9aSMatthew G Knepley   ierr = DMDAGetHeightStratum(dm, -1,  &pStart, &pEnd);CHKERRQ(ierr);
38757459e9aSMatthew G Knepley   ierr = DMDAGetHeightStratum(dm, 0,   &cStart, &cEnd);CHKERRQ(ierr);
38857459e9aSMatthew G Knepley   ierr = DMDAGetHeightStratum(dm, 1,   &fStart, &fEnd);CHKERRQ(ierr);
38957459e9aSMatthew G Knepley   ierr = DMDAGetHeightStratum(dm, dim, &vStart, &vEnd);CHKERRQ(ierr);
39057459e9aSMatthew G Knepley   ierr = DMDAGetNumVertices(dm, &nVx, &nVy, PETSC_NULL, PETSC_NULL);CHKERRQ(ierr);
39157459e9aSMatthew G Knepley   ierr = DMDAGetNumFaces(dm, &nxF, &nXF, &nyF, &nYF, &nzF, &nZF);CHKERRQ(ierr);
39257459e9aSMatthew G Knepley   xfStart = fStart; xfEnd = xfStart+nXF;
39357459e9aSMatthew G Knepley   yfStart = xfEnd;  yfEnd = yfStart+nYF;
39495babc02SJed Brown   zfStart = yfEnd;
39557459e9aSMatthew G Knepley   if ((p < pStart) || (p >= pEnd)) SETERRQ3(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid point %d should be in [%d, %d)", p, pStart, pEnd);
39657459e9aSMatthew G Knepley   if ((p >= cStart) || (p < cEnd)) {
39757459e9aSMatthew G Knepley     /* Cell */
39857459e9aSMatthew G Knepley     if (dim == 1) {
39957459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Not implemented");
40057459e9aSMatthew G Knepley     } else if (dim == 2) {
40157459e9aSMatthew G Knepley       /* 4 faces, 4 vertices
40257459e9aSMatthew G Knepley          Bottom-left vertex follows same order as cells
40357459e9aSMatthew G Knepley          Bottom y-face same order as cells
40457459e9aSMatthew G Knepley          Left x-face follows same order as cells
40557459e9aSMatthew G Knepley          We number the quad:
40657459e9aSMatthew G Knepley 
40757459e9aSMatthew G Knepley            8--3--7
40857459e9aSMatthew G Knepley            |     |
40957459e9aSMatthew G Knepley            4  0  2
41057459e9aSMatthew G Knepley            |     |
41157459e9aSMatthew G Knepley            5--1--6
41257459e9aSMatthew G Knepley       */
41357459e9aSMatthew G Knepley       PetscInt c         = p - cStart;
41457459e9aSMatthew G Knepley       PetscInt points[9] = {p, c+yfStart, c+xfStart+1, c+yfStart+nyF, c+xfStart+0, c+vStart+0, c+vStart+1, c+vStart+nVx+1, c+vStart+nVx+0};
41557459e9aSMatthew G Knepley 
41657459e9aSMatthew G Knepley       ierr = FillClosureVec_Private(dm, section, 9, points, vArray, values, mode);CHKERRQ(ierr);
41757459e9aSMatthew G Knepley     } else {
41857459e9aSMatthew G Knepley       /* 6 faces, 8 vertices
41957459e9aSMatthew G Knepley          Bottom-left-back vertex follows same order as cells
42057459e9aSMatthew G Knepley          Back z-face follows same order as cells
42157459e9aSMatthew G Knepley          Bottom y-face follows same order as cells
42257459e9aSMatthew G Knepley          Left x-face follows same order as cells
42357459e9aSMatthew G Knepley 
42457459e9aSMatthew G Knepley               14-----13
42557459e9aSMatthew G Knepley               /|    /|
42657459e9aSMatthew G Knepley              / | 2 / |
42757459e9aSMatthew G Knepley             / 5|  /  |
42857459e9aSMatthew G Knepley           10-----9  4|
42957459e9aSMatthew G Knepley            |  11-|---12
43057459e9aSMatthew G Knepley            |6 /  |  /
43157459e9aSMatthew G Knepley            | /1 3| /
43257459e9aSMatthew G Knepley            |/    |/
43357459e9aSMatthew G Knepley            7-----8
43457459e9aSMatthew G Knepley       */
43557459e9aSMatthew G Knepley       PetscInt c          = p - cStart;
43657459e9aSMatthew G Knepley       PetscInt points[15] = {p, c+zfStart, c+zfStart+nzF, c+yfStart, c+xfStart+nxF, c+yfStart+nyF, c+xfStart,
43757459e9aSMatthew G Knepley                              c+vStart+0, c+vStart+1, c+vStart+nVx+1, c+vStart+nVx+0, c+vStart+nVx*nVy+0, c+vStart+nVx*nVy+1, c+vStart+nVx*nVy+nVx+1, c+vStart+nVx*nVy+nVx+0};
43857459e9aSMatthew G Knepley 
43957459e9aSMatthew G Knepley       ierr = FillClosureVec_Private(dm, section, 15, points, vArray, values, mode);CHKERRQ(ierr);
44057459e9aSMatthew G Knepley     }
44157459e9aSMatthew G Knepley   } else if ((p >= vStart) || (p < vEnd)) {
44257459e9aSMatthew G Knepley     /* Vertex */
44357459e9aSMatthew G Knepley     ierr = FillClosureVec_Private(dm, section, 1, &p, vArray, values, mode);CHKERRQ(ierr);
44457459e9aSMatthew G Knepley   } else if ((p >= fStart) || (p < fStart + nXF)) {
44557459e9aSMatthew G Knepley     /* X Face */
44657459e9aSMatthew G Knepley     if (dim == 1) {
44757459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "There are no faces in 1D");
44857459e9aSMatthew G Knepley     } else if (dim == 2) {
44957459e9aSMatthew G Knepley       /* 2 vertices: The bottom vertex has the same numbering as the face */
45057459e9aSMatthew G Knepley       PetscInt f         = p - xfStart;
45157459e9aSMatthew G Knepley       PetscInt points[3] = {p, f, f+nVx};
45257459e9aSMatthew G Knepley 
45357459e9aSMatthew G Knepley       ierr = FillClosureVec_Private(dm, section, 3, points, vArray, values, mode);CHKERRQ(ierr);
45457459e9aSMatthew G Knepley     } else if (dim == 3) {
45557459e9aSMatthew G Knepley       /* 4 vertices */
45657459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Not implemented");
45757459e9aSMatthew G Knepley     }
45857459e9aSMatthew G Knepley   } else if ((p >= fStart + nXF) || (p < fStart + nXF + nYF)) {
45957459e9aSMatthew G Knepley     /* Y Face */
46057459e9aSMatthew G Knepley     if (dim == 1) {
46157459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "There are no faces in 1D");
46257459e9aSMatthew G Knepley     } else if (dim == 2) {
46357459e9aSMatthew G Knepley       /* 2 vertices: The left vertex has the same numbering as the face */
46457459e9aSMatthew G Knepley       PetscInt f         = p - yfStart;
46557459e9aSMatthew G Knepley       PetscInt points[3] = {p, f, f+1};
46657459e9aSMatthew G Knepley 
46757459e9aSMatthew G Knepley       ierr = FillClosureVec_Private(dm, section, 3, points, vArray, values, mode);CHKERRQ(ierr);
46857459e9aSMatthew G Knepley     } else if (dim == 3) {
46957459e9aSMatthew G Knepley       /* 4 vertices */
47057459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Not implemented");
47157459e9aSMatthew G Knepley     }
47257459e9aSMatthew G Knepley   } else {
47357459e9aSMatthew G Knepley     /* Z Face */
47457459e9aSMatthew G Knepley     if (dim == 1) {
47557459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "There are no faces in 1D");
47657459e9aSMatthew G Knepley     } else if (dim == 2) {
47757459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "There are no z-faces in 2D");
47857459e9aSMatthew G Knepley     } else if (dim == 3) {
47957459e9aSMatthew G Knepley       /* 4 vertices */
48057459e9aSMatthew G Knepley       SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Not implemented");
48157459e9aSMatthew G Knepley     }
48257459e9aSMatthew G Knepley   }
483*aa1993deSMatthew G Knepley   PetscFunctionReturn(0);
484*aa1993deSMatthew G Knepley }
485*aa1993deSMatthew G Knepley 
486*aa1993deSMatthew G Knepley #undef __FUNCT__
487*aa1993deSMatthew G Knepley #define __FUNCT__ "DMDAVecSetClosure"
488*aa1993deSMatthew G Knepley PetscErrorCode DMDAVecSetClosure(DM dm, PetscSection section, Vec v, PetscInt p, const PetscScalar *values, InsertMode mode)
489*aa1993deSMatthew G Knepley {
490*aa1993deSMatthew G Knepley   PetscScalar   *vArray;
491*aa1993deSMatthew G Knepley   PetscErrorCode ierr;
492*aa1993deSMatthew G Knepley 
493*aa1993deSMatthew G Knepley   PetscFunctionBegin;
494*aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
495*aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(v, VEC_CLASSID, 3);
496*aa1993deSMatthew G Knepley   PetscValidPointer(values, 5);
497*aa1993deSMatthew G Knepley   ierr = VecGetArray(v,&vArray);CHKERRQ(ierr);
498*aa1993deSMatthew G Knepley   ierr = DMDASetClosureScalar(dm,section,p,vArray,values,mode);CHKERRQ(ierr);
49957459e9aSMatthew G Knepley   ierr = VecRestoreArray(v,&vArray);CHKERRQ(ierr);
50057459e9aSMatthew G Knepley   PetscFunctionReturn(0);
50157459e9aSMatthew G Knepley }
50257459e9aSMatthew G Knepley 
503ed4e918cSMatthew G Knepley #undef __FUNCT__
504ed4e918cSMatthew G Knepley #define __FUNCT__ "DMDACnvertToCell"
505ed4e918cSMatthew G Knepley /*@
506f0e3914cSSatish Balay   DMDAConvertToCell - Convert (i,j,k) to local cell number
507341c9bdaSMatthew G Knepley 
508ed4e918cSMatthew G Knepley   Not Collective
509ed4e918cSMatthew G Knepley 
510ed4e918cSMatthew G Knepley   Input Parameter:
511ed4e918cSMatthew G Knepley + da - the distributed array
512ed4e918cSMatthew G Knepley = s - A MatStencil giving (i,j,k)
513ed4e918cSMatthew G Knepley 
514ed4e918cSMatthew G Knepley   Output Parameter:
515ed4e918cSMatthew G Knepley . cell - the local cell number
516ed4e918cSMatthew G Knepley 
517ed4e918cSMatthew G Knepley   Level: developer
518ed4e918cSMatthew G Knepley 
519ed4e918cSMatthew G Knepley .seealso: DMDAVecGetClosure()
520ed4e918cSMatthew G Knepley @*/
521ed4e918cSMatthew G Knepley PetscErrorCode DMDAConvertToCell(DM dm, MatStencil s, PetscInt *cell)
522341c9bdaSMatthew G Knepley {
523341c9bdaSMatthew G Knepley   DM_DA         *da  = (DM_DA *) dm->data;
524341c9bdaSMatthew G Knepley   const PetscInt dim = da->dim;
525341c9bdaSMatthew G Knepley   const PetscInt mx  = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs;
526341c9bdaSMatthew G Knepley   const PetscInt nC  = (mx  )*(dim > 1 ? (my  )*(dim > 2 ? (mz  ) : 1) : 1);
527ed4e918cSMatthew G Knepley   const PetscInt il  = s.i - da->Xs/da->w, jl = dim > 1 ? s.j - da->Ys : 0, kl = dim > 2 ? s.k - da->Zs : 0;
528341c9bdaSMatthew G Knepley 
529341c9bdaSMatthew G Knepley   PetscFunctionBegin;
530ed4e918cSMatthew G Knepley   *cell = -1;
531ed4e918cSMatthew G Knepley   if ((s.i < da->Xs/da->w) || (s.i >= da->Xe/da->w))    SETERRQ3(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Stencil i %d should be in [%d, %d)", s.i, da->Xs/da->w, da->Xe/da->w);
532ed4e918cSMatthew G Knepley   if ((dim > 1) && ((s.j < da->Ys) || (s.j >= da->Ye))) SETERRQ3(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Stencil j %d should be in [%d, %d)", s.j, da->Ys, da->Ye);
533ed4e918cSMatthew G Knepley   if ((dim > 2) && ((s.k < da->Zs) || (s.k >= da->Ze))) SETERRQ3(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Stencil k %d should be in [%d, %d)", s.k, da->Zs, da->Ze);
534ed4e918cSMatthew G Knepley   *cell = (kl*my + jl)*mx + il;
535ed4e918cSMatthew G Knepley   PetscFunctionReturn(0);
536341c9bdaSMatthew G Knepley }
537341c9bdaSMatthew G Knepley 
53857459e9aSMatthew G Knepley #undef __FUNCT__
53957459e9aSMatthew G Knepley #define __FUNCT__ "DMDAComputeCellGeometry_2D"
54015d2e57cSJed Brown PetscErrorCode DMDAComputeCellGeometry_2D(DM dm, const PetscScalar vertices[], const PetscReal refPoint[], PetscReal J[], PetscReal invJ[], PetscReal *detJ)
54157459e9aSMatthew G Knepley {
54257459e9aSMatthew G Knepley   const PetscScalar x0   = vertices[0];
54357459e9aSMatthew G Knepley   const PetscScalar y0   = vertices[1];
54457459e9aSMatthew G Knepley   const PetscScalar x1   = vertices[2];
54557459e9aSMatthew G Knepley   const PetscScalar y1   = vertices[3];
54657459e9aSMatthew G Knepley   const PetscScalar x2   = vertices[4];
54757459e9aSMatthew G Knepley   const PetscScalar y2   = vertices[5];
54857459e9aSMatthew G Knepley   const PetscScalar x3   = vertices[6];
54957459e9aSMatthew G Knepley   const PetscScalar y3   = vertices[7];
55057459e9aSMatthew G Knepley   const PetscScalar f_01 = x2 - x1 - x3 + x0;
55157459e9aSMatthew G Knepley   const PetscScalar g_01 = y2 - y1 - y3 + y0;
55257459e9aSMatthew G Knepley   const PetscScalar x    = refPoint[0];
55357459e9aSMatthew G Knepley   const PetscScalar y    = refPoint[1];
55457459e9aSMatthew G Knepley   PetscReal         invDet;
55557459e9aSMatthew G Knepley   PetscErrorCode    ierr;
55657459e9aSMatthew G Knepley 
55757459e9aSMatthew G Knepley   PetscFunctionBegin;
55815d2e57cSJed Brown #if defined(PETSC_USE_DEBUG)
55915d2e57cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell (%g,%g)--(%g,%g)--(%g,%g)--(%g,%g)\n",
5604c06c320SMatthew G Knepley                      PetscRealPart(x0),PetscRealPart(y0),PetscRealPart(x1),PetscRealPart(y1),PetscRealPart(x2),PetscRealPart(y2),PetscRealPart(x3),PetscRealPart(y3));CHKERRQ(ierr);
56115d2e57cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Ref Point (%g,%g)\n", PetscRealPart(x), PetscRealPart(y));CHKERRQ(ierr);
56215d2e57cSJed Brown #endif
56315d2e57cSJed Brown   J[0] = PetscRealPart(x1 - x0 + f_01*y) * 0.5; J[1] = PetscRealPart(x3 - x0 + f_01*x) * 0.5;
56415d2e57cSJed Brown   J[2] = PetscRealPart(y1 - y0 + g_01*y) * 0.5; J[3] = PetscRealPart(y3 - y0 + g_01*x) * 0.5;
56557459e9aSMatthew G Knepley   *detJ   = J[0]*J[3] - J[1]*J[2];
56657459e9aSMatthew G Knepley   invDet  = 1.0/(*detJ);
56757459e9aSMatthew G Knepley   invJ[0] =  invDet*J[3]; invJ[1] = -invDet*J[1];
56857459e9aSMatthew G Knepley   invJ[2] = -invDet*J[2]; invJ[3] =  invDet*J[0];
56957459e9aSMatthew G Knepley   ierr = PetscLogFlops(30);CHKERRQ(ierr);
57057459e9aSMatthew G Knepley   PetscFunctionReturn(0);
57157459e9aSMatthew G Knepley }
57257459e9aSMatthew G Knepley 
57357459e9aSMatthew G Knepley #undef __FUNCT__
57457459e9aSMatthew G Knepley #define __FUNCT__ "DMDAComputeCellGeometry"
57557459e9aSMatthew G Knepley PetscErrorCode DMDAComputeCellGeometry(DM dm, PetscInt cell, PetscQuadrature *quad, PetscReal v0[], PetscReal J[], PetscReal invJ[], PetscReal detJ[])
57657459e9aSMatthew G Knepley {
57757459e9aSMatthew G Knepley   DM                 cdm;
57857459e9aSMatthew G Knepley   Vec                coordinates;
57957459e9aSMatthew G Knepley   const PetscScalar *vertices;
58057459e9aSMatthew G Knepley   PetscInt           dim, d, q;
58157459e9aSMatthew G Knepley   PetscErrorCode     ierr;
58257459e9aSMatthew G Knepley 
58357459e9aSMatthew G Knepley   PetscFunctionBegin;
58457459e9aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
58557459e9aSMatthew G Knepley   ierr = DMDAGetInfo(dm, &dim, 0,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
58657459e9aSMatthew G Knepley   ierr = DMDAGetCoordinates(dm, &coordinates);CHKERRQ(ierr);
58757459e9aSMatthew G Knepley   ierr = DMDAGetCoordinateDA(dm, &cdm);CHKERRQ(ierr);
58857459e9aSMatthew G Knepley   ierr = DMDAVecGetClosure(cdm, PETSC_NULL, coordinates, cell, &vertices);CHKERRQ(ierr);
58957459e9aSMatthew G Knepley   for(d = 0; d < dim; ++d) {
59015d2e57cSJed Brown     v0[d] = PetscRealPart(vertices[d]);
59157459e9aSMatthew G Knepley   }
59257459e9aSMatthew G Knepley   switch(dim) {
59357459e9aSMatthew G Knepley   case 2:
59457459e9aSMatthew G Knepley     for(q = 0; q < quad->numQuadPoints; ++q) {
59557459e9aSMatthew G Knepley       ierr = DMDAComputeCellGeometry_2D(dm, vertices, &quad->quadPoints[q*dim], J, invJ, detJ);CHKERRQ(ierr);
59657459e9aSMatthew G Knepley     }
59757459e9aSMatthew G Knepley     break;
59857459e9aSMatthew G Knepley   default:
59957459e9aSMatthew G Knepley     SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Dimension %d not supported", dim);
60057459e9aSMatthew G Knepley   }
60157459e9aSMatthew G Knepley   PetscFunctionReturn(0);
60257459e9aSMatthew G Knepley }
603