1 static char help[] = "Tests for cell geometry\n\n"; 2 3 #include <petscdmplex.h> 4 5 typedef enum {RUN_REFERENCE, RUN_HEX_CURVED, RUN_FILE, RUN_DISPLAY} RunType; 6 7 typedef struct { 8 DM dm; 9 RunType runType; /* Type of mesh to use */ 10 PetscBool transform; /* Use random coordinate transformations */ 11 /* Data for input meshes */ 12 PetscReal *v0, *J, *invJ, *detJ; /* FEM data */ 13 PetscReal *centroid, *normal, *vol; /* FVM data */ 14 } AppCtx; 15 16 static PetscErrorCode ReadMesh(MPI_Comm comm, AppCtx *user, DM *dm) 17 { 18 PetscErrorCode ierr; 19 20 PetscFunctionBegin; 21 ierr = DMCreate(comm, dm);CHKERRQ(ierr); 22 ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 23 ierr = DMSetFromOptions(*dm);CHKERRQ(ierr); 24 ierr = DMSetApplicationContext(*dm, user);CHKERRQ(ierr); 25 ierr = PetscObjectSetName((PetscObject) *dm, "Input Mesh");CHKERRQ(ierr); 26 ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr); 27 PetscFunctionReturn(0); 28 } 29 30 static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 31 { 32 const char *runTypes[4] = {"reference", "hex_curved", "file", "display"}; 33 PetscInt run; 34 PetscErrorCode ierr; 35 36 PetscFunctionBeginUser; 37 options->runType = RUN_REFERENCE; 38 options->transform = PETSC_FALSE; 39 40 ierr = PetscOptionsBegin(comm, "", "Geometry Test Options", "DMPLEX");CHKERRQ(ierr); 41 run = options->runType; 42 ierr = PetscOptionsEList("-run_type", "The run type", "ex8.c", runTypes, 3, runTypes[options->runType], &run, NULL);CHKERRQ(ierr); 43 options->runType = (RunType) run; 44 ierr = PetscOptionsBool("-transform", "Use random transforms", "ex8.c", options->transform, &options->transform, NULL);CHKERRQ(ierr); 45 46 if (options->runType == RUN_FILE) { 47 PetscInt dim, cStart, cEnd, numCells, n; 48 PetscBool flg, feFlg; 49 50 ierr = ReadMesh(PETSC_COMM_WORLD, options, &options->dm);CHKERRQ(ierr); 51 ierr = DMGetDimension(options->dm, &dim);CHKERRQ(ierr); 52 ierr = DMPlexGetHeightStratum(options->dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 53 numCells = cEnd-cStart; 54 ierr = PetscMalloc4(numCells*dim, &options->v0, numCells*dim*dim, &options->J, numCells*dim*dim, &options->invJ, numCells, &options->detJ);CHKERRQ(ierr); 55 ierr = PetscMalloc1(numCells*dim, &options->centroid);CHKERRQ(ierr); 56 ierr = PetscMalloc1(numCells*dim, &options->normal);CHKERRQ(ierr); 57 ierr = PetscMalloc1(numCells, &options->vol);CHKERRQ(ierr); 58 n = numCells*dim; 59 ierr = PetscOptionsRealArray("-v0", "Input v0 for each cell", "ex8.c", options->v0, &n, &feFlg);CHKERRQ(ierr); 60 PetscCheckFalse(feFlg && n != numCells*dim,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Invalid size of v0 %D should be %D", n, numCells*dim); 61 n = numCells*dim*dim; 62 ierr = PetscOptionsRealArray("-J", "Input Jacobian for each cell", "ex8.c", options->J, &n, &flg);CHKERRQ(ierr); 63 PetscCheckFalse(flg && n != numCells*dim*dim,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Invalid size of J %D should be %D", n, numCells*dim*dim); 64 n = numCells*dim*dim; 65 ierr = PetscOptionsRealArray("-invJ", "Input inverse Jacobian for each cell", "ex8.c", options->invJ, &n, &flg);CHKERRQ(ierr); 66 PetscCheckFalse(flg && n != numCells*dim*dim,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Invalid size of invJ %D should be %D", n, numCells*dim*dim); 67 n = numCells; 68 ierr = PetscOptionsRealArray("-detJ", "Input Jacobian determinant for each cell", "ex8.c", options->detJ, &n, &flg);CHKERRQ(ierr); 69 PetscCheckFalse(flg && n != numCells,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Invalid size of detJ %D should be %D", n, numCells); 70 n = numCells*dim; 71 if (!feFlg) { 72 ierr = PetscFree4(options->v0, options->J, options->invJ, options->detJ);CHKERRQ(ierr); 73 options->v0 = options->J = options->invJ = options->detJ = NULL; 74 } 75 ierr = PetscOptionsRealArray("-centroid", "Input centroid for each cell", "ex8.c", options->centroid, &n, &flg);CHKERRQ(ierr); 76 PetscCheckFalse(flg && n != numCells*dim,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Invalid size of centroid %D should be %D", n, numCells*dim); 77 if (!flg) { 78 ierr = PetscFree(options->centroid);CHKERRQ(ierr); 79 options->centroid = NULL; 80 } 81 n = numCells*dim; 82 ierr = PetscOptionsRealArray("-normal", "Input normal for each cell", "ex8.c", options->normal, &n, &flg);CHKERRQ(ierr); 83 PetscCheckFalse(flg && n != numCells*dim,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Invalid size of normal %D should be %D", n, numCells*dim); 84 if (!flg) { 85 ierr = PetscFree(options->normal);CHKERRQ(ierr); 86 options->normal = NULL; 87 } 88 n = numCells; 89 ierr = PetscOptionsRealArray("-vol", "Input volume for each cell", "ex8.c", options->vol, &n, &flg);CHKERRQ(ierr); 90 PetscCheckFalse(flg && n != numCells,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Invalid size of vol %D should be %D", n, numCells); 91 if (!flg) { 92 ierr = PetscFree(options->vol);CHKERRQ(ierr); 93 options->vol = NULL; 94 } 95 } else if (options->runType == RUN_DISPLAY) { 96 ierr = ReadMesh(PETSC_COMM_WORLD, options, &options->dm);CHKERRQ(ierr); 97 } 98 ierr = PetscOptionsEnd();CHKERRQ(ierr); 99 100 if (options->transform) {ierr = PetscPrintf(comm, "Using random transforms\n");CHKERRQ(ierr);} 101 PetscFunctionReturn(0); 102 } 103 104 static PetscErrorCode ChangeCoordinates(DM dm, PetscInt spaceDim, PetscScalar vertexCoords[]) 105 { 106 PetscSection coordSection; 107 Vec coordinates; 108 PetscScalar *coords; 109 PetscInt vStart, vEnd, v, d, coordSize; 110 PetscErrorCode ierr; 111 112 PetscFunctionBegin; 113 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 114 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 115 ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 116 ierr = PetscSectionSetFieldComponents(coordSection, 0, spaceDim);CHKERRQ(ierr); 117 ierr = PetscSectionSetChart(coordSection, vStart, vEnd);CHKERRQ(ierr); 118 for (v = vStart; v < vEnd; ++v) { 119 ierr = PetscSectionSetDof(coordSection, v, spaceDim);CHKERRQ(ierr); 120 ierr = PetscSectionSetFieldDof(coordSection, v, 0, spaceDim);CHKERRQ(ierr); 121 } 122 ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 123 ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 124 ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 125 ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 126 ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 127 ierr = VecSetFromOptions(coordinates);CHKERRQ(ierr); 128 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 129 for (v = vStart; v < vEnd; ++v) { 130 PetscInt off; 131 132 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 133 for (d = 0; d < spaceDim; ++d) { 134 coords[off+d] = vertexCoords[(v-vStart)*spaceDim+d]; 135 } 136 } 137 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 138 ierr = DMSetCoordinateDim(dm, spaceDim);CHKERRQ(ierr); 139 ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 140 ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 141 ierr = DMViewFromOptions(dm, NULL, "-dm_view");CHKERRQ(ierr); 142 PetscFunctionReturn(0); 143 } 144 145 #define RelativeError(a,b) PetscAbs(a-b)/(1.0+PetscMax(PetscAbs(a),PetscAbs(b))) 146 147 static PetscErrorCode CheckFEMGeometry(DM dm, PetscInt cell, PetscInt spaceDim, PetscReal v0Ex[], PetscReal JEx[], PetscReal invJEx[], PetscReal detJEx) 148 { 149 PetscReal v0[3], J[9], invJ[9], detJ; 150 PetscInt d, i, j; 151 PetscErrorCode ierr; 152 153 PetscFunctionBegin; 154 ierr = DMPlexComputeCellGeometryFEM(dm, cell, NULL, v0, J, invJ, &detJ);CHKERRQ(ierr); 155 for (d = 0; d < spaceDim; ++d) { 156 if (v0[d] != v0Ex[d]) { 157 switch (spaceDim) { 158 case 2: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid v0 (%g, %g) != (%g, %g)", (double)v0[0], (double)v0[1], (double)v0Ex[0], (double)v0Ex[1]); 159 case 3: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid v0 (%g, %g, %g) != (%g, %g, %g)", (double)v0[0], (double)v0[1], (double)v0[2], (double)v0Ex[0], (double)v0Ex[1], (double)v0Ex[2]); 160 default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid space dimension %D", spaceDim); 161 } 162 } 163 } 164 for (i = 0; i < spaceDim; ++i) { 165 for (j = 0; j < spaceDim; ++j) { 166 PetscCheckFalse(RelativeError(J[i*spaceDim+j],JEx[i*spaceDim+j]) > 10*PETSC_SMALL,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid J[%D,%D]: %g != %g", i, j, (double)J[i*spaceDim+j], (double)JEx[i*spaceDim+j]); 167 PetscCheckFalse(RelativeError(invJ[i*spaceDim+j],invJEx[i*spaceDim+j]) > 10*PETSC_SMALL,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid invJ[%D,%D]: %g != %g", i, j, (double)invJ[i*spaceDim+j], (double)invJEx[i*spaceDim+j]); 168 } 169 } 170 PetscCheckFalse(RelativeError(detJ,detJEx) > 10*PETSC_SMALL,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid |J| = %g != %g diff %g", (double)detJ, (double)detJEx,(double)(detJ - detJEx)); 171 PetscFunctionReturn(0); 172 } 173 174 static PetscErrorCode CheckFVMGeometry(DM dm, PetscInt cell, PetscInt spaceDim, PetscReal centroidEx[], PetscReal normalEx[], PetscReal volEx) 175 { 176 PetscReal tol = PetscMax(10*PETSC_SMALL, 1e-10); 177 PetscReal centroid[3], normal[3], vol; 178 PetscInt d; 179 PetscErrorCode ierr; 180 181 PetscFunctionBegin; 182 ierr = DMPlexComputeCellGeometryFVM(dm, cell, volEx? &vol : NULL, centroidEx? centroid : NULL, normalEx? normal : NULL);CHKERRQ(ierr); 183 for (d = 0; d < spaceDim; ++d) { 184 if (centroidEx) 185 PetscCheckFalse(RelativeError(centroid[d],centroidEx[d]) > tol,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Cell %D, Invalid centroid[%D]: %g != %g diff %g", cell, d, (double)centroid[d], (double)centroidEx[d],(double)(centroid[d]-centroidEx[d])); 186 if (normalEx) 187 PetscCheckFalse(RelativeError(normal[d],normalEx[d]) > tol,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Cell %D, Invalid normal[%D]: %g != %g", cell, d, (double)normal[d], (double)normalEx[d]); 188 } 189 if (volEx) 190 PetscCheckFalse(RelativeError(volEx,vol) > tol,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Cell %D, Invalid volume = %g != %g diff %g", cell, (double)vol, (double)volEx,(double)(vol - volEx)); 191 PetscFunctionReturn(0); 192 } 193 194 static PetscErrorCode CheckGaussLaw(DM dm, PetscInt cell) 195 { 196 DMPolytopeType ct; 197 PetscReal tol = PetscMax(10*PETSC_SMALL, 1e-10); 198 PetscReal normal[3], integral[3] = {0., 0., 0.}, area; 199 const PetscInt *cone, *ornt; 200 PetscInt coneSize, f, dim, cdim, d; 201 PetscErrorCode ierr; 202 203 PetscFunctionBegin; 204 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 205 ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 206 if (dim != cdim) PetscFunctionReturn(0); 207 ierr = DMPlexGetCellType(dm, cell, &ct);CHKERRQ(ierr); 208 if (ct == DM_POLYTOPE_TRI_PRISM_TENSOR) PetscFunctionReturn(0); 209 ierr = DMPlexGetConeSize(dm, cell, &coneSize);CHKERRQ(ierr); 210 ierr = DMPlexGetCone(dm, cell, &cone);CHKERRQ(ierr); 211 ierr = DMPlexGetConeOrientation(dm, cell, &ornt);CHKERRQ(ierr); 212 for (f = 0; f < coneSize; ++f) { 213 const PetscInt sgn = dim == 1? (f == 0 ? -1 : 1) : (ornt[f] < 0 ? -1 : 1); 214 215 ierr = DMPlexComputeCellGeometryFVM(dm, cone[f], &area, NULL, normal);CHKERRQ(ierr); 216 for (d = 0; d < cdim; ++d) integral[d] += sgn*area*normal[d]; 217 } 218 for (d = 0; d < cdim; ++d) PetscCheckFalse(PetscAbsReal(integral[d]) > tol,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Cell %D Surface integral for component %D: %g != 0. as it should be for a constant field", cell, d, (double) integral[d]); 219 PetscFunctionReturn(0); 220 } 221 222 static PetscErrorCode CheckCell(DM dm, PetscInt cell, PetscBool transform, PetscReal v0Ex[], PetscReal JEx[], PetscReal invJEx[], PetscReal detJEx, PetscReal centroidEx[], PetscReal normalEx[], PetscReal volEx, PetscReal faceCentroidEx[], PetscReal faceNormalEx[], PetscReal faceVolEx[]) 223 { 224 const PetscInt *cone; 225 PetscInt coneSize, c; 226 PetscInt dim, depth, cdim; 227 PetscErrorCode ierr; 228 229 PetscFunctionBegin; 230 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 231 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 232 ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 233 if (v0Ex) { 234 ierr = CheckFEMGeometry(dm, cell, cdim, v0Ex, JEx, invJEx, detJEx);CHKERRQ(ierr); 235 } 236 if (dim == depth && centroidEx) { 237 ierr = CheckFVMGeometry(dm, cell, cdim, centroidEx, normalEx, volEx);CHKERRQ(ierr); 238 ierr = CheckGaussLaw(dm, cell);CHKERRQ(ierr); 239 if (faceCentroidEx) { 240 ierr = DMPlexGetConeSize(dm, cell, &coneSize);CHKERRQ(ierr); 241 ierr = DMPlexGetCone(dm, cell, &cone);CHKERRQ(ierr); 242 for (c = 0; c < coneSize; ++c) { 243 ierr = CheckFVMGeometry(dm, cone[c], dim, &faceCentroidEx[c*dim], &faceNormalEx[c*dim], faceVolEx[c]);CHKERRQ(ierr); 244 } 245 } 246 } 247 if (transform) { 248 Vec coordinates; 249 PetscSection coordSection; 250 PetscScalar *coords = NULL, *origCoords, *newCoords; 251 PetscReal *v0ExT, *JExT, *invJExT, detJExT=0, *centroidExT, *normalExT, volExT=0; 252 PetscReal *faceCentroidExT, *faceNormalExT, faceVolExT; 253 PetscRandom r, ang, ang2; 254 PetscInt coordSize, numCorners, t; 255 256 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 257 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 258 ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, cell, &coordSize, &coords);CHKERRQ(ierr); 259 ierr = PetscMalloc2(coordSize, &origCoords, coordSize, &newCoords);CHKERRQ(ierr); 260 ierr = PetscMalloc5(cdim, &v0ExT, cdim*cdim, &JExT, cdim*cdim, &invJExT, cdim, ¢roidExT, cdim, &normalExT);CHKERRQ(ierr); 261 ierr = PetscMalloc2(cdim, &faceCentroidExT, cdim, &faceNormalExT);CHKERRQ(ierr); 262 for (c = 0; c < coordSize; ++c) origCoords[c] = coords[c]; 263 ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, cell, &coordSize, &coords);CHKERRQ(ierr); 264 numCorners = coordSize/cdim; 265 266 ierr = PetscRandomCreate(PETSC_COMM_SELF, &r);CHKERRQ(ierr); 267 ierr = PetscRandomSetFromOptions(r);CHKERRQ(ierr); 268 ierr = PetscRandomSetInterval(r, 0.0, 10.0);CHKERRQ(ierr); 269 ierr = PetscRandomCreate(PETSC_COMM_SELF, &ang);CHKERRQ(ierr); 270 ierr = PetscRandomSetFromOptions(ang);CHKERRQ(ierr); 271 ierr = PetscRandomSetInterval(ang, 0.0, 2*PETSC_PI);CHKERRQ(ierr); 272 ierr = PetscRandomCreate(PETSC_COMM_SELF, &ang2);CHKERRQ(ierr); 273 ierr = PetscRandomSetFromOptions(ang2);CHKERRQ(ierr); 274 ierr = PetscRandomSetInterval(ang2, 0.0, PETSC_PI);CHKERRQ(ierr); 275 for (t = 0; t < 1; ++t) { 276 PetscScalar trans[3]; 277 PetscReal R[9], rot[3], rotM[9]; 278 PetscReal scale, phi, theta, psi = 0.0, norm; 279 PetscInt d, e, f, p; 280 281 for (c = 0; c < coordSize; ++c) newCoords[c] = origCoords[c]; 282 ierr = PetscRandomGetValueReal(r, &scale);CHKERRQ(ierr); 283 ierr = PetscRandomGetValueReal(ang, &phi);CHKERRQ(ierr); 284 ierr = PetscRandomGetValueReal(ang2, &theta);CHKERRQ(ierr); 285 for (d = 0; d < cdim; ++d) { 286 ierr = PetscRandomGetValue(r, &trans[d]);CHKERRQ(ierr); 287 } 288 switch (cdim) { 289 case 2: 290 R[0] = PetscCosReal(phi); R[1] = -PetscSinReal(phi); 291 R[2] = PetscSinReal(phi); R[3] = PetscCosReal(phi); 292 break; 293 case 3: 294 { 295 const PetscReal ct = PetscCosReal(theta), st = PetscSinReal(theta); 296 const PetscReal cp = PetscCosReal(phi), sp = PetscSinReal(phi); 297 const PetscReal cs = PetscCosReal(psi), ss = PetscSinReal(psi); 298 R[0] = ct*cs; R[1] = sp*st*cs - cp*ss; R[2] = sp*ss + cp*st*cs; 299 R[3] = ct*ss; R[4] = cp*cs + sp*st*ss; R[5] = cp*st*ss - sp*cs; 300 R[6] = -st; R[7] = sp*ct; R[8] = cp*ct; 301 break; 302 } 303 default: SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Invalid coordinate dimension %D", cdim); 304 } 305 if (v0Ex) { 306 detJExT = detJEx; 307 for (d = 0; d < cdim; ++d) { 308 v0ExT[d] = v0Ex[d]; 309 for (e = 0; e < cdim; ++e) { 310 JExT[d*cdim+e] = JEx[d*cdim+e]; 311 invJExT[d*cdim+e] = invJEx[d*cdim+e]; 312 } 313 } 314 for (d = 0; d < cdim; ++d) { 315 v0ExT[d] *= scale; 316 v0ExT[d] += PetscRealPart(trans[d]); 317 /* Only scale dimensions in the manifold */ 318 for (e = 0; e < dim; ++e) { 319 JExT[d*cdim+e] *= scale; 320 invJExT[d*cdim+e] /= scale; 321 } 322 if (d < dim) detJExT *= scale; 323 } 324 /* Do scaling and translation before rotation, so that we can leave out the normal dimension for lower dimensional manifolds */ 325 for (d = 0; d < cdim; ++d) { 326 for (e = 0, rot[d] = 0.0; e < cdim; ++e) { 327 rot[d] += R[d*cdim+e] * v0ExT[e]; 328 } 329 } 330 for (d = 0; d < cdim; ++d) v0ExT[d] = rot[d]; 331 for (d = 0; d < cdim; ++d) { 332 for (e = 0; e < cdim; ++e) { 333 for (f = 0, rotM[d*cdim+e] = 0.0; f < cdim; ++f) { 334 rotM[d*cdim+e] += R[d*cdim+f] * JExT[f*cdim+e]; 335 } 336 } 337 } 338 for (d = 0; d < cdim; ++d) { 339 for (e = 0; e < cdim; ++e) { 340 JExT[d*cdim+e] = rotM[d*cdim+e]; 341 } 342 } 343 for (d = 0; d < cdim; ++d) { 344 for (e = 0; e < cdim; ++e) { 345 for (f = 0, rotM[d*cdim+e] = 0.0; f < cdim; ++f) { 346 rotM[d*cdim+e] += invJExT[d*cdim+f] * R[e*cdim+f]; 347 } 348 } 349 } 350 for (d = 0; d < cdim; ++d) { 351 for (e = 0; e < cdim; ++e) { 352 invJExT[d*cdim+e] = rotM[d*cdim+e]; 353 } 354 } 355 } 356 if (centroidEx) { 357 volExT = volEx; 358 for (d = 0; d < cdim; ++d) { 359 centroidExT[d] = centroidEx[d]; 360 normalExT[d] = normalEx[d]; 361 } 362 for (d = 0; d < cdim; ++d) { 363 centroidExT[d] *= scale; 364 centroidExT[d] += PetscRealPart(trans[d]); 365 normalExT[d] /= scale; 366 /* Only scale dimensions in the manifold */ 367 if (d < dim) volExT *= scale; 368 } 369 /* Do scaling and translation before rotation, so that we can leave out the normal dimension for lower dimensional manifolds */ 370 for (d = 0; d < cdim; ++d) { 371 for (e = 0, rot[d] = 0.0; e < cdim; ++e) { 372 rot[d] += R[d*cdim+e] * centroidExT[e]; 373 } 374 } 375 for (d = 0; d < cdim; ++d) centroidExT[d] = rot[d]; 376 for (d = 0; d < cdim; ++d) { 377 for (e = 0, rot[d] = 0.0; e < cdim; ++e) { 378 rot[d] += R[d*cdim+e] * normalExT[e]; 379 } 380 } 381 for (d = 0; d < cdim; ++d) normalExT[d] = rot[d]; 382 for (d = 0, norm = 0.0; d < cdim; ++d) norm += PetscSqr(normalExT[d]); 383 norm = PetscSqrtReal(norm); 384 for (d = 0; d < cdim; ++d) normalExT[d] /= norm; 385 } 386 for (d = 0; d < cdim; ++d) { 387 for (p = 0; p < numCorners; ++p) { 388 newCoords[p*cdim+d] *= scale; 389 newCoords[p*cdim+d] += trans[d]; 390 } 391 } 392 for (p = 0; p < numCorners; ++p) { 393 for (d = 0; d < cdim; ++d) { 394 for (e = 0, rot[d] = 0.0; e < cdim; ++e) { 395 rot[d] += R[d*cdim+e] * PetscRealPart(newCoords[p*cdim+e]); 396 } 397 } 398 for (d = 0; d < cdim; ++d) newCoords[p*cdim+d] = rot[d]; 399 } 400 401 ierr = ChangeCoordinates(dm, cdim, newCoords);CHKERRQ(ierr); 402 if (v0Ex) { 403 ierr = CheckFEMGeometry(dm, 0, cdim, v0ExT, JExT, invJExT, detJExT);CHKERRQ(ierr); 404 } 405 if (dim == depth && centroidEx) { 406 ierr = CheckFVMGeometry(dm, cell, cdim, centroidExT, normalExT, volExT);CHKERRQ(ierr); 407 ierr = CheckGaussLaw(dm, cell);CHKERRQ(ierr); 408 if (faceCentroidEx) { 409 ierr = DMPlexGetConeSize(dm, cell, &coneSize);CHKERRQ(ierr); 410 ierr = DMPlexGetCone(dm, cell, &cone);CHKERRQ(ierr); 411 for (c = 0; c < coneSize; ++c) { 412 PetscInt off = c*cdim; 413 414 faceVolExT = faceVolEx[c]; 415 for (d = 0; d < cdim; ++d) { 416 faceCentroidExT[d] = faceCentroidEx[off+d]; 417 faceNormalExT[d] = faceNormalEx[off+d]; 418 } 419 for (d = 0; d < cdim; ++d) { 420 faceCentroidExT[d] *= scale; 421 faceCentroidExT[d] += PetscRealPart(trans[d]); 422 faceNormalExT[d] /= scale; 423 /* Only scale dimensions in the manifold */ 424 if (d < dim-1) { 425 faceVolExT *= scale; 426 } 427 } 428 for (d = 0; d < cdim; ++d) { 429 for (e = 0, rot[d] = 0.0; e < cdim; ++e) { 430 rot[d] += R[d*cdim+e] * faceCentroidExT[e]; 431 } 432 } 433 for (d = 0; d < cdim; ++d) faceCentroidExT[d] = rot[d]; 434 for (d = 0; d < cdim; ++d) { 435 for (e = 0, rot[d] = 0.0; e < cdim; ++e) { 436 rot[d] += R[d*cdim+e] * faceNormalExT[e]; 437 } 438 } 439 for (d = 0; d < cdim; ++d) faceNormalExT[d] = rot[d]; 440 for (d = 0, norm = 0.0; d < cdim; ++d) norm += PetscSqr(faceNormalExT[d]); 441 norm = PetscSqrtReal(norm); 442 for (d = 0; d < cdim; ++d) faceNormalExT[d] /= norm; 443 444 ierr = CheckFVMGeometry(dm, cone[c], cdim, faceCentroidExT, faceNormalExT, faceVolExT);CHKERRQ(ierr); 445 } 446 } 447 } 448 } 449 ierr = PetscRandomDestroy(&r);CHKERRQ(ierr); 450 ierr = PetscRandomDestroy(&ang);CHKERRQ(ierr); 451 ierr = PetscRandomDestroy(&ang2);CHKERRQ(ierr); 452 ierr = PetscFree2(origCoords, newCoords);CHKERRQ(ierr); 453 ierr = PetscFree5(v0ExT, JExT, invJExT, centroidExT, normalExT);CHKERRQ(ierr); 454 ierr = PetscFree2(faceCentroidExT, faceNormalExT);CHKERRQ(ierr); 455 } 456 PetscFunctionReturn(0); 457 } 458 459 static PetscErrorCode TestTriangle(MPI_Comm comm, PetscBool transform) 460 { 461 DM dm; 462 PetscErrorCode ierr; 463 464 PetscFunctionBegin; 465 ierr = DMPlexCreateReferenceCell(comm, DM_POLYTOPE_TRIANGLE, &dm);CHKERRQ(ierr); 466 ierr = DMViewFromOptions(dm, NULL, "-dm_view");CHKERRQ(ierr); 467 /* Check reference geometry: determinant is scaled by reference volume (2.0) */ 468 { 469 PetscReal v0Ex[2] = {-1.0, -1.0}; 470 PetscReal JEx[4] = {1.0, 0.0, 0.0, 1.0}; 471 PetscReal invJEx[4] = {1.0, 0.0, 0.0, 1.0}; 472 PetscReal detJEx = 1.0; 473 PetscReal centroidEx[2] = {-((PetscReal)1.)/((PetscReal)3.), -((PetscReal)1.)/((PetscReal)3.)}; 474 PetscReal normalEx[2] = {0.0, 0.0}; 475 PetscReal volEx = 2.0; 476 477 ierr = CheckCell(dm, 0, transform, v0Ex, JEx, invJEx, detJEx, centroidEx, normalEx, volEx, NULL, NULL, NULL);CHKERRQ(ierr); 478 } 479 /* Move to 3D: Check reference geometry: determinant is scaled by reference volume (2.0) */ 480 { 481 PetscScalar vertexCoords[9] = {-1.0, -1.0, 0.0, 1.0, -1.0, 0.0, -1.0, 1.0, 0.0}; 482 PetscReal v0Ex[3] = {-1.0, -1.0, 0.0}; 483 PetscReal JEx[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; 484 PetscReal invJEx[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; 485 PetscReal detJEx = 1.0; 486 PetscReal centroidEx[3] = {-((PetscReal)1.)/((PetscReal)3.), -((PetscReal)1.)/((PetscReal)3.), 0.0}; 487 PetscReal normalEx[3] = {0.0, 0.0, 1.0}; 488 PetscReal volEx = 2.0; 489 490 ierr = ChangeCoordinates(dm, 3, vertexCoords);CHKERRQ(ierr); 491 ierr = CheckCell(dm, 0, transform, v0Ex, JEx, invJEx, detJEx, centroidEx, normalEx, volEx, NULL, NULL, NULL);CHKERRQ(ierr); 492 } 493 /* Cleanup */ 494 ierr = DMDestroy(&dm);CHKERRQ(ierr); 495 PetscFunctionReturn(0); 496 } 497 498 static PetscErrorCode TestQuadrilateral(MPI_Comm comm, PetscBool transform) 499 { 500 DM dm; 501 PetscErrorCode ierr; 502 503 PetscFunctionBegin; 504 ierr = DMPlexCreateReferenceCell(comm, DM_POLYTOPE_QUADRILATERAL, &dm);CHKERRQ(ierr); 505 ierr = DMViewFromOptions(dm, NULL, "-dm_view");CHKERRQ(ierr); 506 /* Check reference geometry: determinant is scaled by reference volume (2.0) */ 507 { 508 PetscReal v0Ex[2] = {-1.0, -1.0}; 509 PetscReal JEx[4] = {1.0, 0.0, 0.0, 1.0}; 510 PetscReal invJEx[4] = {1.0, 0.0, 0.0, 1.0}; 511 PetscReal detJEx = 1.0; 512 PetscReal centroidEx[2] = {0.0, 0.0}; 513 PetscReal normalEx[2] = {0.0, 0.0}; 514 PetscReal volEx = 4.0; 515 516 ierr = CheckCell(dm, 0, transform, v0Ex, JEx, invJEx, detJEx, centroidEx, normalEx, volEx, NULL, NULL, NULL);CHKERRQ(ierr); 517 } 518 /* Move to 3D: Check reference geometry: determinant is scaled by reference volume (4.0) */ 519 { 520 PetscScalar vertexCoords[12] = {-1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0, 1.0, 0.0, -1.0, 1.0, 0.0}; 521 PetscReal v0Ex[3] = {-1.0, -1.0, 0.0}; 522 PetscReal JEx[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; 523 PetscReal invJEx[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; 524 PetscReal detJEx = 1.0; 525 PetscReal centroidEx[3] = {0.0, 0.0, 0.0}; 526 PetscReal normalEx[3] = {0.0, 0.0, 1.0}; 527 PetscReal volEx = 4.0; 528 529 ierr = ChangeCoordinates(dm, 3, vertexCoords);CHKERRQ(ierr); 530 ierr = CheckCell(dm, 0, transform, v0Ex, JEx, invJEx, detJEx, centroidEx, normalEx, volEx, NULL, NULL, NULL);CHKERRQ(ierr); 531 } 532 /* Cleanup */ 533 ierr = DMDestroy(&dm);CHKERRQ(ierr); 534 PetscFunctionReturn(0); 535 } 536 537 static PetscErrorCode TestTetrahedron(MPI_Comm comm, PetscBool transform) 538 { 539 DM dm; 540 PetscErrorCode ierr; 541 542 PetscFunctionBegin; 543 ierr = DMPlexCreateReferenceCell(comm, DM_POLYTOPE_TETRAHEDRON, &dm);CHKERRQ(ierr); 544 ierr = DMViewFromOptions(dm, NULL, "-dm_view");CHKERRQ(ierr); 545 /* Check reference geometry: determinant is scaled by reference volume (4/3) */ 546 { 547 PetscReal v0Ex[3] = {-1.0, -1.0, -1.0}; 548 PetscReal JEx[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; 549 PetscReal invJEx[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; 550 PetscReal detJEx = 1.0; 551 PetscReal centroidEx[3] = {-0.5, -0.5, -0.5}; 552 PetscReal normalEx[3] = {0.0, 0.0, 0.0}; 553 PetscReal volEx = (PetscReal)4.0/(PetscReal)3.0; 554 555 ierr = CheckCell(dm, 0, transform, v0Ex, JEx, invJEx, detJEx, centroidEx, normalEx, volEx, NULL, NULL, NULL);CHKERRQ(ierr); 556 } 557 /* Cleanup */ 558 ierr = DMDestroy(&dm);CHKERRQ(ierr); 559 PetscFunctionReturn(0); 560 } 561 562 static PetscErrorCode TestHexahedron(MPI_Comm comm, PetscBool transform) 563 { 564 DM dm; 565 PetscErrorCode ierr; 566 567 PetscFunctionBegin; 568 ierr = DMPlexCreateReferenceCell(comm, DM_POLYTOPE_HEXAHEDRON, &dm);CHKERRQ(ierr); 569 ierr = DMViewFromOptions(dm, NULL, "-dm_view");CHKERRQ(ierr); 570 /* Check reference geometry: determinant is scaled by reference volume 8.0 */ 571 { 572 PetscReal v0Ex[3] = {-1.0, -1.0, -1.0}; 573 PetscReal JEx[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; 574 PetscReal invJEx[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; 575 PetscReal detJEx = 1.0; 576 PetscReal centroidEx[3] = {0.0, 0.0, 0.0}; 577 PetscReal normalEx[3] = {0.0, 0.0, 0.0}; 578 PetscReal volEx = 8.0; 579 580 ierr = CheckCell(dm, 0, transform, v0Ex, JEx, invJEx, detJEx, centroidEx, normalEx, volEx, NULL, NULL, NULL);CHKERRQ(ierr); 581 } 582 /* Cleanup */ 583 ierr = DMDestroy(&dm);CHKERRQ(ierr); 584 PetscFunctionReturn(0); 585 } 586 587 static PetscErrorCode TestHexahedronCurved(MPI_Comm comm) 588 { 589 DM dm; 590 PetscScalar coords[24] = {-1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 591 -1.0, -1.0, 1.1, 1.0, -1.0, 1.0, 1.0, 1.0, 1.1, -1.0, 1.0, 1.0}; 592 PetscErrorCode ierr; 593 594 PetscFunctionBegin; 595 ierr = DMPlexCreateReferenceCell(comm, DM_POLYTOPE_HEXAHEDRON, &dm);CHKERRQ(ierr); 596 ierr = ChangeCoordinates(dm, 3, coords);CHKERRQ(ierr); 597 ierr = DMViewFromOptions(dm, NULL, "-dm_view");CHKERRQ(ierr); 598 { 599 PetscReal centroidEx[3] = {0.0, 0.0, 0.016803278688524603}; 600 PetscReal normalEx[3] = {0.0, 0.0, 0.0}; 601 PetscReal volEx = 8.1333333333333346; 602 603 ierr = CheckCell(dm, 0, PETSC_FALSE, NULL, NULL, NULL, 0.0, centroidEx, normalEx, volEx, NULL, NULL, NULL);CHKERRQ(ierr); 604 } 605 ierr = DMDestroy(&dm);CHKERRQ(ierr); 606 PetscFunctionReturn(0); 607 } 608 609 /* This wedge is a tensor product cell, rather than a normal wedge */ 610 static PetscErrorCode TestWedge(MPI_Comm comm, PetscBool transform) 611 { 612 DM dm; 613 PetscErrorCode ierr; 614 615 PetscFunctionBegin; 616 ierr = DMPlexCreateReferenceCell(comm, DM_POLYTOPE_TRI_PRISM_TENSOR, &dm);CHKERRQ(ierr); 617 ierr = DMViewFromOptions(dm, NULL, "-dm_view");CHKERRQ(ierr); 618 /* Check reference geometry: determinant is scaled by reference volume 4.0 */ 619 { 620 #if 0 621 /* FEM geometry is not functional for wedges */ 622 PetscReal v0Ex[3] = {-1.0, -1.0, -1.0}; 623 PetscReal JEx[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; 624 PetscReal invJEx[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; 625 PetscReal detJEx = 1.0; 626 #endif 627 628 { 629 PetscReal centroidEx[3] = {-((PetscReal)1.)/((PetscReal)3.), -((PetscReal)1.)/((PetscReal)3.), 0.0}; 630 PetscReal normalEx[3] = {0.0, 0.0, 0.0}; 631 PetscReal volEx = 4.0; 632 PetscReal faceVolEx[5] = {2.0, 2.0, 4.0, PETSC_SQRT2*4.0, 4.0}; 633 PetscReal faceNormalEx[15] = {0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0, PETSC_SQRT2/2.0, PETSC_SQRT2/2.0, 0.0, -1.0, 0.0, 0.0}; 634 PetscReal faceCentroidEx[15] = {-((PetscReal)1.)/((PetscReal)3.), -((PetscReal)1.)/((PetscReal)3.), -1.0, 635 -((PetscReal)1.)/((PetscReal)3.), -((PetscReal)1.)/((PetscReal)3.), 1.0, 636 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0}; 637 638 ierr = CheckCell(dm, 0, transform, NULL, NULL, NULL, 0.0, centroidEx, normalEx, volEx, faceCentroidEx, faceNormalEx, faceVolEx);CHKERRQ(ierr); 639 } 640 } 641 /* Cleanup */ 642 ierr = DMDestroy(&dm);CHKERRQ(ierr); 643 PetscFunctionReturn(0); 644 } 645 646 int main(int argc, char **argv) 647 { 648 AppCtx user; 649 PetscErrorCode ierr; 650 651 ierr = PetscInitialize(&argc, &argv, NULL,help);if (ierr) return ierr; 652 ierr = ProcessOptions(PETSC_COMM_WORLD, &user);CHKERRQ(ierr); 653 if (user.runType == RUN_REFERENCE) { 654 ierr = TestTriangle(PETSC_COMM_SELF, user.transform);CHKERRQ(ierr); 655 ierr = TestQuadrilateral(PETSC_COMM_SELF, user.transform);CHKERRQ(ierr); 656 ierr = TestTetrahedron(PETSC_COMM_SELF, user.transform);CHKERRQ(ierr); 657 ierr = TestHexahedron(PETSC_COMM_SELF, user.transform);CHKERRQ(ierr); 658 ierr = TestWedge(PETSC_COMM_SELF, user.transform);CHKERRQ(ierr); 659 } else if (user.runType == RUN_HEX_CURVED) { 660 ierr = TestHexahedronCurved(PETSC_COMM_SELF);CHKERRQ(ierr); 661 } else if (user.runType == RUN_FILE) { 662 PetscInt dim, cStart, cEnd, c; 663 664 ierr = DMGetDimension(user.dm, &dim);CHKERRQ(ierr); 665 ierr = DMPlexGetHeightStratum(user.dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 666 for (c = 0; c < cEnd-cStart; ++c) { 667 PetscReal *v0 = user.v0 ? &user.v0[c*dim] : NULL; 668 PetscReal *J = user.J ? &user.J[c*dim*dim] : NULL; 669 PetscReal *invJ = user.invJ ? &user.invJ[c*dim*dim] : NULL; 670 PetscReal detJ = user.detJ ? user.detJ[c] : 0.0; 671 PetscReal *centroid = user.centroid ? &user.centroid[c*dim] : NULL; 672 PetscReal *normal = user.normal ? &user.normal[c*dim] : NULL; 673 PetscReal vol = user.vol ? user.vol[c] : 0.0; 674 675 ierr = CheckCell(user.dm, c+cStart, PETSC_FALSE, v0, J, invJ, detJ, centroid, normal, vol, NULL, NULL, NULL);CHKERRQ(ierr); 676 } 677 ierr = PetscFree4(user.v0,user.J,user.invJ,user.detJ);CHKERRQ(ierr); 678 ierr = PetscFree(user.centroid);CHKERRQ(ierr); 679 ierr = PetscFree(user.normal);CHKERRQ(ierr); 680 ierr = PetscFree(user.vol);CHKERRQ(ierr); 681 ierr = DMDestroy(&user.dm);CHKERRQ(ierr); 682 } else if (user.runType == RUN_DISPLAY) { 683 DM gdm, dmCell; 684 Vec cellgeom, facegeom; 685 const PetscScalar *cgeom; 686 PetscInt dim, d, cStart, cEnd, cEndInterior, c; 687 688 ierr = DMGetCoordinateDim(user.dm, &dim);CHKERRQ(ierr); 689 ierr = DMPlexConstructGhostCells(user.dm, NULL, NULL, &gdm);CHKERRQ(ierr); 690 if (gdm) { 691 ierr = DMDestroy(&user.dm);CHKERRQ(ierr); 692 user.dm = gdm; 693 } 694 ierr = DMPlexComputeGeometryFVM(user.dm, &cellgeom, &facegeom);CHKERRQ(ierr); 695 ierr = DMPlexGetHeightStratum(user.dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 696 ierr = DMPlexGetGhostCellStratum(user.dm, &cEndInterior, NULL);CHKERRQ(ierr); 697 if (cEndInterior >= 0) cEnd = cEndInterior; 698 ierr = VecGetDM(cellgeom, &dmCell);CHKERRQ(ierr); 699 ierr = VecGetArrayRead(cellgeom, &cgeom);CHKERRQ(ierr); 700 for (c = 0; c < cEnd-cStart; ++c) { 701 PetscFVCellGeom *cg; 702 703 ierr = DMPlexPointLocalRead(dmCell, c, cgeom, &cg);CHKERRQ(ierr); 704 ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %4D: Centroid (", c);CHKERRQ(ierr); 705 for (d = 0; d < dim; ++d) { 706 if (d > 0) {ierr = PetscPrintf(PETSC_COMM_SELF, ", ");CHKERRQ(ierr);} 707 ierr = PetscPrintf(PETSC_COMM_SELF, "%12.2g", cg->centroid[d]);CHKERRQ(ierr); 708 } 709 ierr = PetscPrintf(PETSC_COMM_SELF, ") Vol %12.2g\n", cg->volume);CHKERRQ(ierr); 710 } 711 ierr = VecRestoreArrayRead(cellgeom, &cgeom);CHKERRQ(ierr); 712 ierr = VecDestroy(&cellgeom);CHKERRQ(ierr); 713 ierr = VecDestroy(&facegeom);CHKERRQ(ierr); 714 ierr = DMDestroy(&user.dm);CHKERRQ(ierr); 715 } 716 ierr = PetscFinalize(); 717 return ierr; 718 } 719 720 /*TEST 721 722 test: 723 suffix: 1 724 args: -dm_view ascii::ascii_info_detail 725 test: 726 suffix: 2 727 args: -run_type hex_curved 728 test: 729 suffix: 3 730 args: -transform 731 test: 732 suffix: 4 733 requires: exodusii 734 args: -run_type file -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/simpleblock-100.exo -dm_view ascii::ascii_info_detail -v0 -1.5,-0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5 -J 0.0,0.0,0.5,0.0,0.5,0.0,-0.5,0.0,0.0,0.0,0.0,0.5,0.0,0.5,0.0,-0.5,0.0,0.0,0.0,0.0,0.5,0.0,0.5,0.0,-0.5,0.0,0.0 -invJ 0.0,0.0,-2.0,0.0,2.0,0.0,2.0,0.0,0.0,0.0,0.0,-2.0,0.0,2.0,0.0,2.0,0.0,0.0,0.0,0.0,-2.0,0.0,2.0,0.0,2.0,0.0,0.0 -detJ 0.125,0.125,0.125 -centroid -1.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0 -normal 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 -vol 1.0,1.0,1.0 735 test: 736 suffix: 5 737 args: -run_type file -dm_plex_dim 3 -dm_plex_simplex 0 -dm_plex_box_faces 3,1,1 -dm_plex_box_lower -1.5,-0.5,-0.5 -dm_plex_box_upper 1.5,0.5,0.5 -dm_view ascii::ascii_info_detail -centroid -1.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0 -normal 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 -vol 1.0,1.0,1.0 738 test: 739 suffix: 6 740 args: -run_type file -dm_plex_dim 1 -dm_plex_simplex 0 -dm_plex_box_faces 3 -dm_plex_box_lower -1.5 -dm_plex_box_upper 1.5 -dm_view ascii::ascii_info_detail -centroid -1.0,0.0,1.0 -vol 1.0,1.0,1.0 741 TEST*/ 742