147c6ae99SBarry Smith 247c6ae99SBarry Smith /* 347c6ae99SBarry Smith Code for manipulating distributed regular arrays in parallel. 447c6ae99SBarry Smith */ 547c6ae99SBarry Smith 64035e84dSBarry Smith #include <petsc-private/dmdaimpl.h> /*I "petscdmda.h" I*/ 7b2fff234SMatthew G. Knepley #include <petscbt.h> 80c312b8eSJed Brown #include <petscsf.h> 9*b7a4d31fSMatthew G. Knepley #include <petscproblem.h> 109a800dd8SMatthew G. Knepley #include <petscfe.h> 1147c6ae99SBarry Smith 1247c6ae99SBarry Smith /* 13e3c5b3baSBarry Smith This allows the DMDA vectors to properly tell MATLAB their dimensions 1447c6ae99SBarry Smith */ 1547c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 16c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 17c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 1847c6ae99SBarry Smith #undef __FUNCT__ 1947c6ae99SBarry Smith #define __FUNCT__ "VecMatlabEnginePut_DA2d" 201e6b0712SBarry Smith static PetscErrorCode VecMatlabEnginePut_DA2d(PetscObject obj,void *mengine) 2147c6ae99SBarry Smith { 2247c6ae99SBarry Smith PetscErrorCode ierr; 2347c6ae99SBarry Smith PetscInt n,m; 2447c6ae99SBarry Smith Vec vec = (Vec)obj; 2547c6ae99SBarry Smith PetscScalar *array; 2647c6ae99SBarry Smith mxArray *mat; 279a42bb27SBarry Smith DM da; 2847c6ae99SBarry Smith 2947c6ae99SBarry Smith PetscFunctionBegin; 30c688c046SMatthew G Knepley ierr = VecGetDM(vec, &da);CHKERRQ(ierr); 31ce94432eSBarry Smith if (!da) SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_ARG_WRONGSTATE,"Vector not associated with a DMDA"); 32aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,0,0,0,&m,&n,0);CHKERRQ(ierr); 3347c6ae99SBarry Smith 3447c6ae99SBarry Smith ierr = VecGetArray(vec,&array);CHKERRQ(ierr); 3547c6ae99SBarry Smith #if !defined(PETSC_USE_COMPLEX) 3647c6ae99SBarry Smith mat = mxCreateDoubleMatrix(m,n,mxREAL); 3747c6ae99SBarry Smith #else 3847c6ae99SBarry Smith mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX); 3947c6ae99SBarry Smith #endif 4047c6ae99SBarry Smith ierr = PetscMemcpy(mxGetPr(mat),array,n*m*sizeof(PetscScalar));CHKERRQ(ierr); 4147c6ae99SBarry Smith ierr = PetscObjectName(obj);CHKERRQ(ierr); 4247c6ae99SBarry Smith engPutVariable((Engine*)mengine,obj->name,mat); 4347c6ae99SBarry Smith 4447c6ae99SBarry Smith ierr = VecRestoreArray(vec,&array);CHKERRQ(ierr); 4547c6ae99SBarry Smith PetscFunctionReturn(0); 4647c6ae99SBarry Smith } 4747c6ae99SBarry Smith #endif 4847c6ae99SBarry Smith 4947c6ae99SBarry Smith 5047c6ae99SBarry Smith #undef __FUNCT__ 51564755cdSBarry Smith #define __FUNCT__ "DMCreateLocalVector_DA" 527087cfbeSBarry Smith PetscErrorCode DMCreateLocalVector_DA(DM da,Vec *g) 5347c6ae99SBarry Smith { 5447c6ae99SBarry Smith PetscErrorCode ierr; 5547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 5647c6ae99SBarry Smith 5747c6ae99SBarry Smith PetscFunctionBegin; 5847c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 5947c6ae99SBarry Smith PetscValidPointer(g,2); 6011689aebSJed Brown if (da->defaultSection) { 6111689aebSJed Brown ierr = DMCreateLocalVector_Section_Private(da,g);CHKERRQ(ierr); 6211689aebSJed Brown } else { 6347c6ae99SBarry Smith ierr = VecCreate(PETSC_COMM_SELF,g);CHKERRQ(ierr); 6447c6ae99SBarry Smith ierr = VecSetSizes(*g,dd->nlocal,PETSC_DETERMINE);CHKERRQ(ierr); 6547c6ae99SBarry Smith ierr = VecSetBlockSize(*g,dd->w);CHKERRQ(ierr); 66401ddaa8SBarry Smith ierr = VecSetType(*g,da->vectype);CHKERRQ(ierr); 67c688c046SMatthew G Knepley ierr = VecSetDM(*g, da);CHKERRQ(ierr); 6847c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 6947c6ae99SBarry Smith if (dd->w == 1 && dd->dim == 2) { 70bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)*g,"PetscMatlabEnginePut_C",VecMatlabEnginePut_DA2d);CHKERRQ(ierr); 7147c6ae99SBarry Smith } 7247c6ae99SBarry Smith #endif 7311689aebSJed Brown } 7447c6ae99SBarry Smith PetscFunctionReturn(0); 7547c6ae99SBarry Smith } 7647c6ae99SBarry Smith 77a66d4d66SMatthew G Knepley #undef __FUNCT__ 7857459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumCells" 79939f6067SMatthew G. Knepley /*@ 80939f6067SMatthew G. Knepley DMDAGetNumCells - Get the number of cells in the local piece of the DMDA. This includes ghost cells. 81939f6067SMatthew G. Knepley 82939f6067SMatthew G. Knepley Input Parameter: 83939f6067SMatthew G. Knepley . dm - The DM object 84939f6067SMatthew G. Knepley 85939f6067SMatthew G. Knepley Output Parameters: 86939f6067SMatthew G. Knepley + numCellsX - The number of local cells in the x-direction 87939f6067SMatthew G. Knepley . numCellsY - The number of local cells in the y-direction 88939f6067SMatthew G. Knepley . numCellsZ - The number of local cells in the z-direction 89939f6067SMatthew G. Knepley - numCells - The number of local cells 90939f6067SMatthew G. Knepley 91939f6067SMatthew G. Knepley Level: developer 92939f6067SMatthew G. Knepley 93939f6067SMatthew G. Knepley .seealso: DMDAGetCellPoint() 94939f6067SMatthew G. Knepley @*/ 953582350cSMatthew G. Knepley PetscErrorCode DMDAGetNumCells(DM dm, PetscInt *numCellsX, PetscInt *numCellsY, PetscInt *numCellsZ, PetscInt *numCells) 9657459e9aSMatthew G Knepley { 9757459e9aSMatthew G Knepley DM_DA *da = (DM_DA*) dm->data; 9857459e9aSMatthew G Knepley const PetscInt dim = da->dim; 9957459e9aSMatthew G Knepley const PetscInt mx = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs; 10057459e9aSMatthew G Knepley const PetscInt nC = (mx)*(dim > 1 ? (my)*(dim > 2 ? (mz) : 1) : 1); 10157459e9aSMatthew G Knepley 10257459e9aSMatthew G Knepley PetscFunctionBegin; 103d6401b93SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1043582350cSMatthew G. Knepley if (numCellsX) { 1053582350cSMatthew G. Knepley PetscValidIntPointer(numCellsX,2); 1063582350cSMatthew G. Knepley *numCellsX = mx; 1073582350cSMatthew G. Knepley } 1083582350cSMatthew G. Knepley if (numCellsY) { 1093582350cSMatthew G. Knepley PetscValidIntPointer(numCellsX,3); 1103582350cSMatthew G. Knepley *numCellsY = my; 1113582350cSMatthew G. Knepley } 1123582350cSMatthew G. Knepley if (numCellsZ) { 1133582350cSMatthew G. Knepley PetscValidIntPointer(numCellsX,4); 1143582350cSMatthew G. Knepley *numCellsZ = mz; 1153582350cSMatthew G. Knepley } 11657459e9aSMatthew G Knepley if (numCells) { 1173582350cSMatthew G. Knepley PetscValidIntPointer(numCells,5); 11857459e9aSMatthew G Knepley *numCells = nC; 11957459e9aSMatthew G Knepley } 12057459e9aSMatthew G Knepley PetscFunctionReturn(0); 12157459e9aSMatthew G Knepley } 12257459e9aSMatthew G Knepley 12357459e9aSMatthew G Knepley #undef __FUNCT__ 124d6401b93SMatthew G. Knepley #define __FUNCT__ "DMDAGetCellPoint" 125d6401b93SMatthew G. Knepley /*@ 126d6401b93SMatthew G. Knepley DMDAGetCellPoint - Get the DM point corresponding to the tuple (i, j, k) in the DMDA 127d6401b93SMatthew G. Knepley 128d6401b93SMatthew G. Knepley Input Parameters: 129d6401b93SMatthew G. Knepley + dm - The DM object 130d6401b93SMatthew G. Knepley - i,j,k - The global indices for the cell 131d6401b93SMatthew G. Knepley 132d6401b93SMatthew G. Knepley Output Parameters: 133d6401b93SMatthew G. Knepley . point - The local DM point 134d6401b93SMatthew G. Knepley 135d6401b93SMatthew G. Knepley Level: developer 136d6401b93SMatthew G. Knepley 137d6401b93SMatthew G. Knepley .seealso: DMDAGetNumCells() 138d6401b93SMatthew G. Knepley @*/ 139d6401b93SMatthew G. Knepley PetscErrorCode DMDAGetCellPoint(DM dm, PetscInt i, PetscInt j, PetscInt k, PetscInt *point) 140d6401b93SMatthew G. Knepley { 141d6401b93SMatthew G. Knepley DM_DA *da = (DM_DA*) dm->data; 142d6401b93SMatthew G. Knepley const PetscInt dim = da->dim; 143d6401b93SMatthew G. Knepley DMDALocalInfo info; 144d6401b93SMatthew G. Knepley PetscErrorCode ierr; 145d6401b93SMatthew G. Knepley 146d6401b93SMatthew G. Knepley PetscFunctionBegin; 147d6401b93SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 148d6401b93SMatthew G. Knepley PetscValidIntPointer(point,5); 149d6401b93SMatthew G. Knepley ierr = DMDAGetLocalInfo(dm, &info);CHKERRQ(ierr); 150d6401b93SMatthew G. Knepley if (dim > 0) {if ((i < info.gxs) || (i >= info.gxs+info.gxm)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "X index %d not in [%d, %d)", i, info.gxs, info.gxs+info.gxm);} 151d6401b93SMatthew G. Knepley if (dim > 1) {if ((i < info.gys) || (i >= info.gys+info.gym)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Y index %d not in [%d, %d)", i, info.gys, info.gys+info.gym);} 152d6401b93SMatthew G. Knepley if (dim > 2) {if ((i < info.gzs) || (i >= info.gzs+info.gzm)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Z index %d not in [%d, %d)", i, info.gzs, info.gzs+info.gzm);} 153d6401b93SMatthew G. Knepley *point = i + (dim > 1 ? (j + (dim > 2 ? k*info.gym : 0))*info.gxm : 0); 154d6401b93SMatthew G. Knepley PetscFunctionReturn(0); 155d6401b93SMatthew G. Knepley } 156d6401b93SMatthew G. Knepley 157d6401b93SMatthew G. Knepley #undef __FUNCT__ 15857459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumVertices" 15957459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumVertices(DM dm, PetscInt *numVerticesX, PetscInt *numVerticesY, PetscInt *numVerticesZ, PetscInt *numVertices) 16057459e9aSMatthew G Knepley { 16157459e9aSMatthew G Knepley DM_DA *da = (DM_DA*) dm->data; 16257459e9aSMatthew G Knepley const PetscInt dim = da->dim; 16357459e9aSMatthew G Knepley const PetscInt mx = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs; 16457459e9aSMatthew G Knepley const PetscInt nVx = mx+1; 16557459e9aSMatthew G Knepley const PetscInt nVy = dim > 1 ? (my+1) : 1; 16657459e9aSMatthew G Knepley const PetscInt nVz = dim > 2 ? (mz+1) : 1; 16757459e9aSMatthew G Knepley const PetscInt nV = nVx*nVy*nVz; 16857459e9aSMatthew G Knepley 16957459e9aSMatthew G Knepley PetscFunctionBegin; 17057459e9aSMatthew G Knepley if (numVerticesX) { 17157459e9aSMatthew G Knepley PetscValidIntPointer(numVerticesX,2); 17257459e9aSMatthew G Knepley *numVerticesX = nVx; 17357459e9aSMatthew G Knepley } 17457459e9aSMatthew G Knepley if (numVerticesY) { 17557459e9aSMatthew G Knepley PetscValidIntPointer(numVerticesY,3); 17657459e9aSMatthew G Knepley *numVerticesY = nVy; 17757459e9aSMatthew G Knepley } 17857459e9aSMatthew G Knepley if (numVerticesZ) { 17957459e9aSMatthew G Knepley PetscValidIntPointer(numVerticesZ,4); 18057459e9aSMatthew G Knepley *numVerticesZ = nVz; 18157459e9aSMatthew G Knepley } 18257459e9aSMatthew G Knepley if (numVertices) { 18357459e9aSMatthew G Knepley PetscValidIntPointer(numVertices,5); 18457459e9aSMatthew G Knepley *numVertices = nV; 18557459e9aSMatthew G Knepley } 18657459e9aSMatthew G Knepley PetscFunctionReturn(0); 18757459e9aSMatthew G Knepley } 18857459e9aSMatthew G Knepley 18957459e9aSMatthew G Knepley #undef __FUNCT__ 19057459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumFaces" 19157459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumFaces(DM dm, PetscInt *numXFacesX, PetscInt *numXFaces, PetscInt *numYFacesY, PetscInt *numYFaces, PetscInt *numZFacesZ, PetscInt *numZFaces) 19257459e9aSMatthew G Knepley { 19357459e9aSMatthew G Knepley DM_DA *da = (DM_DA*) dm->data; 19457459e9aSMatthew G Knepley const PetscInt dim = da->dim; 19557459e9aSMatthew G Knepley const PetscInt mx = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs; 19657459e9aSMatthew G Knepley const PetscInt nxF = (dim > 1 ? (my)*(dim > 2 ? (mz) : 1) : 1); 19757459e9aSMatthew G Knepley const PetscInt nXF = (mx+1)*nxF; 19857459e9aSMatthew G Knepley const PetscInt nyF = mx*(dim > 2 ? mz : 1); 19957459e9aSMatthew G Knepley const PetscInt nYF = dim > 1 ? (my+1)*nyF : 0; 20057459e9aSMatthew G Knepley const PetscInt nzF = mx*(dim > 1 ? my : 0); 20157459e9aSMatthew G Knepley const PetscInt nZF = dim > 2 ? (mz+1)*nzF : 0; 20257459e9aSMatthew G Knepley 20357459e9aSMatthew G Knepley PetscFunctionBegin; 20457459e9aSMatthew G Knepley if (numXFacesX) { 20557459e9aSMatthew G Knepley PetscValidIntPointer(numXFacesX,2); 20657459e9aSMatthew G Knepley *numXFacesX = nxF; 20757459e9aSMatthew G Knepley } 20857459e9aSMatthew G Knepley if (numXFaces) { 20957459e9aSMatthew G Knepley PetscValidIntPointer(numXFaces,3); 21057459e9aSMatthew G Knepley *numXFaces = nXF; 21157459e9aSMatthew G Knepley } 21257459e9aSMatthew G Knepley if (numYFacesY) { 21357459e9aSMatthew G Knepley PetscValidIntPointer(numYFacesY,4); 21457459e9aSMatthew G Knepley *numYFacesY = nyF; 21557459e9aSMatthew G Knepley } 21657459e9aSMatthew G Knepley if (numYFaces) { 21757459e9aSMatthew G Knepley PetscValidIntPointer(numYFaces,5); 21857459e9aSMatthew G Knepley *numYFaces = nYF; 21957459e9aSMatthew G Knepley } 22057459e9aSMatthew G Knepley if (numZFacesZ) { 22157459e9aSMatthew G Knepley PetscValidIntPointer(numZFacesZ,6); 22257459e9aSMatthew G Knepley *numZFacesZ = nzF; 22357459e9aSMatthew G Knepley } 22457459e9aSMatthew G Knepley if (numZFaces) { 22557459e9aSMatthew G Knepley PetscValidIntPointer(numZFaces,7); 22657459e9aSMatthew G Knepley *numZFaces = nZF; 22757459e9aSMatthew G Knepley } 22857459e9aSMatthew G Knepley PetscFunctionReturn(0); 22957459e9aSMatthew G Knepley } 23057459e9aSMatthew G Knepley 23157459e9aSMatthew G Knepley #undef __FUNCT__ 23257459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetHeightStratum" 23357459e9aSMatthew G Knepley PetscErrorCode DMDAGetHeightStratum(DM dm, PetscInt height, PetscInt *pStart, PetscInt *pEnd) 23457459e9aSMatthew G Knepley { 23557459e9aSMatthew G Knepley DM_DA *da = (DM_DA*) dm->data; 23657459e9aSMatthew G Knepley const PetscInt dim = da->dim; 23757459e9aSMatthew G Knepley PetscInt nC, nV, nXF, nYF, nZF; 23857459e9aSMatthew G Knepley PetscErrorCode ierr; 23957459e9aSMatthew G Knepley 24057459e9aSMatthew G Knepley PetscFunctionBegin; 2418865f1eaSKarl Rupp if (pStart) PetscValidIntPointer(pStart,3); 2428865f1eaSKarl Rupp if (pEnd) PetscValidIntPointer(pEnd,4); 2433582350cSMatthew G. Knepley ierr = DMDAGetNumCells(dm, NULL, NULL, NULL, &nC);CHKERRQ(ierr); 2440298fd71SBarry Smith ierr = DMDAGetNumVertices(dm, NULL, NULL, NULL, &nV);CHKERRQ(ierr); 2450298fd71SBarry Smith ierr = DMDAGetNumFaces(dm, NULL, &nXF, NULL, &nYF, NULL, &nZF);CHKERRQ(ierr); 24657459e9aSMatthew G Knepley if (height == 0) { 24757459e9aSMatthew G Knepley /* Cells */ 2488865f1eaSKarl Rupp if (pStart) *pStart = 0; 2498865f1eaSKarl Rupp if (pEnd) *pEnd = nC; 25057459e9aSMatthew G Knepley } else if (height == 1) { 25157459e9aSMatthew G Knepley /* Faces */ 2528865f1eaSKarl Rupp if (pStart) *pStart = nC+nV; 2538865f1eaSKarl Rupp if (pEnd) *pEnd = nC+nV+nXF+nYF+nZF; 25457459e9aSMatthew G Knepley } else if (height == dim) { 25557459e9aSMatthew G Knepley /* Vertices */ 2568865f1eaSKarl Rupp if (pStart) *pStart = nC; 2578865f1eaSKarl Rupp if (pEnd) *pEnd = nC+nV; 25857459e9aSMatthew G Knepley } else if (height < 0) { 25957459e9aSMatthew G Knepley /* All points */ 2608865f1eaSKarl Rupp if (pStart) *pStart = 0; 2618865f1eaSKarl Rupp if (pEnd) *pEnd = nC+nV+nXF+nYF+nZF; 26282f516ccSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "No points of height %d in the DA", height); 26357459e9aSMatthew G Knepley PetscFunctionReturn(0); 26457459e9aSMatthew G Knepley } 26557459e9aSMatthew G Knepley 26657459e9aSMatthew G Knepley #undef __FUNCT__ 2673385ff7eSMatthew G. Knepley #define __FUNCT__ "DMDAGetDepthStratum" 2683385ff7eSMatthew G. Knepley PetscErrorCode DMDAGetDepthStratum(DM dm, PetscInt depth, PetscInt *pStart, PetscInt *pEnd) 2693385ff7eSMatthew G. Knepley { 2703385ff7eSMatthew G. Knepley DM_DA *da = (DM_DA*) dm->data; 2713385ff7eSMatthew G. Knepley const PetscInt dim = da->dim; 2723385ff7eSMatthew G. Knepley PetscInt nC, nV, nXF, nYF, nZF; 2733385ff7eSMatthew G. Knepley PetscErrorCode ierr; 2743385ff7eSMatthew G. Knepley 2753385ff7eSMatthew G. Knepley PetscFunctionBegin; 2763385ff7eSMatthew G. Knepley if (pStart) PetscValidIntPointer(pStart,3); 2773385ff7eSMatthew G. Knepley if (pEnd) PetscValidIntPointer(pEnd,4); 2783385ff7eSMatthew G. Knepley ierr = DMDAGetNumCells(dm, NULL, NULL, NULL, &nC);CHKERRQ(ierr); 2793385ff7eSMatthew G. Knepley ierr = DMDAGetNumVertices(dm, NULL, NULL, NULL, &nV);CHKERRQ(ierr); 2803385ff7eSMatthew G. Knepley ierr = DMDAGetNumFaces(dm, NULL, &nXF, NULL, &nYF, NULL, &nZF);CHKERRQ(ierr); 2813385ff7eSMatthew G. Knepley if (depth == dim) { 2823385ff7eSMatthew G. Knepley /* Cells */ 2833385ff7eSMatthew G. Knepley if (pStart) *pStart = 0; 2843385ff7eSMatthew G. Knepley if (pEnd) *pEnd = nC; 2853385ff7eSMatthew G. Knepley } else if (depth == dim-1) { 2863385ff7eSMatthew G. Knepley /* Faces */ 2873385ff7eSMatthew G. Knepley if (pStart) *pStart = nC+nV; 2883385ff7eSMatthew G. Knepley if (pEnd) *pEnd = nC+nV+nXF+nYF+nZF; 2893385ff7eSMatthew G. Knepley } else if (depth == 0) { 2903385ff7eSMatthew G. Knepley /* Vertices */ 2913385ff7eSMatthew G. Knepley if (pStart) *pStart = nC; 2923385ff7eSMatthew G. Knepley if (pEnd) *pEnd = nC+nV; 2933385ff7eSMatthew G. Knepley } else if (depth < 0) { 2943385ff7eSMatthew G. Knepley /* All points */ 2953385ff7eSMatthew G. Knepley if (pStart) *pStart = 0; 2963385ff7eSMatthew G. Knepley if (pEnd) *pEnd = nC+nV+nXF+nYF+nZF; 2973385ff7eSMatthew G. Knepley } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "No points of depth %d in the DA", depth); 2983385ff7eSMatthew G. Knepley PetscFunctionReturn(0); 2993385ff7eSMatthew G. Knepley } 3003385ff7eSMatthew G. Knepley 3013385ff7eSMatthew G. Knepley #undef __FUNCT__ 3023385ff7eSMatthew G. Knepley #define __FUNCT__ "DMDAGetConeSize" 3033385ff7eSMatthew G. Knepley PetscErrorCode DMDAGetConeSize(DM dm, PetscInt p, PetscInt *coneSize) 3043385ff7eSMatthew G. Knepley { 3053385ff7eSMatthew G. Knepley DM_DA *da = (DM_DA*) dm->data; 3063385ff7eSMatthew G. Knepley const PetscInt dim = da->dim; 3073385ff7eSMatthew G. Knepley PetscInt nC, nV, nXF, nYF, nZF; 3083385ff7eSMatthew G. Knepley PetscErrorCode ierr; 3093385ff7eSMatthew G. Knepley 3103385ff7eSMatthew G. Knepley PetscFunctionBegin; 3113385ff7eSMatthew G. Knepley *coneSize = 0; 3123385ff7eSMatthew G. Knepley ierr = DMDAGetNumCells(dm, NULL, NULL, NULL, &nC);CHKERRQ(ierr); 3133385ff7eSMatthew G. Knepley ierr = DMDAGetNumVertices(dm, NULL, NULL, NULL, &nV);CHKERRQ(ierr); 3143385ff7eSMatthew G. Knepley ierr = DMDAGetNumFaces(dm, NULL, &nXF, NULL, &nYF, NULL, &nZF);CHKERRQ(ierr); 3153385ff7eSMatthew G. Knepley switch (dim) { 3163385ff7eSMatthew G. Knepley case 2: 3173385ff7eSMatthew G. Knepley if (p >= 0) { 3183385ff7eSMatthew G. Knepley if (p < nC) { 3193385ff7eSMatthew G. Knepley *coneSize = 4; 3203385ff7eSMatthew G. Knepley } else if (p < nC+nV) { 3213385ff7eSMatthew G. Knepley *coneSize = 0; 3223385ff7eSMatthew G. Knepley } else if (p < nC+nV+nXF+nYF+nZF) { 3233385ff7eSMatthew G. Knepley *coneSize = 2; 3243385ff7eSMatthew G. Knepley } else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point %d should be in [0, %d)", p, nC+nV+nXF+nYF+nZF); 3253385ff7eSMatthew G. Knepley } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative point %d is invalid", p); 3263385ff7eSMatthew G. Knepley break; 3273385ff7eSMatthew G. Knepley case 3: 3283385ff7eSMatthew G. Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Too lazy to do 3D"); 3293385ff7eSMatthew G. Knepley break; 3303385ff7eSMatthew G. Knepley } 3313385ff7eSMatthew G. Knepley PetscFunctionReturn(0); 3323385ff7eSMatthew G. Knepley } 3333385ff7eSMatthew G. Knepley 3343385ff7eSMatthew G. Knepley #undef __FUNCT__ 3353385ff7eSMatthew G. Knepley #define __FUNCT__ "DMDAGetCone" 3363385ff7eSMatthew G. Knepley PetscErrorCode DMDAGetCone(DM dm, PetscInt p, PetscInt *cone[]) 3373385ff7eSMatthew G. Knepley { 3383385ff7eSMatthew G. Knepley DM_DA *da = (DM_DA*) dm->data; 3393385ff7eSMatthew G. Knepley const PetscInt dim = da->dim; 3403385ff7eSMatthew G. Knepley PetscInt nCx, nCy, nCz, nC, nVx, nVy, nVz, nV, nxF, nyF, nzF, nXF, nYF, nZF; 3413385ff7eSMatthew G. Knepley PetscErrorCode ierr; 3423385ff7eSMatthew G. Knepley 3433385ff7eSMatthew G. Knepley PetscFunctionBegin; 3443385ff7eSMatthew G. Knepley if (!cone) {ierr = DMGetWorkArray(dm, 6, PETSC_INT, cone);CHKERRQ(ierr);} 3453385ff7eSMatthew G. Knepley ierr = DMDAGetNumCells(dm, &nCx, &nCy, &nCz, &nC);CHKERRQ(ierr); 3463385ff7eSMatthew G. Knepley ierr = DMDAGetNumVertices(dm, &nVx, &nVy, &nVz, &nV);CHKERRQ(ierr); 3473385ff7eSMatthew G. Knepley ierr = DMDAGetNumFaces(dm, &nxF, &nXF, &nyF, &nYF, &nzF, &nZF);CHKERRQ(ierr); 3483385ff7eSMatthew G. Knepley switch (dim) { 3493385ff7eSMatthew G. Knepley case 2: 3503385ff7eSMatthew G. Knepley if (p >= 0) { 3513385ff7eSMatthew G. Knepley if (p < nC) { 3523385ff7eSMatthew G. Knepley const PetscInt cy = p / nCx; 3533385ff7eSMatthew G. Knepley const PetscInt cx = p % nCx; 3543385ff7eSMatthew G. Knepley 3553385ff7eSMatthew G. Knepley (*cone)[0] = cy*nxF + cx + nC+nV; 3563385ff7eSMatthew G. Knepley (*cone)[1] = cx*nyF + cy + nyF + nC+nV+nXF; 3573385ff7eSMatthew G. Knepley (*cone)[2] = cy*nxF + cx + nxF + nC+nV; 3583385ff7eSMatthew G. Knepley (*cone)[3] = cx*nyF + cy + nC+nV+nXF; 3593385ff7eSMatthew G. Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Too lazy to do cell cones"); 3603385ff7eSMatthew G. Knepley } else if (p < nC+nV) { 3613385ff7eSMatthew G. Knepley } else if (p < nC+nV+nXF) { 3623385ff7eSMatthew G. Knepley const PetscInt fy = (p - nC+nV) / nxF; 3633385ff7eSMatthew G. Knepley const PetscInt fx = (p - nC+nV) % nxF; 3643385ff7eSMatthew G. Knepley 3653385ff7eSMatthew G. Knepley (*cone)[0] = fy*nVx + fx + nC; 3663385ff7eSMatthew G. Knepley (*cone)[1] = fy*nVx + fx + 1 + nC; 3673385ff7eSMatthew G. Knepley } else if (p < nC+nV+nXF+nYF) { 3683385ff7eSMatthew G. Knepley const PetscInt fx = (p - nC+nV+nXF) / nyF; 3693385ff7eSMatthew G. Knepley const PetscInt fy = (p - nC+nV+nXF) % nyF; 3703385ff7eSMatthew G. Knepley 3713385ff7eSMatthew G. Knepley (*cone)[0] = fy*nVx + fx + nC; 3723385ff7eSMatthew G. Knepley (*cone)[1] = fy*nVx + fx + nVx + nC; 3733385ff7eSMatthew G. Knepley } else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point %d should be in [0, %d)", p, nC+nV+nXF+nYF+nZF); 3743385ff7eSMatthew G. Knepley } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative point %d is invalid", p); 3753385ff7eSMatthew G. Knepley break; 3763385ff7eSMatthew G. Knepley case 3: 3773385ff7eSMatthew G. Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Too lazy to do 3D"); 3783385ff7eSMatthew G. Knepley break; 3793385ff7eSMatthew G. Knepley } 3803385ff7eSMatthew G. Knepley PetscFunctionReturn(0); 3813385ff7eSMatthew G. Knepley } 3823385ff7eSMatthew G. Knepley 3833385ff7eSMatthew G. Knepley #undef __FUNCT__ 3843385ff7eSMatthew G. Knepley #define __FUNCT__ "DMDARestoreCone" 3853385ff7eSMatthew G. Knepley PetscErrorCode DMDARestoreCone(DM dm, PetscInt p, PetscInt *cone[]) 3863385ff7eSMatthew G. Knepley { 3873385ff7eSMatthew G. Knepley PetscErrorCode ierr; 3883385ff7eSMatthew G. Knepley 3893385ff7eSMatthew G. Knepley PetscFunctionBegin; 3903385ff7eSMatthew G. Knepley ierr = DMGetWorkArray(dm, 6, PETSC_INT, cone);CHKERRQ(ierr); 3913385ff7eSMatthew G. Knepley PetscFunctionReturn(0); 3923385ff7eSMatthew G. Knepley } 3933385ff7eSMatthew G. Knepley 3943385ff7eSMatthew G. Knepley #undef __FUNCT__ 395a66d4d66SMatthew G Knepley #define __FUNCT__ "DMDACreateSection" 396a66d4d66SMatthew G Knepley /*@C 397a66d4d66SMatthew G Knepley DMDACreateSection - Create a PetscSection inside the DMDA that describes data layout. This allows multiple fields with 398a66d4d66SMatthew G Knepley different numbers of dofs on vertices, cells, and faces in each direction. 399a66d4d66SMatthew G Knepley 400a66d4d66SMatthew G Knepley Input Parameters: 401a66d4d66SMatthew G Knepley + dm- The DMDA 402a66d4d66SMatthew G Knepley . numFields - The number of fields 403affa55c7SMatthew G. Knepley . numComp - The number of components in each field 404affa55c7SMatthew G. Knepley . numDof - The number of dofs per dimension for each field 4050298fd71SBarry Smith . numFaceDof - The number of dofs per face for each field and direction, or NULL 406a66d4d66SMatthew G Knepley 407a66d4d66SMatthew G Knepley Level: developer 408a66d4d66SMatthew G Knepley 409a66d4d66SMatthew G Knepley Note: 410a66d4d66SMatthew G Knepley The default DMDA numbering is as follows: 411a66d4d66SMatthew G Knepley 412a66d4d66SMatthew G Knepley - Cells: [0, nC) 413a66d4d66SMatthew G Knepley - Vertices: [nC, nC+nV) 41488ed4aceSMatthew G Knepley - X-Faces: [nC+nV, nC+nV+nXF) normal is +- x-dir 41588ed4aceSMatthew G Knepley - Y-Faces: [nC+nV+nXF, nC+nV+nXF+nYF) normal is +- y-dir 41688ed4aceSMatthew G Knepley - Z-Faces: [nC+nV+nXF+nYF, nC+nV+nXF+nYF+nZF) normal is +- z-dir 417a66d4d66SMatthew G Knepley 418a66d4d66SMatthew G Knepley We interpret the default DMDA partition as a cell partition, and the data assignment as a cell assignment. 419a66d4d66SMatthew G Knepley @*/ 42044e1f9abSMatthew G. Knepley PetscErrorCode DMDACreateSection(DM dm, const PetscInt numComp[], const PetscInt numDof[], const PetscInt numFaceDof[], PetscSection *s) 421a66d4d66SMatthew G Knepley { 422a66d4d66SMatthew G Knepley DM_DA *da = (DM_DA*) dm->data; 423a4b60ecfSMatthew G. Knepley PetscSection section; 42488ed4aceSMatthew G Knepley const PetscInt dim = da->dim; 42580800b1aSMatthew G Knepley PetscInt numFields, numVertexTotDof = 0, numCellTotDof = 0, numFaceTotDof[3] = {0, 0, 0}; 426b2fff234SMatthew G. Knepley PetscBT isLeaf; 42788ed4aceSMatthew G Knepley PetscSF sf; 428feafbc5cSMatthew G Knepley PetscMPIInt rank; 42988ed4aceSMatthew G Knepley const PetscMPIInt *neighbors; 43088ed4aceSMatthew G Knepley PetscInt *localPoints; 43188ed4aceSMatthew G Knepley PetscSFNode *remotePoints; 432f5eeb527SMatthew G Knepley PetscInt nleaves = 0, nleavesCheck = 0, nL = 0; 43357459e9aSMatthew G Knepley PetscInt nC, nVx, nVy, nVz, nV, nxF, nXF, nyF, nYF, nzF, nZF; 43457459e9aSMatthew G Knepley PetscInt pStart, pEnd, cStart, cEnd, vStart, vEnd, fStart, fEnd, xfStart, xfEnd, yfStart, yfEnd, zfStart, zfEnd; 43588ed4aceSMatthew G Knepley PetscInt f, v, c, xf, yf, zf, xn, yn, zn; 436a66d4d66SMatthew G Knepley PetscErrorCode ierr; 437a66d4d66SMatthew G Knepley 438a66d4d66SMatthew G Knepley PetscFunctionBegin; 439a66d4d66SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4403582350cSMatthew G. Knepley PetscValidPointer(s, 4); 44182f516ccSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr); 4423582350cSMatthew G. Knepley ierr = DMDAGetNumCells(dm, NULL, NULL, NULL, &nC);CHKERRQ(ierr); 44357459e9aSMatthew G Knepley ierr = DMDAGetNumVertices(dm, &nVx, &nVy, &nVz, &nV);CHKERRQ(ierr); 44457459e9aSMatthew G Knepley ierr = DMDAGetNumFaces(dm, &nxF, &nXF, &nyF, &nYF, &nzF, &nZF);CHKERRQ(ierr); 44557459e9aSMatthew G Knepley ierr = DMDAGetHeightStratum(dm, -1, &pStart, &pEnd);CHKERRQ(ierr); 44657459e9aSMatthew G Knepley ierr = DMDAGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 44757459e9aSMatthew G Knepley ierr = DMDAGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 44857459e9aSMatthew G Knepley ierr = DMDAGetHeightStratum(dm, dim, &vStart, &vEnd);CHKERRQ(ierr); 44957459e9aSMatthew G Knepley xfStart = vEnd; xfEnd = xfStart+nXF; 45057459e9aSMatthew G Knepley yfStart = xfEnd; yfEnd = yfStart+nYF; 45157459e9aSMatthew G Knepley zfStart = yfEnd; zfEnd = zfStart+nZF; 45282f516ccSBarry Smith if (zfEnd != fEnd) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Invalid face end %d, should be %d", zfEnd, fEnd); 45388ed4aceSMatthew G Knepley /* Create local section */ 45480800b1aSMatthew G Knepley ierr = DMDAGetInfo(dm, 0,0,0,0,0,0,0, &numFields, 0,0,0,0,0);CHKERRQ(ierr); 455a66d4d66SMatthew G Knepley for (f = 0; f < numFields; ++f) { 456affa55c7SMatthew G. Knepley numVertexTotDof += numDof[f*(dim+1)+0]; 457affa55c7SMatthew G. Knepley numCellTotDof += numDof[f*(dim+1)+dim]; 458affa55c7SMatthew G. Knepley numFaceTotDof[0] += dim > 0 ? (numFaceDof ? numFaceDof[f*dim+0] : numDof[f*(dim+1)+dim-1]) : 0; 459affa55c7SMatthew G. Knepley numFaceTotDof[1] += dim > 1 ? (numFaceDof ? numFaceDof[f*dim+1] : numDof[f*(dim+1)+dim-1]) : 0; 460affa55c7SMatthew G. Knepley numFaceTotDof[2] += dim > 2 ? (numFaceDof ? numFaceDof[f*dim+2] : numDof[f*(dim+1)+dim-1]) : 0; 461a66d4d66SMatthew G Knepley } 462a4b60ecfSMatthew G. Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 463affa55c7SMatthew G. Knepley if (numFields > 0) { 464a4b60ecfSMatthew G. Knepley ierr = PetscSectionSetNumFields(section, numFields);CHKERRQ(ierr); 465a66d4d66SMatthew G Knepley for (f = 0; f < numFields; ++f) { 46680800b1aSMatthew G Knepley const char *name; 46780800b1aSMatthew G Knepley 46880800b1aSMatthew G Knepley ierr = DMDAGetFieldName(dm, f, &name);CHKERRQ(ierr); 469affa55c7SMatthew G. Knepley ierr = PetscSectionSetFieldName(section, f, name ? name : "Field");CHKERRQ(ierr); 47080800b1aSMatthew G Knepley if (numComp) { 471a4b60ecfSMatthew G. Knepley ierr = PetscSectionSetFieldComponents(section, f, numComp[f]);CHKERRQ(ierr); 472a66d4d66SMatthew G Knepley } 473a66d4d66SMatthew G Knepley } 474a66d4d66SMatthew G Knepley } 475a4b60ecfSMatthew G. Knepley ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 476a66d4d66SMatthew G Knepley for (v = vStart; v < vEnd; ++v) { 477a66d4d66SMatthew G Knepley for (f = 0; f < numFields; ++f) { 478affa55c7SMatthew G. Knepley ierr = PetscSectionSetFieldDof(section, v, f, numDof[f*(dim+1)+0]);CHKERRQ(ierr); 479a66d4d66SMatthew G Knepley } 480a4b60ecfSMatthew G. Knepley ierr = PetscSectionSetDof(section, v, numVertexTotDof);CHKERRQ(ierr); 481a66d4d66SMatthew G Knepley } 482a66d4d66SMatthew G Knepley for (xf = xfStart; xf < xfEnd; ++xf) { 483a66d4d66SMatthew G Knepley for (f = 0; f < numFields; ++f) { 484affa55c7SMatthew G. Knepley ierr = PetscSectionSetFieldDof(section, xf, f, numFaceDof ? numFaceDof[f*dim+0] : numDof[f*(dim+1)+dim-1]);CHKERRQ(ierr); 485a66d4d66SMatthew G Knepley } 486a4b60ecfSMatthew G. Knepley ierr = PetscSectionSetDof(section, xf, numFaceTotDof[0]);CHKERRQ(ierr); 487a66d4d66SMatthew G Knepley } 488a66d4d66SMatthew G Knepley for (yf = yfStart; yf < yfEnd; ++yf) { 489a66d4d66SMatthew G Knepley for (f = 0; f < numFields; ++f) { 490affa55c7SMatthew G. Knepley ierr = PetscSectionSetFieldDof(section, yf, f, numFaceDof ? numFaceDof[f*dim+1] : numDof[f*(dim+1)+dim-1]);CHKERRQ(ierr); 491a66d4d66SMatthew G Knepley } 492a4b60ecfSMatthew G. Knepley ierr = PetscSectionSetDof(section, yf, numFaceTotDof[1]);CHKERRQ(ierr); 493a66d4d66SMatthew G Knepley } 494a66d4d66SMatthew G Knepley for (zf = zfStart; zf < zfEnd; ++zf) { 495a66d4d66SMatthew G Knepley for (f = 0; f < numFields; ++f) { 496affa55c7SMatthew G. Knepley ierr = PetscSectionSetFieldDof(section, zf, f, numFaceDof ? numFaceDof[f*dim+2] : numDof[f*(dim+1)+dim-1]);CHKERRQ(ierr); 497a66d4d66SMatthew G Knepley } 498a4b60ecfSMatthew G. Knepley ierr = PetscSectionSetDof(section, zf, numFaceTotDof[2]);CHKERRQ(ierr); 499a66d4d66SMatthew G Knepley } 500a66d4d66SMatthew G Knepley for (c = cStart; c < cEnd; ++c) { 501a66d4d66SMatthew G Knepley for (f = 0; f < numFields; ++f) { 502affa55c7SMatthew G. Knepley ierr = PetscSectionSetFieldDof(section, c, f, numDof[f*(dim+1)+dim]);CHKERRQ(ierr); 503a66d4d66SMatthew G Knepley } 504a4b60ecfSMatthew G. Knepley ierr = PetscSectionSetDof(section, c, numCellTotDof);CHKERRQ(ierr); 505a66d4d66SMatthew G Knepley } 506a4b60ecfSMatthew G. Knepley ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 50788ed4aceSMatthew G Knepley /* Create mesh point SF */ 508b2fff234SMatthew G. Knepley ierr = PetscBTCreate(pEnd-pStart, &isLeaf);CHKERRQ(ierr); 50988ed4aceSMatthew G Knepley ierr = DMDAGetNeighbors(dm, &neighbors);CHKERRQ(ierr); 51088ed4aceSMatthew G Knepley for (zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) { 51188ed4aceSMatthew G Knepley for (yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) { 51288ed4aceSMatthew G Knepley for (xn = 0; xn < 3; ++xn) { 5137128ae9fSMatthew G Knepley const PetscInt xp = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0; 51488ed4aceSMatthew G Knepley const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn]; 515b2fff234SMatthew G. Knepley PetscInt xv, yv, zv; 51688ed4aceSMatthew G Knepley 5173814d604SMatthew G Knepley if (neighbor >= 0 && neighbor < rank) { 518b2fff234SMatthew G. Knepley if (xp < 0) { /* left */ 519b2fff234SMatthew G. Knepley if (yp < 0) { /* bottom */ 520b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 521b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + 0)*nVx + 0 + nC; /* left bottom back vertex */ 522b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 523b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 524b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + 0 + nC; /* left bottom front vertex */ 525b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 526b2fff234SMatthew G. Knepley } else { 527b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 528b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + 0)*nVx + 0 + nC; /* left bottom vertices */ 529b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 530b2fff234SMatthew G. Knepley } 531b2fff234SMatthew G. Knepley } 532b2fff234SMatthew G. Knepley } else if (yp > 0) { /* top */ 533b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 534b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + 0 + nC; /* left top back vertex */ 535b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 536b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 537b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + 0 + nC; /* left top front vertex */ 538b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 539b2fff234SMatthew G. Knepley } else { 540b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 541b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + 0 + nC; /* left top vertices */ 542b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 543b2fff234SMatthew G. Knepley } 544b2fff234SMatthew G. Knepley } 545b2fff234SMatthew G. Knepley } else { 546b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 547b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 548b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + yv)*nVx + 0 + nC; /* left back vertices */ 549b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 550b2fff234SMatthew G. Knepley } 551b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 552b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 553b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + 0 + nC; /* left front vertices */ 554b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 555b2fff234SMatthew G. Knepley } 556b2fff234SMatthew G. Knepley } else { 557b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 558b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 559b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + yv)*nVx + 0 + nC; /* left vertices */ 560b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 561b2fff234SMatthew G. Knepley } 562b2fff234SMatthew G. Knepley } 563b2fff234SMatthew G. Knepley #if 0 564b2fff234SMatthew G. Knepley for (xf = 0; xf < nxF; ++xf) { 565b2fff234SMatthew G. Knepley /* THIS IS WRONG */ 566b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* left faces */ 567b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) ++nleaves; 568b2fff234SMatthew G. Knepley } 569b2fff234SMatthew G. Knepley #endif 570b2fff234SMatthew G. Knepley } 571b2fff234SMatthew G. Knepley } 572b2fff234SMatthew G. Knepley } else if (xp > 0) { /* right */ 573b2fff234SMatthew G. Knepley if (yp < 0) { /* bottom */ 574b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 575b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + 0)*nVx + nVx-1 + nC; /* right bottom back vertex */ 576b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 577b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 578b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + nVx-1 + nC; /* right bottom front vertex */ 579b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 580b2fff234SMatthew G. Knepley } else { 581b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 582b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + 0)*nVx + nVx-1 + nC; /* right bottom vertices */ 583b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 584b2fff234SMatthew G. Knepley } 585b2fff234SMatthew G. Knepley } 586b2fff234SMatthew G. Knepley } else if (yp > 0) { /* top */ 587b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 588b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top back vertex */ 589b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 590b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 591b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top front vertex */ 592b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 593b2fff234SMatthew G. Knepley } else { 594b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 595b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top vertices */ 596b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 597b2fff234SMatthew G. Knepley } 598b2fff234SMatthew G. Knepley } 599b2fff234SMatthew G. Knepley } else { 600b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 601b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 602b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + yv)*nVx + nVx-1 + nC; /* right back vertices */ 603b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 604b2fff234SMatthew G. Knepley } 605b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 606b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 607b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; /* right front vertices */ 608b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 609b2fff234SMatthew G. Knepley } 610b2fff234SMatthew G. Knepley } else { 611b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 612b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 613b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + yv)*nVx + nVx-1 + nC; /* right vertices */ 614b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 615b2fff234SMatthew G. Knepley } 616b2fff234SMatthew G. Knepley } 617b2fff234SMatthew G. Knepley #if 0 618b2fff234SMatthew G. Knepley for (xf = 0; xf < nxF; ++xf) { 619b2fff234SMatthew G. Knepley /* THIS IS WRONG */ 620b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* right faces */ 621b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) ++nleaves; 622b2fff234SMatthew G. Knepley } 623b2fff234SMatthew G. Knepley #endif 624b2fff234SMatthew G. Knepley } 625b2fff234SMatthew G. Knepley } 626b2fff234SMatthew G. Knepley } else { 627b2fff234SMatthew G. Knepley if (yp < 0) { /* bottom */ 628b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 629b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 630b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + 0)*nVx + xv + nC; /* bottom back vertices */ 631b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 632b2fff234SMatthew G. Knepley } 633b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 634b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 635b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + xv + nC; /* bottom front vertices */ 636b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 637b2fff234SMatthew G. Knepley } 638b2fff234SMatthew G. Knepley } else { 639b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 640b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 641b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + 0)*nVx + xv + nC; /* bottom vertices */ 642b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 643b2fff234SMatthew G. Knepley } 644b2fff234SMatthew G. Knepley } 645b2fff234SMatthew G. Knepley #if 0 646b2fff234SMatthew G. Knepley for (yf = 0; yf < nyF; ++yf) { 647b2fff234SMatthew G. Knepley /* THIS IS WRONG */ 648b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* bottom faces */ 649b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVFace)) ++nleaves; 650b2fff234SMatthew G. Knepley } 651b2fff234SMatthew G. Knepley #endif 652b2fff234SMatthew G. Knepley } 653b2fff234SMatthew G. Knepley } else if (yp > 0) { /* top */ 654b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 655b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 656b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + xv + nC; /* top back vertices */ 657b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 658b2fff234SMatthew G. Knepley } 659b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 660b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 661b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; /* top front vertices */ 662b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 663b2fff234SMatthew G. Knepley } 664b2fff234SMatthew G. Knepley } else { 665b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 666b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 667b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + xv + nC; /* top vertices */ 668b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 669b2fff234SMatthew G. Knepley } 670b2fff234SMatthew G. Knepley } 671b2fff234SMatthew G. Knepley #if 0 672b2fff234SMatthew G. Knepley for (yf = 0; yf < nyF; ++yf) { 673b2fff234SMatthew G. Knepley /* THIS IS WRONG */ 674b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* top faces */ 675b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVFace)) ++nleaves; 676b2fff234SMatthew G. Knepley } 677b2fff234SMatthew G. Knepley #endif 678b2fff234SMatthew G. Knepley } 679b2fff234SMatthew G. Knepley } else { 680b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 681b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 682b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 683b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + yv)*nVx + xv + nC; /* back vertices */ 684b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 685b2fff234SMatthew G. Knepley } 686b2fff234SMatthew G. Knepley } 687b2fff234SMatthew G. Knepley #if 0 688b2fff234SMatthew G. Knepley for (zf = 0; zf < nzF; ++zf) { 689b2fff234SMatthew G. Knepley /* THIS IS WRONG */ 690b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* back faces */ 691b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) ++nleaves; 692b2fff234SMatthew G. Knepley } 693b2fff234SMatthew G. Knepley #endif 694b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 695b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 696b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 697b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + xv + nC; /* front vertices */ 698b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 699b2fff234SMatthew G. Knepley } 700b2fff234SMatthew G. Knepley } 701b2fff234SMatthew G. Knepley #if 0 702b2fff234SMatthew G. Knepley for (zf = 0; zf < nzF; ++zf) { 703b2fff234SMatthew G. Knepley /* THIS IS WRONG */ 704b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* front faces */ 705b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) ++nleaves; 706b2fff234SMatthew G. Knepley } 707b2fff234SMatthew G. Knepley #endif 708b2fff234SMatthew G. Knepley } else { 709b2fff234SMatthew G. Knepley /* Nothing is shared from the interior */ 71088ed4aceSMatthew G Knepley } 71188ed4aceSMatthew G Knepley } 71288ed4aceSMatthew G Knepley } 71388ed4aceSMatthew G Knepley } 71488ed4aceSMatthew G Knepley } 715b2fff234SMatthew G. Knepley } 716b2fff234SMatthew G. Knepley } 717b2fff234SMatthew G. Knepley ierr = PetscBTMemzero(pEnd-pStart, isLeaf);CHKERRQ(ierr); 718dcca6d9dSJed Brown ierr = PetscMalloc2(nleaves,&localPoints,nleaves,&remotePoints);CHKERRQ(ierr); 71988ed4aceSMatthew G Knepley for (zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) { 72088ed4aceSMatthew G Knepley for (yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) { 72188ed4aceSMatthew G Knepley for (xn = 0; xn < 3; ++xn) { 7227128ae9fSMatthew G Knepley const PetscInt xp = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0; 72388ed4aceSMatthew G Knepley const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn]; 724f5eeb527SMatthew G Knepley PetscInt xv, yv, zv; 72588ed4aceSMatthew G Knepley 7263814d604SMatthew G Knepley if (neighbor >= 0 && neighbor < rank) { 72788ed4aceSMatthew G Knepley if (xp < 0) { /* left */ 72888ed4aceSMatthew G Knepley if (yp < 0) { /* bottom */ 72988ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 730b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + 0)*nVx + 0 + nC; /* left bottom back vertex */ 731f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 732f5eeb527SMatthew G Knepley 733b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 734f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 735f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 736f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 737f5eeb527SMatthew G Knepley ++nL; 738b2fff234SMatthew G. Knepley } 73988ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 740b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + 0 + nC; /* left bottom front vertex */ 741f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 742f5eeb527SMatthew G Knepley 743b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 744f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 745f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 746f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 747f5eeb527SMatthew G Knepley ++nL; 748b2fff234SMatthew G. Knepley } 74988ed4aceSMatthew G Knepley } else { 750b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 751b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + 0)*nVx + 0 + nC; /* left bottom vertices */ 752f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 753f5eeb527SMatthew G Knepley 754b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 755f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 756f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 757f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 758b2fff234SMatthew G. Knepley ++nL; 759b2fff234SMatthew G. Knepley } 760f5eeb527SMatthew G Knepley } 76188ed4aceSMatthew G Knepley } 76288ed4aceSMatthew G Knepley } else if (yp > 0) { /* top */ 76388ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 764b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + 0 + nC; /* left top back vertex */ 765f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + 0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 766f5eeb527SMatthew G Knepley 767b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 768f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 769f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 770f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 771f5eeb527SMatthew G Knepley ++nL; 772b2fff234SMatthew G. Knepley } 77388ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 774b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + 0 + nC; /* left top front vertex */ 775f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + 0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 776f5eeb527SMatthew G Knepley 777b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 778f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 779f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 780f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 781f5eeb527SMatthew G Knepley ++nL; 782b2fff234SMatthew G. Knepley } 78388ed4aceSMatthew G Knepley } else { 784b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 785b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + 0 + nC; /* left top vertices */ 786f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + 0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 787f5eeb527SMatthew G Knepley 788b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 789f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 790f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 791f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 792b2fff234SMatthew G. Knepley ++nL; 793b2fff234SMatthew G. Knepley } 794f5eeb527SMatthew G Knepley } 79588ed4aceSMatthew G Knepley } 79688ed4aceSMatthew G Knepley } else { 79788ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 798b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 799b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + yv)*nVx + 0 + nC; /* left back vertices */ 800f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 801f5eeb527SMatthew G Knepley 802b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 803f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 804f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 805f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 806b2fff234SMatthew G. Knepley ++nL; 807b2fff234SMatthew G. Knepley } 808f5eeb527SMatthew G Knepley } 80988ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 810b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 811b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + 0 + nC; /* left front vertices */ 812f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 813f5eeb527SMatthew G Knepley 814b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 815f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 816f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 817f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 818b2fff234SMatthew G. Knepley ++nL; 819b2fff234SMatthew G. Knepley } 820f5eeb527SMatthew G Knepley } 82188ed4aceSMatthew G Knepley } else { 822f5eeb527SMatthew G Knepley for (zv = 0; zv < nVz; ++zv) { 823b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 824b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + yv)*nVx + 0 + nC; /* left vertices */ 825f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 826f5eeb527SMatthew G Knepley 827b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 828f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 829f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 830f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 831b2fff234SMatthew G. Knepley ++nL; 832f5eeb527SMatthew G Knepley } 833f5eeb527SMatthew G Knepley } 834b2fff234SMatthew G. Knepley } 835b2fff234SMatthew G. Knepley #if 0 836b2fff234SMatthew G. Knepley for (xf = 0; xf < nxF; ++xf) { 837f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 838b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* left faces */ 839f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 840f5eeb527SMatthew G Knepley 841b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) { 842f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 843f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 844f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 845f5eeb527SMatthew G Knepley } 84688ed4aceSMatthew G Knepley } 847b2fff234SMatthew G. Knepley #endif 848b2fff234SMatthew G. Knepley } 84988ed4aceSMatthew G Knepley } 85088ed4aceSMatthew G Knepley } else if (xp > 0) { /* right */ 85188ed4aceSMatthew G Knepley if (yp < 0) { /* bottom */ 85288ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 853b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + 0)*nVx + nVx-1 + nC; /* right bottom back vertex */ 854f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 855f5eeb527SMatthew G Knepley 856b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 857f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 858f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 859f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 860f5eeb527SMatthew G Knepley ++nL; 861b2fff234SMatthew G. Knepley } 86288ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 863b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + nVx-1 + nC; /* right bottom front vertex */ 864f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + nVy-1)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 865f5eeb527SMatthew G Knepley 866b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 867f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 868f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 869f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 870f5eeb527SMatthew G Knepley ++nL; 871b2fff234SMatthew G. Knepley } 87288ed4aceSMatthew G Knepley } else { 873b2fff234SMatthew G. Knepley nleavesCheck += nVz; 874b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 875b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + 0)*nVx + nVx-1 + nC; /* right bottom vertices */ 876f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 877f5eeb527SMatthew G Knepley 878b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 879f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 880f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 881f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 882b2fff234SMatthew G. Knepley ++nL; 883b2fff234SMatthew G. Knepley } 884f5eeb527SMatthew G Knepley } 88588ed4aceSMatthew G Knepley } 88688ed4aceSMatthew G Knepley } else if (yp > 0) { /* top */ 88788ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 888b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top back vertex */ 889f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + 0)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 890f5eeb527SMatthew G Knepley 891b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 892f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 893f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 894f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 895f5eeb527SMatthew G Knepley ++nL; 896b2fff234SMatthew G. Knepley } 89788ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 898b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top front vertex */ 899f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + 0)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 900f5eeb527SMatthew G Knepley 901b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 902f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 903f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 904f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 905f5eeb527SMatthew G Knepley ++nL; 906b2fff234SMatthew G. Knepley } 90788ed4aceSMatthew G Knepley } else { 908b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 909b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top vertices */ 910f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + 0)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 911f5eeb527SMatthew G Knepley 912b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 913f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 914f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 915f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 916b2fff234SMatthew G. Knepley ++nL; 917b2fff234SMatthew G. Knepley } 918f5eeb527SMatthew G Knepley } 91988ed4aceSMatthew G Knepley } 92088ed4aceSMatthew G Knepley } else { 92188ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 922b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 923b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + yv)*nVx + nVx-1 + nC; /* right back vertices */ 924f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 925f5eeb527SMatthew G Knepley 926b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 927f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 928f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 929f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 930b2fff234SMatthew G. Knepley ++nL; 931b2fff234SMatthew G. Knepley } 932f5eeb527SMatthew G Knepley } 93388ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 934b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 935b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; /* right front vertices */ 936f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + yv)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 937f5eeb527SMatthew G Knepley 938b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 939f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 940f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 941f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 942b2fff234SMatthew G. Knepley ++nL; 943b2fff234SMatthew G. Knepley } 944f5eeb527SMatthew G Knepley } 94588ed4aceSMatthew G Knepley } else { 946f5eeb527SMatthew G Knepley for (zv = 0; zv < nVz; ++zv) { 947b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 948b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + yv)*nVx + nVx-1 + nC; /* right vertices */ 949f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + yv)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 950f5eeb527SMatthew G Knepley 951b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 952f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 953f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 954f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 955b2fff234SMatthew G. Knepley ++nL; 956f5eeb527SMatthew G Knepley } 957f5eeb527SMatthew G Knepley } 958b2fff234SMatthew G. Knepley } 959b2fff234SMatthew G. Knepley #if 0 960b2fff234SMatthew G. Knepley for (xf = 0; xf < nxF; ++xf) { 961f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 962b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* right faces */ 963f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 964f5eeb527SMatthew G Knepley 965b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) { 966f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 967f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 968f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 969b2fff234SMatthew G. Knepley ++nL; 970f5eeb527SMatthew G Knepley } 97188ed4aceSMatthew G Knepley } 972b2fff234SMatthew G. Knepley #endif 973b2fff234SMatthew G. Knepley } 97488ed4aceSMatthew G Knepley } 97588ed4aceSMatthew G Knepley } else { 97688ed4aceSMatthew G Knepley if (yp < 0) { /* bottom */ 97788ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 978b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 979b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + 0)*nVx + xv + nC; /* bottom back vertices */ 980f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 981f5eeb527SMatthew G Knepley 982b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 983f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 984f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 985f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 986b2fff234SMatthew G. Knepley ++nL; 987b2fff234SMatthew G. Knepley } 988f5eeb527SMatthew G Knepley } 98988ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 990b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 991b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + xv + nC; /* bottom front vertices */ 992f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 993f5eeb527SMatthew G Knepley 994b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 995f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 996f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 997f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 998b2fff234SMatthew G. Knepley ++nL; 999b2fff234SMatthew G. Knepley } 1000f5eeb527SMatthew G Knepley } 100188ed4aceSMatthew G Knepley } else { 1002f5eeb527SMatthew G Knepley for (zv = 0; zv < nVz; ++zv) { 1003b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 1004b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + 0)*nVx + xv + nC; /* bottom vertices */ 1005f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 1006f5eeb527SMatthew G Knepley 1007b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 1008f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 1009f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 1010f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 1011b2fff234SMatthew G. Knepley ++nL; 1012f5eeb527SMatthew G Knepley } 1013f5eeb527SMatthew G Knepley } 1014b2fff234SMatthew G. Knepley } 1015b2fff234SMatthew G. Knepley #if 0 1016b2fff234SMatthew G. Knepley for (yf = 0; yf < nyF; ++yf) { 1017f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 1018b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* bottom faces */ 1019f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 1020f5eeb527SMatthew G Knepley 1021b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) { 1022f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 1023f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 1024f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 1025b2fff234SMatthew G. Knepley ++nL; 1026f5eeb527SMatthew G Knepley } 102788ed4aceSMatthew G Knepley } 1028b2fff234SMatthew G. Knepley #endif 1029b2fff234SMatthew G. Knepley } 103088ed4aceSMatthew G Knepley } else if (yp > 0) { /* top */ 103188ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 1032b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 1033b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + xv + nC; /* top back vertices */ 1034f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + 0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 1035f5eeb527SMatthew G Knepley 1036b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 1037f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 1038f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 1039f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 1040b2fff234SMatthew G. Knepley ++nL; 1041b2fff234SMatthew G. Knepley } 1042f5eeb527SMatthew G Knepley } 104388ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 1044b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 1045b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; /* top front vertices */ 1046f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + 0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 1047f5eeb527SMatthew G Knepley 1048b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 1049f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 1050f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 1051f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 1052b2fff234SMatthew G. Knepley ++nL; 1053b2fff234SMatthew G. Knepley } 1054f5eeb527SMatthew G Knepley } 105588ed4aceSMatthew G Knepley } else { 1056f5eeb527SMatthew G Knepley for (zv = 0; zv < nVz; ++zv) { 1057b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 1058b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + xv + nC; /* top vertices */ 1059f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + 0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 1060f5eeb527SMatthew G Knepley 1061b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 1062f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 1063f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 1064f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 1065b2fff234SMatthew G. Knepley ++nL; 1066f5eeb527SMatthew G Knepley } 1067f5eeb527SMatthew G Knepley } 1068b2fff234SMatthew G. Knepley } 1069b2fff234SMatthew G. Knepley #if 0 1070b2fff234SMatthew G. Knepley for (yf = 0; yf < nyF; ++yf) { 1071f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 1072b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* top faces */ 1073f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 1074f5eeb527SMatthew G Knepley 1075b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) { 1076f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 1077f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 1078f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 1079b2fff234SMatthew G. Knepley ++nL; 1080f5eeb527SMatthew G Knepley } 108188ed4aceSMatthew G Knepley } 1082b2fff234SMatthew G. Knepley #endif 1083b2fff234SMatthew G. Knepley } 108488ed4aceSMatthew G Knepley } else { 108588ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 1086f5eeb527SMatthew G Knepley for (yv = 0; yv < nVy; ++yv) { 1087b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 1088b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + yv)*nVx + xv + nC; /* back vertices */ 1089f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 1090f5eeb527SMatthew G Knepley 1091b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 1092f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 1093f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 1094f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 1095b2fff234SMatthew G. Knepley ++nL; 1096f5eeb527SMatthew G Knepley } 1097f5eeb527SMatthew G Knepley } 1098b2fff234SMatthew G. Knepley } 1099b2fff234SMatthew G. Knepley #if 0 1100b2fff234SMatthew G. Knepley for (zf = 0; zf < nzF; ++zf) { 1101f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 1102b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* back faces */ 1103f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 1104f5eeb527SMatthew G Knepley 1105b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) { 1106f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 1107f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 1108f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 1109b2fff234SMatthew G. Knepley ++nL; 1110f5eeb527SMatthew G Knepley } 1111b2fff234SMatthew G. Knepley } 1112b2fff234SMatthew G. Knepley #endif 111388ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 1114f5eeb527SMatthew G Knepley for (yv = 0; yv < nVy; ++yv) { 1115b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 1116b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + xv + nC; /* front vertices */ 1117f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + yv)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 1118f5eeb527SMatthew G Knepley 1119b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 1120f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 1121f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 1122f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 1123b2fff234SMatthew G. Knepley ++nL; 1124f5eeb527SMatthew G Knepley } 1125f5eeb527SMatthew G Knepley } 1126b2fff234SMatthew G. Knepley } 1127b2fff234SMatthew G. Knepley #if 0 1128b2fff234SMatthew G. Knepley for (zf = 0; zf < nzF; ++zf) { 1129f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 1130b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* front faces */ 1131f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 1132f5eeb527SMatthew G Knepley 1133b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) { 1134f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 1135f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 1136f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 1137b2fff234SMatthew G. Knepley ++nL; 1138f5eeb527SMatthew G Knepley } 1139b2fff234SMatthew G. Knepley } 1140b2fff234SMatthew G. Knepley #endif 114188ed4aceSMatthew G Knepley } else { 114288ed4aceSMatthew G Knepley /* Nothing is shared from the interior */ 114388ed4aceSMatthew G Knepley } 114488ed4aceSMatthew G Knepley } 114588ed4aceSMatthew G Knepley } 114688ed4aceSMatthew G Knepley } 114788ed4aceSMatthew G Knepley } 114888ed4aceSMatthew G Knepley } 114988ed4aceSMatthew G Knepley } 1150b2fff234SMatthew G. Knepley ierr = PetscBTDestroy(&isLeaf);CHKERRQ(ierr); 1151b2fff234SMatthew G. Knepley /* Remove duplication in leaf determination */ 1152b2fff234SMatthew G. Knepley if (nleaves != nL) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "The number of leaves %d did not match the number of remote leaves %d", nleaves, nleavesCheck); 115382f516ccSBarry Smith ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), &sf);CHKERRQ(ierr); 115488ed4aceSMatthew G Knepley ierr = PetscSFSetGraph(sf, pEnd, nleaves, localPoints, PETSC_OWN_POINTER, remotePoints, PETSC_OWN_POINTER);CHKERRQ(ierr); 1155a4b60ecfSMatthew G. Knepley ierr = DMSetPointSF(dm, sf);CHKERRQ(ierr); 115688ed4aceSMatthew G Knepley ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 1157affa55c7SMatthew G. Knepley *s = section; 1158affa55c7SMatthew G. Knepley PetscFunctionReturn(0); 1159affa55c7SMatthew G. Knepley } 1160affa55c7SMatthew G. Knepley 11613385ff7eSMatthew G. Knepley #undef __FUNCT__ 11623385ff7eSMatthew G. Knepley #define __FUNCT__ "DMDASetVertexCoordinates" 11633385ff7eSMatthew G. Knepley PetscErrorCode DMDASetVertexCoordinates(DM dm, PetscReal xl, PetscReal xu, PetscReal yl, PetscReal yu, PetscReal zl, PetscReal zu) 11643385ff7eSMatthew G. Knepley { 11653385ff7eSMatthew G. Knepley DM_DA *da = (DM_DA *) dm->data; 11663385ff7eSMatthew G. Knepley Vec coordinates; 11673385ff7eSMatthew G. Knepley PetscSection section; 11683385ff7eSMatthew G. Knepley PetscScalar *coords; 11693385ff7eSMatthew G. Knepley PetscReal h[3]; 11703385ff7eSMatthew G. Knepley PetscInt dim, size, M, N, P, nVx, nVy, nVz, nV, vStart, vEnd, v, i, j, k; 11713385ff7eSMatthew G. Knepley PetscErrorCode ierr; 11723385ff7eSMatthew G. Knepley 11733385ff7eSMatthew G. Knepley PetscFunctionBegin; 11743385ff7eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 11753385ff7eSMatthew G. Knepley ierr = DMDAGetInfo(dm, &dim, &M, &N, &P, 0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); 11763385ff7eSMatthew G. Knepley h[0] = (xu - xl)/M; 11773385ff7eSMatthew G. Knepley h[1] = (yu - yl)/N; 11783385ff7eSMatthew G. Knepley h[2] = (zu - zl)/P; 11793385ff7eSMatthew G. Knepley ierr = DMDAGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 11803385ff7eSMatthew G. Knepley ierr = DMDAGetNumVertices(dm, &nVx, &nVy, &nVz, &nV);CHKERRQ(ierr); 11813385ff7eSMatthew G. Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), §ion);CHKERRQ(ierr); 11823385ff7eSMatthew G. Knepley ierr = PetscSectionSetNumFields(section, 1);CHKERRQ(ierr); 11833385ff7eSMatthew G. Knepley ierr = PetscSectionSetFieldComponents(section, 0, dim);CHKERRQ(ierr); 11843385ff7eSMatthew G. Knepley ierr = PetscSectionSetChart(section, vStart, vEnd);CHKERRQ(ierr); 11853385ff7eSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 11863385ff7eSMatthew G. Knepley ierr = PetscSectionSetDof(section, v, dim);CHKERRQ(ierr); 11873385ff7eSMatthew G. Knepley } 11883385ff7eSMatthew G. Knepley ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 11893385ff7eSMatthew G. Knepley ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 11903385ff7eSMatthew G. Knepley ierr = VecCreateSeq(PETSC_COMM_SELF, size, &coordinates);CHKERRQ(ierr); 11913385ff7eSMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 11923385ff7eSMatthew G. Knepley for (k = 0; k < nVz; ++k) { 1193e4d69e08SBarry Smith PetscInt ind[3], d, off; 11943385ff7eSMatthew G. Knepley 1195e4d69e08SBarry Smith ind[0] = 0; 1196e4d69e08SBarry Smith ind[1] = 0; 1197e4d69e08SBarry Smith ind[2] = k + da->zs; 11983385ff7eSMatthew G. Knepley for (j = 0; j < nVy; ++j) { 11993385ff7eSMatthew G. Knepley ind[1] = j + da->ys; 12003385ff7eSMatthew G. Knepley for (i = 0; i < nVx; ++i) { 12013385ff7eSMatthew G. Knepley const PetscInt vertex = (k*nVy + j)*nVx + i + vStart; 12023385ff7eSMatthew G. Knepley 12033385ff7eSMatthew G. Knepley ierr = PetscSectionGetOffset(section, vertex, &off);CHKERRQ(ierr); 12043385ff7eSMatthew G. Knepley ind[0] = i + da->xs; 12053385ff7eSMatthew G. Knepley for (d = 0; d < dim; ++d) { 12063385ff7eSMatthew G. Knepley coords[off+d] = h[d]*ind[d]; 12073385ff7eSMatthew G. Knepley } 12083385ff7eSMatthew G. Knepley } 12093385ff7eSMatthew G. Knepley } 12103385ff7eSMatthew G. Knepley } 12113385ff7eSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 12123385ff7eSMatthew G. Knepley ierr = DMSetCoordinateSection(dm, section);CHKERRQ(ierr); 12133385ff7eSMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 1214a4b60ecfSMatthew G. Knepley ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 12153385ff7eSMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 12163385ff7eSMatthew G. Knepley PetscFunctionReturn(0); 12173385ff7eSMatthew G. Knepley } 12189a800dd8SMatthew G. Knepley 12199a800dd8SMatthew G. Knepley #undef __FUNCT__ 12209a800dd8SMatthew G. Knepley #define __FUNCT__ "DMDAProjectFunctionLocal" 1221*b7a4d31fSMatthew G. Knepley PetscErrorCode DMDAProjectFunctionLocal(DM dm, void (**funcs)(const PetscReal [], PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 12229a800dd8SMatthew G. Knepley { 1223*b7a4d31fSMatthew G. Knepley PetscProblem prob; 1224*b7a4d31fSMatthew G. Knepley PetscFE fe; 1225*b7a4d31fSMatthew G. Knepley PetscDualSpace sp; 12269a800dd8SMatthew G. Knepley PetscQuadrature q; 12279a800dd8SMatthew G. Knepley PetscSection section; 12289a800dd8SMatthew G. Knepley PetscScalar *values; 12299a800dd8SMatthew G. Knepley PetscReal *v0, *J, *detJ; 1230*b7a4d31fSMatthew G. Knepley PetscInt numFields, numComp, numPoints, dim, spDim, totDim, numValues, cStart, cEnd, f, c, v, d; 12319a800dd8SMatthew G. Knepley PetscErrorCode ierr; 12329a800dd8SMatthew G. Knepley 12339a800dd8SMatthew G. Knepley PetscFunctionBegin; 1234*b7a4d31fSMatthew G. Knepley ierr = DMGetProblem(dm, &prob);CHKERRQ(ierr); 1235*b7a4d31fSMatthew G. Knepley ierr = PetscProblemGetTotalDimension(prob, &totDim);CHKERRQ(ierr); 1236*b7a4d31fSMatthew G. Knepley ierr = PetscProblemGetDiscretization(prob, 0, (PetscObject *) &fe);CHKERRQ(ierr); 1237*b7a4d31fSMatthew G. Knepley ierr = PetscFEGetQuadrature(fe, &q);CHKERRQ(ierr); 12389a800dd8SMatthew G. Knepley ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 12399a800dd8SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 12409a800dd8SMatthew G. Knepley ierr = DMDAGetInfo(dm, &dim,0,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); 12419a800dd8SMatthew G. Knepley ierr = DMDAGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 12429a800dd8SMatthew G. Knepley ierr = DMDAVecGetClosure(dm, section, localX, cStart, &numValues, NULL);CHKERRQ(ierr); 12439a800dd8SMatthew G. Knepley if (numValues != totDim) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "The section cell closure size %d != dual space dimension %d", numValues, totDim); 12449a800dd8SMatthew G. Knepley ierr = DMGetWorkArray(dm, numValues, PETSC_SCALAR, &values);CHKERRQ(ierr); 124521454ff5SMatthew G. Knepley ierr = PetscQuadratureGetData(q, NULL, &numPoints, NULL, NULL);CHKERRQ(ierr); 124621454ff5SMatthew G. Knepley ierr = PetscMalloc3(dim*numPoints,&v0,dim*dim*numPoints,&J,numPoints,&detJ);CHKERRQ(ierr); 12479a800dd8SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 12489a800dd8SMatthew G. Knepley PetscCellGeometry geom; 12499a800dd8SMatthew G. Knepley 125021454ff5SMatthew G. Knepley ierr = DMDAComputeCellGeometry(dm, c, q, v0, J, NULL, detJ);CHKERRQ(ierr); 12519a800dd8SMatthew G. Knepley geom.v0 = v0; 12529a800dd8SMatthew G. Knepley geom.J = J; 12539a800dd8SMatthew G. Knepley geom.detJ = detJ; 12549a800dd8SMatthew G. Knepley for (f = 0, v = 0; f < numFields; ++f) { 1255c110b1eeSGeoffrey Irving void * const ctx = ctxs ? ctxs[f] : NULL; 1256*b7a4d31fSMatthew G. Knepley 1257*b7a4d31fSMatthew G. Knepley ierr = PetscProblemGetDiscretization(prob, f, (PetscObject *) &fe);CHKERRQ(ierr); 1258*b7a4d31fSMatthew G. Knepley ierr = PetscFEGetNumComponents(fe, &numComp);CHKERRQ(ierr); 1259*b7a4d31fSMatthew G. Knepley ierr = PetscFEGetDualSpace(fe, &sp);CHKERRQ(ierr); 1260*b7a4d31fSMatthew G. Knepley ierr = PetscDualSpaceGetDimension(sp, &spDim);CHKERRQ(ierr); 12619a800dd8SMatthew G. Knepley for (d = 0; d < spDim; ++d) { 1262*b7a4d31fSMatthew G. Knepley ierr = PetscDualSpaceApply(sp, d, geom, numComp, funcs[f], ctx, &values[v]);CHKERRQ(ierr); 12639a800dd8SMatthew G. Knepley v += numComp; 12649a800dd8SMatthew G. Knepley } 12659a800dd8SMatthew G. Knepley } 12669a800dd8SMatthew G. Knepley ierr = DMDAVecSetClosure(dm, section, localX, c, values, mode);CHKERRQ(ierr); 12679a800dd8SMatthew G. Knepley } 12689a800dd8SMatthew G. Knepley ierr = DMRestoreWorkArray(dm, numValues, PETSC_SCALAR, &values);CHKERRQ(ierr); 12699a800dd8SMatthew G. Knepley ierr = PetscFree3(v0,J,detJ);CHKERRQ(ierr); 12709a800dd8SMatthew G. Knepley PetscFunctionReturn(0); 12719a800dd8SMatthew G. Knepley } 12729a800dd8SMatthew G. Knepley 12739a800dd8SMatthew G. Knepley #undef __FUNCT__ 12749a800dd8SMatthew G. Knepley #define __FUNCT__ "DMDAProjectFunction" 12759a800dd8SMatthew G. Knepley /*@C 12769a800dd8SMatthew G. Knepley DMDAProjectFunction - This projects the given function into the function space provided. 12779a800dd8SMatthew G. Knepley 12789a800dd8SMatthew G. Knepley Input Parameters: 12799a800dd8SMatthew G. Knepley + dm - The DM 12809a800dd8SMatthew G. Knepley . funcs - The coordinate functions to evaluate 1281c110b1eeSGeoffrey Irving . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 12829a800dd8SMatthew G. Knepley - mode - The insertion mode for values 12839a800dd8SMatthew G. Knepley 12849a800dd8SMatthew G. Knepley Output Parameter: 12859a800dd8SMatthew G. Knepley . X - vector 12869a800dd8SMatthew G. Knepley 12879a800dd8SMatthew G. Knepley Level: developer 12889a800dd8SMatthew G. Knepley 12899a800dd8SMatthew G. Knepley .seealso: DMDAComputeL2Diff() 12909a800dd8SMatthew G. Knepley @*/ 1291*b7a4d31fSMatthew G. Knepley PetscErrorCode DMDAProjectFunction(DM dm, void (**funcs)(const PetscReal [], PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X) 12929a800dd8SMatthew G. Knepley { 12939a800dd8SMatthew G. Knepley Vec localX; 12949a800dd8SMatthew G. Knepley PetscErrorCode ierr; 12959a800dd8SMatthew G. Knepley 12969a800dd8SMatthew G. Knepley PetscFunctionBegin; 12979a800dd8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 12989a800dd8SMatthew G. Knepley ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr); 1299*b7a4d31fSMatthew G. Knepley ierr = DMDAProjectFunctionLocal(dm, funcs, ctxs, mode, localX);CHKERRQ(ierr); 13009a800dd8SMatthew G. Knepley ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr); 13019a800dd8SMatthew G. Knepley ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr); 13029a800dd8SMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr); 13039a800dd8SMatthew G. Knepley PetscFunctionReturn(0); 13049a800dd8SMatthew G. Knepley } 13059a800dd8SMatthew G. Knepley 13069a800dd8SMatthew G. Knepley #undef __FUNCT__ 13079a800dd8SMatthew G. Knepley #define __FUNCT__ "DMDAComputeL2Diff" 13089a800dd8SMatthew G. Knepley /*@C 13099a800dd8SMatthew G. Knepley DMDAComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h. 13109a800dd8SMatthew G. Knepley 13119a800dd8SMatthew G. Knepley Input Parameters: 13129a800dd8SMatthew G. Knepley + dm - The DM 13139a800dd8SMatthew G. Knepley . funcs - The functions to evaluate for each field component 1314c110b1eeSGeoffrey Irving . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 13159a800dd8SMatthew G. Knepley - X - The coefficient vector u_h 13169a800dd8SMatthew G. Knepley 13179a800dd8SMatthew G. Knepley Output Parameter: 13189a800dd8SMatthew G. Knepley . diff - The diff ||u - u_h||_2 13199a800dd8SMatthew G. Knepley 13209a800dd8SMatthew G. Knepley Level: developer 13219a800dd8SMatthew G. Knepley 132223d86601SMatthew G. Knepley .seealso: DMDAProjectFunction(), DMDAComputeL2GradientDiff() 13239a800dd8SMatthew G. Knepley @*/ 1324*b7a4d31fSMatthew G. Knepley PetscErrorCode DMDAComputeL2Diff(DM dm, void (**funcs)(const PetscReal [], PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff) 13259a800dd8SMatthew G. Knepley { 13269a800dd8SMatthew G. Knepley const PetscInt debug = 0; 1327*b7a4d31fSMatthew G. Knepley PetscProblem prob; 1328*b7a4d31fSMatthew G. Knepley PetscFE fe; 13299a800dd8SMatthew G. Knepley PetscQuadrature quad; 1330*b7a4d31fSMatthew G. Knepley PetscSection section; 13319a800dd8SMatthew G. Knepley Vec localX; 13329a800dd8SMatthew G. Knepley PetscScalar *funcVal; 13339a800dd8SMatthew G. Knepley PetscReal *coords, *v0, *J, *invJ, detJ; 13349a800dd8SMatthew G. Knepley PetscReal localDiff = 0.0; 1335*b7a4d31fSMatthew G. Knepley PetscInt dim, numFields, Nc, cStart, cEnd, c, field, fieldOffset, comp; 13369a800dd8SMatthew G. Knepley PetscErrorCode ierr; 13379a800dd8SMatthew G. Knepley 13389a800dd8SMatthew G. Knepley PetscFunctionBegin; 13399a800dd8SMatthew G. Knepley ierr = DMDAGetInfo(dm, &dim,0,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); 1340*b7a4d31fSMatthew G. Knepley ierr = DMGetProblem(dm, &prob);CHKERRQ(ierr); 1341*b7a4d31fSMatthew G. Knepley ierr = PetscProblemGetTotalComponents(prob, &Nc);CHKERRQ(ierr); 1342*b7a4d31fSMatthew G. Knepley ierr = PetscProblemGetDiscretization(prob, 0, (PetscObject *) &fe);CHKERRQ(ierr); 1343*b7a4d31fSMatthew G. Knepley ierr = PetscFEGetQuadrature(fe, &quad);CHKERRQ(ierr); 13449a800dd8SMatthew G. Knepley ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 13459a800dd8SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 13469a800dd8SMatthew G. Knepley ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr); 13479a800dd8SMatthew G. Knepley ierr = DMGlobalToLocalBegin(dm, X, INSERT_VALUES, localX);CHKERRQ(ierr); 13489a800dd8SMatthew G. Knepley ierr = DMGlobalToLocalEnd(dm, X, INSERT_VALUES, localX);CHKERRQ(ierr); 13499a800dd8SMatthew G. Knepley /* There are no BC values in DAs right now: ierr = DMDAProjectFunctionLocal(dm, fe, funcs, INSERT_BC_VALUES, localX);CHKERRQ(ierr); */ 1350*b7a4d31fSMatthew G. Knepley ierr = PetscMalloc5(Nc,&funcVal,dim,&coords,dim,&v0,dim*dim,&J,dim*dim,&invJ);CHKERRQ(ierr); 13519a800dd8SMatthew G. Knepley ierr = DMDAGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 13529a800dd8SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 13539a800dd8SMatthew G. Knepley PetscScalar *x = NULL; 13549a800dd8SMatthew G. Knepley PetscReal elemDiff = 0.0; 13559a800dd8SMatthew G. Knepley 135621454ff5SMatthew G. Knepley ierr = DMDAComputeCellGeometry(dm, c, quad, v0, J, invJ, &detJ);CHKERRQ(ierr); 13579a800dd8SMatthew G. Knepley if (detJ <= 0.0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid determinant %g for element %d", detJ, c); 13589a800dd8SMatthew G. Knepley ierr = DMDAVecGetClosure(dm, NULL, localX, c, NULL, &x);CHKERRQ(ierr); 13599a800dd8SMatthew G. Knepley 13609a800dd8SMatthew G. Knepley for (field = 0, comp = 0, fieldOffset = 0; field < numFields; ++field) { 1361c110b1eeSGeoffrey Irving void * const ctx = ctxs ? ctxs[field] : NULL; 136221454ff5SMatthew G. Knepley const PetscReal *quadPoints, *quadWeights; 13639a800dd8SMatthew G. Knepley PetscReal *basis; 136421454ff5SMatthew G. Knepley PetscInt numQuadPoints, numBasisFuncs, numBasisComps, q, d, e, fc, f; 13659a800dd8SMatthew G. Knepley 1366*b7a4d31fSMatthew G. Knepley ierr = PetscProblemGetDiscretization(prob, field, (PetscObject *) &fe);CHKERRQ(ierr); 136721454ff5SMatthew G. Knepley ierr = PetscQuadratureGetData(quad, NULL, &numQuadPoints, &quadPoints, &quadWeights);CHKERRQ(ierr); 1368*b7a4d31fSMatthew G. Knepley ierr = PetscFEGetDimension(fe, &numBasisFuncs);CHKERRQ(ierr); 1369*b7a4d31fSMatthew G. Knepley ierr = PetscFEGetNumComponents(fe, &numBasisComps);CHKERRQ(ierr); 1370*b7a4d31fSMatthew G. Knepley ierr = PetscFEGetDefaultTabulation(fe, &basis, NULL, NULL);CHKERRQ(ierr); 13719a800dd8SMatthew G. Knepley if (debug) { 13729a800dd8SMatthew G. Knepley char title[1024]; 13739a800dd8SMatthew G. Knepley ierr = PetscSNPrintf(title, 1023, "Solution for Field %d", field);CHKERRQ(ierr); 13749a800dd8SMatthew G. Knepley ierr = DMPrintCellVector(c, title, numBasisFuncs*numBasisComps, &x[fieldOffset]);CHKERRQ(ierr); 13759a800dd8SMatthew G. Knepley } 13769a800dd8SMatthew G. Knepley for (q = 0; q < numQuadPoints; ++q) { 13779a800dd8SMatthew G. Knepley for (d = 0; d < dim; d++) { 13789a800dd8SMatthew G. Knepley coords[d] = v0[d]; 13799a800dd8SMatthew G. Knepley for (e = 0; e < dim; e++) { 13809a800dd8SMatthew G. Knepley coords[d] += J[d*dim+e]*(quadPoints[q*dim+e] + 1.0); 13819a800dd8SMatthew G. Knepley } 13829a800dd8SMatthew G. Knepley } 1383c110b1eeSGeoffrey Irving (*funcs[field])(coords, funcVal, ctx); 13849a800dd8SMatthew G. Knepley for (fc = 0; fc < numBasisComps; ++fc) { 13859a800dd8SMatthew G. Knepley PetscScalar interpolant = 0.0; 13869a800dd8SMatthew G. Knepley 13879a800dd8SMatthew G. Knepley for (f = 0; f < numBasisFuncs; ++f) { 13889a800dd8SMatthew G. Knepley const PetscInt fidx = f*numBasisComps+fc; 13899a800dd8SMatthew G. Knepley interpolant += x[fieldOffset+fidx]*basis[q*numBasisFuncs*numBasisComps+fidx]; 13909a800dd8SMatthew G. Knepley } 13919a800dd8SMatthew G. Knepley if (debug) {ierr = PetscPrintf(PETSC_COMM_SELF, " elem %d field %d diff %g\n", c, field, PetscSqr(PetscRealPart(interpolant - funcVal[fc]))*quadWeights[q]*detJ);CHKERRQ(ierr);} 13929a800dd8SMatthew G. Knepley elemDiff += PetscSqr(PetscRealPart(interpolant - funcVal[fc]))*quadWeights[q]*detJ; 13939a800dd8SMatthew G. Knepley } 13949a800dd8SMatthew G. Knepley } 13959a800dd8SMatthew G. Knepley comp += numBasisComps; 13969a800dd8SMatthew G. Knepley fieldOffset += numBasisFuncs*numBasisComps; 13979a800dd8SMatthew G. Knepley } 13989a800dd8SMatthew G. Knepley ierr = DMDAVecRestoreClosure(dm, NULL, localX, c, NULL, &x);CHKERRQ(ierr); 13999a800dd8SMatthew G. Knepley if (debug) {ierr = PetscPrintf(PETSC_COMM_SELF, " elem %d diff %g\n", c, elemDiff);CHKERRQ(ierr);} 14009a800dd8SMatthew G. Knepley localDiff += elemDiff; 14019a800dd8SMatthew G. Knepley } 14029a800dd8SMatthew G. Knepley ierr = PetscFree5(funcVal,coords,v0,J,invJ);CHKERRQ(ierr); 14039a800dd8SMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr); 14049a800dd8SMatthew G. Knepley ierr = MPI_Allreduce(&localDiff, diff, 1, MPIU_REAL, MPI_SUM, PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 14059a800dd8SMatthew G. Knepley *diff = PetscSqrtReal(*diff); 1406a66d4d66SMatthew G Knepley PetscFunctionReturn(0); 1407a66d4d66SMatthew G Knepley } 1408a66d4d66SMatthew G Knepley 140923d86601SMatthew G. Knepley #undef __FUNCT__ 141023d86601SMatthew G. Knepley #define __FUNCT__ "DMDAComputeL2GradientDiff" 141123d86601SMatthew G. Knepley /*@C 141223d86601SMatthew G. Knepley DMDAComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h. 141323d86601SMatthew G. Knepley 141423d86601SMatthew G. Knepley Input Parameters: 141523d86601SMatthew G. Knepley + dm - The DM 141623d86601SMatthew G. Knepley . funcs - The gradient functions to evaluate for each field component 141723d86601SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 141823d86601SMatthew G. Knepley . X - The coefficient vector u_h 141923d86601SMatthew G. Knepley - n - The vector to project along 142023d86601SMatthew G. Knepley 142123d86601SMatthew G. Knepley Output Parameter: 142223d86601SMatthew G. Knepley . diff - The diff ||(grad u - grad u_h) . n||_2 142323d86601SMatthew G. Knepley 142423d86601SMatthew G. Knepley Level: developer 142523d86601SMatthew G. Knepley 142623d86601SMatthew G. Knepley .seealso: DMDAProjectFunction(), DMPlexComputeL2Diff() 142723d86601SMatthew G. Knepley @*/ 1428*b7a4d31fSMatthew G. Knepley PetscErrorCode DMDAComputeL2GradientDiff(DM dm, void (**funcs)(const PetscReal [], const PetscReal [], PetscScalar *, void *), void **ctxs, Vec X, const PetscReal n[], PetscReal *diff) 142923d86601SMatthew G. Knepley { 143023d86601SMatthew G. Knepley const PetscInt debug = 0; 1431*b7a4d31fSMatthew G. Knepley PetscProblem prob; 1432*b7a4d31fSMatthew G. Knepley PetscFE fe; 143323d86601SMatthew G. Knepley PetscQuadrature quad; 1434*b7a4d31fSMatthew G. Knepley PetscSection section; 143523d86601SMatthew G. Knepley Vec localX; 143623d86601SMatthew G. Knepley PetscScalar *funcVal, *interpolantVec; 143723d86601SMatthew G. Knepley PetscReal *coords, *realSpaceDer, *v0, *J, *invJ, detJ; 143823d86601SMatthew G. Knepley PetscReal localDiff = 0.0; 1439*b7a4d31fSMatthew G. Knepley PetscInt dim, numFields, Nc, cStart, cEnd, c, field, fieldOffset, comp; 144023d86601SMatthew G. Knepley PetscErrorCode ierr; 144123d86601SMatthew G. Knepley 144223d86601SMatthew G. Knepley PetscFunctionBegin; 144323d86601SMatthew G. Knepley ierr = DMDAGetInfo(dm, &dim,0,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); 1444*b7a4d31fSMatthew G. Knepley ierr = DMGetProblem(dm, &prob);CHKERRQ(ierr); 1445*b7a4d31fSMatthew G. Knepley ierr = PetscProblemGetTotalComponents(prob, &Nc);CHKERRQ(ierr); 1446*b7a4d31fSMatthew G. Knepley ierr = PetscProblemGetDiscretization(prob, 0, (PetscObject *) &fe);CHKERRQ(ierr); 1447*b7a4d31fSMatthew G. Knepley ierr = PetscFEGetQuadrature(fe, &quad);CHKERRQ(ierr); 144823d86601SMatthew G. Knepley ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 144923d86601SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 145023d86601SMatthew G. Knepley ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr); 145123d86601SMatthew G. Knepley ierr = DMGlobalToLocalBegin(dm, X, INSERT_VALUES, localX);CHKERRQ(ierr); 145223d86601SMatthew G. Knepley ierr = DMGlobalToLocalEnd(dm, X, INSERT_VALUES, localX);CHKERRQ(ierr); 145323d86601SMatthew G. Knepley /* There are no BC values in DAs right now: ierr = DMDAProjectFunctionLocal(dm, fe, funcs, INSERT_BC_VALUES, localX);CHKERRQ(ierr); */ 1454*b7a4d31fSMatthew G. Knepley ierr = PetscMalloc7(Nc,&funcVal,dim,&coords,dim,&realSpaceDer,dim,&v0,dim*dim,&J,dim*dim,&invJ,dim,&interpolantVec);CHKERRQ(ierr); 145523d86601SMatthew G. Knepley ierr = DMDAGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 145623d86601SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 145723d86601SMatthew G. Knepley PetscScalar *x = NULL; 145823d86601SMatthew G. Knepley PetscReal elemDiff = 0.0; 145923d86601SMatthew G. Knepley 146023d86601SMatthew G. Knepley ierr = DMDAComputeCellGeometry(dm, c, quad, v0, J, invJ, &detJ);CHKERRQ(ierr); 146123d86601SMatthew G. Knepley if (detJ <= 0.0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid determinant %g for element %d", detJ, c); 146223d86601SMatthew G. Knepley ierr = DMDAVecGetClosure(dm, NULL, localX, c, NULL, &x);CHKERRQ(ierr); 146323d86601SMatthew G. Knepley 146423d86601SMatthew G. Knepley for (field = 0, comp = 0, fieldOffset = 0; field < numFields; ++field) { 146523d86601SMatthew G. Knepley void * const ctx = ctxs ? ctxs[field] : NULL; 146623d86601SMatthew G. Knepley const PetscReal *quadPoints, *quadWeights; 146723d86601SMatthew G. Knepley PetscReal *basisDer; 146823d86601SMatthew G. Knepley PetscInt Nq, Nb, Nc, q, d, e, fc, f, g; 146923d86601SMatthew G. Knepley 1470*b7a4d31fSMatthew G. Knepley ierr = PetscProblemGetDiscretization(prob, field, (PetscObject *) &fe);CHKERRQ(ierr); 147123d86601SMatthew G. Knepley ierr = PetscQuadratureGetData(quad, NULL, &Nq, &quadPoints, &quadWeights);CHKERRQ(ierr); 1472*b7a4d31fSMatthew G. Knepley ierr = PetscFEGetDimension(fe, &Nb);CHKERRQ(ierr); 1473*b7a4d31fSMatthew G. Knepley ierr = PetscFEGetNumComponents(fe, &Nc);CHKERRQ(ierr); 1474*b7a4d31fSMatthew G. Knepley ierr = PetscFEGetDefaultTabulation(fe, NULL, &basisDer, NULL);CHKERRQ(ierr); 147523d86601SMatthew G. Knepley if (debug) { 147623d86601SMatthew G. Knepley char title[1024]; 147723d86601SMatthew G. Knepley ierr = PetscSNPrintf(title, 1023, "Solution for Field %d", field);CHKERRQ(ierr); 147823d86601SMatthew G. Knepley ierr = DMPrintCellVector(c, title, Nb*Nc, &x[fieldOffset]);CHKERRQ(ierr); 147923d86601SMatthew G. Knepley } 148023d86601SMatthew G. Knepley for (q = 0; q < Nq; ++q) { 148123d86601SMatthew G. Knepley for (d = 0; d < dim; d++) { 148223d86601SMatthew G. Knepley coords[d] = v0[d]; 148323d86601SMatthew G. Knepley for (e = 0; e < dim; e++) { 148423d86601SMatthew G. Knepley coords[d] += J[d*dim+e]*(quadPoints[q*dim+e] + 1.0); 148523d86601SMatthew G. Knepley } 148623d86601SMatthew G. Knepley } 148723d86601SMatthew G. Knepley (*funcs[field])(coords, n, funcVal, ctx); 148823d86601SMatthew G. Knepley for (fc = 0; fc < Nc; ++fc) { 148923d86601SMatthew G. Knepley PetscScalar interpolant = 0.0; 149023d86601SMatthew G. Knepley 149123d86601SMatthew G. Knepley for (d = 0; d < dim; ++d) interpolantVec[d] = 0.0; 149223d86601SMatthew G. Knepley for (f = 0; f < Nb; ++f) { 149323d86601SMatthew G. Knepley const PetscInt fidx = f*Nc+fc; 149423d86601SMatthew G. Knepley 149523d86601SMatthew G. Knepley for (d = 0; d < dim; ++d) { 149623d86601SMatthew G. Knepley realSpaceDer[d] = 0.0; 149723d86601SMatthew G. Knepley for (g = 0; g < dim; ++g) { 149823d86601SMatthew G. Knepley realSpaceDer[d] += invJ[g*dim+d]*basisDer[(q*Nb*Nc+fidx)*dim+g]; 149923d86601SMatthew G. Knepley } 150023d86601SMatthew G. Knepley interpolantVec[d] += x[fieldOffset+fidx]*realSpaceDer[d]; 150123d86601SMatthew G. Knepley } 150223d86601SMatthew G. Knepley } 150323d86601SMatthew G. Knepley for (d = 0; d < dim; ++d) interpolant += interpolantVec[d]*n[d]; 150423d86601SMatthew G. Knepley if (debug) {ierr = PetscPrintf(PETSC_COMM_SELF, " elem %d fieldDer %d diff %g\n", c, field, PetscSqr(PetscRealPart(interpolant - funcVal[fc]))*quadWeights[q]*detJ);CHKERRQ(ierr);} 150523d86601SMatthew G. Knepley elemDiff += PetscSqr(PetscRealPart(interpolant - funcVal[fc]))*quadWeights[q]*detJ; 150623d86601SMatthew G. Knepley } 150723d86601SMatthew G. Knepley } 150823d86601SMatthew G. Knepley comp += Nc; 150923d86601SMatthew G. Knepley fieldOffset += Nb*Nc; 151023d86601SMatthew G. Knepley } 151123d86601SMatthew G. Knepley ierr = DMDAVecRestoreClosure(dm, NULL, localX, c, NULL, &x);CHKERRQ(ierr); 151223d86601SMatthew G. Knepley if (debug) {ierr = PetscPrintf(PETSC_COMM_SELF, " elem %d diff %g\n", c, elemDiff);CHKERRQ(ierr);} 151323d86601SMatthew G. Knepley localDiff += elemDiff; 151423d86601SMatthew G. Knepley } 151523d86601SMatthew G. Knepley ierr = PetscFree7(funcVal,coords,realSpaceDer,v0,J,invJ,interpolantVec);CHKERRQ(ierr); 151623d86601SMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr); 151723d86601SMatthew G. Knepley ierr = MPI_Allreduce(&localDiff, diff, 1, MPIU_REAL, MPI_SUM, PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 151823d86601SMatthew G. Knepley *diff = PetscSqrtReal(*diff); 151923d86601SMatthew G. Knepley PetscFunctionReturn(0); 152023d86601SMatthew G. Knepley } 152123d86601SMatthew G. Knepley 152247c6ae99SBarry Smith /* ------------------------------------------------------------------- */ 152347c6ae99SBarry Smith 152447c6ae99SBarry Smith #undef __FUNCT__ 1525aa219208SBarry Smith #define __FUNCT__ "DMDAGetArray" 152647c6ae99SBarry Smith /*@C 1527aa219208SBarry Smith DMDAGetArray - Gets a work array for a DMDA 152847c6ae99SBarry Smith 152947c6ae99SBarry Smith Input Parameter: 153047c6ae99SBarry Smith + da - information about my local patch 153147c6ae99SBarry Smith - ghosted - do you want arrays for the ghosted or nonghosted patch 153247c6ae99SBarry Smith 153347c6ae99SBarry Smith Output Parameters: 153447c6ae99SBarry Smith . vptr - array data structured 153547c6ae99SBarry Smith 153647c6ae99SBarry Smith Note: The vector values are NOT initialized and may have garbage in them, so you may need 153747c6ae99SBarry Smith to zero them. 153847c6ae99SBarry Smith 153947c6ae99SBarry Smith Level: advanced 154047c6ae99SBarry Smith 1541bcaeba4dSBarry Smith .seealso: DMDARestoreArray() 154247c6ae99SBarry Smith 154347c6ae99SBarry Smith @*/ 15447087cfbeSBarry Smith PetscErrorCode DMDAGetArray(DM da,PetscBool ghosted,void *vptr) 154547c6ae99SBarry Smith { 154647c6ae99SBarry Smith PetscErrorCode ierr; 154747c6ae99SBarry Smith PetscInt j,i,xs,ys,xm,ym,zs,zm; 154847c6ae99SBarry Smith char *iarray_start; 154947c6ae99SBarry Smith void **iptr = (void**)vptr; 155047c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 155147c6ae99SBarry Smith 155247c6ae99SBarry Smith PetscFunctionBegin; 155347c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 155447c6ae99SBarry Smith if (ghosted) { 1555aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 155647c6ae99SBarry Smith if (dd->arrayghostedin[i]) { 155747c6ae99SBarry Smith *iptr = dd->arrayghostedin[i]; 155847c6ae99SBarry Smith iarray_start = (char*)dd->startghostedin[i]; 15590298fd71SBarry Smith dd->arrayghostedin[i] = NULL; 15600298fd71SBarry Smith dd->startghostedin[i] = NULL; 156147c6ae99SBarry Smith 156247c6ae99SBarry Smith goto done; 156347c6ae99SBarry Smith } 156447c6ae99SBarry Smith } 156547c6ae99SBarry Smith xs = dd->Xs; 156647c6ae99SBarry Smith ys = dd->Ys; 156747c6ae99SBarry Smith zs = dd->Zs; 156847c6ae99SBarry Smith xm = dd->Xe-dd->Xs; 156947c6ae99SBarry Smith ym = dd->Ye-dd->Ys; 157047c6ae99SBarry Smith zm = dd->Ze-dd->Zs; 157147c6ae99SBarry Smith } else { 1572aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 157347c6ae99SBarry Smith if (dd->arrayin[i]) { 157447c6ae99SBarry Smith *iptr = dd->arrayin[i]; 157547c6ae99SBarry Smith iarray_start = (char*)dd->startin[i]; 15760298fd71SBarry Smith dd->arrayin[i] = NULL; 15770298fd71SBarry Smith dd->startin[i] = NULL; 157847c6ae99SBarry Smith 157947c6ae99SBarry Smith goto done; 158047c6ae99SBarry Smith } 158147c6ae99SBarry Smith } 158247c6ae99SBarry Smith xs = dd->xs; 158347c6ae99SBarry Smith ys = dd->ys; 158447c6ae99SBarry Smith zs = dd->zs; 158547c6ae99SBarry Smith xm = dd->xe-dd->xs; 158647c6ae99SBarry Smith ym = dd->ye-dd->ys; 158747c6ae99SBarry Smith zm = dd->ze-dd->zs; 158847c6ae99SBarry Smith } 158947c6ae99SBarry Smith 159047c6ae99SBarry Smith switch (dd->dim) { 159147c6ae99SBarry Smith case 1: { 159247c6ae99SBarry Smith void *ptr; 159347c6ae99SBarry Smith 1594901f1932SJed Brown ierr = PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 159547c6ae99SBarry Smith 159647c6ae99SBarry Smith ptr = (void*)(iarray_start - xs*sizeof(PetscScalar)); 159747c6ae99SBarry Smith *iptr = (void*)ptr; 15988865f1eaSKarl Rupp break; 15998865f1eaSKarl Rupp } 160047c6ae99SBarry Smith case 2: { 160147c6ae99SBarry Smith void **ptr; 160247c6ae99SBarry Smith 1603901f1932SJed Brown ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 160447c6ae99SBarry Smith 160547c6ae99SBarry Smith ptr = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*)); 16068865f1eaSKarl Rupp for (j=ys; j<ys+ym; j++) ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs); 160747c6ae99SBarry Smith *iptr = (void*)ptr; 16088865f1eaSKarl Rupp break; 16098865f1eaSKarl Rupp } 161047c6ae99SBarry Smith case 3: { 161147c6ae99SBarry Smith void ***ptr,**bptr; 161247c6ae99SBarry Smith 1613901f1932SJed Brown ierr = PetscMalloc((zm+1)*sizeof(void**)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 161447c6ae99SBarry Smith 161547c6ae99SBarry Smith ptr = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*)); 161647c6ae99SBarry Smith bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**)); 16178865f1eaSKarl Rupp for (i=zs; i<zs+zm; i++) ptr[i] = bptr + ((i-zs)*ym - ys); 161847c6ae99SBarry Smith for (i=zs; i<zs+zm; i++) { 161947c6ae99SBarry Smith for (j=ys; j<ys+ym; j++) { 162047c6ae99SBarry Smith ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs); 162147c6ae99SBarry Smith } 162247c6ae99SBarry Smith } 162347c6ae99SBarry Smith *iptr = (void*)ptr; 16248865f1eaSKarl Rupp break; 16258865f1eaSKarl Rupp } 162647c6ae99SBarry Smith default: 1627ce94432eSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Dimension %D not supported",dd->dim); 162847c6ae99SBarry Smith } 162947c6ae99SBarry Smith 163047c6ae99SBarry Smith done: 163147c6ae99SBarry Smith /* add arrays to the checked out list */ 163247c6ae99SBarry Smith if (ghosted) { 1633aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 163447c6ae99SBarry Smith if (!dd->arrayghostedout[i]) { 163547c6ae99SBarry Smith dd->arrayghostedout[i] = *iptr; 163647c6ae99SBarry Smith dd->startghostedout[i] = iarray_start; 163747c6ae99SBarry Smith break; 163847c6ae99SBarry Smith } 163947c6ae99SBarry Smith } 164047c6ae99SBarry Smith } else { 1641aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 164247c6ae99SBarry Smith if (!dd->arrayout[i]) { 164347c6ae99SBarry Smith dd->arrayout[i] = *iptr; 164447c6ae99SBarry Smith dd->startout[i] = iarray_start; 164547c6ae99SBarry Smith break; 164647c6ae99SBarry Smith } 164747c6ae99SBarry Smith } 164847c6ae99SBarry Smith } 164947c6ae99SBarry Smith PetscFunctionReturn(0); 165047c6ae99SBarry Smith } 165147c6ae99SBarry Smith 165247c6ae99SBarry Smith #undef __FUNCT__ 1653aa219208SBarry Smith #define __FUNCT__ "DMDARestoreArray" 165447c6ae99SBarry Smith /*@C 1655aa219208SBarry Smith DMDARestoreArray - Restores an array of derivative types for a DMDA 165647c6ae99SBarry Smith 165747c6ae99SBarry Smith Input Parameter: 165847c6ae99SBarry Smith + da - information about my local patch 165947c6ae99SBarry Smith . ghosted - do you want arrays for the ghosted or nonghosted patch 166047c6ae99SBarry Smith - vptr - array data structured to be passed to ad_FormFunctionLocal() 166147c6ae99SBarry Smith 166247c6ae99SBarry Smith Level: advanced 166347c6ae99SBarry Smith 1664bcaeba4dSBarry Smith .seealso: DMDAGetArray() 166547c6ae99SBarry Smith 166647c6ae99SBarry Smith @*/ 16677087cfbeSBarry Smith PetscErrorCode DMDARestoreArray(DM da,PetscBool ghosted,void *vptr) 166847c6ae99SBarry Smith { 166947c6ae99SBarry Smith PetscInt i; 167047c6ae99SBarry Smith void **iptr = (void**)vptr,*iarray_start = 0; 167147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 167247c6ae99SBarry Smith 167347c6ae99SBarry Smith PetscFunctionBegin; 167447c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 167547c6ae99SBarry Smith if (ghosted) { 1676aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 167747c6ae99SBarry Smith if (dd->arrayghostedout[i] == *iptr) { 167847c6ae99SBarry Smith iarray_start = dd->startghostedout[i]; 16790298fd71SBarry Smith dd->arrayghostedout[i] = NULL; 16800298fd71SBarry Smith dd->startghostedout[i] = NULL; 168147c6ae99SBarry Smith break; 168247c6ae99SBarry Smith } 168347c6ae99SBarry Smith } 1684aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 168547c6ae99SBarry Smith if (!dd->arrayghostedin[i]) { 168647c6ae99SBarry Smith dd->arrayghostedin[i] = *iptr; 168747c6ae99SBarry Smith dd->startghostedin[i] = iarray_start; 168847c6ae99SBarry Smith break; 168947c6ae99SBarry Smith } 169047c6ae99SBarry Smith } 169147c6ae99SBarry Smith } else { 1692aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 169347c6ae99SBarry Smith if (dd->arrayout[i] == *iptr) { 169447c6ae99SBarry Smith iarray_start = dd->startout[i]; 16950298fd71SBarry Smith dd->arrayout[i] = NULL; 16960298fd71SBarry Smith dd->startout[i] = NULL; 169747c6ae99SBarry Smith break; 169847c6ae99SBarry Smith } 169947c6ae99SBarry Smith } 1700aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 170147c6ae99SBarry Smith if (!dd->arrayin[i]) { 170247c6ae99SBarry Smith dd->arrayin[i] = *iptr; 170347c6ae99SBarry Smith dd->startin[i] = iarray_start; 170447c6ae99SBarry Smith break; 170547c6ae99SBarry Smith } 170647c6ae99SBarry Smith } 170747c6ae99SBarry Smith } 170847c6ae99SBarry Smith PetscFunctionReturn(0); 170947c6ae99SBarry Smith } 171047c6ae99SBarry Smith 1711