1 2 /* 3 Code for manipulating distributed regular arrays in parallel. 4 */ 5 6 #include <petsc-private/dmdaimpl.h> /*I "petscdmda.h" I*/ 7 #include <petscsf.h> 8 9 /* 10 This allows the DMDA vectors to properly tell MATLAB their dimensions 11 */ 12 #if defined(PETSC_HAVE_MATLAB_ENGINE) 13 #include <engine.h> /* MATLAB include file */ 14 #include <mex.h> /* MATLAB include file */ 15 #undef __FUNCT__ 16 #define __FUNCT__ "VecMatlabEnginePut_DA2d" 17 static PetscErrorCode VecMatlabEnginePut_DA2d(PetscObject obj,void *mengine) 18 { 19 PetscErrorCode ierr; 20 PetscInt n,m; 21 Vec vec = (Vec)obj; 22 PetscScalar *array; 23 mxArray *mat; 24 DM da; 25 26 PetscFunctionBegin; 27 ierr = VecGetDM(vec, &da);CHKERRQ(ierr); 28 if (!da) SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_ARG_WRONGSTATE,"Vector not associated with a DMDA"); 29 ierr = DMDAGetGhostCorners(da,0,0,0,&m,&n,0);CHKERRQ(ierr); 30 31 ierr = VecGetArray(vec,&array);CHKERRQ(ierr); 32 #if !defined(PETSC_USE_COMPLEX) 33 mat = mxCreateDoubleMatrix(m,n,mxREAL); 34 #else 35 mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX); 36 #endif 37 ierr = PetscMemcpy(mxGetPr(mat),array,n*m*sizeof(PetscScalar));CHKERRQ(ierr); 38 ierr = PetscObjectName(obj);CHKERRQ(ierr); 39 engPutVariable((Engine*)mengine,obj->name,mat); 40 41 ierr = VecRestoreArray(vec,&array);CHKERRQ(ierr); 42 PetscFunctionReturn(0); 43 } 44 #endif 45 46 47 #undef __FUNCT__ 48 #define __FUNCT__ "DMCreateLocalVector_DA" 49 PetscErrorCode DMCreateLocalVector_DA(DM da,Vec *g) 50 { 51 PetscErrorCode ierr; 52 DM_DA *dd = (DM_DA*)da->data; 53 54 PetscFunctionBegin; 55 PetscValidHeaderSpecific(da,DM_CLASSID,1); 56 PetscValidPointer(g,2); 57 if (da->defaultSection) { 58 ierr = DMCreateLocalVector_Section_Private(da,g);CHKERRQ(ierr); 59 } else { 60 ierr = VecCreate(PETSC_COMM_SELF,g);CHKERRQ(ierr); 61 ierr = VecSetSizes(*g,dd->nlocal,PETSC_DETERMINE);CHKERRQ(ierr); 62 ierr = VecSetBlockSize(*g,dd->w);CHKERRQ(ierr); 63 ierr = VecSetType(*g,da->vectype);CHKERRQ(ierr); 64 ierr = VecSetDM(*g, da);CHKERRQ(ierr); 65 #if defined(PETSC_HAVE_MATLAB_ENGINE) 66 if (dd->w == 1 && dd->dim == 2) { 67 ierr = PetscObjectComposeFunction((PetscObject)*g,"PetscMatlabEnginePut_C",VecMatlabEnginePut_DA2d);CHKERRQ(ierr); 68 } 69 #endif 70 } 71 PetscFunctionReturn(0); 72 } 73 74 #undef __FUNCT__ 75 #define __FUNCT__ "DMDAGetNumCells" 76 PetscErrorCode DMDAGetNumCells(DM dm, PetscInt *numCellsX, PetscInt *numCellsY, PetscInt *numCellsZ, PetscInt *numCells) 77 { 78 DM_DA *da = (DM_DA*) dm->data; 79 const PetscInt dim = da->dim; 80 const PetscInt mx = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs; 81 const PetscInt nC = (mx)*(dim > 1 ? (my)*(dim > 2 ? (mz) : 1) : 1); 82 83 PetscFunctionBegin; 84 if (numCellsX) { 85 PetscValidIntPointer(numCellsX,2); 86 *numCellsX = mx; 87 } 88 if (numCellsY) { 89 PetscValidIntPointer(numCellsX,3); 90 *numCellsY = my; 91 } 92 if (numCellsZ) { 93 PetscValidIntPointer(numCellsX,4); 94 *numCellsZ = mz; 95 } 96 if (numCells) { 97 PetscValidIntPointer(numCells,5); 98 *numCells = nC; 99 } 100 PetscFunctionReturn(0); 101 } 102 103 #undef __FUNCT__ 104 #define __FUNCT__ "DMDAGetNumVertices" 105 PetscErrorCode DMDAGetNumVertices(DM dm, PetscInt *numVerticesX, PetscInt *numVerticesY, PetscInt *numVerticesZ, PetscInt *numVertices) 106 { 107 DM_DA *da = (DM_DA*) dm->data; 108 const PetscInt dim = da->dim; 109 const PetscInt mx = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs; 110 const PetscInt nVx = mx+1; 111 const PetscInt nVy = dim > 1 ? (my+1) : 1; 112 const PetscInt nVz = dim > 2 ? (mz+1) : 1; 113 const PetscInt nV = nVx*nVy*nVz; 114 115 PetscFunctionBegin; 116 if (numVerticesX) { 117 PetscValidIntPointer(numVerticesX,2); 118 *numVerticesX = nVx; 119 } 120 if (numVerticesY) { 121 PetscValidIntPointer(numVerticesY,3); 122 *numVerticesY = nVy; 123 } 124 if (numVerticesZ) { 125 PetscValidIntPointer(numVerticesZ,4); 126 *numVerticesZ = nVz; 127 } 128 if (numVertices) { 129 PetscValidIntPointer(numVertices,5); 130 *numVertices = nV; 131 } 132 PetscFunctionReturn(0); 133 } 134 135 #undef __FUNCT__ 136 #define __FUNCT__ "DMDAGetNumFaces" 137 PetscErrorCode DMDAGetNumFaces(DM dm, PetscInt *numXFacesX, PetscInt *numXFaces, PetscInt *numYFacesY, PetscInt *numYFaces, PetscInt *numZFacesZ, PetscInt *numZFaces) 138 { 139 DM_DA *da = (DM_DA*) dm->data; 140 const PetscInt dim = da->dim; 141 const PetscInt mx = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs; 142 const PetscInt nxF = (dim > 1 ? (my)*(dim > 2 ? (mz) : 1) : 1); 143 const PetscInt nXF = (mx+1)*nxF; 144 const PetscInt nyF = mx*(dim > 2 ? mz : 1); 145 const PetscInt nYF = dim > 1 ? (my+1)*nyF : 0; 146 const PetscInt nzF = mx*(dim > 1 ? my : 0); 147 const PetscInt nZF = dim > 2 ? (mz+1)*nzF : 0; 148 149 PetscFunctionBegin; 150 if (numXFacesX) { 151 PetscValidIntPointer(numXFacesX,2); 152 *numXFacesX = nxF; 153 } 154 if (numXFaces) { 155 PetscValidIntPointer(numXFaces,3); 156 *numXFaces = nXF; 157 } 158 if (numYFacesY) { 159 PetscValidIntPointer(numYFacesY,4); 160 *numYFacesY = nyF; 161 } 162 if (numYFaces) { 163 PetscValidIntPointer(numYFaces,5); 164 *numYFaces = nYF; 165 } 166 if (numZFacesZ) { 167 PetscValidIntPointer(numZFacesZ,6); 168 *numZFacesZ = nzF; 169 } 170 if (numZFaces) { 171 PetscValidIntPointer(numZFaces,7); 172 *numZFaces = nZF; 173 } 174 PetscFunctionReturn(0); 175 } 176 177 #undef __FUNCT__ 178 #define __FUNCT__ "DMDAGetHeightStratum" 179 PetscErrorCode DMDAGetHeightStratum(DM dm, PetscInt height, PetscInt *pStart, PetscInt *pEnd) 180 { 181 DM_DA *da = (DM_DA*) dm->data; 182 const PetscInt dim = da->dim; 183 PetscInt nC, nV, nXF, nYF, nZF; 184 PetscErrorCode ierr; 185 186 PetscFunctionBegin; 187 if (pStart) PetscValidIntPointer(pStart,3); 188 if (pEnd) PetscValidIntPointer(pEnd,4); 189 ierr = DMDAGetNumCells(dm, NULL, NULL, NULL, &nC);CHKERRQ(ierr); 190 ierr = DMDAGetNumVertices(dm, NULL, NULL, NULL, &nV);CHKERRQ(ierr); 191 ierr = DMDAGetNumFaces(dm, NULL, &nXF, NULL, &nYF, NULL, &nZF);CHKERRQ(ierr); 192 if (height == 0) { 193 /* Cells */ 194 if (pStart) *pStart = 0; 195 if (pEnd) *pEnd = nC; 196 } else if (height == 1) { 197 /* Faces */ 198 if (pStart) *pStart = nC+nV; 199 if (pEnd) *pEnd = nC+nV+nXF+nYF+nZF; 200 } else if (height == dim) { 201 /* Vertices */ 202 if (pStart) *pStart = nC; 203 if (pEnd) *pEnd = nC+nV; 204 } else if (height < 0) { 205 /* All points */ 206 if (pStart) *pStart = 0; 207 if (pEnd) *pEnd = nC+nV+nXF+nYF+nZF; 208 } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "No points of height %d in the DA", height); 209 PetscFunctionReturn(0); 210 } 211 212 #undef __FUNCT__ 213 #define __FUNCT__ "DMDAGetDepthStratum" 214 PetscErrorCode DMDAGetDepthStratum(DM dm, PetscInt depth, PetscInt *pStart, PetscInt *pEnd) 215 { 216 DM_DA *da = (DM_DA*) dm->data; 217 const PetscInt dim = da->dim; 218 PetscInt nC, nV, nXF, nYF, nZF; 219 PetscErrorCode ierr; 220 221 PetscFunctionBegin; 222 if (pStart) PetscValidIntPointer(pStart,3); 223 if (pEnd) PetscValidIntPointer(pEnd,4); 224 ierr = DMDAGetNumCells(dm, NULL, NULL, NULL, &nC);CHKERRQ(ierr); 225 ierr = DMDAGetNumVertices(dm, NULL, NULL, NULL, &nV);CHKERRQ(ierr); 226 ierr = DMDAGetNumFaces(dm, NULL, &nXF, NULL, &nYF, NULL, &nZF);CHKERRQ(ierr); 227 if (depth == dim) { 228 /* Cells */ 229 if (pStart) *pStart = 0; 230 if (pEnd) *pEnd = nC; 231 } else if (depth == dim-1) { 232 /* Faces */ 233 if (pStart) *pStart = nC+nV; 234 if (pEnd) *pEnd = nC+nV+nXF+nYF+nZF; 235 } else if (depth == 0) { 236 /* Vertices */ 237 if (pStart) *pStart = nC; 238 if (pEnd) *pEnd = nC+nV; 239 } else if (depth < 0) { 240 /* All points */ 241 if (pStart) *pStart = 0; 242 if (pEnd) *pEnd = nC+nV+nXF+nYF+nZF; 243 } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "No points of depth %d in the DA", depth); 244 PetscFunctionReturn(0); 245 } 246 247 #undef __FUNCT__ 248 #define __FUNCT__ "DMDAGetConeSize" 249 PetscErrorCode DMDAGetConeSize(DM dm, PetscInt p, PetscInt *coneSize) 250 { 251 DM_DA *da = (DM_DA*) dm->data; 252 const PetscInt dim = da->dim; 253 PetscInt nC, nV, nXF, nYF, nZF; 254 PetscErrorCode ierr; 255 256 PetscFunctionBegin; 257 *coneSize = 0; 258 ierr = DMDAGetNumCells(dm, NULL, NULL, NULL, &nC);CHKERRQ(ierr); 259 ierr = DMDAGetNumVertices(dm, NULL, NULL, NULL, &nV);CHKERRQ(ierr); 260 ierr = DMDAGetNumFaces(dm, NULL, &nXF, NULL, &nYF, NULL, &nZF);CHKERRQ(ierr); 261 switch (dim) { 262 case 2: 263 if (p >= 0) { 264 if (p < nC) { 265 *coneSize = 4; 266 } else if (p < nC+nV) { 267 *coneSize = 0; 268 } else if (p < nC+nV+nXF+nYF+nZF) { 269 *coneSize = 2; 270 } else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point %d should be in [0, %d)", p, nC+nV+nXF+nYF+nZF); 271 } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative point %d is invalid", p); 272 break; 273 case 3: 274 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Too lazy to do 3D"); 275 break; 276 } 277 PetscFunctionReturn(0); 278 } 279 280 #undef __FUNCT__ 281 #define __FUNCT__ "DMDAGetCone" 282 PetscErrorCode DMDAGetCone(DM dm, PetscInt p, PetscInt *cone[]) 283 { 284 DM_DA *da = (DM_DA*) dm->data; 285 const PetscInt dim = da->dim; 286 PetscInt nCx, nCy, nCz, nC, nVx, nVy, nVz, nV, nxF, nyF, nzF, nXF, nYF, nZF; 287 PetscErrorCode ierr; 288 289 PetscFunctionBegin; 290 if (!cone) {ierr = DMGetWorkArray(dm, 6, PETSC_INT, cone);CHKERRQ(ierr);} 291 ierr = DMDAGetNumCells(dm, &nCx, &nCy, &nCz, &nC);CHKERRQ(ierr); 292 ierr = DMDAGetNumVertices(dm, &nVx, &nVy, &nVz, &nV);CHKERRQ(ierr); 293 ierr = DMDAGetNumFaces(dm, &nxF, &nXF, &nyF, &nYF, &nzF, &nZF);CHKERRQ(ierr); 294 switch (dim) { 295 case 2: 296 if (p >= 0) { 297 if (p < nC) { 298 const PetscInt cy = p / nCx; 299 const PetscInt cx = p % nCx; 300 301 (*cone)[0] = cy*nxF + cx + nC+nV; 302 (*cone)[1] = cx*nyF + cy + nyF + nC+nV+nXF; 303 (*cone)[2] = cy*nxF + cx + nxF + nC+nV; 304 (*cone)[3] = cx*nyF + cy + nC+nV+nXF; 305 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Too lazy to do cell cones"); 306 } else if (p < nC+nV) { 307 } else if (p < nC+nV+nXF) { 308 const PetscInt fy = (p - nC+nV) / nxF; 309 const PetscInt fx = (p - nC+nV) % nxF; 310 311 (*cone)[0] = fy*nVx + fx + nC; 312 (*cone)[1] = fy*nVx + fx + 1 + nC; 313 } else if (p < nC+nV+nXF+nYF) { 314 const PetscInt fx = (p - nC+nV+nXF) / nyF; 315 const PetscInt fy = (p - nC+nV+nXF) % nyF; 316 317 (*cone)[0] = fy*nVx + fx + nC; 318 (*cone)[1] = fy*nVx + fx + nVx + nC; 319 } else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point %d should be in [0, %d)", p, nC+nV+nXF+nYF+nZF); 320 } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative point %d is invalid", p); 321 break; 322 case 3: 323 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Too lazy to do 3D"); 324 break; 325 } 326 PetscFunctionReturn(0); 327 } 328 329 #undef __FUNCT__ 330 #define __FUNCT__ "DMDARestoreCone" 331 PetscErrorCode DMDARestoreCone(DM dm, PetscInt p, PetscInt *cone[]) 332 { 333 PetscErrorCode ierr; 334 335 PetscFunctionBegin; 336 ierr = DMGetWorkArray(dm, 6, PETSC_INT, cone);CHKERRQ(ierr); 337 PetscFunctionReturn(0); 338 } 339 340 #undef __FUNCT__ 341 #define __FUNCT__ "DMDACreateSection" 342 /*@C 343 DMDACreateSection - Create a PetscSection inside the DMDA that describes data layout. This allows multiple fields with 344 different numbers of dofs on vertices, cells, and faces in each direction. 345 346 Input Parameters: 347 + dm- The DMDA 348 . numFields - The number of fields 349 . numComp - The number of components in each field, or NULL for 1 350 . numVertexDof - The number of dofs per vertex for each field, or NULL 351 . numFaceDof - The number of dofs per face for each field and direction, or NULL 352 - numCellDof - The number of dofs per cell for each field, or NULL 353 354 Level: developer 355 356 Note: 357 The default DMDA numbering is as follows: 358 359 - Cells: [0, nC) 360 - Vertices: [nC, nC+nV) 361 - X-Faces: [nC+nV, nC+nV+nXF) normal is +- x-dir 362 - Y-Faces: [nC+nV+nXF, nC+nV+nXF+nYF) normal is +- y-dir 363 - Z-Faces: [nC+nV+nXF+nYF, nC+nV+nXF+nYF+nZF) normal is +- z-dir 364 365 We interpret the default DMDA partition as a cell partition, and the data assignment as a cell assignment. 366 @*/ 367 PetscErrorCode DMDACreateSection(DM dm, PetscInt numComp[], PetscInt numVertexDof[], PetscInt numFaceDof[], PetscInt numCellDof[]) 368 { 369 DM_DA *da = (DM_DA*) dm->data; 370 PetscSection section; 371 const PetscInt dim = da->dim; 372 PetscInt numFields, numVertexTotDof = 0, numCellTotDof = 0, numFaceTotDof[3] = {0, 0, 0}; 373 PetscSF sf; 374 PetscMPIInt rank; 375 const PetscMPIInt *neighbors; 376 PetscInt *localPoints; 377 PetscSFNode *remotePoints; 378 PetscInt nleaves = 0, nleavesCheck = 0, nL = 0; 379 PetscInt nC, nVx, nVy, nVz, nV, nxF, nXF, nyF, nYF, nzF, nZF; 380 PetscInt pStart, pEnd, cStart, cEnd, vStart, vEnd, fStart, fEnd, xfStart, xfEnd, yfStart, yfEnd, zfStart, zfEnd; 381 PetscInt f, v, c, xf, yf, zf, xn, yn, zn; 382 PetscErrorCode ierr; 383 384 PetscFunctionBegin; 385 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 386 PetscValidPointer(s, 4); 387 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr); 388 ierr = DMDAGetNumCells(dm, NULL, NULL, NULL, &nC);CHKERRQ(ierr); 389 ierr = DMDAGetNumVertices(dm, &nVx, &nVy, &nVz, &nV);CHKERRQ(ierr); 390 ierr = DMDAGetNumFaces(dm, &nxF, &nXF, &nyF, &nYF, &nzF, &nZF);CHKERRQ(ierr); 391 ierr = DMDAGetHeightStratum(dm, -1, &pStart, &pEnd);CHKERRQ(ierr); 392 ierr = DMDAGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 393 ierr = DMDAGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 394 ierr = DMDAGetHeightStratum(dm, dim, &vStart, &vEnd);CHKERRQ(ierr); 395 xfStart = vEnd; xfEnd = xfStart+nXF; 396 yfStart = xfEnd; yfEnd = yfStart+nYF; 397 zfStart = yfEnd; zfEnd = zfStart+nZF; 398 if (zfEnd != fEnd) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Invalid face end %d, should be %d", zfEnd, fEnd); 399 /* Create local section */ 400 ierr = DMDAGetInfo(dm, 0,0,0,0,0,0,0, &numFields, 0,0,0,0,0);CHKERRQ(ierr); 401 for (f = 0; f < numFields; ++f) { 402 if (numVertexDof) numVertexTotDof += numVertexDof[f]; 403 if (numCellDof) numCellTotDof += numCellDof[f]; 404 if (numFaceDof) { 405 numFaceTotDof[0] += numFaceDof[f*dim+0]; 406 numFaceTotDof[1] += dim > 1 ? numFaceDof[f*dim+1] : 0; 407 numFaceTotDof[2] += dim > 2 ? numFaceDof[f*dim+2] : 0; 408 } 409 } 410 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 411 if (numFields > 1) { 412 ierr = PetscSectionSetNumFields(section, numFields);CHKERRQ(ierr); 413 for (f = 0; f < numFields; ++f) { 414 const char *name; 415 416 ierr = DMDAGetFieldName(dm, f, &name);CHKERRQ(ierr); 417 ierr = PetscSectionSetFieldName(section, f, name);CHKERRQ(ierr); 418 if (numComp) { 419 ierr = PetscSectionSetFieldComponents(section, f, numComp[f]);CHKERRQ(ierr); 420 } 421 } 422 } else { 423 numFields = 0; 424 } 425 ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 426 if (numVertexDof) { 427 for (v = vStart; v < vEnd; ++v) { 428 for (f = 0; f < numFields; ++f) { 429 ierr = PetscSectionSetFieldDof(section, v, f, numVertexDof[f]);CHKERRQ(ierr); 430 } 431 ierr = PetscSectionSetDof(section, v, numVertexTotDof);CHKERRQ(ierr); 432 } 433 } 434 if (numFaceDof) { 435 for (xf = xfStart; xf < xfEnd; ++xf) { 436 for (f = 0; f < numFields; ++f) { 437 ierr = PetscSectionSetFieldDof(section, xf, f, numFaceDof[f*dim+0]);CHKERRQ(ierr); 438 } 439 ierr = PetscSectionSetDof(section, xf, numFaceTotDof[0]);CHKERRQ(ierr); 440 } 441 for (yf = yfStart; yf < yfEnd; ++yf) { 442 for (f = 0; f < numFields; ++f) { 443 ierr = PetscSectionSetFieldDof(section, yf, f, numFaceDof[f*dim+1]);CHKERRQ(ierr); 444 } 445 ierr = PetscSectionSetDof(section, yf, numFaceTotDof[1]);CHKERRQ(ierr); 446 } 447 for (zf = zfStart; zf < zfEnd; ++zf) { 448 for (f = 0; f < numFields; ++f) { 449 ierr = PetscSectionSetFieldDof(section, zf, f, numFaceDof[f*dim+2]);CHKERRQ(ierr); 450 } 451 ierr = PetscSectionSetDof(section, zf, numFaceTotDof[2]);CHKERRQ(ierr); 452 } 453 } 454 if (numCellDof) { 455 for (c = cStart; c < cEnd; ++c) { 456 for (f = 0; f < numFields; ++f) { 457 ierr = PetscSectionSetFieldDof(section, c, f, numCellDof[f]);CHKERRQ(ierr); 458 } 459 ierr = PetscSectionSetDof(section, c, numCellTotDof);CHKERRQ(ierr); 460 } 461 } 462 ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 463 /* Create mesh point SF */ 464 ierr = DMDAGetNeighbors(dm, &neighbors);CHKERRQ(ierr); 465 for (zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) { 466 for (yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) { 467 for (xn = 0; xn < 3; ++xn) { 468 const PetscInt xp = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0; 469 const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn]; 470 471 if (neighbor >= 0 && neighbor < rank) { 472 nleaves += (!xp ? nVx : 1) * (!yp ? nVy : 1) * (!zp ? nVz : 1); /* vertices */ 473 if (xp && !yp && !zp) { 474 nleaves += nxF; /* x faces */ 475 } else if (yp && !zp && !xp) { 476 nleaves += nyF; /* y faces */ 477 } else if (zp && !xp && !yp) { 478 nleaves += nzF; /* z faces */ 479 } 480 } 481 } 482 } 483 } 484 ierr = PetscMalloc2(nleaves,&localPoints,nleaves,&remotePoints);CHKERRQ(ierr); 485 for (zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) { 486 for (yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) { 487 for (xn = 0; xn < 3; ++xn) { 488 const PetscInt xp = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0; 489 const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn]; 490 PetscInt xv, yv, zv; 491 492 if (neighbor >= 0 && neighbor < rank) { 493 if (xp < 0) { /* left */ 494 if (yp < 0) { /* bottom */ 495 if (zp < 0) { /* back */ 496 const PetscInt localVertex = ( 0*nVy + 0)*nVx + 0 + nC; 497 const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 498 nleavesCheck += 1; /* left bottom back vertex */ 499 500 localPoints[nL] = localVertex; 501 remotePoints[nL].rank = neighbor; 502 remotePoints[nL].index = remoteVertex; 503 ++nL; 504 } else if (zp > 0) { /* front */ 505 const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + 0 + nC; 506 const PetscInt remoteVertex = ( 0*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 507 nleavesCheck += 1; /* left bottom front vertex */ 508 509 localPoints[nL] = localVertex; 510 remotePoints[nL].rank = neighbor; 511 remotePoints[nL].index = remoteVertex; 512 ++nL; 513 } else { 514 nleavesCheck += nVz; /* left bottom vertices */ 515 for (zv = 0; zv < nVz; ++zv, ++nL) { 516 const PetscInt localVertex = (zv*nVy + 0)*nVx + 0 + nC; 517 const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 518 519 localPoints[nL] = localVertex; 520 remotePoints[nL].rank = neighbor; 521 remotePoints[nL].index = remoteVertex; 522 } 523 } 524 } else if (yp > 0) { /* top */ 525 if (zp < 0) { /* back */ 526 const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + 0 + nC; 527 const PetscInt remoteVertex = ((nVz-1)*nVy + 0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 528 nleavesCheck += 1; /* left top back vertex */ 529 530 localPoints[nL] = localVertex; 531 remotePoints[nL].rank = neighbor; 532 remotePoints[nL].index = remoteVertex; 533 ++nL; 534 } else if (zp > 0) { /* front */ 535 const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + 0 + nC; 536 const PetscInt remoteVertex = ( 0*nVy + 0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 537 nleavesCheck += 1; /* left top front vertex */ 538 539 localPoints[nL] = localVertex; 540 remotePoints[nL].rank = neighbor; 541 remotePoints[nL].index = remoteVertex; 542 ++nL; 543 } else { 544 nleavesCheck += nVz; /* left top vertices */ 545 for (zv = 0; zv < nVz; ++zv, ++nL) { 546 const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + 0 + nC; 547 const PetscInt remoteVertex = (zv*nVy + 0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 548 549 localPoints[nL] = localVertex; 550 remotePoints[nL].rank = neighbor; 551 remotePoints[nL].index = remoteVertex; 552 } 553 } 554 } else { 555 if (zp < 0) { /* back */ 556 nleavesCheck += nVy; /* left back vertices */ 557 for (yv = 0; yv < nVy; ++yv, ++nL) { 558 const PetscInt localVertex = ( 0*nVy + yv)*nVx + 0 + nC; 559 const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 560 561 localPoints[nL] = localVertex; 562 remotePoints[nL].rank = neighbor; 563 remotePoints[nL].index = remoteVertex; 564 } 565 } else if (zp > 0) { /* front */ 566 nleavesCheck += nVy; /* left front vertices */ 567 for (yv = 0; yv < nVy; ++yv, ++nL) { 568 const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + 0 + nC; 569 const PetscInt remoteVertex = ( 0*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 570 571 localPoints[nL] = localVertex; 572 remotePoints[nL].rank = neighbor; 573 remotePoints[nL].index = remoteVertex; 574 } 575 } else { 576 nleavesCheck += nVy*nVz; /* left vertices */ 577 for (zv = 0; zv < nVz; ++zv) { 578 for (yv = 0; yv < nVy; ++yv, ++nL) { 579 const PetscInt localVertex = (zv*nVy + yv)*nVx + 0 + nC; 580 const PetscInt remoteVertex = (zv*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */ 581 582 localPoints[nL] = localVertex; 583 remotePoints[nL].rank = neighbor; 584 remotePoints[nL].index = remoteVertex; 585 } 586 } 587 nleavesCheck += nxF; /* left faces */ 588 for (xf = 0; xf < nxF; ++xf, ++nL) { 589 /* THIS IS WRONG */ 590 const PetscInt localFace = 0 + nC+nV; 591 const PetscInt remoteFace = 0 + nC+nV; 592 593 localPoints[nL] = localFace; 594 remotePoints[nL].rank = neighbor; 595 remotePoints[nL].index = remoteFace; 596 } 597 } 598 } 599 } else if (xp > 0) { /* right */ 600 if (yp < 0) { /* bottom */ 601 if (zp < 0) { /* back */ 602 const PetscInt localVertex = ( 0*nVy + 0)*nVx + nVx-1 + nC; 603 const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 604 nleavesCheck += 1; /* right bottom back vertex */ 605 606 localPoints[nL] = localVertex; 607 remotePoints[nL].rank = neighbor; 608 remotePoints[nL].index = remoteVertex; 609 ++nL; 610 } else if (zp > 0) { /* front */ 611 const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + nVx-1 + nC; 612 const PetscInt remoteVertex = ( 0*nVy + nVy-1)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 613 nleavesCheck += 1; /* right bottom front vertex */ 614 615 localPoints[nL] = localVertex; 616 remotePoints[nL].rank = neighbor; 617 remotePoints[nL].index = remoteVertex; 618 ++nL; 619 } else { 620 nleavesCheck += nVz; /* right bottom vertices */ 621 for (zv = 0; zv < nVz; ++zv, ++nL) { 622 const PetscInt localVertex = (zv*nVy + 0)*nVx + nVx-1 + nC; 623 const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 624 625 localPoints[nL] = localVertex; 626 remotePoints[nL].rank = neighbor; 627 remotePoints[nL].index = remoteVertex; 628 } 629 } 630 } else if (yp > 0) { /* top */ 631 if (zp < 0) { /* back */ 632 const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + nVx-1 + nC; 633 const PetscInt remoteVertex = ((nVz-1)*nVy + 0)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 634 nleavesCheck += 1; /* right top back vertex */ 635 636 localPoints[nL] = localVertex; 637 remotePoints[nL].rank = neighbor; 638 remotePoints[nL].index = remoteVertex; 639 ++nL; 640 } else if (zp > 0) { /* front */ 641 const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; 642 const PetscInt remoteVertex = ( 0*nVy + 0)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 643 nleavesCheck += 1; /* right top front vertex */ 644 645 localPoints[nL] = localVertex; 646 remotePoints[nL].rank = neighbor; 647 remotePoints[nL].index = remoteVertex; 648 ++nL; 649 } else { 650 nleavesCheck += nVz; /* right top vertices */ 651 for (zv = 0; zv < nVz; ++zv, ++nL) { 652 const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; 653 const PetscInt remoteVertex = (zv*nVy + 0)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 654 655 localPoints[nL] = localVertex; 656 remotePoints[nL].rank = neighbor; 657 remotePoints[nL].index = remoteVertex; 658 } 659 } 660 } else { 661 if (zp < 0) { /* back */ 662 nleavesCheck += nVy; /* right back vertices */ 663 for (yv = 0; yv < nVy; ++yv, ++nL) { 664 const PetscInt localVertex = ( 0*nVy + yv)*nVx + nVx-1 + nC; 665 const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 666 667 localPoints[nL] = localVertex; 668 remotePoints[nL].rank = neighbor; 669 remotePoints[nL].index = remoteVertex; 670 } 671 } else if (zp > 0) { /* front */ 672 nleavesCheck += nVy; /* right front vertices */ 673 for (yv = 0; yv < nVy; ++yv, ++nL) { 674 const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; 675 const PetscInt remoteVertex = ( 0*nVy + yv)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 676 677 localPoints[nL] = localVertex; 678 remotePoints[nL].rank = neighbor; 679 remotePoints[nL].index = remoteVertex; 680 } 681 } else { 682 nleavesCheck += nVy*nVz; /* right vertices */ 683 for (zv = 0; zv < nVz; ++zv) { 684 for (yv = 0; yv < nVy; ++yv, ++nL) { 685 const PetscInt localVertex = (zv*nVy + yv)*nVx + nVx-1 + nC; 686 const PetscInt remoteVertex = (zv*nVy + yv)*nVx + 0 + nC; /* TODO: Correct this for neighbor sizes */ 687 688 localPoints[nL] = localVertex; 689 remotePoints[nL].rank = neighbor; 690 remotePoints[nL].index = remoteVertex; 691 } 692 } 693 nleavesCheck += nxF; /* right faces */ 694 for (xf = 0; xf < nxF; ++xf, ++nL) { 695 /* THIS IS WRONG */ 696 const PetscInt localFace = 0 + nC+nV; 697 const PetscInt remoteFace = 0 + nC+nV; 698 699 localPoints[nL] = localFace; 700 remotePoints[nL].rank = neighbor; 701 remotePoints[nL].index = remoteFace; 702 } 703 } 704 } 705 } else { 706 if (yp < 0) { /* bottom */ 707 if (zp < 0) { /* back */ 708 nleavesCheck += nVx; /* bottom back vertices */ 709 for (xv = 0; xv < nVx; ++xv, ++nL) { 710 const PetscInt localVertex = ( 0*nVy + 0)*nVx + xv + nC; 711 const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 712 713 localPoints[nL] = localVertex; 714 remotePoints[nL].rank = neighbor; 715 remotePoints[nL].index = remoteVertex; 716 } 717 } else if (zp > 0) { /* front */ 718 nleavesCheck += nVx; /* bottom front vertices */ 719 for (xv = 0; xv < nVx; ++xv, ++nL) { 720 const PetscInt localVertex = ((nVz-1)*nVy + 0)*nVx + xv + nC; 721 const PetscInt remoteVertex = ( 0*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 722 723 localPoints[nL] = localVertex; 724 remotePoints[nL].rank = neighbor; 725 remotePoints[nL].index = remoteVertex; 726 } 727 } else { 728 nleavesCheck += nVx*nVz; /* bottom vertices */ 729 for (zv = 0; zv < nVz; ++zv) { 730 for (xv = 0; xv < nVx; ++xv, ++nL) { 731 const PetscInt localVertex = (zv*nVy + 0)*nVx + xv + nC; 732 const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 733 734 localPoints[nL] = localVertex; 735 remotePoints[nL].rank = neighbor; 736 remotePoints[nL].index = remoteVertex; 737 } 738 } 739 nleavesCheck += nyF; /* bottom faces */ 740 for (yf = 0; yf < nyF; ++yf, ++nL) { 741 /* THIS IS WRONG */ 742 const PetscInt localFace = 0 + nC+nV; 743 const PetscInt remoteFace = 0 + nC+nV; 744 745 localPoints[nL] = localFace; 746 remotePoints[nL].rank = neighbor; 747 remotePoints[nL].index = remoteFace; 748 } 749 } 750 } else if (yp > 0) { /* top */ 751 if (zp < 0) { /* back */ 752 nleavesCheck += nVx; /* top back vertices */ 753 for (xv = 0; xv < nVx; ++xv, ++nL) { 754 const PetscInt localVertex = ( 0*nVy + nVy-1)*nVx + xv + nC; 755 const PetscInt remoteVertex = ((nVz-1)*nVy + 0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 756 757 localPoints[nL] = localVertex; 758 remotePoints[nL].rank = neighbor; 759 remotePoints[nL].index = remoteVertex; 760 } 761 } else if (zp > 0) { /* front */ 762 nleavesCheck += nVx; /* top front vertices */ 763 for (xv = 0; xv < nVx; ++xv, ++nL) { 764 const PetscInt localVertex = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; 765 const PetscInt remoteVertex = ( 0*nVy + 0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 766 767 localPoints[nL] = localVertex; 768 remotePoints[nL].rank = neighbor; 769 remotePoints[nL].index = remoteVertex; 770 } 771 } else { 772 nleavesCheck += nVx*nVz; /* top vertices */ 773 for (zv = 0; zv < nVz; ++zv) { 774 for (xv = 0; xv < nVx; ++xv, ++nL) { 775 const PetscInt localVertex = (zv*nVy + nVy-1)*nVx + xv + nC; 776 const PetscInt remoteVertex = (zv*nVy + 0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 777 778 localPoints[nL] = localVertex; 779 remotePoints[nL].rank = neighbor; 780 remotePoints[nL].index = remoteVertex; 781 } 782 } 783 nleavesCheck += nyF; /* top faces */ 784 for (yf = 0; yf < nyF; ++yf, ++nL) { 785 /* THIS IS WRONG */ 786 const PetscInt localFace = 0 + nC+nV; 787 const PetscInt remoteFace = 0 + nC+nV; 788 789 localPoints[nL] = localFace; 790 remotePoints[nL].rank = neighbor; 791 remotePoints[nL].index = remoteFace; 792 } 793 } 794 } else { 795 if (zp < 0) { /* back */ 796 nleavesCheck += nVx*nVy; /* back vertices */ 797 for (yv = 0; yv < nVy; ++yv) { 798 for (xv = 0; xv < nVx; ++xv, ++nL) { 799 const PetscInt localVertex = ( 0*nVy + yv)*nVx + xv + nC; 800 const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 801 802 localPoints[nL] = localVertex; 803 remotePoints[nL].rank = neighbor; 804 remotePoints[nL].index = remoteVertex; 805 } 806 } 807 nleavesCheck += nzF; /* back faces */ 808 for (zf = 0; zf < nzF; ++zf, ++nL) { 809 /* THIS IS WRONG */ 810 const PetscInt localFace = 0 + nC+nV; 811 const PetscInt remoteFace = 0 + nC+nV; 812 813 localPoints[nL] = localFace; 814 remotePoints[nL].rank = neighbor; 815 remotePoints[nL].index = remoteFace; 816 } 817 } else if (zp > 0) { /* front */ 818 nleavesCheck += nVx*nVy; /* front vertices */ 819 for (yv = 0; yv < nVy; ++yv) { 820 for (xv = 0; xv < nVx; ++xv, ++nL) { 821 const PetscInt localVertex = ((nVz-1)*nVy + yv)*nVx + xv + nC; 822 const PetscInt remoteVertex = ( 0*nVy + yv)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */ 823 824 localPoints[nL] = localVertex; 825 remotePoints[nL].rank = neighbor; 826 remotePoints[nL].index = remoteVertex; 827 } 828 } 829 nleavesCheck += nzF; /* front faces */ 830 for (zf = 0; zf < nzF; ++zf, ++nL) { 831 /* THIS IS WRONG */ 832 const PetscInt localFace = 0 + nC+nV; 833 const PetscInt remoteFace = 0 + nC+nV; 834 835 localPoints[nL] = localFace; 836 remotePoints[nL].rank = neighbor; 837 remotePoints[nL].index = remoteFace; 838 } 839 } else { 840 /* Nothing is shared from the interior */ 841 } 842 } 843 } 844 } 845 } 846 } 847 } 848 /* TODO: Remove duplication in leaf determination */ 849 if (nleaves != nleavesCheck) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "The number of leaves %d did not match the number of remote leaves %d", nleaves, nleavesCheck); 850 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), &sf);CHKERRQ(ierr); 851 ierr = PetscSFSetGraph(sf, pEnd, nleaves, localPoints, PETSC_OWN_POINTER, remotePoints, PETSC_OWN_POINTER);CHKERRQ(ierr); 852 ierr = DMSetPointSF(dm, sf);CHKERRQ(ierr); 853 ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 854 ierr = DMSetDefaultSection(dm, section);CHKERRQ(ierr); 855 #undef __FUNCT__ 856 #define __FUNCT__ "DMDASetVertexCoordinates" 857 PetscErrorCode DMDASetVertexCoordinates(DM dm, PetscReal xl, PetscReal xu, PetscReal yl, PetscReal yu, PetscReal zl, PetscReal zu) 858 { 859 DM_DA *da = (DM_DA *) dm->data; 860 Vec coordinates; 861 PetscSection section; 862 PetscScalar *coords; 863 PetscReal h[3]; 864 PetscInt dim, size, M, N, P, nVx, nVy, nVz, nV, vStart, vEnd, v, i, j, k; 865 PetscErrorCode ierr; 866 867 PetscFunctionBegin; 868 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 869 ierr = DMDAGetInfo(dm, &dim, &M, &N, &P, 0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); 870 h[0] = (xu - xl)/M; 871 h[1] = (yu - yl)/N; 872 h[2] = (zu - zl)/P; 873 ierr = DMDAGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 874 ierr = DMDAGetNumVertices(dm, &nVx, &nVy, &nVz, &nV);CHKERRQ(ierr); 875 ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), §ion);CHKERRQ(ierr); 876 ierr = PetscSectionSetNumFields(section, 1);CHKERRQ(ierr); 877 ierr = PetscSectionSetFieldComponents(section, 0, dim);CHKERRQ(ierr); 878 ierr = PetscSectionSetChart(section, vStart, vEnd);CHKERRQ(ierr); 879 for (v = vStart; v < vEnd; ++v) { 880 ierr = PetscSectionSetDof(section, v, dim);CHKERRQ(ierr); 881 } 882 ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 883 ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 884 ierr = VecCreateSeq(PETSC_COMM_SELF, size, &coordinates);CHKERRQ(ierr); 885 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 886 for (k = 0; k < nVz; ++k) { 887 PetscInt ind[3] = {0, 0, k + da->zs}, d, off; 888 889 for (j = 0; j < nVy; ++j) { 890 ind[1] = j + da->ys; 891 for (i = 0; i < nVx; ++i) { 892 const PetscInt vertex = (k*nVy + j)*nVx + i + vStart; 893 894 ierr = PetscSectionGetOffset(section, vertex, &off);CHKERRQ(ierr); 895 ind[0] = i + da->xs; 896 for (d = 0; d < dim; ++d) { 897 coords[off+d] = h[d]*ind[d]; 898 } 899 } 900 } 901 } 902 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 903 ierr = DMSetCoordinateSection(dm, section);CHKERRQ(ierr); 904 ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 905 ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 906 ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 907 PetscFunctionReturn(0); 908 } 909 PetscFunctionReturn(0); 910 } 911 912 /* ------------------------------------------------------------------- */ 913 914 #undef __FUNCT__ 915 #define __FUNCT__ "DMDAGetArray" 916 /*@C 917 DMDAGetArray - Gets a work array for a DMDA 918 919 Input Parameter: 920 + da - information about my local patch 921 - ghosted - do you want arrays for the ghosted or nonghosted patch 922 923 Output Parameters: 924 . vptr - array data structured 925 926 Note: The vector values are NOT initialized and may have garbage in them, so you may need 927 to zero them. 928 929 Level: advanced 930 931 .seealso: DMDARestoreArray() 932 933 @*/ 934 PetscErrorCode DMDAGetArray(DM da,PetscBool ghosted,void *vptr) 935 { 936 PetscErrorCode ierr; 937 PetscInt j,i,xs,ys,xm,ym,zs,zm; 938 char *iarray_start; 939 void **iptr = (void**)vptr; 940 DM_DA *dd = (DM_DA*)da->data; 941 942 PetscFunctionBegin; 943 PetscValidHeaderSpecific(da,DM_CLASSID,1); 944 if (ghosted) { 945 for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 946 if (dd->arrayghostedin[i]) { 947 *iptr = dd->arrayghostedin[i]; 948 iarray_start = (char*)dd->startghostedin[i]; 949 dd->arrayghostedin[i] = NULL; 950 dd->startghostedin[i] = NULL; 951 952 goto done; 953 } 954 } 955 xs = dd->Xs; 956 ys = dd->Ys; 957 zs = dd->Zs; 958 xm = dd->Xe-dd->Xs; 959 ym = dd->Ye-dd->Ys; 960 zm = dd->Ze-dd->Zs; 961 } else { 962 for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 963 if (dd->arrayin[i]) { 964 *iptr = dd->arrayin[i]; 965 iarray_start = (char*)dd->startin[i]; 966 dd->arrayin[i] = NULL; 967 dd->startin[i] = NULL; 968 969 goto done; 970 } 971 } 972 xs = dd->xs; 973 ys = dd->ys; 974 zs = dd->zs; 975 xm = dd->xe-dd->xs; 976 ym = dd->ye-dd->ys; 977 zm = dd->ze-dd->zs; 978 } 979 980 switch (dd->dim) { 981 case 1: { 982 void *ptr; 983 984 ierr = PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 985 986 ptr = (void*)(iarray_start - xs*sizeof(PetscScalar)); 987 *iptr = (void*)ptr; 988 break; 989 } 990 case 2: { 991 void **ptr; 992 993 ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 994 995 ptr = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*)); 996 for (j=ys; j<ys+ym; j++) ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs); 997 *iptr = (void*)ptr; 998 break; 999 } 1000 case 3: { 1001 void ***ptr,**bptr; 1002 1003 ierr = PetscMalloc((zm+1)*sizeof(void**)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 1004 1005 ptr = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*)); 1006 bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**)); 1007 for (i=zs; i<zs+zm; i++) ptr[i] = bptr + ((i-zs)*ym - ys); 1008 for (i=zs; i<zs+zm; i++) { 1009 for (j=ys; j<ys+ym; j++) { 1010 ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs); 1011 } 1012 } 1013 *iptr = (void*)ptr; 1014 break; 1015 } 1016 default: 1017 SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Dimension %D not supported",dd->dim); 1018 } 1019 1020 done: 1021 /* add arrays to the checked out list */ 1022 if (ghosted) { 1023 for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 1024 if (!dd->arrayghostedout[i]) { 1025 dd->arrayghostedout[i] = *iptr; 1026 dd->startghostedout[i] = iarray_start; 1027 break; 1028 } 1029 } 1030 } else { 1031 for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 1032 if (!dd->arrayout[i]) { 1033 dd->arrayout[i] = *iptr; 1034 dd->startout[i] = iarray_start; 1035 break; 1036 } 1037 } 1038 } 1039 PetscFunctionReturn(0); 1040 } 1041 1042 #undef __FUNCT__ 1043 #define __FUNCT__ "DMDARestoreArray" 1044 /*@C 1045 DMDARestoreArray - Restores an array of derivative types for a DMDA 1046 1047 Input Parameter: 1048 + da - information about my local patch 1049 . ghosted - do you want arrays for the ghosted or nonghosted patch 1050 - vptr - array data structured to be passed to ad_FormFunctionLocal() 1051 1052 Level: advanced 1053 1054 .seealso: DMDAGetArray() 1055 1056 @*/ 1057 PetscErrorCode DMDARestoreArray(DM da,PetscBool ghosted,void *vptr) 1058 { 1059 PetscInt i; 1060 void **iptr = (void**)vptr,*iarray_start = 0; 1061 DM_DA *dd = (DM_DA*)da->data; 1062 1063 PetscFunctionBegin; 1064 PetscValidHeaderSpecific(da,DM_CLASSID,1); 1065 if (ghosted) { 1066 for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 1067 if (dd->arrayghostedout[i] == *iptr) { 1068 iarray_start = dd->startghostedout[i]; 1069 dd->arrayghostedout[i] = NULL; 1070 dd->startghostedout[i] = NULL; 1071 break; 1072 } 1073 } 1074 for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 1075 if (!dd->arrayghostedin[i]) { 1076 dd->arrayghostedin[i] = *iptr; 1077 dd->startghostedin[i] = iarray_start; 1078 break; 1079 } 1080 } 1081 } else { 1082 for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 1083 if (dd->arrayout[i] == *iptr) { 1084 iarray_start = dd->startout[i]; 1085 dd->arrayout[i] = NULL; 1086 dd->startout[i] = NULL; 1087 break; 1088 } 1089 } 1090 for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 1091 if (!dd->arrayin[i]) { 1092 dd->arrayin[i] = *iptr; 1093 dd->startin[i] = iarray_start; 1094 break; 1095 } 1096 } 1097 } 1098 PetscFunctionReturn(0); 1099 } 1100 1101