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*/ 7*b2fff234SMatthew G. Knepley #include <petscbt.h> 80c312b8eSJed Brown #include <petscsf.h> 947c6ae99SBarry Smith 1047c6ae99SBarry Smith /* 11e3c5b3baSBarry Smith This allows the DMDA vectors to properly tell MATLAB their dimensions 1247c6ae99SBarry Smith */ 1347c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 14c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 15c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 1647c6ae99SBarry Smith #undef __FUNCT__ 1747c6ae99SBarry Smith #define __FUNCT__ "VecMatlabEnginePut_DA2d" 181e6b0712SBarry Smith static PetscErrorCode VecMatlabEnginePut_DA2d(PetscObject obj,void *mengine) 1947c6ae99SBarry Smith { 2047c6ae99SBarry Smith PetscErrorCode ierr; 2147c6ae99SBarry Smith PetscInt n,m; 2247c6ae99SBarry Smith Vec vec = (Vec)obj; 2347c6ae99SBarry Smith PetscScalar *array; 2447c6ae99SBarry Smith mxArray *mat; 259a42bb27SBarry Smith DM da; 2647c6ae99SBarry Smith 2747c6ae99SBarry Smith PetscFunctionBegin; 28c688c046SMatthew G Knepley ierr = VecGetDM(vec, &da);CHKERRQ(ierr); 29ce94432eSBarry Smith if (!da) SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_ARG_WRONGSTATE,"Vector not associated with a DMDA"); 30aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,0,0,0,&m,&n,0);CHKERRQ(ierr); 3147c6ae99SBarry Smith 3247c6ae99SBarry Smith ierr = VecGetArray(vec,&array);CHKERRQ(ierr); 3347c6ae99SBarry Smith #if !defined(PETSC_USE_COMPLEX) 3447c6ae99SBarry Smith mat = mxCreateDoubleMatrix(m,n,mxREAL); 3547c6ae99SBarry Smith #else 3647c6ae99SBarry Smith mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX); 3747c6ae99SBarry Smith #endif 3847c6ae99SBarry Smith ierr = PetscMemcpy(mxGetPr(mat),array,n*m*sizeof(PetscScalar));CHKERRQ(ierr); 3947c6ae99SBarry Smith ierr = PetscObjectName(obj);CHKERRQ(ierr); 4047c6ae99SBarry Smith engPutVariable((Engine*)mengine,obj->name,mat); 4147c6ae99SBarry Smith 4247c6ae99SBarry Smith ierr = VecRestoreArray(vec,&array);CHKERRQ(ierr); 4347c6ae99SBarry Smith PetscFunctionReturn(0); 4447c6ae99SBarry Smith } 4547c6ae99SBarry Smith #endif 4647c6ae99SBarry Smith 4747c6ae99SBarry Smith 4847c6ae99SBarry Smith #undef __FUNCT__ 49564755cdSBarry Smith #define __FUNCT__ "DMCreateLocalVector_DA" 507087cfbeSBarry Smith PetscErrorCode DMCreateLocalVector_DA(DM da,Vec *g) 5147c6ae99SBarry Smith { 5247c6ae99SBarry Smith PetscErrorCode ierr; 5347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 5447c6ae99SBarry Smith 5547c6ae99SBarry Smith PetscFunctionBegin; 5647c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 5747c6ae99SBarry Smith PetscValidPointer(g,2); 5811689aebSJed Brown if (da->defaultSection) { 5911689aebSJed Brown ierr = DMCreateLocalVector_Section_Private(da,g);CHKERRQ(ierr); 6011689aebSJed Brown } else { 6147c6ae99SBarry Smith ierr = VecCreate(PETSC_COMM_SELF,g);CHKERRQ(ierr); 6247c6ae99SBarry Smith ierr = VecSetSizes(*g,dd->nlocal,PETSC_DETERMINE);CHKERRQ(ierr); 6347c6ae99SBarry Smith ierr = VecSetBlockSize(*g,dd->w);CHKERRQ(ierr); 64401ddaa8SBarry Smith ierr = VecSetType(*g,da->vectype);CHKERRQ(ierr); 65c688c046SMatthew G Knepley ierr = VecSetDM(*g, da);CHKERRQ(ierr); 6647c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 6747c6ae99SBarry Smith if (dd->w == 1 && dd->dim == 2) { 68bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)*g,"PetscMatlabEnginePut_C",VecMatlabEnginePut_DA2d);CHKERRQ(ierr); 6947c6ae99SBarry Smith } 7047c6ae99SBarry Smith #endif 7111689aebSJed Brown } 7247c6ae99SBarry Smith PetscFunctionReturn(0); 7347c6ae99SBarry Smith } 7447c6ae99SBarry Smith 75a66d4d66SMatthew G Knepley #undef __FUNCT__ 7657459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumCells" 7757459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumCells(DM dm, PetscInt *numCells) 7857459e9aSMatthew G Knepley { 7957459e9aSMatthew G Knepley DM_DA *da = (DM_DA*) dm->data; 8057459e9aSMatthew G Knepley const PetscInt dim = da->dim; 8157459e9aSMatthew G Knepley const PetscInt mx = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs; 8257459e9aSMatthew G Knepley const PetscInt nC = (mx)*(dim > 1 ? (my)*(dim > 2 ? (mz) : 1) : 1); 8357459e9aSMatthew G Knepley 8457459e9aSMatthew G Knepley PetscFunctionBegin; 8557459e9aSMatthew G Knepley if (numCells) { 8657459e9aSMatthew G Knepley PetscValidIntPointer(numCells,2); 8757459e9aSMatthew G Knepley *numCells = nC; 8857459e9aSMatthew G Knepley } 8957459e9aSMatthew G Knepley PetscFunctionReturn(0); 9057459e9aSMatthew G Knepley } 9157459e9aSMatthew G Knepley 9257459e9aSMatthew G Knepley #undef __FUNCT__ 9357459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumVertices" 9457459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumVertices(DM dm, PetscInt *numVerticesX, PetscInt *numVerticesY, PetscInt *numVerticesZ, PetscInt *numVertices) 9557459e9aSMatthew G Knepley { 9657459e9aSMatthew G Knepley DM_DA *da = (DM_DA*) dm->data; 9757459e9aSMatthew G Knepley const PetscInt dim = da->dim; 9857459e9aSMatthew G Knepley const PetscInt mx = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs; 9957459e9aSMatthew G Knepley const PetscInt nVx = mx+1; 10057459e9aSMatthew G Knepley const PetscInt nVy = dim > 1 ? (my+1) : 1; 10157459e9aSMatthew G Knepley const PetscInt nVz = dim > 2 ? (mz+1) : 1; 10257459e9aSMatthew G Knepley const PetscInt nV = nVx*nVy*nVz; 10357459e9aSMatthew G Knepley 10457459e9aSMatthew G Knepley PetscFunctionBegin; 10557459e9aSMatthew G Knepley if (numVerticesX) { 10657459e9aSMatthew G Knepley PetscValidIntPointer(numVerticesX,2); 10757459e9aSMatthew G Knepley *numVerticesX = nVx; 10857459e9aSMatthew G Knepley } 10957459e9aSMatthew G Knepley if (numVerticesY) { 11057459e9aSMatthew G Knepley PetscValidIntPointer(numVerticesY,3); 11157459e9aSMatthew G Knepley *numVerticesY = nVy; 11257459e9aSMatthew G Knepley } 11357459e9aSMatthew G Knepley if (numVerticesZ) { 11457459e9aSMatthew G Knepley PetscValidIntPointer(numVerticesZ,4); 11557459e9aSMatthew G Knepley *numVerticesZ = nVz; 11657459e9aSMatthew G Knepley } 11757459e9aSMatthew G Knepley if (numVertices) { 11857459e9aSMatthew G Knepley PetscValidIntPointer(numVertices,5); 11957459e9aSMatthew G Knepley *numVertices = nV; 12057459e9aSMatthew G Knepley } 12157459e9aSMatthew G Knepley PetscFunctionReturn(0); 12257459e9aSMatthew G Knepley } 12357459e9aSMatthew G Knepley 12457459e9aSMatthew G Knepley #undef __FUNCT__ 12557459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumFaces" 12657459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumFaces(DM dm, PetscInt *numXFacesX, PetscInt *numXFaces, PetscInt *numYFacesY, PetscInt *numYFaces, PetscInt *numZFacesZ, PetscInt *numZFaces) 12757459e9aSMatthew G Knepley { 12857459e9aSMatthew G Knepley DM_DA *da = (DM_DA*) dm->data; 12957459e9aSMatthew G Knepley const PetscInt dim = da->dim; 13057459e9aSMatthew G Knepley const PetscInt mx = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs; 13157459e9aSMatthew G Knepley const PetscInt nxF = (dim > 1 ? (my)*(dim > 2 ? (mz) : 1) : 1); 13257459e9aSMatthew G Knepley const PetscInt nXF = (mx+1)*nxF; 13357459e9aSMatthew G Knepley const PetscInt nyF = mx*(dim > 2 ? mz : 1); 13457459e9aSMatthew G Knepley const PetscInt nYF = dim > 1 ? (my+1)*nyF : 0; 13557459e9aSMatthew G Knepley const PetscInt nzF = mx*(dim > 1 ? my : 0); 13657459e9aSMatthew G Knepley const PetscInt nZF = dim > 2 ? (mz+1)*nzF : 0; 13757459e9aSMatthew G Knepley 13857459e9aSMatthew G Knepley PetscFunctionBegin; 13957459e9aSMatthew G Knepley if (numXFacesX) { 14057459e9aSMatthew G Knepley PetscValidIntPointer(numXFacesX,2); 14157459e9aSMatthew G Knepley *numXFacesX = nxF; 14257459e9aSMatthew G Knepley } 14357459e9aSMatthew G Knepley if (numXFaces) { 14457459e9aSMatthew G Knepley PetscValidIntPointer(numXFaces,3); 14557459e9aSMatthew G Knepley *numXFaces = nXF; 14657459e9aSMatthew G Knepley } 14757459e9aSMatthew G Knepley if (numYFacesY) { 14857459e9aSMatthew G Knepley PetscValidIntPointer(numYFacesY,4); 14957459e9aSMatthew G Knepley *numYFacesY = nyF; 15057459e9aSMatthew G Knepley } 15157459e9aSMatthew G Knepley if (numYFaces) { 15257459e9aSMatthew G Knepley PetscValidIntPointer(numYFaces,5); 15357459e9aSMatthew G Knepley *numYFaces = nYF; 15457459e9aSMatthew G Knepley } 15557459e9aSMatthew G Knepley if (numZFacesZ) { 15657459e9aSMatthew G Knepley PetscValidIntPointer(numZFacesZ,6); 15757459e9aSMatthew G Knepley *numZFacesZ = nzF; 15857459e9aSMatthew G Knepley } 15957459e9aSMatthew G Knepley if (numZFaces) { 16057459e9aSMatthew G Knepley PetscValidIntPointer(numZFaces,7); 16157459e9aSMatthew G Knepley *numZFaces = nZF; 16257459e9aSMatthew G Knepley } 16357459e9aSMatthew G Knepley PetscFunctionReturn(0); 16457459e9aSMatthew G Knepley } 16557459e9aSMatthew G Knepley 16657459e9aSMatthew G Knepley #undef __FUNCT__ 16757459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetHeightStratum" 16857459e9aSMatthew G Knepley PetscErrorCode DMDAGetHeightStratum(DM dm, PetscInt height, PetscInt *pStart, PetscInt *pEnd) 16957459e9aSMatthew G Knepley { 17057459e9aSMatthew G Knepley DM_DA *da = (DM_DA*) dm->data; 17157459e9aSMatthew G Knepley const PetscInt dim = da->dim; 17257459e9aSMatthew G Knepley PetscInt nC, nV, nXF, nYF, nZF; 17357459e9aSMatthew G Knepley PetscErrorCode ierr; 17457459e9aSMatthew G Knepley 17557459e9aSMatthew G Knepley PetscFunctionBegin; 1768865f1eaSKarl Rupp if (pStart) PetscValidIntPointer(pStart,3); 1778865f1eaSKarl Rupp if (pEnd) PetscValidIntPointer(pEnd,4); 17857459e9aSMatthew G Knepley ierr = DMDAGetNumCells(dm, &nC);CHKERRQ(ierr); 1790298fd71SBarry Smith ierr = DMDAGetNumVertices(dm, NULL, NULL, NULL, &nV);CHKERRQ(ierr); 1800298fd71SBarry Smith ierr = DMDAGetNumFaces(dm, NULL, &nXF, NULL, &nYF, NULL, &nZF);CHKERRQ(ierr); 18157459e9aSMatthew G Knepley if (height == 0) { 18257459e9aSMatthew G Knepley /* Cells */ 1838865f1eaSKarl Rupp if (pStart) *pStart = 0; 1848865f1eaSKarl Rupp if (pEnd) *pEnd = nC; 18557459e9aSMatthew G Knepley } else if (height == 1) { 18657459e9aSMatthew G Knepley /* Faces */ 1878865f1eaSKarl Rupp if (pStart) *pStart = nC+nV; 1888865f1eaSKarl Rupp if (pEnd) *pEnd = nC+nV+nXF+nYF+nZF; 18957459e9aSMatthew G Knepley } else if (height == dim) { 19057459e9aSMatthew G Knepley /* Vertices */ 1918865f1eaSKarl Rupp if (pStart) *pStart = nC; 1928865f1eaSKarl Rupp if (pEnd) *pEnd = nC+nV; 19357459e9aSMatthew G Knepley } else if (height < 0) { 19457459e9aSMatthew G Knepley /* All points */ 1958865f1eaSKarl Rupp if (pStart) *pStart = 0; 1968865f1eaSKarl Rupp if (pEnd) *pEnd = nC+nV+nXF+nYF+nZF; 19782f516ccSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "No points of height %d in the DA", height); 19857459e9aSMatthew G Knepley PetscFunctionReturn(0); 19957459e9aSMatthew G Knepley } 20057459e9aSMatthew G Knepley 20157459e9aSMatthew G Knepley #undef __FUNCT__ 202a66d4d66SMatthew G Knepley #define __FUNCT__ "DMDACreateSection" 203a66d4d66SMatthew G Knepley /*@C 204a66d4d66SMatthew G Knepley DMDACreateSection - Create a PetscSection inside the DMDA that describes data layout. This allows multiple fields with 205a66d4d66SMatthew G Knepley different numbers of dofs on vertices, cells, and faces in each direction. 206a66d4d66SMatthew G Knepley 207a66d4d66SMatthew G Knepley Input Parameters: 208a66d4d66SMatthew G Knepley + dm- The DMDA 209a66d4d66SMatthew G Knepley . numFields - The number of fields 2100298fd71SBarry Smith . numComp - The number of components in each field, or NULL for 1 2110298fd71SBarry Smith . numVertexDof - The number of dofs per vertex for each field, or NULL 2120298fd71SBarry Smith . numFaceDof - The number of dofs per face for each field and direction, or NULL 2130298fd71SBarry Smith - numCellDof - The number of dofs per cell for each field, or NULL 214a66d4d66SMatthew G Knepley 215a66d4d66SMatthew G Knepley Level: developer 216a66d4d66SMatthew G Knepley 217a66d4d66SMatthew G Knepley Note: 218a66d4d66SMatthew G Knepley The default DMDA numbering is as follows: 219a66d4d66SMatthew G Knepley 220a66d4d66SMatthew G Knepley - Cells: [0, nC) 221a66d4d66SMatthew G Knepley - Vertices: [nC, nC+nV) 22288ed4aceSMatthew G Knepley - X-Faces: [nC+nV, nC+nV+nXF) normal is +- x-dir 22388ed4aceSMatthew G Knepley - Y-Faces: [nC+nV+nXF, nC+nV+nXF+nYF) normal is +- y-dir 22488ed4aceSMatthew G Knepley - Z-Faces: [nC+nV+nXF+nYF, nC+nV+nXF+nYF+nZF) normal is +- z-dir 225a66d4d66SMatthew G Knepley 226a66d4d66SMatthew G Knepley We interpret the default DMDA partition as a cell partition, and the data assignment as a cell assignment. 227a66d4d66SMatthew G Knepley @*/ 22880800b1aSMatthew G Knepley PetscErrorCode DMDACreateSection(DM dm, PetscInt numComp[], PetscInt numVertexDof[], PetscInt numFaceDof[], PetscInt numCellDof[]) 229a66d4d66SMatthew G Knepley { 230a66d4d66SMatthew G Knepley DM_DA *da = (DM_DA*) dm->data; 23188ed4aceSMatthew G Knepley const PetscInt dim = da->dim; 23280800b1aSMatthew G Knepley PetscInt numFields, numVertexTotDof = 0, numCellTotDof = 0, numFaceTotDof[3] = {0, 0, 0}; 233*b2fff234SMatthew G. Knepley PetscBT isLeaf; 23488ed4aceSMatthew G Knepley PetscSF sf; 235feafbc5cSMatthew G Knepley PetscMPIInt rank; 23688ed4aceSMatthew G Knepley const PetscMPIInt *neighbors; 23788ed4aceSMatthew G Knepley PetscInt *localPoints; 23888ed4aceSMatthew G Knepley PetscSFNode *remotePoints; 239f5eeb527SMatthew G Knepley PetscInt nleaves = 0, nleavesCheck = 0, nL = 0; 24057459e9aSMatthew G Knepley PetscInt nC, nVx, nVy, nVz, nV, nxF, nXF, nyF, nYF, nzF, nZF; 24157459e9aSMatthew G Knepley PetscInt pStart, pEnd, cStart, cEnd, vStart, vEnd, fStart, fEnd, xfStart, xfEnd, yfStart, yfEnd, zfStart, zfEnd; 24288ed4aceSMatthew G Knepley PetscInt f, v, c, xf, yf, zf, xn, yn, zn; 243a66d4d66SMatthew G Knepley PetscErrorCode ierr; 244a66d4d66SMatthew G Knepley 245a66d4d66SMatthew G Knepley PetscFunctionBegin; 246a66d4d66SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 24782f516ccSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr); 24857459e9aSMatthew G Knepley ierr = DMDAGetNumCells(dm, &nC);CHKERRQ(ierr); 24957459e9aSMatthew G Knepley ierr = DMDAGetNumVertices(dm, &nVx, &nVy, &nVz, &nV);CHKERRQ(ierr); 25057459e9aSMatthew G Knepley ierr = DMDAGetNumFaces(dm, &nxF, &nXF, &nyF, &nYF, &nzF, &nZF);CHKERRQ(ierr); 25157459e9aSMatthew G Knepley ierr = DMDAGetHeightStratum(dm, -1, &pStart, &pEnd);CHKERRQ(ierr); 25257459e9aSMatthew G Knepley ierr = DMDAGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 25357459e9aSMatthew G Knepley ierr = DMDAGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 25457459e9aSMatthew G Knepley ierr = DMDAGetHeightStratum(dm, dim, &vStart, &vEnd);CHKERRQ(ierr); 25557459e9aSMatthew G Knepley xfStart = vEnd; xfEnd = xfStart+nXF; 25657459e9aSMatthew G Knepley yfStart = xfEnd; yfEnd = yfStart+nYF; 25757459e9aSMatthew G Knepley zfStart = yfEnd; zfEnd = zfStart+nZF; 25882f516ccSBarry Smith if (zfEnd != fEnd) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Invalid face end %d, should be %d", zfEnd, fEnd); 25988ed4aceSMatthew G Knepley /* Create local section */ 26080800b1aSMatthew G Knepley ierr = DMDAGetInfo(dm, 0,0,0,0,0,0,0, &numFields, 0,0,0,0,0);CHKERRQ(ierr); 261a66d4d66SMatthew G Knepley for (f = 0; f < numFields; ++f) { 2628865f1eaSKarl Rupp if (numVertexDof) numVertexTotDof += numVertexDof[f]; 2638865f1eaSKarl Rupp if (numCellDof) numCellTotDof += numCellDof[f]; 2648865f1eaSKarl Rupp if (numFaceDof) { 2658865f1eaSKarl Rupp numFaceTotDof[0] += numFaceDof[f*dim+0]; 26688ed4aceSMatthew G Knepley numFaceTotDof[1] += dim > 1 ? numFaceDof[f*dim+1] : 0; 2670ad7597dSKarl Rupp numFaceTotDof[2] += dim > 2 ? numFaceDof[f*dim+2] : 0; 2680ad7597dSKarl Rupp } 269a66d4d66SMatthew G Knepley } 27082f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &dm->defaultSection);CHKERRQ(ierr); 271a66d4d66SMatthew G Knepley if (numFields > 1) { 27288ed4aceSMatthew G Knepley ierr = PetscSectionSetNumFields(dm->defaultSection, numFields);CHKERRQ(ierr); 273a66d4d66SMatthew G Knepley for (f = 0; f < numFields; ++f) { 27480800b1aSMatthew G Knepley const char *name; 27580800b1aSMatthew G Knepley 27680800b1aSMatthew G Knepley ierr = DMDAGetFieldName(dm, f, &name);CHKERRQ(ierr); 27788ed4aceSMatthew G Knepley ierr = PetscSectionSetFieldName(dm->defaultSection, f, name);CHKERRQ(ierr); 27880800b1aSMatthew G Knepley if (numComp) { 27988ed4aceSMatthew G Knepley ierr = PetscSectionSetFieldComponents(dm->defaultSection, f, numComp[f]);CHKERRQ(ierr); 280a66d4d66SMatthew G Knepley } 281a66d4d66SMatthew G Knepley } 282a66d4d66SMatthew G Knepley } else { 283a66d4d66SMatthew G Knepley numFields = 0; 284a66d4d66SMatthew G Knepley } 28588ed4aceSMatthew G Knepley ierr = PetscSectionSetChart(dm->defaultSection, pStart, pEnd);CHKERRQ(ierr); 286a66d4d66SMatthew G Knepley if (numVertexDof) { 287a66d4d66SMatthew G Knepley for (v = vStart; v < vEnd; ++v) { 288a66d4d66SMatthew G Knepley for (f = 0; f < numFields; ++f) { 28988ed4aceSMatthew G Knepley ierr = PetscSectionSetFieldDof(dm->defaultSection, v, f, numVertexDof[f]);CHKERRQ(ierr); 290a66d4d66SMatthew G Knepley } 29188ed4aceSMatthew G Knepley ierr = PetscSectionSetDof(dm->defaultSection, v, numVertexTotDof);CHKERRQ(ierr); 292a66d4d66SMatthew G Knepley } 293a66d4d66SMatthew G Knepley } 294a66d4d66SMatthew G Knepley if (numFaceDof) { 295a66d4d66SMatthew G Knepley for (xf = xfStart; xf < xfEnd; ++xf) { 296a66d4d66SMatthew G Knepley for (f = 0; f < numFields; ++f) { 29788ed4aceSMatthew G Knepley ierr = PetscSectionSetFieldDof(dm->defaultSection, xf, f, numFaceDof[f*dim+0]);CHKERRQ(ierr); 298a66d4d66SMatthew G Knepley } 29988ed4aceSMatthew G Knepley ierr = PetscSectionSetDof(dm->defaultSection, xf, numFaceTotDof[0]);CHKERRQ(ierr); 300a66d4d66SMatthew G Knepley } 301a66d4d66SMatthew G Knepley for (yf = yfStart; yf < yfEnd; ++yf) { 302a66d4d66SMatthew G Knepley for (f = 0; f < numFields; ++f) { 30388ed4aceSMatthew G Knepley ierr = PetscSectionSetFieldDof(dm->defaultSection, yf, f, numFaceDof[f*dim+1]);CHKERRQ(ierr); 304a66d4d66SMatthew G Knepley } 30588ed4aceSMatthew G Knepley ierr = PetscSectionSetDof(dm->defaultSection, yf, numFaceTotDof[1]);CHKERRQ(ierr); 306a66d4d66SMatthew G Knepley } 307a66d4d66SMatthew G Knepley for (zf = zfStart; zf < zfEnd; ++zf) { 308a66d4d66SMatthew G Knepley for (f = 0; f < numFields; ++f) { 30988ed4aceSMatthew G Knepley ierr = PetscSectionSetFieldDof(dm->defaultSection, zf, f, numFaceDof[f*dim+2]);CHKERRQ(ierr); 310a66d4d66SMatthew G Knepley } 31188ed4aceSMatthew G Knepley ierr = PetscSectionSetDof(dm->defaultSection, zf, numFaceTotDof[2]);CHKERRQ(ierr); 312a66d4d66SMatthew G Knepley } 313a66d4d66SMatthew G Knepley } 314a66d4d66SMatthew G Knepley if (numCellDof) { 315a66d4d66SMatthew G Knepley for (c = cStart; c < cEnd; ++c) { 316a66d4d66SMatthew G Knepley for (f = 0; f < numFields; ++f) { 31788ed4aceSMatthew G Knepley ierr = PetscSectionSetFieldDof(dm->defaultSection, c, f, numCellDof[f]);CHKERRQ(ierr); 318a66d4d66SMatthew G Knepley } 31988ed4aceSMatthew G Knepley ierr = PetscSectionSetDof(dm->defaultSection, c, numCellTotDof);CHKERRQ(ierr); 320a66d4d66SMatthew G Knepley } 321a66d4d66SMatthew G Knepley } 32288ed4aceSMatthew G Knepley ierr = PetscSectionSetUp(dm->defaultSection);CHKERRQ(ierr); 32388ed4aceSMatthew G Knepley /* Create mesh point SF */ 324*b2fff234SMatthew G. Knepley ierr = PetscBTCreate(pEnd-pStart, &isLeaf);CHKERRQ(ierr); 32588ed4aceSMatthew G Knepley ierr = DMDAGetNeighbors(dm, &neighbors);CHKERRQ(ierr); 32688ed4aceSMatthew G Knepley for (zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) { 32788ed4aceSMatthew G Knepley for (yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) { 32888ed4aceSMatthew G Knepley for (xn = 0; xn < 3; ++xn) { 3297128ae9fSMatthew G Knepley const PetscInt xp = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0; 33088ed4aceSMatthew G Knepley const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn]; 331*b2fff234SMatthew G. Knepley PetscInt xv, yv, zv; 33288ed4aceSMatthew G Knepley 3333814d604SMatthew G Knepley if (neighbor >= 0 && neighbor < rank) { 334*b2fff234SMatthew G. Knepley if (xp < 0) { /* left */ 335*b2fff234SMatthew G. Knepley if (yp < 0) { /* bottom */ 336*b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 337*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + 0)*nVx + 0 + nC; /* left bottom back vertex */ 338*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 339*b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 340*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + 0 + nC; /* left bottom front vertex */ 341*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 342*b2fff234SMatthew G. Knepley } else { 343*b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 344*b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + 0)*nVx + 0 + nC; /* left bottom vertices */ 345*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 346*b2fff234SMatthew G. Knepley } 347*b2fff234SMatthew G. Knepley } 348*b2fff234SMatthew G. Knepley } else if (yp > 0) { /* top */ 349*b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 350*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + 0 + nC; /* left top back vertex */ 351*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 352*b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 353*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + 0 + nC; /* left top front vertex */ 354*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 355*b2fff234SMatthew G. Knepley } else { 356*b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 357*b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + 0 + nC; /* left top vertices */ 358*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 359*b2fff234SMatthew G. Knepley } 360*b2fff234SMatthew G. Knepley } 361*b2fff234SMatthew G. Knepley } else { 362*b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 363*b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 364*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + yv)*nVx + 0 + nC; /* left back vertices */ 365*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 366*b2fff234SMatthew G. Knepley } 367*b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 368*b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 369*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + 0 + nC; /* left front vertices */ 370*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 371*b2fff234SMatthew G. Knepley } 372*b2fff234SMatthew G. Knepley } else { 373*b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 374*b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 375*b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + yv)*nVx + 0 + nC; /* left vertices */ 376*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 377*b2fff234SMatthew G. Knepley } 378*b2fff234SMatthew G. Knepley } 379*b2fff234SMatthew G. Knepley #if 0 380*b2fff234SMatthew G. Knepley for (xf = 0; xf < nxF; ++xf) { 381*b2fff234SMatthew G. Knepley /* THIS IS WRONG */ 382*b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* left faces */ 383*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) ++nleaves; 384*b2fff234SMatthew G. Knepley } 385*b2fff234SMatthew G. Knepley #endif 386*b2fff234SMatthew G. Knepley } 387*b2fff234SMatthew G. Knepley } 388*b2fff234SMatthew G. Knepley } else if (xp > 0) { /* right */ 389*b2fff234SMatthew G. Knepley if (yp < 0) { /* bottom */ 390*b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 391*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + 0)*nVx + nVx-1 + nC; /* right bottom back vertex */ 392*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 393*b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 394*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + nVx-1 + nC; /* right bottom front vertex */ 395*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 396*b2fff234SMatthew G. Knepley } else { 397*b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 398*b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + 0)*nVx + nVx-1 + nC; /* right bottom vertices */ 399*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 400*b2fff234SMatthew G. Knepley } 401*b2fff234SMatthew G. Knepley } 402*b2fff234SMatthew G. Knepley } else if (yp > 0) { /* top */ 403*b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 404*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top back vertex */ 405*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 406*b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 407*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top front vertex */ 408*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 409*b2fff234SMatthew G. Knepley } else { 410*b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 411*b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top vertices */ 412*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 413*b2fff234SMatthew G. Knepley } 414*b2fff234SMatthew G. Knepley } 415*b2fff234SMatthew G. Knepley } else { 416*b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 417*b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 418*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + yv)*nVx + nVx-1 + nC; /* right back vertices */ 419*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 420*b2fff234SMatthew G. Knepley } 421*b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 422*b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 423*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; /* right front vertices */ 424*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 425*b2fff234SMatthew G. Knepley } 426*b2fff234SMatthew G. Knepley } else { 427*b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 428*b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 429*b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + yv)*nVx + nVx-1 + nC; /* right vertices */ 430*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 431*b2fff234SMatthew G. Knepley } 432*b2fff234SMatthew G. Knepley } 433*b2fff234SMatthew G. Knepley #if 0 434*b2fff234SMatthew G. Knepley for (xf = 0; xf < nxF; ++xf) { 435*b2fff234SMatthew G. Knepley /* THIS IS WRONG */ 436*b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* right faces */ 437*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) ++nleaves; 438*b2fff234SMatthew G. Knepley } 439*b2fff234SMatthew G. Knepley #endif 440*b2fff234SMatthew G. Knepley } 441*b2fff234SMatthew G. Knepley } 442*b2fff234SMatthew G. Knepley } else { 443*b2fff234SMatthew G. Knepley if (yp < 0) { /* bottom */ 444*b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 445*b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 446*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + 0)*nVx + xv + nC; /* bottom back vertices */ 447*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 448*b2fff234SMatthew G. Knepley } 449*b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 450*b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 451*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + xv + nC; /* bottom front vertices */ 452*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 453*b2fff234SMatthew G. Knepley } 454*b2fff234SMatthew G. Knepley } else { 455*b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 456*b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 457*b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + 0)*nVx + xv + nC; /* bottom vertices */ 458*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 459*b2fff234SMatthew G. Knepley } 460*b2fff234SMatthew G. Knepley } 461*b2fff234SMatthew G. Knepley #if 0 462*b2fff234SMatthew G. Knepley for (yf = 0; yf < nyF; ++yf) { 463*b2fff234SMatthew G. Knepley /* THIS IS WRONG */ 464*b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* bottom faces */ 465*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVFace)) ++nleaves; 466*b2fff234SMatthew G. Knepley } 467*b2fff234SMatthew G. Knepley #endif 468*b2fff234SMatthew G. Knepley } 469*b2fff234SMatthew G. Knepley } else if (yp > 0) { /* top */ 470*b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 471*b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 472*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + xv + nC; /* top back vertices */ 473*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 474*b2fff234SMatthew G. Knepley } 475*b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 476*b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 477*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; /* top front vertices */ 478*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 479*b2fff234SMatthew G. Knepley } 480*b2fff234SMatthew G. Knepley } else { 481*b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 482*b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 483*b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + xv + nC; /* top vertices */ 484*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 485*b2fff234SMatthew G. Knepley } 486*b2fff234SMatthew G. Knepley } 487*b2fff234SMatthew G. Knepley #if 0 488*b2fff234SMatthew G. Knepley for (yf = 0; yf < nyF; ++yf) { 489*b2fff234SMatthew G. Knepley /* THIS IS WRONG */ 490*b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* top faces */ 491*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVFace)) ++nleaves; 492*b2fff234SMatthew G. Knepley } 493*b2fff234SMatthew G. Knepley #endif 494*b2fff234SMatthew G. Knepley } 495*b2fff234SMatthew G. Knepley } else { 496*b2fff234SMatthew G. Knepley if (zp < 0) { /* back */ 497*b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 498*b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 499*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + yv)*nVx + xv + nC; /* back vertices */ 500*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 501*b2fff234SMatthew G. Knepley } 502*b2fff234SMatthew G. Knepley } 503*b2fff234SMatthew G. Knepley #if 0 504*b2fff234SMatthew G. Knepley for (zf = 0; zf < nzF; ++zf) { 505*b2fff234SMatthew G. Knepley /* THIS IS WRONG */ 506*b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* back faces */ 507*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) ++nleaves; 508*b2fff234SMatthew G. Knepley } 509*b2fff234SMatthew G. Knepley #endif 510*b2fff234SMatthew G. Knepley } else if (zp > 0) { /* front */ 511*b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 512*b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 513*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + xv + nC; /* front vertices */ 514*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves; 515*b2fff234SMatthew G. Knepley } 516*b2fff234SMatthew G. Knepley } 517*b2fff234SMatthew G. Knepley #if 0 518*b2fff234SMatthew G. Knepley for (zf = 0; zf < nzF; ++zf) { 519*b2fff234SMatthew G. Knepley /* THIS IS WRONG */ 520*b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* front faces */ 521*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) ++nleaves; 522*b2fff234SMatthew G. Knepley } 523*b2fff234SMatthew G. Knepley #endif 524*b2fff234SMatthew G. Knepley } else { 525*b2fff234SMatthew G. Knepley /* Nothing is shared from the interior */ 52688ed4aceSMatthew G Knepley } 52788ed4aceSMatthew G Knepley } 52888ed4aceSMatthew G Knepley } 52988ed4aceSMatthew G Knepley } 53088ed4aceSMatthew G Knepley } 531*b2fff234SMatthew G. Knepley } 532*b2fff234SMatthew G. Knepley } 533*b2fff234SMatthew G. Knepley ierr = PetscBTMemzero(pEnd-pStart, isLeaf);CHKERRQ(ierr); 53488ed4aceSMatthew G Knepley ierr = PetscMalloc2(nleaves,PetscInt,&localPoints,nleaves,PetscSFNode,&remotePoints);CHKERRQ(ierr); 53588ed4aceSMatthew G Knepley for (zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) { 53688ed4aceSMatthew G Knepley for (yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) { 53788ed4aceSMatthew G Knepley for (xn = 0; xn < 3; ++xn) { 5387128ae9fSMatthew G Knepley const PetscInt xp = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0; 53988ed4aceSMatthew G Knepley const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn]; 540f5eeb527SMatthew G Knepley PetscInt xv, yv, zv; 54188ed4aceSMatthew G Knepley 5423814d604SMatthew G Knepley if (neighbor >= 0 && neighbor < rank) { 54388ed4aceSMatthew G Knepley if (xp < 0) { /* left */ 54488ed4aceSMatthew G Knepley if (yp < 0) { /* bottom */ 54588ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 546*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + 0)*nVx + 0 + nC; /* left bottom back vertex */ 547f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 548f5eeb527SMatthew G Knepley 549*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 550f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 551f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 552f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 553f5eeb527SMatthew G Knepley ++nL; 554*b2fff234SMatthew G. Knepley } 55588ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 556*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + 0 + nC; /* left bottom front vertex */ 557f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 558f5eeb527SMatthew G Knepley 559*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 560f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 561f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 562f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 563f5eeb527SMatthew G Knepley ++nL; 564*b2fff234SMatthew G. Knepley } 56588ed4aceSMatthew G Knepley } else { 566*b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 567*b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + 0)*nVx + 0 + nC; /* left bottom vertices */ 568f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 569f5eeb527SMatthew G Knepley 570*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 571f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 572f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 573f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 574*b2fff234SMatthew G. Knepley ++nL; 575*b2fff234SMatthew G. Knepley } 576f5eeb527SMatthew G Knepley } 57788ed4aceSMatthew G Knepley } 57888ed4aceSMatthew G Knepley } else if (yp > 0) { /* top */ 57988ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 580*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + 0 + nC; /* left top back vertex */ 581f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + 0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 582f5eeb527SMatthew G Knepley 583*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 584f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 585f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 586f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 587f5eeb527SMatthew G Knepley ++nL; 588*b2fff234SMatthew G. Knepley } 58988ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 590*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + 0 + nC; /* left top front vertex */ 591f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + 0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 592f5eeb527SMatthew G Knepley 593*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 594f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 595f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 596f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 597f5eeb527SMatthew G Knepley ++nL; 598*b2fff234SMatthew G. Knepley } 59988ed4aceSMatthew G Knepley } else { 600*b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 601*b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + 0 + nC; /* left top vertices */ 602f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + 0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 603f5eeb527SMatthew G Knepley 604*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 605f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 606f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 607f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 608*b2fff234SMatthew G. Knepley ++nL; 609*b2fff234SMatthew G. Knepley } 610f5eeb527SMatthew G Knepley } 61188ed4aceSMatthew G Knepley } 61288ed4aceSMatthew G Knepley } else { 61388ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 614*b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 615*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + yv)*nVx + 0 + nC; /* left back vertices */ 616f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 617f5eeb527SMatthew G Knepley 618*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 619f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 620f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 621f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 622*b2fff234SMatthew G. Knepley ++nL; 623*b2fff234SMatthew G. Knepley } 624f5eeb527SMatthew G Knepley } 62588ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 626*b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 627*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + 0 + nC; /* left front vertices */ 628f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 629f5eeb527SMatthew G Knepley 630*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 631f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 632f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 633f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 634*b2fff234SMatthew G. Knepley ++nL; 635*b2fff234SMatthew G. Knepley } 636f5eeb527SMatthew G Knepley } 63788ed4aceSMatthew G Knepley } else { 638f5eeb527SMatthew G Knepley for (zv = 0; zv < nVz; ++zv) { 639*b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 640*b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + yv)*nVx + 0 + nC; /* left vertices */ 641f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 642f5eeb527SMatthew G Knepley 643*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 644f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 645f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 646f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 647*b2fff234SMatthew G. Knepley ++nL; 648f5eeb527SMatthew G Knepley } 649f5eeb527SMatthew G Knepley } 650*b2fff234SMatthew G. Knepley } 651*b2fff234SMatthew G. Knepley #if 0 652*b2fff234SMatthew G. Knepley for (xf = 0; xf < nxF; ++xf) { 653f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 654*b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* left faces */ 655f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 656f5eeb527SMatthew G Knepley 657*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) { 658f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 659f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 660f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 661f5eeb527SMatthew G Knepley } 66288ed4aceSMatthew G Knepley } 663*b2fff234SMatthew G. Knepley #endif 664*b2fff234SMatthew G. Knepley } 66588ed4aceSMatthew G Knepley } 66688ed4aceSMatthew G Knepley } else if (xp > 0) { /* right */ 66788ed4aceSMatthew G Knepley if (yp < 0) { /* bottom */ 66888ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 669*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + 0)*nVx + nVx-1 + nC; /* right bottom back vertex */ 670f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 671f5eeb527SMatthew G Knepley 672*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 673f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 674f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 675f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 676f5eeb527SMatthew G Knepley ++nL; 677*b2fff234SMatthew G. Knepley } 67888ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 679*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + nVx-1 + nC; /* right bottom front vertex */ 680f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + nVy-1)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 681f5eeb527SMatthew G Knepley 682*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 683f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 684f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 685f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 686f5eeb527SMatthew G Knepley ++nL; 687*b2fff234SMatthew G. Knepley } 68888ed4aceSMatthew G Knepley } else { 689*b2fff234SMatthew G. Knepley nleavesCheck += nVz; 690*b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 691*b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + 0)*nVx + nVx-1 + nC; /* right bottom vertices */ 692f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 693f5eeb527SMatthew G Knepley 694*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 695f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 696f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 697f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 698*b2fff234SMatthew G. Knepley ++nL; 699*b2fff234SMatthew G. Knepley } 700f5eeb527SMatthew G Knepley } 70188ed4aceSMatthew G Knepley } 70288ed4aceSMatthew G Knepley } else if (yp > 0) { /* top */ 70388ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 704*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top back vertex */ 705f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + 0)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 706f5eeb527SMatthew G Knepley 707*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 708f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 709f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 710f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 711f5eeb527SMatthew G Knepley ++nL; 712*b2fff234SMatthew G. Knepley } 71388ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 714*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top front vertex */ 715f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + 0)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 716f5eeb527SMatthew G Knepley 717*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 718f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 719f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 720f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 721f5eeb527SMatthew G Knepley ++nL; 722*b2fff234SMatthew G. Knepley } 72388ed4aceSMatthew G Knepley } else { 724*b2fff234SMatthew G. Knepley for (zv = 0; zv < nVz; ++zv) { 725*b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top vertices */ 726f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + 0)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 727f5eeb527SMatthew G Knepley 728*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 729f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 730f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 731f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 732*b2fff234SMatthew G. Knepley ++nL; 733*b2fff234SMatthew G. Knepley } 734f5eeb527SMatthew G Knepley } 73588ed4aceSMatthew G Knepley } 73688ed4aceSMatthew G Knepley } else { 73788ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 738*b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 739*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + yv)*nVx + nVx-1 + nC; /* right back vertices */ 740f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 741f5eeb527SMatthew G Knepley 742*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 743f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 744f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 745f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 746*b2fff234SMatthew G. Knepley ++nL; 747*b2fff234SMatthew G. Knepley } 748f5eeb527SMatthew G Knepley } 74988ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 750*b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 751*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; /* right front vertices */ 752f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + yv)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 753f5eeb527SMatthew G Knepley 754*b2fff234SMatthew 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; 758*b2fff234SMatthew G. Knepley ++nL; 759*b2fff234SMatthew G. Knepley } 760f5eeb527SMatthew G Knepley } 76188ed4aceSMatthew G Knepley } else { 762f5eeb527SMatthew G Knepley for (zv = 0; zv < nVz; ++zv) { 763*b2fff234SMatthew G. Knepley for (yv = 0; yv < nVy; ++yv) { 764*b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + yv)*nVx + nVx-1 + nC; /* right vertices */ 765f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + yv)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 766f5eeb527SMatthew G Knepley 767*b2fff234SMatthew 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; 771*b2fff234SMatthew G. Knepley ++nL; 772f5eeb527SMatthew G Knepley } 773f5eeb527SMatthew G Knepley } 774*b2fff234SMatthew G. Knepley } 775*b2fff234SMatthew G. Knepley #if 0 776*b2fff234SMatthew G. Knepley for (xf = 0; xf < nxF; ++xf) { 777f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 778*b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* right faces */ 779f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 780f5eeb527SMatthew G Knepley 781*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) { 782f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 783f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 784f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 785*b2fff234SMatthew G. Knepley ++nL; 786f5eeb527SMatthew G Knepley } 78788ed4aceSMatthew G Knepley } 788*b2fff234SMatthew G. Knepley #endif 789*b2fff234SMatthew G. Knepley } 79088ed4aceSMatthew G Knepley } 79188ed4aceSMatthew G Knepley } else { 79288ed4aceSMatthew G Knepley if (yp < 0) { /* bottom */ 79388ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 794*b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 795*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + 0)*nVx + xv + nC; /* bottom back vertices */ 796f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 797f5eeb527SMatthew G Knepley 798*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 799f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 800f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 801f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 802*b2fff234SMatthew G. Knepley ++nL; 803*b2fff234SMatthew G. Knepley } 804f5eeb527SMatthew G Knepley } 80588ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 806*b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 807*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + xv + nC; /* bottom front vertices */ 808f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 809f5eeb527SMatthew G Knepley 810*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 811f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 812f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 813f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 814*b2fff234SMatthew G. Knepley ++nL; 815*b2fff234SMatthew G. Knepley } 816f5eeb527SMatthew G Knepley } 81788ed4aceSMatthew G Knepley } else { 818f5eeb527SMatthew G Knepley for (zv = 0; zv < nVz; ++zv) { 819*b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 820*b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + 0)*nVx + xv + nC; /* bottom vertices */ 821f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 822f5eeb527SMatthew G Knepley 823*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 824f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 825f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 826f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 827*b2fff234SMatthew G. Knepley ++nL; 828f5eeb527SMatthew G Knepley } 829f5eeb527SMatthew G Knepley } 830*b2fff234SMatthew G. Knepley } 831*b2fff234SMatthew G. Knepley #if 0 832*b2fff234SMatthew G. Knepley for (yf = 0; yf < nyF; ++yf) { 833f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 834*b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* bottom faces */ 835f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 836f5eeb527SMatthew G Knepley 837*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) { 838f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 839f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 840f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 841*b2fff234SMatthew G. Knepley ++nL; 842f5eeb527SMatthew G Knepley } 84388ed4aceSMatthew G Knepley } 844*b2fff234SMatthew G. Knepley #endif 845*b2fff234SMatthew G. Knepley } 84688ed4aceSMatthew G Knepley } else if (yp > 0) { /* top */ 84788ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 848*b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 849*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + xv + nC; /* top back vertices */ 850f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + 0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 851f5eeb527SMatthew G Knepley 852*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 853f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 854f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 855f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 856*b2fff234SMatthew G. Knepley ++nL; 857*b2fff234SMatthew G. Knepley } 858f5eeb527SMatthew G Knepley } 85988ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 860*b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 861*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; /* top front vertices */ 862f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + 0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 863f5eeb527SMatthew G Knepley 864*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 865f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 866f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 867f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 868*b2fff234SMatthew G. Knepley ++nL; 869*b2fff234SMatthew G. Knepley } 870f5eeb527SMatthew G Knepley } 87188ed4aceSMatthew G Knepley } else { 872f5eeb527SMatthew G Knepley for (zv = 0; zv < nVz; ++zv) { 873*b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 874*b2fff234SMatthew G. Knepley const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + xv + nC; /* top vertices */ 875f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + 0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 876f5eeb527SMatthew G Knepley 877*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 878f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 879f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 880f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 881*b2fff234SMatthew G. Knepley ++nL; 882f5eeb527SMatthew G Knepley } 883f5eeb527SMatthew G Knepley } 884*b2fff234SMatthew G. Knepley } 885*b2fff234SMatthew G. Knepley #if 0 886*b2fff234SMatthew G. Knepley for (yf = 0; yf < nyF; ++yf) { 887f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 888*b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* top faces */ 889f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 890f5eeb527SMatthew G Knepley 891*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) { 892f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 893f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 894f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 895*b2fff234SMatthew G. Knepley ++nL; 896f5eeb527SMatthew G Knepley } 89788ed4aceSMatthew G Knepley } 898*b2fff234SMatthew G. Knepley #endif 899*b2fff234SMatthew G. Knepley } 90088ed4aceSMatthew G Knepley } else { 90188ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 902f5eeb527SMatthew G Knepley for (yv = 0; yv < nVy; ++yv) { 903*b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 904*b2fff234SMatthew G. Knepley const PetscInt localVertex = ( 0*nVy + yv)*nVx + xv + nC; /* back vertices */ 905f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 906f5eeb527SMatthew G Knepley 907*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 908f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 909f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 910f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 911*b2fff234SMatthew G. Knepley ++nL; 912f5eeb527SMatthew G Knepley } 913f5eeb527SMatthew G Knepley } 914*b2fff234SMatthew G. Knepley } 915*b2fff234SMatthew G. Knepley #if 0 916*b2fff234SMatthew G. Knepley for (zf = 0; zf < nzF; ++zf) { 917f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 918*b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* back faces */ 919f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 920f5eeb527SMatthew G Knepley 921*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) { 922f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 923f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 924f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 925*b2fff234SMatthew G. Knepley ++nL; 926f5eeb527SMatthew G Knepley } 927*b2fff234SMatthew G. Knepley } 928*b2fff234SMatthew G. Knepley #endif 92988ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 930f5eeb527SMatthew G Knepley for (yv = 0; yv < nVy; ++yv) { 931*b2fff234SMatthew G. Knepley for (xv = 0; xv < nVx; ++xv) { 932*b2fff234SMatthew G. Knepley const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + xv + nC; /* front vertices */ 933f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + yv)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 934f5eeb527SMatthew G Knepley 935*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localVertex)) { 936f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 937f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 938f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 939*b2fff234SMatthew G. Knepley ++nL; 940f5eeb527SMatthew G Knepley } 941f5eeb527SMatthew G Knepley } 942*b2fff234SMatthew G. Knepley } 943*b2fff234SMatthew G. Knepley #if 0 944*b2fff234SMatthew G. Knepley for (zf = 0; zf < nzF; ++zf) { 945f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 946*b2fff234SMatthew G. Knepley const PetscInt localFace = 0 + nC+nV; /* front faces */ 947f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 948f5eeb527SMatthew G Knepley 949*b2fff234SMatthew G. Knepley if (!PetscBTLookupSet(isLeaf, localFace)) { 950f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 951f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 952f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 953*b2fff234SMatthew G. Knepley ++nL; 954f5eeb527SMatthew G Knepley } 955*b2fff234SMatthew G. Knepley } 956*b2fff234SMatthew G. Knepley #endif 95788ed4aceSMatthew G Knepley } else { 95888ed4aceSMatthew G Knepley /* Nothing is shared from the interior */ 95988ed4aceSMatthew G Knepley } 96088ed4aceSMatthew G Knepley } 96188ed4aceSMatthew G Knepley } 96288ed4aceSMatthew G Knepley } 96388ed4aceSMatthew G Knepley } 96488ed4aceSMatthew G Knepley } 96588ed4aceSMatthew G Knepley } 966*b2fff234SMatthew G. Knepley ierr = PetscBTDestroy(&isLeaf);CHKERRQ(ierr); 967*b2fff234SMatthew G. Knepley /* Remove duplication in leaf determination */ 968*b2fff234SMatthew 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); 96982f516ccSBarry Smith ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), &sf);CHKERRQ(ierr); 97088ed4aceSMatthew G Knepley ierr = PetscSFSetGraph(sf, pEnd, nleaves, localPoints, PETSC_OWN_POINTER, remotePoints, PETSC_OWN_POINTER);CHKERRQ(ierr); 97188ed4aceSMatthew G Knepley /* Create global section */ 972eaf8d80aSMatthew G Knepley ierr = PetscSectionCreateGlobalSection(dm->defaultSection, sf, PETSC_FALSE, &dm->defaultGlobalSection);CHKERRQ(ierr); 97388ed4aceSMatthew G Knepley ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 97488ed4aceSMatthew G Knepley /* Create default SF */ 97588ed4aceSMatthew G Knepley ierr = DMCreateDefaultSF(dm, dm->defaultSection, dm->defaultGlobalSection);CHKERRQ(ierr); 976a66d4d66SMatthew G Knepley PetscFunctionReturn(0); 977a66d4d66SMatthew G Knepley } 978a66d4d66SMatthew G Knepley 97947c6ae99SBarry Smith /* ------------------------------------------------------------------- */ 98047c6ae99SBarry Smith 98147c6ae99SBarry Smith #undef __FUNCT__ 982aa219208SBarry Smith #define __FUNCT__ "DMDAGetArray" 98347c6ae99SBarry Smith /*@C 984aa219208SBarry Smith DMDAGetArray - Gets a work array for a DMDA 98547c6ae99SBarry Smith 98647c6ae99SBarry Smith Input Parameter: 98747c6ae99SBarry Smith + da - information about my local patch 98847c6ae99SBarry Smith - ghosted - do you want arrays for the ghosted or nonghosted patch 98947c6ae99SBarry Smith 99047c6ae99SBarry Smith Output Parameters: 99147c6ae99SBarry Smith . vptr - array data structured 99247c6ae99SBarry Smith 99347c6ae99SBarry Smith Note: The vector values are NOT initialized and may have garbage in them, so you may need 99447c6ae99SBarry Smith to zero them. 99547c6ae99SBarry Smith 99647c6ae99SBarry Smith Level: advanced 99747c6ae99SBarry Smith 998bcaeba4dSBarry Smith .seealso: DMDARestoreArray() 99947c6ae99SBarry Smith 100047c6ae99SBarry Smith @*/ 10017087cfbeSBarry Smith PetscErrorCode DMDAGetArray(DM da,PetscBool ghosted,void *vptr) 100247c6ae99SBarry Smith { 100347c6ae99SBarry Smith PetscErrorCode ierr; 100447c6ae99SBarry Smith PetscInt j,i,xs,ys,xm,ym,zs,zm; 100547c6ae99SBarry Smith char *iarray_start; 100647c6ae99SBarry Smith void **iptr = (void**)vptr; 100747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 100847c6ae99SBarry Smith 100947c6ae99SBarry Smith PetscFunctionBegin; 101047c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 101147c6ae99SBarry Smith if (ghosted) { 1012aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 101347c6ae99SBarry Smith if (dd->arrayghostedin[i]) { 101447c6ae99SBarry Smith *iptr = dd->arrayghostedin[i]; 101547c6ae99SBarry Smith iarray_start = (char*)dd->startghostedin[i]; 10160298fd71SBarry Smith dd->arrayghostedin[i] = NULL; 10170298fd71SBarry Smith dd->startghostedin[i] = NULL; 101847c6ae99SBarry Smith 101947c6ae99SBarry Smith goto done; 102047c6ae99SBarry Smith } 102147c6ae99SBarry Smith } 102247c6ae99SBarry Smith xs = dd->Xs; 102347c6ae99SBarry Smith ys = dd->Ys; 102447c6ae99SBarry Smith zs = dd->Zs; 102547c6ae99SBarry Smith xm = dd->Xe-dd->Xs; 102647c6ae99SBarry Smith ym = dd->Ye-dd->Ys; 102747c6ae99SBarry Smith zm = dd->Ze-dd->Zs; 102847c6ae99SBarry Smith } else { 1029aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 103047c6ae99SBarry Smith if (dd->arrayin[i]) { 103147c6ae99SBarry Smith *iptr = dd->arrayin[i]; 103247c6ae99SBarry Smith iarray_start = (char*)dd->startin[i]; 10330298fd71SBarry Smith dd->arrayin[i] = NULL; 10340298fd71SBarry Smith dd->startin[i] = NULL; 103547c6ae99SBarry Smith 103647c6ae99SBarry Smith goto done; 103747c6ae99SBarry Smith } 103847c6ae99SBarry Smith } 103947c6ae99SBarry Smith xs = dd->xs; 104047c6ae99SBarry Smith ys = dd->ys; 104147c6ae99SBarry Smith zs = dd->zs; 104247c6ae99SBarry Smith xm = dd->xe-dd->xs; 104347c6ae99SBarry Smith ym = dd->ye-dd->ys; 104447c6ae99SBarry Smith zm = dd->ze-dd->zs; 104547c6ae99SBarry Smith } 104647c6ae99SBarry Smith 104747c6ae99SBarry Smith switch (dd->dim) { 104847c6ae99SBarry Smith case 1: { 104947c6ae99SBarry Smith void *ptr; 105047c6ae99SBarry Smith 105147c6ae99SBarry Smith ierr = PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 105247c6ae99SBarry Smith 105347c6ae99SBarry Smith ptr = (void*)(iarray_start - xs*sizeof(PetscScalar)); 105447c6ae99SBarry Smith *iptr = (void*)ptr; 10558865f1eaSKarl Rupp break; 10568865f1eaSKarl Rupp } 105747c6ae99SBarry Smith case 2: { 105847c6ae99SBarry Smith void **ptr; 105947c6ae99SBarry Smith 106047c6ae99SBarry Smith ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 106147c6ae99SBarry Smith 106247c6ae99SBarry Smith ptr = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*)); 10638865f1eaSKarl Rupp for (j=ys; j<ys+ym; j++) ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs); 106447c6ae99SBarry Smith *iptr = (void*)ptr; 10658865f1eaSKarl Rupp break; 10668865f1eaSKarl Rupp } 106747c6ae99SBarry Smith case 3: { 106847c6ae99SBarry Smith void ***ptr,**bptr; 106947c6ae99SBarry Smith 107047c6ae99SBarry Smith ierr = PetscMalloc((zm+1)*sizeof(void**)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 107147c6ae99SBarry Smith 107247c6ae99SBarry Smith ptr = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*)); 107347c6ae99SBarry Smith bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**)); 10748865f1eaSKarl Rupp for (i=zs; i<zs+zm; i++) ptr[i] = bptr + ((i-zs)*ym - ys); 107547c6ae99SBarry Smith for (i=zs; i<zs+zm; i++) { 107647c6ae99SBarry Smith for (j=ys; j<ys+ym; j++) { 107747c6ae99SBarry Smith ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs); 107847c6ae99SBarry Smith } 107947c6ae99SBarry Smith } 108047c6ae99SBarry Smith *iptr = (void*)ptr; 10818865f1eaSKarl Rupp break; 10828865f1eaSKarl Rupp } 108347c6ae99SBarry Smith default: 1084ce94432eSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Dimension %D not supported",dd->dim); 108547c6ae99SBarry Smith } 108647c6ae99SBarry Smith 108747c6ae99SBarry Smith done: 108847c6ae99SBarry Smith /* add arrays to the checked out list */ 108947c6ae99SBarry Smith if (ghosted) { 1090aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 109147c6ae99SBarry Smith if (!dd->arrayghostedout[i]) { 109247c6ae99SBarry Smith dd->arrayghostedout[i] = *iptr; 109347c6ae99SBarry Smith dd->startghostedout[i] = iarray_start; 109447c6ae99SBarry Smith break; 109547c6ae99SBarry Smith } 109647c6ae99SBarry Smith } 109747c6ae99SBarry Smith } else { 1098aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 109947c6ae99SBarry Smith if (!dd->arrayout[i]) { 110047c6ae99SBarry Smith dd->arrayout[i] = *iptr; 110147c6ae99SBarry Smith dd->startout[i] = iarray_start; 110247c6ae99SBarry Smith break; 110347c6ae99SBarry Smith } 110447c6ae99SBarry Smith } 110547c6ae99SBarry Smith } 110647c6ae99SBarry Smith PetscFunctionReturn(0); 110747c6ae99SBarry Smith } 110847c6ae99SBarry Smith 110947c6ae99SBarry Smith #undef __FUNCT__ 1110aa219208SBarry Smith #define __FUNCT__ "DMDARestoreArray" 111147c6ae99SBarry Smith /*@C 1112aa219208SBarry Smith DMDARestoreArray - Restores an array of derivative types for a DMDA 111347c6ae99SBarry Smith 111447c6ae99SBarry Smith Input Parameter: 111547c6ae99SBarry Smith + da - information about my local patch 111647c6ae99SBarry Smith . ghosted - do you want arrays for the ghosted or nonghosted patch 111747c6ae99SBarry Smith - vptr - array data structured to be passed to ad_FormFunctionLocal() 111847c6ae99SBarry Smith 111947c6ae99SBarry Smith Level: advanced 112047c6ae99SBarry Smith 1121bcaeba4dSBarry Smith .seealso: DMDAGetArray() 112247c6ae99SBarry Smith 112347c6ae99SBarry Smith @*/ 11247087cfbeSBarry Smith PetscErrorCode DMDARestoreArray(DM da,PetscBool ghosted,void *vptr) 112547c6ae99SBarry Smith { 112647c6ae99SBarry Smith PetscInt i; 112747c6ae99SBarry Smith void **iptr = (void**)vptr,*iarray_start = 0; 112847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 112947c6ae99SBarry Smith 113047c6ae99SBarry Smith PetscFunctionBegin; 113147c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 113247c6ae99SBarry Smith if (ghosted) { 1133aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 113447c6ae99SBarry Smith if (dd->arrayghostedout[i] == *iptr) { 113547c6ae99SBarry Smith iarray_start = dd->startghostedout[i]; 11360298fd71SBarry Smith dd->arrayghostedout[i] = NULL; 11370298fd71SBarry Smith dd->startghostedout[i] = NULL; 113847c6ae99SBarry Smith break; 113947c6ae99SBarry Smith } 114047c6ae99SBarry Smith } 1141aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 114247c6ae99SBarry Smith if (!dd->arrayghostedin[i]) { 114347c6ae99SBarry Smith dd->arrayghostedin[i] = *iptr; 114447c6ae99SBarry Smith dd->startghostedin[i] = iarray_start; 114547c6ae99SBarry Smith break; 114647c6ae99SBarry Smith } 114747c6ae99SBarry Smith } 114847c6ae99SBarry Smith } else { 1149aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 115047c6ae99SBarry Smith if (dd->arrayout[i] == *iptr) { 115147c6ae99SBarry Smith iarray_start = dd->startout[i]; 11520298fd71SBarry Smith dd->arrayout[i] = NULL; 11530298fd71SBarry Smith dd->startout[i] = NULL; 115447c6ae99SBarry Smith break; 115547c6ae99SBarry Smith } 115647c6ae99SBarry Smith } 1157aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 115847c6ae99SBarry Smith if (!dd->arrayin[i]) { 115947c6ae99SBarry Smith dd->arrayin[i] = *iptr; 116047c6ae99SBarry Smith dd->startin[i] = iarray_start; 116147c6ae99SBarry Smith break; 116247c6ae99SBarry Smith } 116347c6ae99SBarry Smith } 116447c6ae99SBarry Smith } 116547c6ae99SBarry Smith PetscFunctionReturn(0); 116647c6ae99SBarry Smith } 116747c6ae99SBarry Smith 1168