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