147c6ae99SBarry Smith 247c6ae99SBarry Smith /* 347c6ae99SBarry Smith Code for manipulating distributed regular arrays in parallel. 447c6ae99SBarry Smith */ 547c6ae99SBarry Smith 6b45d2f2cSJed Brown #include <petsc-private/daimpl.h> /*I "petscdmda.h" I*/ 747c6ae99SBarry Smith 847c6ae99SBarry Smith /* 9e3c5b3baSBarry Smith This allows the DMDA vectors to properly tell MATLAB their dimensions 1047c6ae99SBarry Smith */ 1147c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 12c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 13c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 1447c6ae99SBarry Smith EXTERN_C_BEGIN 1547c6ae99SBarry Smith #undef __FUNCT__ 1647c6ae99SBarry Smith #define __FUNCT__ "VecMatlabEnginePut_DA2d" 177087cfbeSBarry Smith PetscErrorCode VecMatlabEnginePut_DA2d(PetscObject obj,void *mengine) 1847c6ae99SBarry Smith { 1947c6ae99SBarry Smith PetscErrorCode ierr; 2047c6ae99SBarry Smith PetscInt n,m; 2147c6ae99SBarry Smith Vec vec = (Vec)obj; 2247c6ae99SBarry Smith PetscScalar *array; 2347c6ae99SBarry Smith mxArray *mat; 249a42bb27SBarry Smith DM da; 2547c6ae99SBarry Smith 2647c6ae99SBarry Smith PetscFunctionBegin; 273c0c59f3SBarry Smith ierr = PetscObjectQuery((PetscObject)vec,"DM",(PetscObject*)&da);CHKERRQ(ierr); 28aa219208SBarry Smith if (!da) SETERRQ(((PetscObject)vec)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vector not associated with a DMDA"); 29aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,0,0,0,&m,&n,0);CHKERRQ(ierr); 3047c6ae99SBarry Smith 3147c6ae99SBarry Smith ierr = VecGetArray(vec,&array);CHKERRQ(ierr); 3247c6ae99SBarry Smith #if !defined(PETSC_USE_COMPLEX) 3347c6ae99SBarry Smith mat = mxCreateDoubleMatrix(m,n,mxREAL); 3447c6ae99SBarry Smith #else 3547c6ae99SBarry Smith mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX); 3647c6ae99SBarry Smith #endif 3747c6ae99SBarry Smith ierr = PetscMemcpy(mxGetPr(mat),array,n*m*sizeof(PetscScalar));CHKERRQ(ierr); 3847c6ae99SBarry Smith ierr = PetscObjectName(obj);CHKERRQ(ierr); 3947c6ae99SBarry Smith engPutVariable((Engine *)mengine,obj->name,mat); 4047c6ae99SBarry Smith 4147c6ae99SBarry Smith ierr = VecRestoreArray(vec,&array);CHKERRQ(ierr); 4247c6ae99SBarry Smith PetscFunctionReturn(0); 4347c6ae99SBarry Smith } 4447c6ae99SBarry Smith EXTERN_C_END 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); 5847c6ae99SBarry Smith ierr = VecCreate(PETSC_COMM_SELF,g);CHKERRQ(ierr); 5947c6ae99SBarry Smith ierr = VecSetSizes(*g,dd->nlocal,PETSC_DETERMINE);CHKERRQ(ierr); 6047c6ae99SBarry Smith ierr = VecSetBlockSize(*g,dd->w);CHKERRQ(ierr); 61401ddaa8SBarry Smith ierr = VecSetType(*g,da->vectype);CHKERRQ(ierr); 623c0c59f3SBarry Smith ierr = PetscObjectCompose((PetscObject)*g,"DM",(PetscObject)da);CHKERRQ(ierr); 6347c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 6447c6ae99SBarry Smith if (dd->w == 1 && dd->dim == 2) { 6547c6ae99SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)*g,"PetscMatlabEnginePut_C","VecMatlabEnginePut_DA2d",VecMatlabEnginePut_DA2d);CHKERRQ(ierr); 6647c6ae99SBarry Smith } 6747c6ae99SBarry Smith #endif 6847c6ae99SBarry Smith PetscFunctionReturn(0); 6947c6ae99SBarry Smith } 7047c6ae99SBarry Smith 71a66d4d66SMatthew G Knepley #undef __FUNCT__ 7257459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumCells" 7357459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumCells(DM dm, PetscInt *numCells) 7457459e9aSMatthew G Knepley { 7557459e9aSMatthew G Knepley DM_DA *da = (DM_DA *) dm->data; 7657459e9aSMatthew G Knepley const PetscInt dim = da->dim; 7757459e9aSMatthew G Knepley const PetscInt mx = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs; 7857459e9aSMatthew G Knepley const PetscInt nC = (mx )*(dim > 1 ? (my )*(dim > 2 ? (mz ) : 1) : 1); 7957459e9aSMatthew G Knepley 8057459e9aSMatthew G Knepley PetscFunctionBegin; 8157459e9aSMatthew G Knepley if (numCells) { 8257459e9aSMatthew G Knepley PetscValidIntPointer(numCells,2); 8357459e9aSMatthew G Knepley *numCells = nC; 8457459e9aSMatthew G Knepley } 8557459e9aSMatthew G Knepley PetscFunctionReturn(0); 8657459e9aSMatthew G Knepley } 8757459e9aSMatthew G Knepley 8857459e9aSMatthew G Knepley #undef __FUNCT__ 8957459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumVertices" 9057459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumVertices(DM dm, PetscInt *numVerticesX, PetscInt *numVerticesY, PetscInt *numVerticesZ, PetscInt *numVertices) 9157459e9aSMatthew G Knepley { 9257459e9aSMatthew G Knepley DM_DA *da = (DM_DA *) dm->data; 9357459e9aSMatthew G Knepley const PetscInt dim = da->dim; 9457459e9aSMatthew G Knepley const PetscInt mx = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs; 9557459e9aSMatthew G Knepley const PetscInt nVx = mx+1; 9657459e9aSMatthew G Knepley const PetscInt nVy = dim > 1 ? (my+1) : 1; 9757459e9aSMatthew G Knepley const PetscInt nVz = dim > 2 ? (mz+1) : 1; 9857459e9aSMatthew G Knepley const PetscInt nV = nVx*nVy*nVz; 9957459e9aSMatthew G Knepley 10057459e9aSMatthew G Knepley PetscFunctionBegin; 10157459e9aSMatthew G Knepley if (numVerticesX) { 10257459e9aSMatthew G Knepley PetscValidIntPointer(numVerticesX,2); 10357459e9aSMatthew G Knepley *numVerticesX = nVx; 10457459e9aSMatthew G Knepley } 10557459e9aSMatthew G Knepley if (numVerticesY) { 10657459e9aSMatthew G Knepley PetscValidIntPointer(numVerticesY,3); 10757459e9aSMatthew G Knepley *numVerticesY = nVy; 10857459e9aSMatthew G Knepley } 10957459e9aSMatthew G Knepley if (numVerticesZ) { 11057459e9aSMatthew G Knepley PetscValidIntPointer(numVerticesZ,4); 11157459e9aSMatthew G Knepley *numVerticesZ = nVz; 11257459e9aSMatthew G Knepley } 11357459e9aSMatthew G Knepley if (numVertices) { 11457459e9aSMatthew G Knepley PetscValidIntPointer(numVertices,5); 11557459e9aSMatthew G Knepley *numVertices = nV; 11657459e9aSMatthew G Knepley } 11757459e9aSMatthew G Knepley PetscFunctionReturn(0); 11857459e9aSMatthew G Knepley } 11957459e9aSMatthew G Knepley 12057459e9aSMatthew G Knepley #undef __FUNCT__ 12157459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumFaces" 12257459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumFaces(DM dm, PetscInt *numXFacesX, PetscInt *numXFaces, PetscInt *numYFacesY, PetscInt *numYFaces, PetscInt *numZFacesZ, PetscInt *numZFaces) 12357459e9aSMatthew G Knepley { 12457459e9aSMatthew G Knepley DM_DA *da = (DM_DA *) dm->data; 12557459e9aSMatthew G Knepley const PetscInt dim = da->dim; 12657459e9aSMatthew G Knepley const PetscInt mx = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs; 12757459e9aSMatthew G Knepley const PetscInt nxF = (dim > 1 ? (my )*(dim > 2 ? (mz ) : 1) : 1); 12857459e9aSMatthew G Knepley const PetscInt nXF = (mx+1)*nxF; 12957459e9aSMatthew G Knepley const PetscInt nyF = mx*(dim > 2 ? mz : 1); 13057459e9aSMatthew G Knepley const PetscInt nYF = dim > 1 ? (my+1)*nyF : 0; 13157459e9aSMatthew G Knepley const PetscInt nzF = mx*(dim > 1 ? my : 0); 13257459e9aSMatthew G Knepley const PetscInt nZF = dim > 2 ? (mz+1)*nzF : 0; 13357459e9aSMatthew G Knepley 13457459e9aSMatthew G Knepley PetscFunctionBegin; 13557459e9aSMatthew G Knepley if (numXFacesX) { 13657459e9aSMatthew G Knepley PetscValidIntPointer(numXFacesX,2); 13757459e9aSMatthew G Knepley *numXFacesX = nxF; 13857459e9aSMatthew G Knepley } 13957459e9aSMatthew G Knepley if (numXFaces) { 14057459e9aSMatthew G Knepley PetscValidIntPointer(numXFaces,3); 14157459e9aSMatthew G Knepley *numXFaces = nXF; 14257459e9aSMatthew G Knepley } 14357459e9aSMatthew G Knepley if (numYFacesY) { 14457459e9aSMatthew G Knepley PetscValidIntPointer(numYFacesY,4); 14557459e9aSMatthew G Knepley *numYFacesY = nyF; 14657459e9aSMatthew G Knepley } 14757459e9aSMatthew G Knepley if (numYFaces) { 14857459e9aSMatthew G Knepley PetscValidIntPointer(numYFaces,5); 14957459e9aSMatthew G Knepley *numYFaces = nYF; 15057459e9aSMatthew G Knepley } 15157459e9aSMatthew G Knepley if (numZFacesZ) { 15257459e9aSMatthew G Knepley PetscValidIntPointer(numZFacesZ,6); 15357459e9aSMatthew G Knepley *numZFacesZ = nzF; 15457459e9aSMatthew G Knepley } 15557459e9aSMatthew G Knepley if (numZFaces) { 15657459e9aSMatthew G Knepley PetscValidIntPointer(numZFaces,7); 15757459e9aSMatthew G Knepley *numZFaces = nZF; 15857459e9aSMatthew G Knepley } 15957459e9aSMatthew G Knepley PetscFunctionReturn(0); 16057459e9aSMatthew G Knepley } 16157459e9aSMatthew G Knepley 16257459e9aSMatthew G Knepley #undef __FUNCT__ 16357459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetHeightStratum" 16457459e9aSMatthew G Knepley PetscErrorCode DMDAGetHeightStratum(DM dm, PetscInt height, PetscInt *pStart, PetscInt *pEnd) 16557459e9aSMatthew G Knepley { 16657459e9aSMatthew G Knepley DM_DA *da = (DM_DA *) dm->data; 16757459e9aSMatthew G Knepley const PetscInt dim = da->dim; 16857459e9aSMatthew G Knepley PetscInt nC, nV, nXF, nYF, nZF; 16957459e9aSMatthew G Knepley PetscErrorCode ierr; 17057459e9aSMatthew G Knepley 17157459e9aSMatthew G Knepley PetscFunctionBegin; 17257459e9aSMatthew G Knepley if (pStart) {PetscValidIntPointer(pStart,3);} 17357459e9aSMatthew G Knepley if (pEnd) {PetscValidIntPointer(pEnd,4);} 17457459e9aSMatthew G Knepley ierr = DMDAGetNumCells(dm, &nC);CHKERRQ(ierr); 17557459e9aSMatthew G Knepley ierr = DMDAGetNumVertices(dm, PETSC_NULL, PETSC_NULL, PETSC_NULL, &nV);CHKERRQ(ierr); 17657459e9aSMatthew G Knepley ierr = DMDAGetNumFaces(dm, PETSC_NULL, &nXF, PETSC_NULL, &nYF, PETSC_NULL, &nZF);CHKERRQ(ierr); 17757459e9aSMatthew G Knepley if (height == 0) { 17857459e9aSMatthew G Knepley /* Cells */ 17957459e9aSMatthew G Knepley if (pStart) {*pStart = 0;} 18057459e9aSMatthew G Knepley if (pEnd) {*pEnd = nC;} 18157459e9aSMatthew G Knepley } else if (height == 1) { 18257459e9aSMatthew G Knepley /* Faces */ 18357459e9aSMatthew G Knepley if (pStart) {*pStart = nC+nV;} 18457459e9aSMatthew G Knepley if (pEnd) {*pEnd = nC+nV+nXF+nYF+nZF;} 18557459e9aSMatthew G Knepley } else if (height == dim) { 18657459e9aSMatthew G Knepley /* Vertices */ 18757459e9aSMatthew G Knepley if (pStart) {*pStart = nC;} 18857459e9aSMatthew G Knepley if (pEnd) {*pEnd = nC+nV;} 18957459e9aSMatthew G Knepley } else if (height < 0) { 19057459e9aSMatthew G Knepley /* All points */ 19157459e9aSMatthew G Knepley if (pStart) {*pStart = 0;} 19257459e9aSMatthew G Knepley if (pEnd) {*pEnd = nC+nV+nXF+nYF+nZF;} 19357459e9aSMatthew G Knepley } else { 19457459e9aSMatthew G Knepley SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "No points of height %d in the DA", height); 19557459e9aSMatthew G Knepley } 19657459e9aSMatthew G Knepley PetscFunctionReturn(0); 19757459e9aSMatthew G Knepley } 19857459e9aSMatthew G Knepley 19957459e9aSMatthew G Knepley #undef __FUNCT__ 200a66d4d66SMatthew G Knepley #define __FUNCT__ "DMDACreateSection" 201a66d4d66SMatthew G Knepley /*@C 202a66d4d66SMatthew G Knepley DMDACreateSection - Create a PetscSection inside the DMDA that describes data layout. This allows multiple fields with 203a66d4d66SMatthew G Knepley different numbers of dofs on vertices, cells, and faces in each direction. 204a66d4d66SMatthew G Knepley 205a66d4d66SMatthew G Knepley Input Parameters: 206a66d4d66SMatthew G Knepley + dm- The DMDA 207a66d4d66SMatthew G Knepley . numFields - The number of fields 208a66d4d66SMatthew G Knepley . numComp - The number of components in each field, or PETSC_NULL for 1 209a66d4d66SMatthew G Knepley . numVertexDof - The number of dofs per vertex for each field, or PETSC_NULL 210a66d4d66SMatthew G Knepley . numFaceDof - The number of dofs per face for each field and direction, or PETSC_NULL 211a66d4d66SMatthew G Knepley - numCellDof - The number of dofs per cell for each field, or PETSC_NULL 212a66d4d66SMatthew G Knepley 213a66d4d66SMatthew G Knepley Level: developer 214a66d4d66SMatthew G Knepley 215a66d4d66SMatthew G Knepley Note: 216a66d4d66SMatthew G Knepley The default DMDA numbering is as follows: 217a66d4d66SMatthew G Knepley 218a66d4d66SMatthew G Knepley - Cells: [0, nC) 219a66d4d66SMatthew G Knepley - Vertices: [nC, nC+nV) 22088ed4aceSMatthew G Knepley - X-Faces: [nC+nV, nC+nV+nXF) normal is +- x-dir 22188ed4aceSMatthew G Knepley - Y-Faces: [nC+nV+nXF, nC+nV+nXF+nYF) normal is +- y-dir 22288ed4aceSMatthew G Knepley - Z-Faces: [nC+nV+nXF+nYF, nC+nV+nXF+nYF+nZF) normal is +- z-dir 223a66d4d66SMatthew G Knepley 224a66d4d66SMatthew G Knepley We interpret the default DMDA partition as a cell partition, and the data assignment as a cell assignment. 225a66d4d66SMatthew G Knepley @*/ 22680800b1aSMatthew G Knepley PetscErrorCode DMDACreateSection(DM dm, PetscInt numComp[], PetscInt numVertexDof[], PetscInt numFaceDof[], PetscInt numCellDof[]) 227a66d4d66SMatthew G Knepley { 228a66d4d66SMatthew G Knepley DM_DA *da = (DM_DA *) dm->data; 22988ed4aceSMatthew G Knepley const PetscInt dim = da->dim; 23080800b1aSMatthew G Knepley PetscInt numFields, numVertexTotDof = 0, numCellTotDof = 0, numFaceTotDof[3] = {0, 0, 0}; 23188ed4aceSMatthew G Knepley PetscSF sf; 232feafbc5cSMatthew G Knepley PetscMPIInt rank; 23388ed4aceSMatthew G Knepley const PetscMPIInt *neighbors; 23488ed4aceSMatthew G Knepley PetscInt *localPoints; 23588ed4aceSMatthew G Knepley PetscSFNode *remotePoints; 236f5eeb527SMatthew G Knepley PetscInt nleaves = 0, nleavesCheck = 0, nL = 0; 23757459e9aSMatthew G Knepley PetscInt nC, nVx, nVy, nVz, nV, nxF, nXF, nyF, nYF, nzF, nZF; 23857459e9aSMatthew G Knepley PetscInt pStart, pEnd, cStart, cEnd, vStart, vEnd, fStart, fEnd, xfStart, xfEnd, yfStart, yfEnd, zfStart, zfEnd; 23988ed4aceSMatthew G Knepley PetscInt f, v, c, xf, yf, zf, xn, yn, zn; 240a66d4d66SMatthew G Knepley PetscErrorCode ierr; 241a66d4d66SMatthew G Knepley 242a66d4d66SMatthew G Knepley PetscFunctionBegin; 243a66d4d66SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 244feafbc5cSMatthew G Knepley ierr = MPI_Comm_rank(((PetscObject) dm)->comm, &rank);CHKERRQ(ierr); 24557459e9aSMatthew G Knepley ierr = DMDAGetNumCells(dm, &nC);CHKERRQ(ierr); 24657459e9aSMatthew G Knepley ierr = DMDAGetNumVertices(dm, &nVx, &nVy, &nVz, &nV);CHKERRQ(ierr); 24757459e9aSMatthew G Knepley ierr = DMDAGetNumFaces(dm, &nxF, &nXF, &nyF, &nYF, &nzF, &nZF);CHKERRQ(ierr); 24857459e9aSMatthew G Knepley ierr = DMDAGetHeightStratum(dm, -1, &pStart, &pEnd);CHKERRQ(ierr); 24957459e9aSMatthew G Knepley ierr = DMDAGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 25057459e9aSMatthew G Knepley ierr = DMDAGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 25157459e9aSMatthew G Knepley ierr = DMDAGetHeightStratum(dm, dim, &vStart, &vEnd);CHKERRQ(ierr); 25257459e9aSMatthew G Knepley xfStart = vEnd; xfEnd = xfStart+nXF; 25357459e9aSMatthew G Knepley yfStart = xfEnd; yfEnd = yfStart+nYF; 25457459e9aSMatthew G Knepley zfStart = yfEnd; zfEnd = zfStart+nZF; 25557459e9aSMatthew G Knepley if (zfEnd != fEnd) SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "Invalid face end %d, should be %d", zfEnd, fEnd); 25688ed4aceSMatthew G Knepley /* Create local section */ 25780800b1aSMatthew G Knepley ierr = DMDAGetInfo(dm, 0,0,0,0,0,0,0, &numFields, 0,0,0,0,0);CHKERRQ(ierr); 258a66d4d66SMatthew G Knepley for(f = 0; f < numFields; ++f) { 259a66d4d66SMatthew G Knepley if (numVertexDof) {numVertexTotDof += numVertexDof[f];} 260a66d4d66SMatthew G Knepley if (numCellDof) {numCellTotDof += numCellDof[f];} 26188ed4aceSMatthew G Knepley if (numFaceDof) {numFaceTotDof[0] += numFaceDof[f*dim+0]; 26288ed4aceSMatthew G Knepley numFaceTotDof[1] += dim > 1 ? numFaceDof[f*dim+1] : 0; 26388ed4aceSMatthew G Knepley numFaceTotDof[2] += dim > 2 ? numFaceDof[f*dim+2] : 0;} 264a66d4d66SMatthew G Knepley } 26588ed4aceSMatthew G Knepley ierr = PetscSectionCreate(((PetscObject) dm)->comm, &dm->defaultSection);CHKERRQ(ierr); 266a66d4d66SMatthew G Knepley if (numFields > 1) { 26788ed4aceSMatthew G Knepley ierr = PetscSectionSetNumFields(dm->defaultSection, numFields);CHKERRQ(ierr); 268a66d4d66SMatthew G Knepley for(f = 0; f < numFields; ++f) { 26980800b1aSMatthew G Knepley const char *name; 27080800b1aSMatthew G Knepley 27180800b1aSMatthew G Knepley ierr = DMDAGetFieldName(dm, f, &name);CHKERRQ(ierr); 27288ed4aceSMatthew G Knepley ierr = PetscSectionSetFieldName(dm->defaultSection, f, name);CHKERRQ(ierr); 27380800b1aSMatthew G Knepley if (numComp) { 27488ed4aceSMatthew G Knepley ierr = PetscSectionSetFieldComponents(dm->defaultSection, f, numComp[f]);CHKERRQ(ierr); 275a66d4d66SMatthew G Knepley } 276a66d4d66SMatthew G Knepley } 277a66d4d66SMatthew G Knepley } else { 278a66d4d66SMatthew G Knepley numFields = 0; 279a66d4d66SMatthew G Knepley } 28088ed4aceSMatthew G Knepley ierr = PetscSectionSetChart(dm->defaultSection, pStart, pEnd);CHKERRQ(ierr); 281a66d4d66SMatthew G Knepley if (numVertexDof) { 282a66d4d66SMatthew G Knepley for(v = vStart; v < vEnd; ++v) { 283a66d4d66SMatthew G Knepley for(f = 0; f < numFields; ++f) { 28488ed4aceSMatthew G Knepley ierr = PetscSectionSetFieldDof(dm->defaultSection, v, f, numVertexDof[f]);CHKERRQ(ierr); 285a66d4d66SMatthew G Knepley } 28688ed4aceSMatthew G Knepley ierr = PetscSectionSetDof(dm->defaultSection, v, numVertexTotDof);CHKERRQ(ierr); 287a66d4d66SMatthew G Knepley } 288a66d4d66SMatthew G Knepley } 289a66d4d66SMatthew G Knepley if (numFaceDof) { 290a66d4d66SMatthew G Knepley for(xf = xfStart; xf < xfEnd; ++xf) { 291a66d4d66SMatthew G Knepley for(f = 0; f < numFields; ++f) { 29288ed4aceSMatthew G Knepley ierr = PetscSectionSetFieldDof(dm->defaultSection, xf, f, numFaceDof[f*dim+0]);CHKERRQ(ierr); 293a66d4d66SMatthew G Knepley } 29488ed4aceSMatthew G Knepley ierr = PetscSectionSetDof(dm->defaultSection, xf, numFaceTotDof[0]);CHKERRQ(ierr); 295a66d4d66SMatthew G Knepley } 296a66d4d66SMatthew G Knepley for(yf = yfStart; yf < yfEnd; ++yf) { 297a66d4d66SMatthew G Knepley for(f = 0; f < numFields; ++f) { 29888ed4aceSMatthew G Knepley ierr = PetscSectionSetFieldDof(dm->defaultSection, yf, f, numFaceDof[f*dim+1]);CHKERRQ(ierr); 299a66d4d66SMatthew G Knepley } 30088ed4aceSMatthew G Knepley ierr = PetscSectionSetDof(dm->defaultSection, yf, numFaceTotDof[1]);CHKERRQ(ierr); 301a66d4d66SMatthew G Knepley } 302a66d4d66SMatthew G Knepley for(zf = zfStart; zf < zfEnd; ++zf) { 303a66d4d66SMatthew G Knepley for(f = 0; f < numFields; ++f) { 30488ed4aceSMatthew G Knepley ierr = PetscSectionSetFieldDof(dm->defaultSection, zf, f, numFaceDof[f*dim+2]);CHKERRQ(ierr); 305a66d4d66SMatthew G Knepley } 30688ed4aceSMatthew G Knepley ierr = PetscSectionSetDof(dm->defaultSection, zf, numFaceTotDof[2]);CHKERRQ(ierr); 307a66d4d66SMatthew G Knepley } 308a66d4d66SMatthew G Knepley } 309a66d4d66SMatthew G Knepley if (numCellDof) { 310a66d4d66SMatthew G Knepley for(c = cStart; c < cEnd; ++c) { 311a66d4d66SMatthew G Knepley for(f = 0; f < numFields; ++f) { 31288ed4aceSMatthew G Knepley ierr = PetscSectionSetFieldDof(dm->defaultSection, c, f, numCellDof[f]);CHKERRQ(ierr); 313a66d4d66SMatthew G Knepley } 31488ed4aceSMatthew G Knepley ierr = PetscSectionSetDof(dm->defaultSection, c, numCellTotDof);CHKERRQ(ierr); 315a66d4d66SMatthew G Knepley } 316a66d4d66SMatthew G Knepley } 31788ed4aceSMatthew G Knepley ierr = PetscSectionSetUp(dm->defaultSection);CHKERRQ(ierr); 31888ed4aceSMatthew G Knepley /* Create mesh point SF */ 31988ed4aceSMatthew G Knepley ierr = DMDAGetNeighbors(dm, &neighbors);CHKERRQ(ierr); 32088ed4aceSMatthew G Knepley for(zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) { 32188ed4aceSMatthew G Knepley for(yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) { 32288ed4aceSMatthew G Knepley for(xn = 0; xn < 3; ++xn) { 3237128ae9fSMatthew G Knepley const PetscInt xp = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0; 32488ed4aceSMatthew G Knepley const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn]; 32588ed4aceSMatthew G Knepley 3263814d604SMatthew G Knepley if (neighbor >= 0 && neighbor < rank) { 327feafbc5cSMatthew G Knepley nleaves += (!xp ? nVx : 1) * (!yp ? nVy : 1) * (!zp ? nVz : 1); /* vertices */ 32888ed4aceSMatthew G Knepley if (xp && !yp && !zp) { 32988ed4aceSMatthew G Knepley nleaves += nxF; /* x faces */ 33088ed4aceSMatthew G Knepley } else if (yp && !zp && !xp) { 33188ed4aceSMatthew G Knepley nleaves += nyF; /* y faces */ 33288ed4aceSMatthew G Knepley } else if (zp && !xp && !yp) { 33388ed4aceSMatthew G Knepley nleaves += nzF; /* z faces */ 33488ed4aceSMatthew G Knepley } 33588ed4aceSMatthew G Knepley } 33688ed4aceSMatthew G Knepley } 33788ed4aceSMatthew G Knepley } 33888ed4aceSMatthew G Knepley } 33988ed4aceSMatthew G Knepley ierr = PetscMalloc2(nleaves,PetscInt,&localPoints,nleaves,PetscSFNode,&remotePoints);CHKERRQ(ierr); 34088ed4aceSMatthew G Knepley for(zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) { 34188ed4aceSMatthew G Knepley for(yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) { 34288ed4aceSMatthew G Knepley for(xn = 0; xn < 3; ++xn) { 3437128ae9fSMatthew G Knepley const PetscInt xp = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0; 34488ed4aceSMatthew G Knepley const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn]; 345f5eeb527SMatthew G Knepley PetscInt xv, yv, zv; 34688ed4aceSMatthew G Knepley 3473814d604SMatthew G Knepley if (neighbor >= 0 && neighbor < rank) { 34888ed4aceSMatthew G Knepley if (xp < 0) { /* left */ 34988ed4aceSMatthew G Knepley if (yp < 0) { /* bottom */ 35088ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 35188ed4aceSMatthew G Knepley nleavesCheck += 1; /* left bottom back vertex */ 352f5eeb527SMatthew G Knepley const PetscInt localVertex = ( 0*nVy + 0)*nVx + 0 + nC; 353f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 354f5eeb527SMatthew G Knepley 355f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 356f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 357f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 358f5eeb527SMatthew G Knepley ++nL; 35988ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 36088ed4aceSMatthew G Knepley nleavesCheck += 1; /* left bottom front vertex */ 361f5eeb527SMatthew G Knepley const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + 0 + nC; 362f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 363f5eeb527SMatthew G Knepley 364f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 365f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 366f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 367f5eeb527SMatthew G Knepley ++nL; 36888ed4aceSMatthew G Knepley } else { 36988ed4aceSMatthew G Knepley nleavesCheck += nVz; /* left bottom vertices */ 370f5eeb527SMatthew G Knepley for(zv = 0; zv < nVz; ++zv, ++nL) { 371f5eeb527SMatthew G Knepley const PetscInt localVertex = (zv*nVy + 0)*nVx + 0 + nC; 372f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 373f5eeb527SMatthew G Knepley 374f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 375f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 376f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 377f5eeb527SMatthew G Knepley } 37888ed4aceSMatthew G Knepley } 37988ed4aceSMatthew G Knepley } else if (yp > 0) { /* top */ 38088ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 38188ed4aceSMatthew G Knepley nleavesCheck += 1; /* left top back vertex */ 382f5eeb527SMatthew G Knepley const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + 0 + nC; 383f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + 0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 384f5eeb527SMatthew G Knepley 385f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 386f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 387f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 388f5eeb527SMatthew G Knepley ++nL; 38988ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 39088ed4aceSMatthew G Knepley nleavesCheck += 1; /* left top front vertex */ 391f5eeb527SMatthew G Knepley const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + 0 + nC; 392f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + 0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 393f5eeb527SMatthew G Knepley 394f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 395f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 396f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 397f5eeb527SMatthew G Knepley ++nL; 39888ed4aceSMatthew G Knepley } else { 39988ed4aceSMatthew G Knepley nleavesCheck += nVz; /* left top vertices */ 400f5eeb527SMatthew G Knepley for(zv = 0; zv < nVz; ++zv, ++nL) { 401f5eeb527SMatthew G Knepley const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + 0 + nC; 402f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + 0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 403f5eeb527SMatthew G Knepley 404f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 405f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 406f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 407f5eeb527SMatthew G Knepley } 40888ed4aceSMatthew G Knepley } 40988ed4aceSMatthew G Knepley } else { 41088ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 41188ed4aceSMatthew G Knepley nleavesCheck += nVy; /* left back vertices */ 412f5eeb527SMatthew G Knepley for(yv = 0; yv < nVy; ++yv, ++nL) { 413f5eeb527SMatthew G Knepley const PetscInt localVertex = ( 0*nVy + yv)*nVx + 0 + nC; 414f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 415f5eeb527SMatthew G Knepley 416f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 417f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 418f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 419f5eeb527SMatthew G Knepley } 42088ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 42188ed4aceSMatthew G Knepley nleavesCheck += nVy; /* left front vertices */ 422f5eeb527SMatthew G Knepley for(yv = 0; yv < nVy; ++yv, ++nL) { 423f5eeb527SMatthew G Knepley const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + 0 + nC; 424f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 425f5eeb527SMatthew G Knepley 426f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 427f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 428f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 429f5eeb527SMatthew G Knepley } 43088ed4aceSMatthew G Knepley } else { 43188ed4aceSMatthew G Knepley nleavesCheck += nVy*nVz; /* left vertices */ 432f5eeb527SMatthew G Knepley for(zv = 0; zv < nVz; ++zv) { 433f5eeb527SMatthew G Knepley for(yv = 0; yv < nVy; ++yv, ++nL) { 434f5eeb527SMatthew G Knepley const PetscInt localVertex = (zv*nVy + yv)*nVx + 0 + nC; 435f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 436f5eeb527SMatthew G Knepley 437f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 438f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 439f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 440f5eeb527SMatthew G Knepley } 441f5eeb527SMatthew G Knepley } 44288ed4aceSMatthew G Knepley nleavesCheck += nxF; /* left faces */ 443f5eeb527SMatthew G Knepley for(xf = 0; xf < nxF; ++xf, ++nL) { 444f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 445f5eeb527SMatthew G Knepley const PetscInt localFace = 0 + nC+nV; 446f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 447f5eeb527SMatthew G Knepley 448f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 449f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 450f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 451f5eeb527SMatthew G Knepley } 45288ed4aceSMatthew G Knepley } 45388ed4aceSMatthew G Knepley } 45488ed4aceSMatthew G Knepley } else if (xp > 0) { /* right */ 45588ed4aceSMatthew G Knepley if (yp < 0) { /* bottom */ 45688ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 45788ed4aceSMatthew G Knepley nleavesCheck += 1; /* right bottom back vertex */ 458f5eeb527SMatthew G Knepley const PetscInt localVertex = ( 0*nVy + 0)*nVx + nVx-1 + nC; 459f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 460f5eeb527SMatthew G Knepley 461f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 462f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 463f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 464f5eeb527SMatthew G Knepley ++nL; 46588ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 46688ed4aceSMatthew G Knepley nleavesCheck += 1; /* right bottom front vertex */ 467f5eeb527SMatthew G Knepley const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + nVx-1 + nC; 468f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + nVy-1)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 469f5eeb527SMatthew G Knepley 470f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 471f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 472f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 473f5eeb527SMatthew G Knepley ++nL; 47488ed4aceSMatthew G Knepley } else { 47588ed4aceSMatthew G Knepley nleavesCheck += nVz; /* right bottom vertices */ 476f5eeb527SMatthew G Knepley for(zv = 0; zv < nVz; ++zv, ++nL) { 477f5eeb527SMatthew G Knepley const PetscInt localVertex = (zv*nVy + 0)*nVx + nVx-1 + nC; 478f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 479f5eeb527SMatthew G Knepley 480f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 481f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 482f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 483f5eeb527SMatthew G Knepley } 48488ed4aceSMatthew G Knepley } 48588ed4aceSMatthew G Knepley } else if (yp > 0) { /* top */ 48688ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 48788ed4aceSMatthew G Knepley nleavesCheck += 1; /* right top back vertex */ 488f5eeb527SMatthew G Knepley const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + nVx-1 + nC; 489f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + 0)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 490f5eeb527SMatthew G Knepley 491f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 492f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 493f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 494f5eeb527SMatthew G Knepley ++nL; 49588ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 49688ed4aceSMatthew G Knepley nleavesCheck += 1; /* right top front vertex */ 497f5eeb527SMatthew G Knepley const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; 498f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + 0)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 499f5eeb527SMatthew G Knepley 500f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 501f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 502f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 503f5eeb527SMatthew G Knepley ++nL; 50488ed4aceSMatthew G Knepley } else { 50588ed4aceSMatthew G Knepley nleavesCheck += nVz; /* right top vertices */ 506f5eeb527SMatthew G Knepley for(zv = 0; zv < nVz; ++zv, ++nL) { 507f5eeb527SMatthew G Knepley const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; 508f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + 0)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 509f5eeb527SMatthew G Knepley 510f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 511f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 512f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 513f5eeb527SMatthew G Knepley } 51488ed4aceSMatthew G Knepley } 51588ed4aceSMatthew G Knepley } else { 51688ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 51788ed4aceSMatthew G Knepley nleavesCheck += nVy; /* right back vertices */ 518f5eeb527SMatthew G Knepley for(yv = 0; yv < nVy; ++yv, ++nL) { 519f5eeb527SMatthew G Knepley const PetscInt localVertex = ( 0*nVy + yv)*nVx + nVx-1 + nC; 520f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 521f5eeb527SMatthew G Knepley 522f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 523f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 524f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 525f5eeb527SMatthew G Knepley } 52688ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 52788ed4aceSMatthew G Knepley nleavesCheck += nVy; /* right front vertices */ 528f5eeb527SMatthew G Knepley for(yv = 0; yv < nVy; ++yv, ++nL) { 529f5eeb527SMatthew G Knepley const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; 530f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + yv)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 531f5eeb527SMatthew G Knepley 532f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 533f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 534f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 535f5eeb527SMatthew G Knepley } 53688ed4aceSMatthew G Knepley } else { 53788ed4aceSMatthew G Knepley nleavesCheck += nVy*nVz; /* right vertices */ 538f5eeb527SMatthew G Knepley for(zv = 0; zv < nVz; ++zv) { 539f5eeb527SMatthew G Knepley for(yv = 0; yv < nVy; ++yv, ++nL) { 540f5eeb527SMatthew G Knepley const PetscInt localVertex = (zv*nVy + yv)*nVx + nVx-1 + nC; 541f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + yv)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 542f5eeb527SMatthew G Knepley 543f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 544f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 545f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 546f5eeb527SMatthew G Knepley } 547f5eeb527SMatthew G Knepley } 54888ed4aceSMatthew G Knepley nleavesCheck += nxF; /* right faces */ 549f5eeb527SMatthew G Knepley for(xf = 0; xf < nxF; ++xf, ++nL) { 550f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 551f5eeb527SMatthew G Knepley const PetscInt localFace = 0 + nC+nV; 552f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 553f5eeb527SMatthew G Knepley 554f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 555f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 556f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 557f5eeb527SMatthew G Knepley } 55888ed4aceSMatthew G Knepley } 55988ed4aceSMatthew G Knepley } 56088ed4aceSMatthew G Knepley } else { 56188ed4aceSMatthew G Knepley if (yp < 0) { /* bottom */ 56288ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 56388ed4aceSMatthew G Knepley nleavesCheck += nVx; /* bottom back vertices */ 564f5eeb527SMatthew G Knepley for(xv = 0; xv < nVx; ++xv, ++nL) { 565f5eeb527SMatthew G Knepley const PetscInt localVertex = ( 0*nVy + 0)*nVx + xv + nC; 566f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 567f5eeb527SMatthew G Knepley 568f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 569f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 570f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 571f5eeb527SMatthew G Knepley } 57288ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 57388ed4aceSMatthew G Knepley nleavesCheck += nVx; /* bottom front vertices */ 574f5eeb527SMatthew G Knepley for(xv = 0; xv < nVx; ++xv, ++nL) { 575f5eeb527SMatthew G Knepley const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + xv + nC; 576f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 577f5eeb527SMatthew G Knepley 578f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 579f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 580f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 581f5eeb527SMatthew G Knepley } 58288ed4aceSMatthew G Knepley } else { 58388ed4aceSMatthew G Knepley nleavesCheck += nVx*nVz; /* bottom vertices */ 584f5eeb527SMatthew G Knepley for(zv = 0; zv < nVz; ++zv) { 585f5eeb527SMatthew G Knepley for(xv = 0; xv < nVx; ++xv, ++nL) { 586f5eeb527SMatthew G Knepley const PetscInt localVertex = (zv*nVy + 0)*nVx + xv + nC; 587f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 588f5eeb527SMatthew G Knepley 589f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 590f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 591f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 592f5eeb527SMatthew G Knepley } 593f5eeb527SMatthew G Knepley } 59488ed4aceSMatthew G Knepley nleavesCheck += nyF; /* bottom faces */ 595f5eeb527SMatthew G Knepley for(yf = 0; yf < nyF; ++yf, ++nL) { 596f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 597f5eeb527SMatthew G Knepley const PetscInt localFace = 0 + nC+nV; 598f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 599f5eeb527SMatthew G Knepley 600f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 601f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 602f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 603f5eeb527SMatthew G Knepley } 60488ed4aceSMatthew G Knepley } 60588ed4aceSMatthew G Knepley } else if (yp > 0) { /* top */ 60688ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 60788ed4aceSMatthew G Knepley nleavesCheck += nVx; /* top back vertices */ 608f5eeb527SMatthew G Knepley for(xv = 0; xv < nVx; ++xv, ++nL) { 609f5eeb527SMatthew G Knepley const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + xv + nC; 610f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + 0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 611f5eeb527SMatthew G Knepley 612f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 613f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 614f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 615f5eeb527SMatthew G Knepley } 61688ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 61788ed4aceSMatthew G Knepley nleavesCheck += nVx; /* top front vertices */ 618f5eeb527SMatthew G Knepley for(xv = 0; xv < nVx; ++xv, ++nL) { 619f5eeb527SMatthew G Knepley const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; 620f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + 0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 621f5eeb527SMatthew G Knepley 622f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 623f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 624f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 625f5eeb527SMatthew G Knepley } 62688ed4aceSMatthew G Knepley } else { 62788ed4aceSMatthew G Knepley nleavesCheck += nVx*nVz; /* top vertices */ 628f5eeb527SMatthew G Knepley for(zv = 0; zv < nVz; ++zv) { 629f5eeb527SMatthew G Knepley for(xv = 0; xv < nVx; ++xv, ++nL) { 630f5eeb527SMatthew G Knepley const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + xv + nC; 631f5eeb527SMatthew G Knepley const PetscInt remoteVertex = (zv*nVy + 0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 632f5eeb527SMatthew G Knepley 633f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 634f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 635f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 636f5eeb527SMatthew G Knepley } 637f5eeb527SMatthew G Knepley } 63888ed4aceSMatthew G Knepley nleavesCheck += nyF; /* top faces */ 639f5eeb527SMatthew G Knepley for(yf = 0; yf < nyF; ++yf, ++nL) { 640f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 641f5eeb527SMatthew G Knepley const PetscInt localFace = 0 + nC+nV; 642f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 643f5eeb527SMatthew G Knepley 644f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 645f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 646f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 647f5eeb527SMatthew G Knepley } 64888ed4aceSMatthew G Knepley } 64988ed4aceSMatthew G Knepley } else { 65088ed4aceSMatthew G Knepley if (zp < 0) { /* back */ 65188ed4aceSMatthew G Knepley nleavesCheck += nVx*nVy; /* back vertices */ 652f5eeb527SMatthew G Knepley for(yv = 0; yv < nVy; ++yv) { 653f5eeb527SMatthew G Knepley for(xv = 0; xv < nVx; ++xv, ++nL) { 654f5eeb527SMatthew G Knepley const PetscInt localVertex = ( 0*nVy + yv)*nVx + xv + nC; 655f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 656f5eeb527SMatthew G Knepley 657f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 658f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 659f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 660f5eeb527SMatthew G Knepley } 661f5eeb527SMatthew G Knepley } 66288ed4aceSMatthew G Knepley nleavesCheck += nzF; /* back faces */ 663f5eeb527SMatthew G Knepley for(zf = 0; zf < nzF; ++zf, ++nL) { 664f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 665f5eeb527SMatthew G Knepley const PetscInt localFace = 0 + nC+nV; 666f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 667f5eeb527SMatthew G Knepley 668f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 669f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 670f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 671f5eeb527SMatthew G Knepley } 67288ed4aceSMatthew G Knepley } else if (zp > 0) { /* front */ 67388ed4aceSMatthew G Knepley nleavesCheck += nVx*nVy; /* front vertices */ 674f5eeb527SMatthew G Knepley for(yv = 0; yv < nVy; ++yv) { 675f5eeb527SMatthew G Knepley for(xv = 0; xv < nVx; ++xv, ++nL) { 676f5eeb527SMatthew G Knepley const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + xv + nC; 677f5eeb527SMatthew G Knepley const PetscInt remoteVertex = ( 0*nVy + yv)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 678f5eeb527SMatthew G Knepley 679f5eeb527SMatthew G Knepley localPoints[nL] = localVertex; 680f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 681f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteVertex; 682f5eeb527SMatthew G Knepley } 683f5eeb527SMatthew G Knepley } 68488ed4aceSMatthew G Knepley nleavesCheck += nzF; /* front faces */ 685f5eeb527SMatthew G Knepley for(zf = 0; zf < nzF; ++zf, ++nL) { 686f5eeb527SMatthew G Knepley /* THIS IS WRONG */ 687f5eeb527SMatthew G Knepley const PetscInt localFace = 0 + nC+nV; 688f5eeb527SMatthew G Knepley const PetscInt remoteFace = 0 + nC+nV; 689f5eeb527SMatthew G Knepley 690f5eeb527SMatthew G Knepley localPoints[nL] = localFace; 691f5eeb527SMatthew G Knepley remotePoints[nL].rank = neighbor; 692f5eeb527SMatthew G Knepley remotePoints[nL].index = remoteFace; 693f5eeb527SMatthew G Knepley } 69488ed4aceSMatthew G Knepley } else { 69588ed4aceSMatthew G Knepley /* Nothing is shared from the interior */ 69688ed4aceSMatthew G Knepley } 69788ed4aceSMatthew G Knepley } 69888ed4aceSMatthew G Knepley } 69988ed4aceSMatthew G Knepley } 70088ed4aceSMatthew G Knepley } 70188ed4aceSMatthew G Knepley } 70288ed4aceSMatthew G Knepley } 7033814d604SMatthew G Knepley /* TODO: Remove duplication in leaf determination */ 70488ed4aceSMatthew G Knepley if (nleaves != nleavesCheck) SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "The number of leaves %d did not match the number of remote leaves %d", nleaves, nleavesCheck); 70588ed4aceSMatthew G Knepley ierr = PetscSFCreate(((PetscObject) dm)->comm, &sf);CHKERRQ(ierr); 70688ed4aceSMatthew G Knepley ierr = PetscSFSetGraph(sf, pEnd, nleaves, localPoints, PETSC_OWN_POINTER, remotePoints, PETSC_OWN_POINTER);CHKERRQ(ierr); 70788ed4aceSMatthew G Knepley /* Create global section */ 708*eaf8d80aSMatthew G Knepley ierr = PetscSectionCreateGlobalSection(dm->defaultSection, sf, PETSC_FALSE, &dm->defaultGlobalSection);CHKERRQ(ierr); 70988ed4aceSMatthew G Knepley ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 71088ed4aceSMatthew G Knepley /* Create default SF */ 71188ed4aceSMatthew G Knepley ierr = DMCreateDefaultSF(dm, dm->defaultSection, dm->defaultGlobalSection);CHKERRQ(ierr); 712a66d4d66SMatthew G Knepley PetscFunctionReturn(0); 713a66d4d66SMatthew G Knepley } 714a66d4d66SMatthew G Knepley 71547c6ae99SBarry Smith /* ------------------------------------------------------------------- */ 71647c6ae99SBarry Smith #if defined(PETSC_HAVE_ADIC) 71747c6ae99SBarry Smith 71847c6ae99SBarry Smith EXTERN_C_BEGIN 719c6db04a5SJed Brown #include <adic/ad_utils.h> 72047c6ae99SBarry Smith EXTERN_C_END 72147c6ae99SBarry Smith 72247c6ae99SBarry Smith #undef __FUNCT__ 723aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicArray" 72447c6ae99SBarry Smith /*@C 725aa219208SBarry Smith DMDAGetAdicArray - Gets an array of derivative types for a DMDA 72647c6ae99SBarry Smith 72747c6ae99SBarry Smith Input Parameter: 72847c6ae99SBarry Smith + da - information about my local patch 72947c6ae99SBarry Smith - ghosted - do you want arrays for the ghosted or nonghosted patch 73047c6ae99SBarry Smith 73147c6ae99SBarry Smith Output Parameters: 73247c6ae99SBarry Smith + vptr - array data structured to be passed to ad_FormFunctionLocal() 73347c6ae99SBarry Smith . array_start - actual start of 1d array of all values that adiC can access directly (may be null) 73447c6ae99SBarry Smith - tdof - total number of degrees of freedom represented in array_start (may be null) 73547c6ae99SBarry Smith 73647c6ae99SBarry Smith Notes: 73747c6ae99SBarry Smith The vector values are NOT initialized and may have garbage in them, so you may need 73847c6ae99SBarry Smith to zero them. 73947c6ae99SBarry Smith 740aa219208SBarry Smith Returns the same type of object as the DMDAVecGetArray() except its elements are 74147c6ae99SBarry Smith derivative types instead of PetscScalars 74247c6ae99SBarry Smith 74347c6ae99SBarry Smith Level: advanced 74447c6ae99SBarry Smith 745aa219208SBarry Smith .seealso: DMDARestoreAdicArray() 74647c6ae99SBarry Smith 74747c6ae99SBarry Smith @*/ 7487087cfbeSBarry Smith PetscErrorCode DMDAGetAdicArray(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof) 74947c6ae99SBarry Smith { 75047c6ae99SBarry Smith PetscErrorCode ierr; 75147c6ae99SBarry Smith PetscInt j,i,deriv_type_size,xs,ys,xm,ym,zs,zm,itdof; 75247c6ae99SBarry Smith char *iarray_start; 75347c6ae99SBarry Smith void **iptr = (void**)vptr; 75447c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 75547c6ae99SBarry Smith 75647c6ae99SBarry Smith PetscFunctionBegin; 75747c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 75847c6ae99SBarry Smith if (ghosted) { 759aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 76047c6ae99SBarry Smith if (dd->adarrayghostedin[i]) { 76147c6ae99SBarry Smith *iptr = dd->adarrayghostedin[i]; 76247c6ae99SBarry Smith iarray_start = (char*)dd->adstartghostedin[i]; 76347c6ae99SBarry Smith itdof = dd->ghostedtdof; 76447c6ae99SBarry Smith dd->adarrayghostedin[i] = PETSC_NULL; 76547c6ae99SBarry Smith dd->adstartghostedin[i] = PETSC_NULL; 76647c6ae99SBarry Smith 76747c6ae99SBarry Smith goto done; 76847c6ae99SBarry Smith } 76947c6ae99SBarry Smith } 77047c6ae99SBarry Smith xs = dd->Xs; 77147c6ae99SBarry Smith ys = dd->Ys; 77247c6ae99SBarry Smith zs = dd->Zs; 77347c6ae99SBarry Smith xm = dd->Xe-dd->Xs; 77447c6ae99SBarry Smith ym = dd->Ye-dd->Ys; 77547c6ae99SBarry Smith zm = dd->Ze-dd->Zs; 77647c6ae99SBarry Smith } else { 777aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 77847c6ae99SBarry Smith if (dd->adarrayin[i]) { 77947c6ae99SBarry Smith *iptr = dd->adarrayin[i]; 78047c6ae99SBarry Smith iarray_start = (char*)dd->adstartin[i]; 78147c6ae99SBarry Smith itdof = dd->tdof; 78247c6ae99SBarry Smith dd->adarrayin[i] = PETSC_NULL; 78347c6ae99SBarry Smith dd->adstartin[i] = PETSC_NULL; 78447c6ae99SBarry Smith 78547c6ae99SBarry Smith goto done; 78647c6ae99SBarry Smith } 78747c6ae99SBarry Smith } 78847c6ae99SBarry Smith xs = dd->xs; 78947c6ae99SBarry Smith ys = dd->ys; 79047c6ae99SBarry Smith zs = dd->zs; 79147c6ae99SBarry Smith xm = dd->xe-dd->xs; 79247c6ae99SBarry Smith ym = dd->ye-dd->ys; 79347c6ae99SBarry Smith zm = dd->ze-dd->zs; 79447c6ae99SBarry Smith } 79547c6ae99SBarry Smith deriv_type_size = PetscADGetDerivTypeSize(); 79647c6ae99SBarry Smith 79747c6ae99SBarry Smith switch (dd->dim) { 79847c6ae99SBarry Smith case 1: { 79947c6ae99SBarry Smith void *ptr; 80047c6ae99SBarry Smith itdof = xm; 80147c6ae99SBarry Smith 80247c6ae99SBarry Smith ierr = PetscMalloc(xm*deriv_type_size,&iarray_start);CHKERRQ(ierr); 80347c6ae99SBarry Smith 80447c6ae99SBarry Smith ptr = (void*)(iarray_start - xs*deriv_type_size); 80547c6ae99SBarry Smith *iptr = (void*)ptr; 80647c6ae99SBarry Smith break;} 80747c6ae99SBarry Smith case 2: { 80847c6ae99SBarry Smith void **ptr; 80947c6ae99SBarry Smith itdof = xm*ym; 81047c6ae99SBarry Smith 81147c6ae99SBarry Smith ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*deriv_type_size,&iarray_start);CHKERRQ(ierr); 81247c6ae99SBarry Smith 81347c6ae99SBarry Smith ptr = (void**)(iarray_start + xm*ym*deriv_type_size - ys*sizeof(void*)); 81447c6ae99SBarry Smith for(j=ys;j<ys+ym;j++) { 81547c6ae99SBarry Smith ptr[j] = iarray_start + deriv_type_size*(xm*(j-ys) - xs); 81647c6ae99SBarry Smith } 81747c6ae99SBarry Smith *iptr = (void*)ptr; 81847c6ae99SBarry Smith break;} 81947c6ae99SBarry Smith case 3: { 82047c6ae99SBarry Smith void ***ptr,**bptr; 82147c6ae99SBarry Smith itdof = xm*ym*zm; 82247c6ae99SBarry Smith 82347c6ae99SBarry Smith ierr = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*deriv_type_size,&iarray_start);CHKERRQ(ierr); 82447c6ae99SBarry Smith 82547c6ae99SBarry Smith ptr = (void***)(iarray_start + xm*ym*zm*deriv_type_size - zs*sizeof(void*)); 82647c6ae99SBarry Smith bptr = (void**)(iarray_start + xm*ym*zm*deriv_type_size + zm*sizeof(void**)); 82747c6ae99SBarry Smith 82847c6ae99SBarry Smith for(i=zs;i<zs+zm;i++) { 82947c6ae99SBarry Smith ptr[i] = bptr + ((i-zs)*ym - ys); 83047c6ae99SBarry Smith } 83147c6ae99SBarry Smith for (i=zs; i<zs+zm; i++) { 83247c6ae99SBarry Smith for (j=ys; j<ys+ym; j++) { 83347c6ae99SBarry Smith ptr[i][j] = iarray_start + deriv_type_size*(xm*ym*(i-zs) + xm*(j-ys) - xs); 83447c6ae99SBarry Smith } 83547c6ae99SBarry Smith } 83647c6ae99SBarry Smith 83747c6ae99SBarry Smith *iptr = (void*)ptr; 83847c6ae99SBarry Smith break;} 83947c6ae99SBarry Smith default: 84047c6ae99SBarry Smith SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim); 84147c6ae99SBarry Smith } 84247c6ae99SBarry Smith 84347c6ae99SBarry Smith done: 84447c6ae99SBarry Smith /* add arrays to the checked out list */ 84547c6ae99SBarry Smith if (ghosted) { 846aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 84747c6ae99SBarry Smith if (!dd->adarrayghostedout[i]) { 84847c6ae99SBarry Smith dd->adarrayghostedout[i] = *iptr ; 84947c6ae99SBarry Smith dd->adstartghostedout[i] = iarray_start; 85047c6ae99SBarry Smith dd->ghostedtdof = itdof; 85147c6ae99SBarry Smith break; 85247c6ae99SBarry Smith } 85347c6ae99SBarry Smith } 85447c6ae99SBarry Smith } else { 855aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 85647c6ae99SBarry Smith if (!dd->adarrayout[i]) { 85747c6ae99SBarry Smith dd->adarrayout[i] = *iptr ; 85847c6ae99SBarry Smith dd->adstartout[i] = iarray_start; 85947c6ae99SBarry Smith dd->tdof = itdof; 86047c6ae99SBarry Smith break; 86147c6ae99SBarry Smith } 86247c6ae99SBarry Smith } 86347c6ae99SBarry Smith } 864aa219208SBarry Smith if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Too many DMDA ADIC arrays obtained"); 86547c6ae99SBarry Smith if (tdof) *tdof = itdof; 86647c6ae99SBarry Smith if (array_start) *(void**)array_start = iarray_start; 86747c6ae99SBarry Smith PetscFunctionReturn(0); 86847c6ae99SBarry Smith } 86947c6ae99SBarry Smith 87047c6ae99SBarry Smith #undef __FUNCT__ 871aa219208SBarry Smith #define __FUNCT__ "DMDARestoreAdicArray" 87247c6ae99SBarry Smith /*@C 873aa219208SBarry Smith DMDARestoreAdicArray - Restores an array of derivative types for a DMDA 87447c6ae99SBarry Smith 87547c6ae99SBarry Smith Input Parameter: 87647c6ae99SBarry Smith + da - information about my local patch 87747c6ae99SBarry Smith - ghosted - do you want arrays for the ghosted or nonghosted patch 87847c6ae99SBarry Smith 87947c6ae99SBarry Smith Output Parameters: 88047c6ae99SBarry Smith + ptr - array data structured to be passed to ad_FormFunctionLocal() 88147c6ae99SBarry Smith . array_start - actual start of 1d array of all values that adiC can access directly 88247c6ae99SBarry Smith - tdof - total number of degrees of freedom represented in array_start 88347c6ae99SBarry Smith 88447c6ae99SBarry Smith Level: advanced 88547c6ae99SBarry Smith 886aa219208SBarry Smith .seealso: DMDAGetAdicArray() 88747c6ae99SBarry Smith 88847c6ae99SBarry Smith @*/ 8897087cfbeSBarry Smith PetscErrorCode DMDARestoreAdicArray(DM da,PetscBool ghosted,void *ptr,void *array_start,PetscInt *tdof) 89047c6ae99SBarry Smith { 89147c6ae99SBarry Smith PetscInt i; 89247c6ae99SBarry Smith void **iptr = (void**)ptr,iarray_start = 0; 89347c6ae99SBarry Smith 89447c6ae99SBarry Smith PetscFunctionBegin; 89547c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 89647c6ae99SBarry Smith if (ghosted) { 897aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 89847c6ae99SBarry Smith if (dd->adarrayghostedout[i] == *iptr) { 89947c6ae99SBarry Smith iarray_start = dd->adstartghostedout[i]; 90047c6ae99SBarry Smith dd->adarrayghostedout[i] = PETSC_NULL; 90147c6ae99SBarry Smith dd->adstartghostedout[i] = PETSC_NULL; 90247c6ae99SBarry Smith break; 90347c6ae99SBarry Smith } 90447c6ae99SBarry Smith } 90547c6ae99SBarry Smith if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list"); 906aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 90747c6ae99SBarry Smith if (!dd->adarrayghostedin[i]){ 90847c6ae99SBarry Smith dd->adarrayghostedin[i] = *iptr; 90947c6ae99SBarry Smith dd->adstartghostedin[i] = iarray_start; 91047c6ae99SBarry Smith break; 91147c6ae99SBarry Smith } 91247c6ae99SBarry Smith } 91347c6ae99SBarry Smith } else { 914aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 91547c6ae99SBarry Smith if (dd->adarrayout[i] == *iptr) { 91647c6ae99SBarry Smith iarray_start = dd->adstartout[i]; 91747c6ae99SBarry Smith dd->adarrayout[i] = PETSC_NULL; 91847c6ae99SBarry Smith dd->adstartout[i] = PETSC_NULL; 91947c6ae99SBarry Smith break; 92047c6ae99SBarry Smith } 92147c6ae99SBarry Smith } 92247c6ae99SBarry Smith if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list"); 923aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 92447c6ae99SBarry Smith if (!dd->adarrayin[i]){ 92547c6ae99SBarry Smith dd->adarrayin[i] = *iptr; 92647c6ae99SBarry Smith dd->adstartin[i] = iarray_start; 92747c6ae99SBarry Smith break; 92847c6ae99SBarry Smith } 92947c6ae99SBarry Smith } 93047c6ae99SBarry Smith } 93147c6ae99SBarry Smith PetscFunctionReturn(0); 93247c6ae99SBarry Smith } 93347c6ae99SBarry Smith 93447c6ae99SBarry Smith #undef __FUNCT__ 93547c6ae99SBarry Smith #define __FUNCT__ "ad_DAGetArray" 9367087cfbeSBarry Smith PetscErrorCode ad_DAGetArray(DM da,PetscBool ghosted,void *iptr) 93747c6ae99SBarry Smith { 93847c6ae99SBarry Smith PetscErrorCode ierr; 93947c6ae99SBarry Smith PetscFunctionBegin; 940aa219208SBarry Smith ierr = DMDAGetAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr); 94147c6ae99SBarry Smith PetscFunctionReturn(0); 94247c6ae99SBarry Smith } 94347c6ae99SBarry Smith 94447c6ae99SBarry Smith #undef __FUNCT__ 94547c6ae99SBarry Smith #define __FUNCT__ "ad_DARestoreArray" 9467087cfbeSBarry Smith PetscErrorCode ad_DARestoreArray(DM da,PetscBool ghosted,void *iptr) 94747c6ae99SBarry Smith { 94847c6ae99SBarry Smith PetscErrorCode ierr; 94947c6ae99SBarry Smith PetscFunctionBegin; 950aa219208SBarry Smith ierr = DMDARestoreAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr); 95147c6ae99SBarry Smith PetscFunctionReturn(0); 95247c6ae99SBarry Smith } 95347c6ae99SBarry Smith 95447c6ae99SBarry Smith #endif 95547c6ae99SBarry Smith 95647c6ae99SBarry Smith #undef __FUNCT__ 957aa219208SBarry Smith #define __FUNCT__ "DMDAGetArray" 95847c6ae99SBarry Smith /*@C 959aa219208SBarry Smith DMDAGetArray - Gets a work array for a DMDA 96047c6ae99SBarry Smith 96147c6ae99SBarry Smith Input Parameter: 96247c6ae99SBarry Smith + da - information about my local patch 96347c6ae99SBarry Smith - ghosted - do you want arrays for the ghosted or nonghosted patch 96447c6ae99SBarry Smith 96547c6ae99SBarry Smith Output Parameters: 96647c6ae99SBarry Smith . vptr - array data structured 96747c6ae99SBarry Smith 96847c6ae99SBarry Smith Note: The vector values are NOT initialized and may have garbage in them, so you may need 96947c6ae99SBarry Smith to zero them. 97047c6ae99SBarry Smith 97147c6ae99SBarry Smith Level: advanced 97247c6ae99SBarry Smith 973aa219208SBarry Smith .seealso: DMDARestoreArray(), DMDAGetAdicArray() 97447c6ae99SBarry Smith 97547c6ae99SBarry Smith @*/ 9767087cfbeSBarry Smith PetscErrorCode DMDAGetArray(DM da,PetscBool ghosted,void *vptr) 97747c6ae99SBarry Smith { 97847c6ae99SBarry Smith PetscErrorCode ierr; 97947c6ae99SBarry Smith PetscInt j,i,xs,ys,xm,ym,zs,zm; 98047c6ae99SBarry Smith char *iarray_start; 98147c6ae99SBarry Smith void **iptr = (void**)vptr; 98247c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 98347c6ae99SBarry Smith 98447c6ae99SBarry Smith PetscFunctionBegin; 98547c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 98647c6ae99SBarry Smith if (ghosted) { 987aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 98847c6ae99SBarry Smith if (dd->arrayghostedin[i]) { 98947c6ae99SBarry Smith *iptr = dd->arrayghostedin[i]; 99047c6ae99SBarry Smith iarray_start = (char*)dd->startghostedin[i]; 99147c6ae99SBarry Smith dd->arrayghostedin[i] = PETSC_NULL; 99247c6ae99SBarry Smith dd->startghostedin[i] = PETSC_NULL; 99347c6ae99SBarry Smith 99447c6ae99SBarry Smith goto done; 99547c6ae99SBarry Smith } 99647c6ae99SBarry Smith } 99747c6ae99SBarry Smith xs = dd->Xs; 99847c6ae99SBarry Smith ys = dd->Ys; 99947c6ae99SBarry Smith zs = dd->Zs; 100047c6ae99SBarry Smith xm = dd->Xe-dd->Xs; 100147c6ae99SBarry Smith ym = dd->Ye-dd->Ys; 100247c6ae99SBarry Smith zm = dd->Ze-dd->Zs; 100347c6ae99SBarry Smith } else { 1004aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 100547c6ae99SBarry Smith if (dd->arrayin[i]) { 100647c6ae99SBarry Smith *iptr = dd->arrayin[i]; 100747c6ae99SBarry Smith iarray_start = (char*)dd->startin[i]; 100847c6ae99SBarry Smith dd->arrayin[i] = PETSC_NULL; 100947c6ae99SBarry Smith dd->startin[i] = PETSC_NULL; 101047c6ae99SBarry Smith 101147c6ae99SBarry Smith goto done; 101247c6ae99SBarry Smith } 101347c6ae99SBarry Smith } 101447c6ae99SBarry Smith xs = dd->xs; 101547c6ae99SBarry Smith ys = dd->ys; 101647c6ae99SBarry Smith zs = dd->zs; 101747c6ae99SBarry Smith xm = dd->xe-dd->xs; 101847c6ae99SBarry Smith ym = dd->ye-dd->ys; 101947c6ae99SBarry Smith zm = dd->ze-dd->zs; 102047c6ae99SBarry Smith } 102147c6ae99SBarry Smith 102247c6ae99SBarry Smith switch (dd->dim) { 102347c6ae99SBarry Smith case 1: { 102447c6ae99SBarry Smith void *ptr; 102547c6ae99SBarry Smith 102647c6ae99SBarry Smith ierr = PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 102747c6ae99SBarry Smith 102847c6ae99SBarry Smith ptr = (void*)(iarray_start - xs*sizeof(PetscScalar)); 102947c6ae99SBarry Smith *iptr = (void*)ptr; 103047c6ae99SBarry Smith break;} 103147c6ae99SBarry Smith case 2: { 103247c6ae99SBarry Smith void **ptr; 103347c6ae99SBarry Smith 103447c6ae99SBarry Smith ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 103547c6ae99SBarry Smith 103647c6ae99SBarry Smith ptr = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*)); 103747c6ae99SBarry Smith for(j=ys;j<ys+ym;j++) { 103847c6ae99SBarry Smith ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs); 103947c6ae99SBarry Smith } 104047c6ae99SBarry Smith *iptr = (void*)ptr; 104147c6ae99SBarry Smith break;} 104247c6ae99SBarry Smith case 3: { 104347c6ae99SBarry Smith void ***ptr,**bptr; 104447c6ae99SBarry Smith 104547c6ae99SBarry Smith ierr = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 104647c6ae99SBarry Smith 104747c6ae99SBarry Smith ptr = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*)); 104847c6ae99SBarry Smith bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**)); 104947c6ae99SBarry Smith for(i=zs;i<zs+zm;i++) { 105047c6ae99SBarry Smith ptr[i] = bptr + ((i-zs)*ym - ys); 105147c6ae99SBarry Smith } 105247c6ae99SBarry Smith for (i=zs; i<zs+zm; i++) { 105347c6ae99SBarry Smith for (j=ys; j<ys+ym; j++) { 105447c6ae99SBarry Smith ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs); 105547c6ae99SBarry Smith } 105647c6ae99SBarry Smith } 105747c6ae99SBarry Smith 105847c6ae99SBarry Smith *iptr = (void*)ptr; 105947c6ae99SBarry Smith break;} 106047c6ae99SBarry Smith default: 106147c6ae99SBarry Smith SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim); 106247c6ae99SBarry Smith } 106347c6ae99SBarry Smith 106447c6ae99SBarry Smith done: 106547c6ae99SBarry Smith /* add arrays to the checked out list */ 106647c6ae99SBarry Smith if (ghosted) { 1067aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 106847c6ae99SBarry Smith if (!dd->arrayghostedout[i]) { 106947c6ae99SBarry Smith dd->arrayghostedout[i] = *iptr ; 107047c6ae99SBarry Smith dd->startghostedout[i] = iarray_start; 107147c6ae99SBarry Smith break; 107247c6ae99SBarry Smith } 107347c6ae99SBarry Smith } 107447c6ae99SBarry Smith } else { 1075aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 107647c6ae99SBarry Smith if (!dd->arrayout[i]) { 107747c6ae99SBarry Smith dd->arrayout[i] = *iptr ; 107847c6ae99SBarry Smith dd->startout[i] = iarray_start; 107947c6ae99SBarry Smith break; 108047c6ae99SBarry Smith } 108147c6ae99SBarry Smith } 108247c6ae99SBarry Smith } 108347c6ae99SBarry Smith PetscFunctionReturn(0); 108447c6ae99SBarry Smith } 108547c6ae99SBarry Smith 108647c6ae99SBarry Smith #undef __FUNCT__ 1087aa219208SBarry Smith #define __FUNCT__ "DMDARestoreArray" 108847c6ae99SBarry Smith /*@C 1089aa219208SBarry Smith DMDARestoreArray - Restores an array of derivative types for a DMDA 109047c6ae99SBarry Smith 109147c6ae99SBarry Smith Input Parameter: 109247c6ae99SBarry Smith + da - information about my local patch 109347c6ae99SBarry Smith . ghosted - do you want arrays for the ghosted or nonghosted patch 109447c6ae99SBarry Smith - vptr - array data structured to be passed to ad_FormFunctionLocal() 109547c6ae99SBarry Smith 109647c6ae99SBarry Smith Level: advanced 109747c6ae99SBarry Smith 1098aa219208SBarry Smith .seealso: DMDAGetArray(), DMDAGetAdicArray() 109947c6ae99SBarry Smith 110047c6ae99SBarry Smith @*/ 11017087cfbeSBarry Smith PetscErrorCode DMDARestoreArray(DM da,PetscBool ghosted,void *vptr) 110247c6ae99SBarry Smith { 110347c6ae99SBarry Smith PetscInt i; 110447c6ae99SBarry Smith void **iptr = (void**)vptr,*iarray_start = 0; 110547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 110647c6ae99SBarry Smith 110747c6ae99SBarry Smith PetscFunctionBegin; 110847c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 110947c6ae99SBarry Smith if (ghosted) { 1110aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 111147c6ae99SBarry Smith if (dd->arrayghostedout[i] == *iptr) { 111247c6ae99SBarry Smith iarray_start = dd->startghostedout[i]; 111347c6ae99SBarry Smith dd->arrayghostedout[i] = PETSC_NULL; 111447c6ae99SBarry Smith dd->startghostedout[i] = PETSC_NULL; 111547c6ae99SBarry Smith break; 111647c6ae99SBarry Smith } 111747c6ae99SBarry Smith } 1118aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 111947c6ae99SBarry Smith if (!dd->arrayghostedin[i]){ 112047c6ae99SBarry Smith dd->arrayghostedin[i] = *iptr; 112147c6ae99SBarry Smith dd->startghostedin[i] = iarray_start; 112247c6ae99SBarry Smith break; 112347c6ae99SBarry Smith } 112447c6ae99SBarry Smith } 112547c6ae99SBarry Smith } else { 1126aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 112747c6ae99SBarry Smith if (dd->arrayout[i] == *iptr) { 112847c6ae99SBarry Smith iarray_start = dd->startout[i]; 112947c6ae99SBarry Smith dd->arrayout[i] = PETSC_NULL; 113047c6ae99SBarry Smith dd->startout[i] = PETSC_NULL; 113147c6ae99SBarry Smith break; 113247c6ae99SBarry Smith } 113347c6ae99SBarry Smith } 1134aa219208SBarry Smith for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 113547c6ae99SBarry Smith if (!dd->arrayin[i]){ 113647c6ae99SBarry Smith dd->arrayin[i] = *iptr; 113747c6ae99SBarry Smith dd->startin[i] = iarray_start; 113847c6ae99SBarry Smith break; 113947c6ae99SBarry Smith } 114047c6ae99SBarry Smith } 114147c6ae99SBarry Smith } 114247c6ae99SBarry Smith PetscFunctionReturn(0); 114347c6ae99SBarry Smith } 114447c6ae99SBarry Smith 114547c6ae99SBarry Smith #undef __FUNCT__ 1146aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray" 114747c6ae99SBarry Smith /*@C 1148aa219208SBarry Smith DMDAGetAdicMFArray - Gets an array of derivative types for a DMDA for matrix-free ADIC. 114947c6ae99SBarry Smith 115047c6ae99SBarry Smith Input Parameter: 115147c6ae99SBarry Smith + da - information about my local patch 115247c6ae99SBarry Smith - ghosted - do you want arrays for the ghosted or nonghosted patch? 115347c6ae99SBarry Smith 115447c6ae99SBarry Smith Output Parameters: 115547c6ae99SBarry Smith + vptr - array data structured to be passed to ad_FormFunctionLocal() 115647c6ae99SBarry Smith . array_start - actual start of 1d array of all values that adiC can access directly (may be null) 115747c6ae99SBarry Smith - tdof - total number of degrees of freedom represented in array_start (may be null) 115847c6ae99SBarry Smith 115947c6ae99SBarry Smith Notes: 116047c6ae99SBarry Smith The vector values are NOT initialized and may have garbage in them, so you may need 116147c6ae99SBarry Smith to zero them. 116247c6ae99SBarry Smith 1163aa219208SBarry Smith This routine returns the same type of object as the DMDAVecGetArray(), except its 116447c6ae99SBarry Smith elements are derivative types instead of PetscScalars. 116547c6ae99SBarry Smith 116647c6ae99SBarry Smith Level: advanced 116747c6ae99SBarry Smith 1168aa219208SBarry Smith .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray() 116947c6ae99SBarry Smith 117047c6ae99SBarry Smith @*/ 11717087cfbeSBarry Smith PetscErrorCode DMDAGetAdicMFArray(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof) 117247c6ae99SBarry Smith { 117347c6ae99SBarry Smith PetscErrorCode ierr; 117447c6ae99SBarry Smith PetscInt j,i,xs,ys,xm,ym,zs,zm,itdof = 0; 117547c6ae99SBarry Smith char *iarray_start; 117647c6ae99SBarry Smith void **iptr = (void**)vptr; 117747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 117847c6ae99SBarry Smith 117947c6ae99SBarry Smith PetscFunctionBegin; 118047c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 118147c6ae99SBarry Smith if (ghosted) { 1182aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 118347c6ae99SBarry Smith if (dd->admfarrayghostedin[i]) { 118447c6ae99SBarry Smith *iptr = dd->admfarrayghostedin[i]; 118547c6ae99SBarry Smith iarray_start = (char*)dd->admfstartghostedin[i]; 118647c6ae99SBarry Smith itdof = dd->ghostedtdof; 118747c6ae99SBarry Smith dd->admfarrayghostedin[i] = PETSC_NULL; 118847c6ae99SBarry Smith dd->admfstartghostedin[i] = PETSC_NULL; 118947c6ae99SBarry Smith 119047c6ae99SBarry Smith goto done; 119147c6ae99SBarry Smith } 119247c6ae99SBarry Smith } 119347c6ae99SBarry Smith xs = dd->Xs; 119447c6ae99SBarry Smith ys = dd->Ys; 119547c6ae99SBarry Smith zs = dd->Zs; 119647c6ae99SBarry Smith xm = dd->Xe-dd->Xs; 119747c6ae99SBarry Smith ym = dd->Ye-dd->Ys; 119847c6ae99SBarry Smith zm = dd->Ze-dd->Zs; 119947c6ae99SBarry Smith } else { 1200aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 120147c6ae99SBarry Smith if (dd->admfarrayin[i]) { 120247c6ae99SBarry Smith *iptr = dd->admfarrayin[i]; 120347c6ae99SBarry Smith iarray_start = (char*)dd->admfstartin[i]; 120447c6ae99SBarry Smith itdof = dd->tdof; 120547c6ae99SBarry Smith dd->admfarrayin[i] = PETSC_NULL; 120647c6ae99SBarry Smith dd->admfstartin[i] = PETSC_NULL; 120747c6ae99SBarry Smith 120847c6ae99SBarry Smith goto done; 120947c6ae99SBarry Smith } 121047c6ae99SBarry Smith } 121147c6ae99SBarry Smith xs = dd->xs; 121247c6ae99SBarry Smith ys = dd->ys; 121347c6ae99SBarry Smith zs = dd->zs; 121447c6ae99SBarry Smith xm = dd->xe-dd->xs; 121547c6ae99SBarry Smith ym = dd->ye-dd->ys; 121647c6ae99SBarry Smith zm = dd->ze-dd->zs; 121747c6ae99SBarry Smith } 121847c6ae99SBarry Smith 121947c6ae99SBarry Smith switch (dd->dim) { 122047c6ae99SBarry Smith case 1: { 122147c6ae99SBarry Smith void *ptr; 122247c6ae99SBarry Smith itdof = xm; 122347c6ae99SBarry Smith 122447c6ae99SBarry Smith ierr = PetscMalloc(xm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 122547c6ae99SBarry Smith 122647c6ae99SBarry Smith ptr = (void*)(iarray_start - xs*2*sizeof(PetscScalar)); 122747c6ae99SBarry Smith *iptr = (void*)ptr; 122847c6ae99SBarry Smith break;} 122947c6ae99SBarry Smith case 2: { 123047c6ae99SBarry Smith void **ptr; 123147c6ae99SBarry Smith itdof = xm*ym; 123247c6ae99SBarry Smith 123347c6ae99SBarry Smith ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 123447c6ae99SBarry Smith 123547c6ae99SBarry Smith ptr = (void**)(iarray_start + xm*ym*2*sizeof(PetscScalar) - ys*sizeof(void*)); 123647c6ae99SBarry Smith for(j=ys;j<ys+ym;j++) { 123747c6ae99SBarry Smith ptr[j] = iarray_start + 2*sizeof(PetscScalar)*(xm*(j-ys) - xs); 123847c6ae99SBarry Smith } 123947c6ae99SBarry Smith *iptr = (void*)ptr; 124047c6ae99SBarry Smith break;} 124147c6ae99SBarry Smith case 3: { 124247c6ae99SBarry Smith void ***ptr,**bptr; 124347c6ae99SBarry Smith itdof = xm*ym*zm; 124447c6ae99SBarry Smith 124547c6ae99SBarry Smith ierr = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 124647c6ae99SBarry Smith 124747c6ae99SBarry Smith ptr = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*)); 124847c6ae99SBarry Smith bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**)); 124947c6ae99SBarry Smith for(i=zs;i<zs+zm;i++) { 125047c6ae99SBarry Smith ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*); 125147c6ae99SBarry Smith } 125247c6ae99SBarry Smith for (i=zs; i<zs+zm; i++) { 125347c6ae99SBarry Smith for (j=ys; j<ys+ym; j++) { 125447c6ae99SBarry Smith ptr[i][j] = iarray_start + 2*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs); 125547c6ae99SBarry Smith } 125647c6ae99SBarry Smith } 125747c6ae99SBarry Smith 125847c6ae99SBarry Smith *iptr = (void*)ptr; 125947c6ae99SBarry Smith break;} 126047c6ae99SBarry Smith default: 126147c6ae99SBarry Smith SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim); 126247c6ae99SBarry Smith } 126347c6ae99SBarry Smith 126447c6ae99SBarry Smith done: 126547c6ae99SBarry Smith /* add arrays to the checked out list */ 126647c6ae99SBarry Smith if (ghosted) { 1267aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 126847c6ae99SBarry Smith if (!dd->admfarrayghostedout[i]) { 126947c6ae99SBarry Smith dd->admfarrayghostedout[i] = *iptr ; 127047c6ae99SBarry Smith dd->admfstartghostedout[i] = iarray_start; 127147c6ae99SBarry Smith dd->ghostedtdof = itdof; 127247c6ae99SBarry Smith break; 127347c6ae99SBarry Smith } 127447c6ae99SBarry Smith } 127547c6ae99SBarry Smith } else { 1276aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 127747c6ae99SBarry Smith if (!dd->admfarrayout[i]) { 127847c6ae99SBarry Smith dd->admfarrayout[i] = *iptr ; 127947c6ae99SBarry Smith dd->admfstartout[i] = iarray_start; 128047c6ae99SBarry Smith dd->tdof = itdof; 128147c6ae99SBarry Smith break; 128247c6ae99SBarry Smith } 128347c6ae99SBarry Smith } 128447c6ae99SBarry Smith } 1285aa219208SBarry Smith if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained"); 128647c6ae99SBarry Smith if (tdof) *tdof = itdof; 128747c6ae99SBarry Smith if (array_start) *(void**)array_start = iarray_start; 128847c6ae99SBarry Smith PetscFunctionReturn(0); 128947c6ae99SBarry Smith } 129047c6ae99SBarry Smith 129147c6ae99SBarry Smith #undef __FUNCT__ 1292aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray4" 12937087cfbeSBarry Smith PetscErrorCode DMDAGetAdicMFArray4(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof) 129447c6ae99SBarry Smith { 129547c6ae99SBarry Smith PetscErrorCode ierr; 129687130e5eSHong Zhang PetscInt j,i,xs,ys,xm,ym,itdof = 0; 129747c6ae99SBarry Smith char *iarray_start; 129847c6ae99SBarry Smith void **iptr = (void**)vptr; 129947c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 130047c6ae99SBarry Smith 130147c6ae99SBarry Smith PetscFunctionBegin; 130247c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 130347c6ae99SBarry Smith if (ghosted) { 1304aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 130547c6ae99SBarry Smith if (dd->admfarrayghostedin[i]) { 130647c6ae99SBarry Smith *iptr = dd->admfarrayghostedin[i]; 130747c6ae99SBarry Smith iarray_start = (char*)dd->admfstartghostedin[i]; 130847c6ae99SBarry Smith itdof = dd->ghostedtdof; 130947c6ae99SBarry Smith dd->admfarrayghostedin[i] = PETSC_NULL; 131047c6ae99SBarry Smith dd->admfstartghostedin[i] = PETSC_NULL; 131147c6ae99SBarry Smith 131247c6ae99SBarry Smith goto done; 131347c6ae99SBarry Smith } 131447c6ae99SBarry Smith } 131547c6ae99SBarry Smith xs = dd->Xs; 131647c6ae99SBarry Smith ys = dd->Ys; 131747c6ae99SBarry Smith xm = dd->Xe-dd->Xs; 131847c6ae99SBarry Smith ym = dd->Ye-dd->Ys; 131947c6ae99SBarry Smith } else { 1320aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 132147c6ae99SBarry Smith if (dd->admfarrayin[i]) { 132247c6ae99SBarry Smith *iptr = dd->admfarrayin[i]; 132347c6ae99SBarry Smith iarray_start = (char*)dd->admfstartin[i]; 132447c6ae99SBarry Smith itdof = dd->tdof; 132547c6ae99SBarry Smith dd->admfarrayin[i] = PETSC_NULL; 132647c6ae99SBarry Smith dd->admfstartin[i] = PETSC_NULL; 132747c6ae99SBarry Smith 132847c6ae99SBarry Smith goto done; 132947c6ae99SBarry Smith } 133047c6ae99SBarry Smith } 133147c6ae99SBarry Smith xs = dd->xs; 133247c6ae99SBarry Smith ys = dd->ys; 133347c6ae99SBarry Smith xm = dd->xe-dd->xs; 133447c6ae99SBarry Smith ym = dd->ye-dd->ys; 133547c6ae99SBarry Smith } 133647c6ae99SBarry Smith 133747c6ae99SBarry Smith switch (dd->dim) { 133847c6ae99SBarry Smith case 2: { 133947c6ae99SBarry Smith void **ptr; 134047c6ae99SBarry Smith itdof = xm*ym; 134147c6ae99SBarry Smith 134247c6ae99SBarry Smith ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*5*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 134347c6ae99SBarry Smith 134447c6ae99SBarry Smith ptr = (void**)(iarray_start + xm*ym*5*sizeof(PetscScalar) - ys*sizeof(void*)); 134547c6ae99SBarry Smith for(j=ys;j<ys+ym;j++) { 134647c6ae99SBarry Smith ptr[j] = iarray_start + 5*sizeof(PetscScalar)*(xm*(j-ys) - xs); 134747c6ae99SBarry Smith } 134847c6ae99SBarry Smith *iptr = (void*)ptr; 134947c6ae99SBarry Smith break;} 135047c6ae99SBarry Smith default: 135147c6ae99SBarry Smith SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim); 135247c6ae99SBarry Smith } 135347c6ae99SBarry Smith 135447c6ae99SBarry Smith done: 135547c6ae99SBarry Smith /* add arrays to the checked out list */ 135647c6ae99SBarry Smith if (ghosted) { 1357aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 135847c6ae99SBarry Smith if (!dd->admfarrayghostedout[i]) { 135947c6ae99SBarry Smith dd->admfarrayghostedout[i] = *iptr ; 136047c6ae99SBarry Smith dd->admfstartghostedout[i] = iarray_start; 136147c6ae99SBarry Smith dd->ghostedtdof = itdof; 136247c6ae99SBarry Smith break; 136347c6ae99SBarry Smith } 136447c6ae99SBarry Smith } 136547c6ae99SBarry Smith } else { 1366aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 136747c6ae99SBarry Smith if (!dd->admfarrayout[i]) { 136847c6ae99SBarry Smith dd->admfarrayout[i] = *iptr ; 136947c6ae99SBarry Smith dd->admfstartout[i] = iarray_start; 137047c6ae99SBarry Smith dd->tdof = itdof; 137147c6ae99SBarry Smith break; 137247c6ae99SBarry Smith } 137347c6ae99SBarry Smith } 137447c6ae99SBarry Smith } 1375aa219208SBarry Smith if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained"); 137647c6ae99SBarry Smith if (tdof) *tdof = itdof; 137747c6ae99SBarry Smith if (array_start) *(void**)array_start = iarray_start; 137847c6ae99SBarry Smith PetscFunctionReturn(0); 137947c6ae99SBarry Smith } 138047c6ae99SBarry Smith 138147c6ae99SBarry Smith #undef __FUNCT__ 1382aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray9" 13837087cfbeSBarry Smith PetscErrorCode DMDAGetAdicMFArray9(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof) 138447c6ae99SBarry Smith { 138547c6ae99SBarry Smith PetscErrorCode ierr; 138687130e5eSHong Zhang PetscInt j,i,xs,ys,xm,ym,itdof = 0; 138747c6ae99SBarry Smith char *iarray_start; 138847c6ae99SBarry Smith void **iptr = (void**)vptr; 138947c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 139047c6ae99SBarry Smith 139147c6ae99SBarry Smith PetscFunctionBegin; 139247c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 139347c6ae99SBarry Smith if (ghosted) { 1394aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 139547c6ae99SBarry Smith if (dd->admfarrayghostedin[i]) { 139647c6ae99SBarry Smith *iptr = dd->admfarrayghostedin[i]; 139747c6ae99SBarry Smith iarray_start = (char*)dd->admfstartghostedin[i]; 139847c6ae99SBarry Smith itdof = dd->ghostedtdof; 139947c6ae99SBarry Smith dd->admfarrayghostedin[i] = PETSC_NULL; 140047c6ae99SBarry Smith dd->admfstartghostedin[i] = PETSC_NULL; 140147c6ae99SBarry Smith 140247c6ae99SBarry Smith goto done; 140347c6ae99SBarry Smith } 140447c6ae99SBarry Smith } 140547c6ae99SBarry Smith xs = dd->Xs; 140647c6ae99SBarry Smith ys = dd->Ys; 140747c6ae99SBarry Smith xm = dd->Xe-dd->Xs; 140847c6ae99SBarry Smith ym = dd->Ye-dd->Ys; 140947c6ae99SBarry Smith } else { 1410aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 141147c6ae99SBarry Smith if (dd->admfarrayin[i]) { 141247c6ae99SBarry Smith *iptr = dd->admfarrayin[i]; 141347c6ae99SBarry Smith iarray_start = (char*)dd->admfstartin[i]; 141447c6ae99SBarry Smith itdof = dd->tdof; 141547c6ae99SBarry Smith dd->admfarrayin[i] = PETSC_NULL; 141647c6ae99SBarry Smith dd->admfstartin[i] = PETSC_NULL; 141747c6ae99SBarry Smith 141847c6ae99SBarry Smith goto done; 141947c6ae99SBarry Smith } 142047c6ae99SBarry Smith } 142147c6ae99SBarry Smith xs = dd->xs; 142247c6ae99SBarry Smith ys = dd->ys; 142347c6ae99SBarry Smith xm = dd->xe-dd->xs; 142447c6ae99SBarry Smith ym = dd->ye-dd->ys; 142547c6ae99SBarry Smith } 142647c6ae99SBarry Smith 142747c6ae99SBarry Smith switch (dd->dim) { 142847c6ae99SBarry Smith case 2: { 142947c6ae99SBarry Smith void **ptr; 143047c6ae99SBarry Smith itdof = xm*ym; 143147c6ae99SBarry Smith 143247c6ae99SBarry Smith ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*10*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 143347c6ae99SBarry Smith 143447c6ae99SBarry Smith ptr = (void**)(iarray_start + xm*ym*10*sizeof(PetscScalar) - ys*sizeof(void*)); 143547c6ae99SBarry Smith for(j=ys;j<ys+ym;j++) { 143647c6ae99SBarry Smith ptr[j] = iarray_start + 10*sizeof(PetscScalar)*(xm*(j-ys) - xs); 143747c6ae99SBarry Smith } 143847c6ae99SBarry Smith *iptr = (void*)ptr; 143947c6ae99SBarry Smith break;} 144047c6ae99SBarry Smith default: 144147c6ae99SBarry Smith SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim); 144247c6ae99SBarry Smith } 144347c6ae99SBarry Smith 144447c6ae99SBarry Smith done: 144547c6ae99SBarry Smith /* add arrays to the checked out list */ 144647c6ae99SBarry Smith if (ghosted) { 1447aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 144847c6ae99SBarry Smith if (!dd->admfarrayghostedout[i]) { 144947c6ae99SBarry Smith dd->admfarrayghostedout[i] = *iptr ; 145047c6ae99SBarry Smith dd->admfstartghostedout[i] = iarray_start; 145147c6ae99SBarry Smith dd->ghostedtdof = itdof; 145247c6ae99SBarry Smith break; 145347c6ae99SBarry Smith } 145447c6ae99SBarry Smith } 145547c6ae99SBarry Smith } else { 1456aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 145747c6ae99SBarry Smith if (!dd->admfarrayout[i]) { 145847c6ae99SBarry Smith dd->admfarrayout[i] = *iptr ; 145947c6ae99SBarry Smith dd->admfstartout[i] = iarray_start; 146047c6ae99SBarry Smith dd->tdof = itdof; 146147c6ae99SBarry Smith break; 146247c6ae99SBarry Smith } 146347c6ae99SBarry Smith } 146447c6ae99SBarry Smith } 1465aa219208SBarry Smith if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained"); 146647c6ae99SBarry Smith if (tdof) *tdof = itdof; 146747c6ae99SBarry Smith if (array_start) *(void**)array_start = iarray_start; 146847c6ae99SBarry Smith PetscFunctionReturn(0); 146947c6ae99SBarry Smith } 147047c6ae99SBarry Smith 147147c6ae99SBarry Smith #undef __FUNCT__ 1472aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArrayb" 147347c6ae99SBarry Smith /*@C 1474aa219208SBarry Smith DMDAGetAdicMFArrayb - Gets an array of derivative types for a DMDA for matrix-free ADIC. 147547c6ae99SBarry Smith 147647c6ae99SBarry Smith Input Parameter: 147747c6ae99SBarry Smith + da - information about my local patch 147847c6ae99SBarry Smith - ghosted - do you want arrays for the ghosted or nonghosted patch? 147947c6ae99SBarry Smith 148047c6ae99SBarry Smith Output Parameters: 148147c6ae99SBarry Smith + vptr - array data structured to be passed to ad_FormFunctionLocal() 148247c6ae99SBarry Smith . array_start - actual start of 1d array of all values that adiC can access directly (may be null) 148347c6ae99SBarry Smith - tdof - total number of degrees of freedom represented in array_start (may be null) 148447c6ae99SBarry Smith 148547c6ae99SBarry Smith Notes: 148647c6ae99SBarry Smith The vector values are NOT initialized and may have garbage in them, so you may need 148747c6ae99SBarry Smith to zero them. 148847c6ae99SBarry Smith 1489aa219208SBarry Smith This routine returns the same type of object as the DMDAVecGetArray(), except its 149047c6ae99SBarry Smith elements are derivative types instead of PetscScalars. 149147c6ae99SBarry Smith 149247c6ae99SBarry Smith Level: advanced 149347c6ae99SBarry Smith 1494aa219208SBarry Smith .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray() 149547c6ae99SBarry Smith 149647c6ae99SBarry Smith @*/ 14977087cfbeSBarry Smith PetscErrorCode DMDAGetAdicMFArrayb(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof) 149847c6ae99SBarry Smith { 149947c6ae99SBarry Smith PetscErrorCode ierr; 150047c6ae99SBarry Smith PetscInt j,i,xs,ys,xm,ym,zs,zm,itdof = 0; 150147c6ae99SBarry Smith char *iarray_start; 150247c6ae99SBarry Smith void **iptr = (void**)vptr; 150347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 150447c6ae99SBarry Smith PetscInt bs = dd->w,bs1 = bs+1; 150547c6ae99SBarry Smith 150647c6ae99SBarry Smith PetscFunctionBegin; 150747c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 150847c6ae99SBarry Smith if (ghosted) { 1509aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 151047c6ae99SBarry Smith if (dd->admfarrayghostedin[i]) { 151147c6ae99SBarry Smith *iptr = dd->admfarrayghostedin[i]; 151247c6ae99SBarry Smith iarray_start = (char*)dd->admfstartghostedin[i]; 151347c6ae99SBarry Smith itdof = dd->ghostedtdof; 151447c6ae99SBarry Smith dd->admfarrayghostedin[i] = PETSC_NULL; 151547c6ae99SBarry Smith dd->admfstartghostedin[i] = PETSC_NULL; 151647c6ae99SBarry Smith 151747c6ae99SBarry Smith goto done; 151847c6ae99SBarry Smith } 151947c6ae99SBarry Smith } 152047c6ae99SBarry Smith xs = dd->Xs; 152147c6ae99SBarry Smith ys = dd->Ys; 152247c6ae99SBarry Smith zs = dd->Zs; 152347c6ae99SBarry Smith xm = dd->Xe-dd->Xs; 152447c6ae99SBarry Smith ym = dd->Ye-dd->Ys; 152547c6ae99SBarry Smith zm = dd->Ze-dd->Zs; 152647c6ae99SBarry Smith } else { 1527aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 152847c6ae99SBarry Smith if (dd->admfarrayin[i]) { 152947c6ae99SBarry Smith *iptr = dd->admfarrayin[i]; 153047c6ae99SBarry Smith iarray_start = (char*)dd->admfstartin[i]; 153147c6ae99SBarry Smith itdof = dd->tdof; 153247c6ae99SBarry Smith dd->admfarrayin[i] = PETSC_NULL; 153347c6ae99SBarry Smith dd->admfstartin[i] = PETSC_NULL; 153447c6ae99SBarry Smith 153547c6ae99SBarry Smith goto done; 153647c6ae99SBarry Smith } 153747c6ae99SBarry Smith } 153847c6ae99SBarry Smith xs = dd->xs; 153947c6ae99SBarry Smith ys = dd->ys; 154047c6ae99SBarry Smith zs = dd->zs; 154147c6ae99SBarry Smith xm = dd->xe-dd->xs; 154247c6ae99SBarry Smith ym = dd->ye-dd->ys; 154347c6ae99SBarry Smith zm = dd->ze-dd->zs; 154447c6ae99SBarry Smith } 154547c6ae99SBarry Smith 154647c6ae99SBarry Smith switch (dd->dim) { 154747c6ae99SBarry Smith case 1: { 154847c6ae99SBarry Smith void *ptr; 154947c6ae99SBarry Smith itdof = xm; 155047c6ae99SBarry Smith 155147c6ae99SBarry Smith ierr = PetscMalloc(xm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 155247c6ae99SBarry Smith 155347c6ae99SBarry Smith ptr = (void*)(iarray_start - xs*bs1*sizeof(PetscScalar)); 155447c6ae99SBarry Smith *iptr = (void*)ptr; 155547c6ae99SBarry Smith break;} 155647c6ae99SBarry Smith case 2: { 155747c6ae99SBarry Smith void **ptr; 155847c6ae99SBarry Smith itdof = xm*ym; 155947c6ae99SBarry Smith 156047c6ae99SBarry Smith ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 156147c6ae99SBarry Smith 156247c6ae99SBarry Smith ptr = (void**)(iarray_start + xm*ym*bs1*sizeof(PetscScalar) - ys*sizeof(void*)); 156347c6ae99SBarry Smith for(j=ys;j<ys+ym;j++) { 156447c6ae99SBarry Smith ptr[j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*(j-ys) - xs); 156547c6ae99SBarry Smith } 156647c6ae99SBarry Smith *iptr = (void*)ptr; 156747c6ae99SBarry Smith break;} 156847c6ae99SBarry Smith case 3: { 156947c6ae99SBarry Smith void ***ptr,**bptr; 157047c6ae99SBarry Smith itdof = xm*ym*zm; 157147c6ae99SBarry Smith 157247c6ae99SBarry Smith ierr = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 157347c6ae99SBarry Smith 157447c6ae99SBarry Smith ptr = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*)); 157547c6ae99SBarry Smith bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**)); 157647c6ae99SBarry Smith for(i=zs;i<zs+zm;i++) { 157747c6ae99SBarry Smith ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*); 157847c6ae99SBarry Smith } 157947c6ae99SBarry Smith for (i=zs; i<zs+zm; i++) { 158047c6ae99SBarry Smith for (j=ys; j<ys+ym; j++) { 158147c6ae99SBarry Smith ptr[i][j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs); 158247c6ae99SBarry Smith } 158347c6ae99SBarry Smith } 158447c6ae99SBarry Smith 158547c6ae99SBarry Smith *iptr = (void*)ptr; 158647c6ae99SBarry Smith break;} 158747c6ae99SBarry Smith default: 158847c6ae99SBarry Smith SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim); 158947c6ae99SBarry Smith } 159047c6ae99SBarry Smith 159147c6ae99SBarry Smith done: 159247c6ae99SBarry Smith /* add arrays to the checked out list */ 159347c6ae99SBarry Smith if (ghosted) { 1594aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 159547c6ae99SBarry Smith if (!dd->admfarrayghostedout[i]) { 159647c6ae99SBarry Smith dd->admfarrayghostedout[i] = *iptr ; 159747c6ae99SBarry Smith dd->admfstartghostedout[i] = iarray_start; 159847c6ae99SBarry Smith dd->ghostedtdof = itdof; 159947c6ae99SBarry Smith break; 160047c6ae99SBarry Smith } 160147c6ae99SBarry Smith } 160247c6ae99SBarry Smith } else { 1603aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 160447c6ae99SBarry Smith if (!dd->admfarrayout[i]) { 160547c6ae99SBarry Smith dd->admfarrayout[i] = *iptr ; 160647c6ae99SBarry Smith dd->admfstartout[i] = iarray_start; 160747c6ae99SBarry Smith dd->tdof = itdof; 160847c6ae99SBarry Smith break; 160947c6ae99SBarry Smith } 161047c6ae99SBarry Smith } 161147c6ae99SBarry Smith } 1612aa219208SBarry Smith if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained"); 161347c6ae99SBarry Smith if (tdof) *tdof = itdof; 161447c6ae99SBarry Smith if (array_start) *(void**)array_start = iarray_start; 161547c6ae99SBarry Smith PetscFunctionReturn(0); 161647c6ae99SBarry Smith } 161747c6ae99SBarry Smith 161847c6ae99SBarry Smith #undef __FUNCT__ 1619aa219208SBarry Smith #define __FUNCT__ "DMDARestoreAdicMFArray" 162047c6ae99SBarry Smith /*@C 1621aa219208SBarry Smith DMDARestoreAdicMFArray - Restores an array of derivative types for a DMDA. 162247c6ae99SBarry Smith 162347c6ae99SBarry Smith Input Parameter: 162447c6ae99SBarry Smith + da - information about my local patch 162547c6ae99SBarry Smith - ghosted - do you want arrays for the ghosted or nonghosted patch? 162647c6ae99SBarry Smith 162747c6ae99SBarry Smith Output Parameters: 162847c6ae99SBarry Smith + ptr - array data structure to be passed to ad_FormFunctionLocal() 162947c6ae99SBarry Smith . array_start - actual start of 1d array of all values that adiC can access directly 163047c6ae99SBarry Smith - tdof - total number of degrees of freedom represented in array_start 163147c6ae99SBarry Smith 163247c6ae99SBarry Smith Level: advanced 163347c6ae99SBarry Smith 1634aa219208SBarry Smith .seealso: DMDAGetAdicArray() 163547c6ae99SBarry Smith 163647c6ae99SBarry Smith @*/ 16377087cfbeSBarry Smith PetscErrorCode DMDARestoreAdicMFArray(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof) 163847c6ae99SBarry Smith { 163947c6ae99SBarry Smith PetscInt i; 164047c6ae99SBarry Smith void **iptr = (void**)vptr,*iarray_start = 0; 164147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 164247c6ae99SBarry Smith 164347c6ae99SBarry Smith PetscFunctionBegin; 164447c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 164547c6ae99SBarry Smith if (ghosted) { 1646aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 164747c6ae99SBarry Smith if (dd->admfarrayghostedout[i] == *iptr) { 164847c6ae99SBarry Smith iarray_start = dd->admfstartghostedout[i]; 164947c6ae99SBarry Smith dd->admfarrayghostedout[i] = PETSC_NULL; 165047c6ae99SBarry Smith dd->admfstartghostedout[i] = PETSC_NULL; 165147c6ae99SBarry Smith break; 165247c6ae99SBarry Smith } 165347c6ae99SBarry Smith } 165447c6ae99SBarry Smith if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list"); 1655aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 165647c6ae99SBarry Smith if (!dd->admfarrayghostedin[i]){ 165747c6ae99SBarry Smith dd->admfarrayghostedin[i] = *iptr; 165847c6ae99SBarry Smith dd->admfstartghostedin[i] = iarray_start; 165947c6ae99SBarry Smith break; 166047c6ae99SBarry Smith } 166147c6ae99SBarry Smith } 166247c6ae99SBarry Smith } else { 1663aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 166447c6ae99SBarry Smith if (dd->admfarrayout[i] == *iptr) { 166547c6ae99SBarry Smith iarray_start = dd->admfstartout[i]; 166647c6ae99SBarry Smith dd->admfarrayout[i] = PETSC_NULL; 166747c6ae99SBarry Smith dd->admfstartout[i] = PETSC_NULL; 166847c6ae99SBarry Smith break; 166947c6ae99SBarry Smith } 167047c6ae99SBarry Smith } 167147c6ae99SBarry Smith if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list"); 1672aa219208SBarry Smith for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 167347c6ae99SBarry Smith if (!dd->admfarrayin[i]){ 167447c6ae99SBarry Smith dd->admfarrayin[i] = *iptr; 167547c6ae99SBarry Smith dd->admfstartin[i] = iarray_start; 167647c6ae99SBarry Smith break; 167747c6ae99SBarry Smith } 167847c6ae99SBarry Smith } 167947c6ae99SBarry Smith } 168047c6ae99SBarry Smith PetscFunctionReturn(0); 168147c6ae99SBarry Smith } 168247c6ae99SBarry Smith 168347c6ae99SBarry Smith #undef __FUNCT__ 168447c6ae99SBarry Smith #define __FUNCT__ "admf_DAGetArray" 16857087cfbeSBarry Smith PetscErrorCode admf_DAGetArray(DM da,PetscBool ghosted,void *iptr) 168647c6ae99SBarry Smith { 168747c6ae99SBarry Smith PetscErrorCode ierr; 168847c6ae99SBarry Smith PetscFunctionBegin; 1689aa219208SBarry Smith ierr = DMDAGetAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr); 169047c6ae99SBarry Smith PetscFunctionReturn(0); 169147c6ae99SBarry Smith } 169247c6ae99SBarry Smith 169347c6ae99SBarry Smith #undef __FUNCT__ 169447c6ae99SBarry Smith #define __FUNCT__ "admf_DARestoreArray" 16957087cfbeSBarry Smith PetscErrorCode admf_DARestoreArray(DM da,PetscBool ghosted,void *iptr) 169647c6ae99SBarry Smith { 169747c6ae99SBarry Smith PetscErrorCode ierr; 169847c6ae99SBarry Smith PetscFunctionBegin; 1699aa219208SBarry Smith ierr = DMDARestoreAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr); 170047c6ae99SBarry Smith PetscFunctionReturn(0); 170147c6ae99SBarry Smith } 170247c6ae99SBarry Smith 1703