1552f7358SJed Brown #define PETSCDM_DLL 2af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 3e8f14785SLisandro Dalcin #include <petsc/private/hashseti.h> /*I "petscdmplex.h" I*/ 40c312b8eSJed Brown #include <petscsf.h> 5552f7358SJed Brown 6b09969d6SVaclav Hapla PetscLogEvent DMPLEX_CreateFromFile, DMPLEX_BuildFromCellList, DMPLEX_BuildCoordinatesFromCellList; 758cd63d5SVaclav Hapla 89318fe57SMatthew G. Knepley /* External function declarations here */ 99318fe57SMatthew G. Knepley static PetscErrorCode DMInitialize_Plex(DM dm); 109318fe57SMatthew G. Knepley 119318fe57SMatthew G. Knepley /* Replace dm with the contents of ndm, and then destroy ndm 129318fe57SMatthew G. Knepley - Share the DM_Plex structure 139318fe57SMatthew G. Knepley - Share the coordinates 149318fe57SMatthew G. Knepley - Share the SF 159318fe57SMatthew G. Knepley */ 169318fe57SMatthew G. Knepley static PetscErrorCode DMPlexReplace_Static(DM dm, DM *ndm) 179318fe57SMatthew G. Knepley { 189318fe57SMatthew G. Knepley PetscSF sf; 199318fe57SMatthew G. Knepley DM dmNew = *ndm, coordDM, coarseDM; 209318fe57SMatthew G. Knepley Vec coords; 219318fe57SMatthew G. Knepley PetscBool isper; 229318fe57SMatthew G. Knepley const PetscReal *maxCell, *L; 239318fe57SMatthew G. Knepley const DMBoundaryType *bd; 249318fe57SMatthew G. Knepley PetscInt dim, cdim; 259318fe57SMatthew G. Knepley PetscErrorCode ierr; 269318fe57SMatthew G. Knepley 279318fe57SMatthew G. Knepley PetscFunctionBegin; 289318fe57SMatthew G. Knepley if (dm == dmNew) { 299318fe57SMatthew G. Knepley ierr = DMDestroy(ndm);CHKERRQ(ierr); 309318fe57SMatthew G. Knepley PetscFunctionReturn(0); 319318fe57SMatthew G. Knepley } 329318fe57SMatthew G. Knepley dm->setupcalled = dmNew->setupcalled; 339318fe57SMatthew G. Knepley ierr = DMGetDimension(dmNew, &dim);CHKERRQ(ierr); 349318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 359318fe57SMatthew G. Knepley ierr = DMGetCoordinateDim(dmNew, &cdim);CHKERRQ(ierr); 369318fe57SMatthew G. Knepley ierr = DMSetCoordinateDim(dm, cdim);CHKERRQ(ierr); 379318fe57SMatthew G. Knepley ierr = DMGetPointSF(dmNew, &sf);CHKERRQ(ierr); 389318fe57SMatthew G. Knepley ierr = DMSetPointSF(dm, sf);CHKERRQ(ierr); 399318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dmNew, &coordDM);CHKERRQ(ierr); 409318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dmNew, &coords);CHKERRQ(ierr); 419318fe57SMatthew G. Knepley ierr = DMSetCoordinateDM(dm, coordDM);CHKERRQ(ierr); 429318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coords);CHKERRQ(ierr); 439318fe57SMatthew G. Knepley /* Do not want to create the coordinate field if it does not already exist, so do not call DMGetCoordinateField() */ 449318fe57SMatthew G. Knepley ierr = DMFieldDestroy(&dm->coordinateField);CHKERRQ(ierr); 459318fe57SMatthew G. Knepley dm->coordinateField = dmNew->coordinateField; 4661a622f3SMatthew G. Knepley ((DM_Plex *) dmNew->data)->coordFunc = ((DM_Plex *) dm->data)->coordFunc; 479318fe57SMatthew G. Knepley ierr = DMGetPeriodicity(dmNew, &isper, &maxCell, &L, &bd);CHKERRQ(ierr); 489318fe57SMatthew G. Knepley ierr = DMSetPeriodicity(dm, isper, maxCell, L, bd);CHKERRQ(ierr); 499318fe57SMatthew G. Knepley ierr = DMDestroy_Plex(dm);CHKERRQ(ierr); 509318fe57SMatthew G. Knepley ierr = DMInitialize_Plex(dm);CHKERRQ(ierr); 519318fe57SMatthew G. Knepley dm->data = dmNew->data; 529318fe57SMatthew G. Knepley ((DM_Plex *) dmNew->data)->refct++; 539318fe57SMatthew G. Knepley ierr = DMDestroyLabelLinkList_Internal(dm);CHKERRQ(ierr); 549318fe57SMatthew G. Knepley ierr = DMCopyLabels(dmNew, dm, PETSC_OWN_POINTER, PETSC_TRUE);CHKERRQ(ierr); 559318fe57SMatthew G. Knepley ierr = DMGetCoarseDM(dmNew,&coarseDM);CHKERRQ(ierr); 569318fe57SMatthew G. Knepley ierr = DMSetCoarseDM(dm,coarseDM);CHKERRQ(ierr); 579318fe57SMatthew G. Knepley ierr = DMDestroy(ndm);CHKERRQ(ierr); 589318fe57SMatthew G. Knepley PetscFunctionReturn(0); 599318fe57SMatthew G. Knepley } 609318fe57SMatthew G. Knepley 619318fe57SMatthew G. Knepley /* Swap dm with the contents of dmNew 629318fe57SMatthew G. Knepley - Swap the DM_Plex structure 639318fe57SMatthew G. Knepley - Swap the coordinates 649318fe57SMatthew G. Knepley - Swap the point PetscSF 659318fe57SMatthew G. Knepley */ 669318fe57SMatthew G. Knepley static PetscErrorCode DMPlexSwap_Static(DM dmA, DM dmB) 679318fe57SMatthew G. Knepley { 689318fe57SMatthew G. Knepley DM coordDMA, coordDMB; 699318fe57SMatthew G. Knepley Vec coordsA, coordsB; 709318fe57SMatthew G. Knepley PetscSF sfA, sfB; 719318fe57SMatthew G. Knepley DMField fieldTmp; 729318fe57SMatthew G. Knepley void *tmp; 739318fe57SMatthew G. Knepley DMLabelLink listTmp; 749318fe57SMatthew G. Knepley DMLabel depthTmp; 759318fe57SMatthew G. Knepley PetscInt tmpI; 769318fe57SMatthew G. Knepley PetscErrorCode ierr; 779318fe57SMatthew G. Knepley 789318fe57SMatthew G. Knepley PetscFunctionBegin; 799318fe57SMatthew G. Knepley if (dmA == dmB) PetscFunctionReturn(0); 809318fe57SMatthew G. Knepley ierr = DMGetPointSF(dmA, &sfA);CHKERRQ(ierr); 819318fe57SMatthew G. Knepley ierr = DMGetPointSF(dmB, &sfB);CHKERRQ(ierr); 829318fe57SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) sfA);CHKERRQ(ierr); 839318fe57SMatthew G. Knepley ierr = DMSetPointSF(dmA, sfB);CHKERRQ(ierr); 849318fe57SMatthew G. Knepley ierr = DMSetPointSF(dmB, sfA);CHKERRQ(ierr); 859318fe57SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) sfA);CHKERRQ(ierr); 869318fe57SMatthew G. Knepley 879318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dmA, &coordDMA);CHKERRQ(ierr); 889318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dmB, &coordDMB);CHKERRQ(ierr); 899318fe57SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) coordDMA);CHKERRQ(ierr); 909318fe57SMatthew G. Knepley ierr = DMSetCoordinateDM(dmA, coordDMB);CHKERRQ(ierr); 919318fe57SMatthew G. Knepley ierr = DMSetCoordinateDM(dmB, coordDMA);CHKERRQ(ierr); 929318fe57SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) coordDMA);CHKERRQ(ierr); 939318fe57SMatthew G. Knepley 949318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dmA, &coordsA);CHKERRQ(ierr); 959318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dmB, &coordsB);CHKERRQ(ierr); 969318fe57SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) coordsA);CHKERRQ(ierr); 979318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dmA, coordsB);CHKERRQ(ierr); 989318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dmB, coordsA);CHKERRQ(ierr); 999318fe57SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) coordsA);CHKERRQ(ierr); 1009318fe57SMatthew G. Knepley 1019318fe57SMatthew G. Knepley fieldTmp = dmA->coordinateField; 1029318fe57SMatthew G. Knepley dmA->coordinateField = dmB->coordinateField; 1039318fe57SMatthew G. Knepley dmB->coordinateField = fieldTmp; 1049318fe57SMatthew G. Knepley tmp = dmA->data; 1059318fe57SMatthew G. Knepley dmA->data = dmB->data; 1069318fe57SMatthew G. Knepley dmB->data = tmp; 1079318fe57SMatthew G. Knepley listTmp = dmA->labels; 1089318fe57SMatthew G. Knepley dmA->labels = dmB->labels; 1099318fe57SMatthew G. Knepley dmB->labels = listTmp; 1109318fe57SMatthew G. Knepley depthTmp = dmA->depthLabel; 1119318fe57SMatthew G. Knepley dmA->depthLabel = dmB->depthLabel; 1129318fe57SMatthew G. Knepley dmB->depthLabel = depthTmp; 1139318fe57SMatthew G. Knepley depthTmp = dmA->celltypeLabel; 1149318fe57SMatthew G. Knepley dmA->celltypeLabel = dmB->celltypeLabel; 1159318fe57SMatthew G. Knepley dmB->celltypeLabel = depthTmp; 1169318fe57SMatthew G. Knepley tmpI = dmA->levelup; 1179318fe57SMatthew G. Knepley dmA->levelup = dmB->levelup; 1189318fe57SMatthew G. Knepley dmB->levelup = tmpI; 1199318fe57SMatthew G. Knepley PetscFunctionReturn(0); 1209318fe57SMatthew G. Knepley } 1219318fe57SMatthew G. Knepley 1229318fe57SMatthew G. Knepley static PetscErrorCode DMPlexInterpolateInPlace_Internal(DM dm) 1239318fe57SMatthew G. Knepley { 1249318fe57SMatthew G. Knepley DM idm; 1259318fe57SMatthew G. Knepley PetscErrorCode ierr; 1269318fe57SMatthew G. Knepley 1279318fe57SMatthew G. Knepley PetscFunctionBegin; 1289318fe57SMatthew G. Knepley ierr = DMPlexInterpolate(dm, &idm);CHKERRQ(ierr); 1299318fe57SMatthew G. Knepley ierr = DMPlexCopyCoordinates(dm, idm);CHKERRQ(ierr); 1309318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &idm);CHKERRQ(ierr); 1319318fe57SMatthew G. Knepley PetscFunctionReturn(0); 1329318fe57SMatthew G. Knepley } 1339318fe57SMatthew G. Knepley 1349318fe57SMatthew G. Knepley /*@C 1359318fe57SMatthew G. Knepley DMPlexCreateCoordinateSpace - Creates a finite element space for the coordinates 1369318fe57SMatthew G. Knepley 1379318fe57SMatthew G. Knepley Collective 1389318fe57SMatthew G. Knepley 1399318fe57SMatthew G. Knepley Input Parameters: 1409318fe57SMatthew G. Knepley + DM - The DM 1419318fe57SMatthew G. Knepley . degree - The degree of the finite element 1429318fe57SMatthew G. Knepley - coordFunc - An optional function to map new points from refinement to the surface 1439318fe57SMatthew G. Knepley 1449318fe57SMatthew G. Knepley Level: advanced 1459318fe57SMatthew G. Knepley 1469318fe57SMatthew G. Knepley .seealso: PetscFECreateLagrange(), DMGetCoordinateDM() 1479318fe57SMatthew G. Knepley @*/ 1489318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateCoordinateSpace(DM dm, PetscInt degree, PetscPointFunc coordFunc) 1499318fe57SMatthew G. Knepley { 1509318fe57SMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) dm->data; 1519318fe57SMatthew G. Knepley DM cdm; 1529318fe57SMatthew G. Knepley PetscDS cds; 1539318fe57SMatthew G. Knepley PetscFE fe; 1549318fe57SMatthew G. Knepley PetscClassId id; 1559318fe57SMatthew G. Knepley PetscErrorCode ierr; 1569318fe57SMatthew G. Knepley 1579318fe57SMatthew G. Knepley PetscFunctionBegin; 1589318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 1599318fe57SMatthew G. Knepley ierr = DMGetDS(cdm, &cds);CHKERRQ(ierr); 1609318fe57SMatthew G. Knepley ierr = PetscDSGetDiscretization(cds, 0, (PetscObject *) &fe);CHKERRQ(ierr); 1619318fe57SMatthew G. Knepley ierr = PetscObjectGetClassId((PetscObject) fe, &id);CHKERRQ(ierr); 1629318fe57SMatthew G. Knepley if (id != PETSCFE_CLASSID) { 1639318fe57SMatthew G. Knepley PetscBool simplex; 1649318fe57SMatthew G. Knepley PetscInt dim, dE, qorder; 1659318fe57SMatthew G. Knepley 1669318fe57SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1679318fe57SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 1689318fe57SMatthew G. Knepley ierr = DMPlexIsSimplex(dm, &simplex);CHKERRQ(ierr); 1699318fe57SMatthew G. Knepley qorder = degree; 1709318fe57SMatthew G. Knepley ierr = PetscObjectOptionsBegin((PetscObject) cdm);CHKERRQ(ierr); 1719318fe57SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-coord_dm_default_quadrature_order", "Quadrature order is one less than quadrature points per edge", "DMPlexCreateCoordinateSpace", qorder, &qorder, NULL, 0);CHKERRQ(ierr); 1729318fe57SMatthew G. Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 1739318fe57SMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, dE, simplex, degree, qorder, &fe);CHKERRQ(ierr); 1749318fe57SMatthew G. Knepley ierr = DMSetField(cdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 1759318fe57SMatthew G. Knepley ierr = DMCreateDS(cdm);CHKERRQ(ierr); 1769318fe57SMatthew G. Knepley ierr = DMProjectCoordinates(dm, fe);CHKERRQ(ierr); 1779318fe57SMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 1789318fe57SMatthew G. Knepley } 1799318fe57SMatthew G. Knepley mesh->coordFunc = coordFunc; 1809318fe57SMatthew G. Knepley PetscFunctionReturn(0); 1819318fe57SMatthew G. Knepley } 1829318fe57SMatthew G. Knepley 1831df5d5c5SMatthew G. Knepley /*@ 1841df5d5c5SMatthew G. Knepley DMPlexCreateDoublet - Creates a mesh of two cells of the specified type, optionally with later refinement. 1851df5d5c5SMatthew G. Knepley 186d083f849SBarry Smith Collective 1871df5d5c5SMatthew G. Knepley 1881df5d5c5SMatthew G. Knepley Input Parameters: 1891df5d5c5SMatthew G. Knepley + comm - The communicator for the DM object 1901df5d5c5SMatthew G. Knepley . dim - The spatial dimension 1911df5d5c5SMatthew G. Knepley . simplex - Flag for simplicial cells, otherwise they are tensor product cells 1921df5d5c5SMatthew G. Knepley . interpolate - Flag to create intermediate mesh pieces (edges, faces) 1931df5d5c5SMatthew G. Knepley - refinementLimit - A nonzero number indicates the largest admissible volume for a refined cell 1941df5d5c5SMatthew G. Knepley 1951df5d5c5SMatthew G. Knepley Output Parameter: 1961df5d5c5SMatthew G. Knepley . dm - The DM object 1971df5d5c5SMatthew G. Knepley 1981df5d5c5SMatthew G. Knepley Level: beginner 1991df5d5c5SMatthew G. Knepley 2001df5d5c5SMatthew G. Knepley .seealso: DMSetType(), DMCreate() 2011df5d5c5SMatthew G. Knepley @*/ 2020fdc7489SMatthew Knepley PetscErrorCode DMPlexCreateDoublet(MPI_Comm comm, PetscInt dim, PetscBool simplex, PetscBool interpolate, PetscReal refinementLimit, DM *newdm) 2031df5d5c5SMatthew G. Knepley { 2041df5d5c5SMatthew G. Knepley DM dm; 2051df5d5c5SMatthew G. Knepley PetscMPIInt rank; 2061df5d5c5SMatthew G. Knepley PetscErrorCode ierr; 2071df5d5c5SMatthew G. Knepley 2081df5d5c5SMatthew G. Knepley PetscFunctionBegin; 2091df5d5c5SMatthew G. Knepley ierr = DMCreate(comm, &dm);CHKERRQ(ierr); 2101df5d5c5SMatthew G. Knepley ierr = DMSetType(dm, DMPLEX);CHKERRQ(ierr); 211c73cfb54SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 212ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 213ce78fa2fSMatthew G. Knepley switch (dim) { 214ce78fa2fSMatthew G. Knepley case 2: 215ce78fa2fSMatthew G. Knepley if (simplex) {ierr = PetscObjectSetName((PetscObject) dm, "triangular");CHKERRQ(ierr);} 216ce78fa2fSMatthew G. Knepley else {ierr = PetscObjectSetName((PetscObject) dm, "quadrilateral");CHKERRQ(ierr);} 217ce78fa2fSMatthew G. Knepley break; 218ce78fa2fSMatthew G. Knepley case 3: 219ce78fa2fSMatthew G. Knepley if (simplex) {ierr = PetscObjectSetName((PetscObject) dm, "tetrahedral");CHKERRQ(ierr);} 220ce78fa2fSMatthew G. Knepley else {ierr = PetscObjectSetName((PetscObject) dm, "hexahedral");CHKERRQ(ierr);} 221ce78fa2fSMatthew G. Knepley break; 222ce78fa2fSMatthew G. Knepley default: 22389c010cfSBarry Smith SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make meshes for dimension %D", dim); 224ce78fa2fSMatthew G. Knepley } 2251df5d5c5SMatthew G. Knepley if (rank) { 2261df5d5c5SMatthew G. Knepley PetscInt numPoints[2] = {0, 0}; 2271df5d5c5SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm, 1, numPoints, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 2281df5d5c5SMatthew G. Knepley } else { 2291df5d5c5SMatthew G. Knepley switch (dim) { 2301df5d5c5SMatthew G. Knepley case 2: 2311df5d5c5SMatthew G. Knepley if (simplex) { 2321df5d5c5SMatthew G. Knepley PetscInt numPoints[2] = {4, 2}; 2331df5d5c5SMatthew G. Knepley PetscInt coneSize[6] = {3, 3, 0, 0, 0, 0}; 2341df5d5c5SMatthew G. Knepley PetscInt cones[6] = {2, 3, 4, 5, 4, 3}; 2351df5d5c5SMatthew G. Knepley PetscInt coneOrientations[6] = {0, 0, 0, 0, 0, 0}; 2361df5d5c5SMatthew G. Knepley PetscScalar vertexCoords[8] = {-0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 0.5, 0.5}; 2371df5d5c5SMatthew G. Knepley 2381df5d5c5SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 2391df5d5c5SMatthew G. Knepley } else { 2401df5d5c5SMatthew G. Knepley PetscInt numPoints[2] = {6, 2}; 2411df5d5c5SMatthew G. Knepley PetscInt coneSize[8] = {4, 4, 0, 0, 0, 0, 0, 0}; 2421df5d5c5SMatthew G. Knepley PetscInt cones[8] = {2, 3, 4, 5, 3, 6, 7, 4}; 2431df5d5c5SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 2441df5d5c5SMatthew G. Knepley PetscScalar vertexCoords[12] = {-1.0, -0.5, 0.0, -0.5, 0.0, 0.5, -1.0, 0.5, 1.0, -0.5, 1.0, 0.5}; 2451df5d5c5SMatthew G. Knepley 2461df5d5c5SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 2471df5d5c5SMatthew G. Knepley } 2481df5d5c5SMatthew G. Knepley break; 2491df5d5c5SMatthew G. Knepley case 3: 2501df5d5c5SMatthew G. Knepley if (simplex) { 2511df5d5c5SMatthew G. Knepley PetscInt numPoints[2] = {5, 2}; 2521df5d5c5SMatthew G. Knepley PetscInt coneSize[7] = {4, 4, 0, 0, 0, 0, 0}; 2531df5d5c5SMatthew G. Knepley PetscInt cones[8] = {4, 3, 5, 2, 5, 3, 4, 6}; 2541df5d5c5SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 2551df5d5c5SMatthew G. Knepley PetscScalar vertexCoords[15] = {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}; 2561df5d5c5SMatthew G. Knepley 2571df5d5c5SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 2581df5d5c5SMatthew G. Knepley } else { 2591df5d5c5SMatthew G. Knepley PetscInt numPoints[2] = {12, 2}; 2601df5d5c5SMatthew G. Knepley PetscInt coneSize[14] = {8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 2611df5d5c5SMatthew G. Knepley PetscInt cones[16] = {2, 3, 4, 5, 6, 7, 8, 9, 5, 4, 10, 11, 7, 12, 13, 8}; 2621df5d5c5SMatthew G. Knepley PetscInt coneOrientations[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 2631df5d5c5SMatthew G. Knepley PetscScalar vertexCoords[36] = {-1.0, -0.5, -0.5, -1.0, 0.5, -0.5, 0.0, 0.5, -0.5, 0.0, -0.5, -0.5, 2641df5d5c5SMatthew G. Knepley -1.0, -0.5, 0.5, 0.0, -0.5, 0.5, 0.0, 0.5, 0.5, -1.0, 0.5, 0.5, 2651df5d5c5SMatthew G. Knepley 1.0, 0.5, -0.5, 1.0, -0.5, -0.5, 1.0, -0.5, 0.5, 1.0, 0.5, 0.5}; 2661df5d5c5SMatthew G. Knepley 2671df5d5c5SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 2681df5d5c5SMatthew G. Knepley } 2691df5d5c5SMatthew G. Knepley break; 2701df5d5c5SMatthew G. Knepley default: 27189c010cfSBarry Smith SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make meshes for dimension %D", dim); 2721df5d5c5SMatthew G. Knepley } 2731df5d5c5SMatthew G. Knepley } 2741df5d5c5SMatthew G. Knepley *newdm = dm; 2751df5d5c5SMatthew G. Knepley if (refinementLimit > 0.0) { 2761df5d5c5SMatthew G. Knepley DM rdm; 2771df5d5c5SMatthew G. Knepley const char *name; 2781df5d5c5SMatthew G. Knepley 2791df5d5c5SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*newdm, PETSC_FALSE);CHKERRQ(ierr); 2801df5d5c5SMatthew G. Knepley ierr = DMPlexSetRefinementLimit(*newdm, refinementLimit);CHKERRQ(ierr); 2811df5d5c5SMatthew G. Knepley ierr = DMRefine(*newdm, comm, &rdm);CHKERRQ(ierr); 2821df5d5c5SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) *newdm, &name);CHKERRQ(ierr); 2831df5d5c5SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) rdm, name);CHKERRQ(ierr); 2841df5d5c5SMatthew G. Knepley ierr = DMDestroy(newdm);CHKERRQ(ierr); 2851df5d5c5SMatthew G. Knepley *newdm = rdm; 2861df5d5c5SMatthew G. Knepley } 2871df5d5c5SMatthew G. Knepley if (interpolate) { 2885fd9971aSMatthew G. Knepley DM idm; 2891df5d5c5SMatthew G. Knepley 2901df5d5c5SMatthew G. Knepley ierr = DMPlexInterpolate(*newdm, &idm);CHKERRQ(ierr); 2911df5d5c5SMatthew G. Knepley ierr = DMDestroy(newdm);CHKERRQ(ierr); 2921df5d5c5SMatthew G. Knepley *newdm = idm; 2931df5d5c5SMatthew G. Knepley } 2941df5d5c5SMatthew G. Knepley PetscFunctionReturn(0); 2951df5d5c5SMatthew G. Knepley } 2961df5d5c5SMatthew G. Knepley 2979318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxSurfaceMesh_Tensor_1D_Internal(DM dm, const PetscReal lower[], const PetscReal upper[], const PetscInt edges[]) 2989318fe57SMatthew G. Knepley { 2999318fe57SMatthew G. Knepley const PetscInt numVertices = 2; 3009318fe57SMatthew G. Knepley PetscInt markerRight = 1; 3019318fe57SMatthew G. Knepley PetscInt markerLeft = 1; 3029318fe57SMatthew G. Knepley PetscBool markerSeparate = PETSC_FALSE; 3039318fe57SMatthew G. Knepley Vec coordinates; 3049318fe57SMatthew G. Knepley PetscSection coordSection; 3059318fe57SMatthew G. Knepley PetscScalar *coords; 3069318fe57SMatthew G. Knepley PetscInt coordSize; 3079318fe57SMatthew G. Knepley PetscMPIInt rank; 3089318fe57SMatthew G. Knepley PetscInt cdim = 1, v; 3099318fe57SMatthew G. Knepley PetscErrorCode ierr; 310552f7358SJed Brown 3119318fe57SMatthew G. Knepley PetscFunctionBegin; 3129318fe57SMatthew G. Knepley ierr = PetscOptionsGetBool(((PetscObject) dm)->options,((PetscObject) dm)->prefix, "-dm_plex_separate_marker", &markerSeparate, NULL);CHKERRQ(ierr); 3139318fe57SMatthew G. Knepley if (markerSeparate) { 3149318fe57SMatthew G. Knepley markerRight = 2; 3159318fe57SMatthew G. Knepley markerLeft = 1; 3169318fe57SMatthew G. Knepley } 3179318fe57SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 3189318fe57SMatthew G. Knepley if (!rank) { 3199318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numVertices);CHKERRQ(ierr); 3209318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 3219318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", 0, markerLeft);CHKERRQ(ierr); 3229318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", 1, markerRight);CHKERRQ(ierr); 3239318fe57SMatthew G. Knepley } 3249318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 3259318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 3269318fe57SMatthew G. Knepley /* Build coordinates */ 3279318fe57SMatthew G. Knepley ierr = DMSetCoordinateDim(dm, cdim);CHKERRQ(ierr); 3289318fe57SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 3299318fe57SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 3309318fe57SMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, 0, numVertices);CHKERRQ(ierr); 3319318fe57SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, cdim);CHKERRQ(ierr); 3329318fe57SMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 3339318fe57SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, cdim);CHKERRQ(ierr); 3349318fe57SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, cdim);CHKERRQ(ierr); 3359318fe57SMatthew G. Knepley } 3369318fe57SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 3379318fe57SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 3389318fe57SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 3399318fe57SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 3409318fe57SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 3419318fe57SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, cdim);CHKERRQ(ierr); 3429318fe57SMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 3439318fe57SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 3449318fe57SMatthew G. Knepley coords[0] = lower[0]; 3459318fe57SMatthew G. Knepley coords[1] = upper[0]; 3469318fe57SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 3479318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 3489318fe57SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 3499318fe57SMatthew G. Knepley PetscFunctionReturn(0); 3509318fe57SMatthew G. Knepley } 35126492d91SMatthew G. Knepley 3529318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxSurfaceMesh_Tensor_2D_Internal(DM dm, const PetscReal lower[], const PetscReal upper[], const PetscInt edges[]) 353552f7358SJed Brown { 3541df21d24SMatthew G. Knepley const PetscInt numVertices = (edges[0]+1)*(edges[1]+1); 3551df21d24SMatthew G. Knepley const PetscInt numEdges = edges[0]*(edges[1]+1) + (edges[0]+1)*edges[1]; 356552f7358SJed Brown PetscInt markerTop = 1; 357552f7358SJed Brown PetscInt markerBottom = 1; 358552f7358SJed Brown PetscInt markerRight = 1; 359552f7358SJed Brown PetscInt markerLeft = 1; 360552f7358SJed Brown PetscBool markerSeparate = PETSC_FALSE; 361552f7358SJed Brown Vec coordinates; 362552f7358SJed Brown PetscSection coordSection; 363552f7358SJed Brown PetscScalar *coords; 364552f7358SJed Brown PetscInt coordSize; 365552f7358SJed Brown PetscMPIInt rank; 366552f7358SJed Brown PetscInt v, vx, vy; 367552f7358SJed Brown PetscErrorCode ierr; 368552f7358SJed Brown 369552f7358SJed Brown PetscFunctionBegin; 370c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject) dm)->options,((PetscObject) dm)->prefix, "-dm_plex_separate_marker", &markerSeparate, NULL);CHKERRQ(ierr); 371552f7358SJed Brown if (markerSeparate) { 3721df21d24SMatthew G. Knepley markerTop = 3; 3731df21d24SMatthew G. Knepley markerBottom = 1; 3741df21d24SMatthew G. Knepley markerRight = 2; 3751df21d24SMatthew G. Knepley markerLeft = 4; 376552f7358SJed Brown } 377ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 378552f7358SJed Brown if (!rank) { 379552f7358SJed Brown PetscInt e, ex, ey; 380552f7358SJed Brown 381552f7358SJed Brown ierr = DMPlexSetChart(dm, 0, numEdges+numVertices);CHKERRQ(ierr); 382552f7358SJed Brown for (e = 0; e < numEdges; ++e) { 383552f7358SJed Brown ierr = DMPlexSetConeSize(dm, e, 2);CHKERRQ(ierr); 384552f7358SJed Brown } 385552f7358SJed Brown ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 386552f7358SJed Brown for (vx = 0; vx <= edges[0]; vx++) { 387552f7358SJed Brown for (ey = 0; ey < edges[1]; ey++) { 388552f7358SJed Brown PetscInt edge = vx*edges[1] + ey + edges[0]*(edges[1]+1); 389552f7358SJed Brown PetscInt vertex = ey*(edges[0]+1) + vx + numEdges; 390da80777bSKarl Rupp PetscInt cone[2]; 391552f7358SJed Brown 392da80777bSKarl Rupp cone[0] = vertex; cone[1] = vertex+edges[0]+1; 393552f7358SJed Brown ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); 394552f7358SJed Brown if (vx == edges[0]) { 395c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerRight);CHKERRQ(ierr); 396c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerRight);CHKERRQ(ierr); 397552f7358SJed Brown if (ey == edges[1]-1) { 398c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerRight);CHKERRQ(ierr); 399c668006fSMatthew G. Knepley ierr = DMSetLabelValue(dm, "Face Sets", cone[1], markerRight);CHKERRQ(ierr); 400552f7358SJed Brown } 401552f7358SJed Brown } else if (vx == 0) { 402c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerLeft);CHKERRQ(ierr); 403c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerLeft);CHKERRQ(ierr); 404552f7358SJed Brown if (ey == edges[1]-1) { 405c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerLeft);CHKERRQ(ierr); 406c668006fSMatthew G. Knepley ierr = DMSetLabelValue(dm, "Face Sets", cone[1], markerLeft);CHKERRQ(ierr); 407552f7358SJed Brown } 408552f7358SJed Brown } 409552f7358SJed Brown } 410552f7358SJed Brown } 411552f7358SJed Brown for (vy = 0; vy <= edges[1]; vy++) { 412552f7358SJed Brown for (ex = 0; ex < edges[0]; ex++) { 413552f7358SJed Brown PetscInt edge = vy*edges[0] + ex; 414552f7358SJed Brown PetscInt vertex = vy*(edges[0]+1) + ex + numEdges; 415da80777bSKarl Rupp PetscInt cone[2]; 416552f7358SJed Brown 417da80777bSKarl Rupp cone[0] = vertex; cone[1] = vertex+1; 418552f7358SJed Brown ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); 419552f7358SJed Brown if (vy == edges[1]) { 420c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerTop);CHKERRQ(ierr); 421c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerTop);CHKERRQ(ierr); 422552f7358SJed Brown if (ex == edges[0]-1) { 423c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerTop);CHKERRQ(ierr); 424c668006fSMatthew G. Knepley ierr = DMSetLabelValue(dm, "Face Sets", cone[1], markerTop);CHKERRQ(ierr); 425552f7358SJed Brown } 426552f7358SJed Brown } else if (vy == 0) { 427c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBottom);CHKERRQ(ierr); 428c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerBottom);CHKERRQ(ierr); 429552f7358SJed Brown if (ex == edges[0]-1) { 430c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerBottom);CHKERRQ(ierr); 431c668006fSMatthew G. Knepley ierr = DMSetLabelValue(dm, "Face Sets", cone[1], markerBottom);CHKERRQ(ierr); 432552f7358SJed Brown } 433552f7358SJed Brown } 434552f7358SJed Brown } 435552f7358SJed Brown } 436552f7358SJed Brown } 437552f7358SJed Brown ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 438552f7358SJed Brown ierr = DMPlexStratify(dm);CHKERRQ(ierr); 439552f7358SJed Brown /* Build coordinates */ 4409596c6baSMatthew G. Knepley ierr = DMSetCoordinateDim(dm, 2);CHKERRQ(ierr); 441c2166f76SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 442972bc18aSToby Isaac ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 443552f7358SJed Brown ierr = PetscSectionSetChart(coordSection, numEdges, numEdges + numVertices);CHKERRQ(ierr); 444972bc18aSToby Isaac ierr = PetscSectionSetFieldComponents(coordSection, 0, 2);CHKERRQ(ierr); 445552f7358SJed Brown for (v = numEdges; v < numEdges+numVertices; ++v) { 446552f7358SJed Brown ierr = PetscSectionSetDof(coordSection, v, 2);CHKERRQ(ierr); 447972bc18aSToby Isaac ierr = PetscSectionSetFieldDof(coordSection, v, 0, 2);CHKERRQ(ierr); 448552f7358SJed Brown } 449552f7358SJed Brown ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 450552f7358SJed Brown ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 4518b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 452da16285aSMichael Lange ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 453552f7358SJed Brown ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 4548b9ced59SLisandro Dalcin ierr = VecSetBlockSize(coordinates, 2);CHKERRQ(ierr); 4552eb5907fSJed Brown ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 456552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 457552f7358SJed Brown for (vy = 0; vy <= edges[1]; ++vy) { 458552f7358SJed Brown for (vx = 0; vx <= edges[0]; ++vx) { 459552f7358SJed Brown coords[(vy*(edges[0]+1)+vx)*2+0] = lower[0] + ((upper[0] - lower[0])/edges[0])*vx; 460552f7358SJed Brown coords[(vy*(edges[0]+1)+vx)*2+1] = lower[1] + ((upper[1] - lower[1])/edges[1])*vy; 461552f7358SJed Brown } 462552f7358SJed Brown } 463552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 464552f7358SJed Brown ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 465552f7358SJed Brown ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 466552f7358SJed Brown PetscFunctionReturn(0); 467552f7358SJed Brown } 468552f7358SJed Brown 4699318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxSurfaceMesh_Tensor_3D_Internal(DM dm, const PetscReal lower[], const PetscReal upper[], const PetscInt faces[]) 470552f7358SJed Brown { 4719e8abbc3SMichael Lange PetscInt vertices[3], numVertices; 4727b59f5a9SMichael Lange PetscInt numFaces = 2*faces[0]*faces[1] + 2*faces[1]*faces[2] + 2*faces[0]*faces[2]; 473552f7358SJed Brown Vec coordinates; 474552f7358SJed Brown PetscSection coordSection; 475552f7358SJed Brown PetscScalar *coords; 476552f7358SJed Brown PetscInt coordSize; 477552f7358SJed Brown PetscMPIInt rank; 478552f7358SJed Brown PetscInt v, vx, vy, vz; 4797b59f5a9SMichael Lange PetscInt voffset, iface=0, cone[4]; 480552f7358SJed Brown PetscErrorCode ierr; 481552f7358SJed Brown 482552f7358SJed Brown PetscFunctionBegin; 48382f516ccSBarry Smith if ((faces[0] < 1) || (faces[1] < 1) || (faces[2] < 1)) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Must have at least 1 face per side"); 484ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 4859e8abbc3SMichael Lange vertices[0] = faces[0]+1; vertices[1] = faces[1]+1; vertices[2] = faces[2]+1; 4869e8abbc3SMichael Lange numVertices = vertices[0]*vertices[1]*vertices[2]; 487552f7358SJed Brown if (!rank) { 488552f7358SJed Brown PetscInt f; 489552f7358SJed Brown 490552f7358SJed Brown ierr = DMPlexSetChart(dm, 0, numFaces+numVertices);CHKERRQ(ierr); 491552f7358SJed Brown for (f = 0; f < numFaces; ++f) { 492552f7358SJed Brown ierr = DMPlexSetConeSize(dm, f, 4);CHKERRQ(ierr); 493552f7358SJed Brown } 494552f7358SJed Brown ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 4957b59f5a9SMichael Lange 4967b59f5a9SMichael Lange /* Side 0 (Top) */ 4977b59f5a9SMichael Lange for (vy = 0; vy < faces[1]; vy++) { 4987b59f5a9SMichael Lange for (vx = 0; vx < faces[0]; vx++) { 4997b59f5a9SMichael Lange voffset = numFaces + vertices[0]*vertices[1]*(vertices[2]-1) + vy*vertices[0] + vx; 5007b59f5a9SMichael Lange cone[0] = voffset; cone[1] = voffset+1; cone[2] = voffset+vertices[0]+1; cone[3] = voffset+vertices[0]; 5017b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 502c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 503c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 504c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+1, 1);CHKERRQ(ierr); 505c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+0, 1);CHKERRQ(ierr); 506c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+1, 1);CHKERRQ(ierr); 5077b59f5a9SMichael Lange iface++; 508552f7358SJed Brown } 509552f7358SJed Brown } 5107b59f5a9SMichael Lange 5117b59f5a9SMichael Lange /* Side 1 (Bottom) */ 5127b59f5a9SMichael Lange for (vy = 0; vy < faces[1]; vy++) { 5137b59f5a9SMichael Lange for (vx = 0; vx < faces[0]; vx++) { 5147b59f5a9SMichael Lange voffset = numFaces + vy*(faces[0]+1) + vx; 5157b59f5a9SMichael Lange cone[0] = voffset+1; cone[1] = voffset; cone[2] = voffset+vertices[0]; cone[3] = voffset+vertices[0]+1; 5167b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 517c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 518c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 519c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+1, 1);CHKERRQ(ierr); 520c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+0, 1);CHKERRQ(ierr); 521c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+1, 1);CHKERRQ(ierr); 5227b59f5a9SMichael Lange iface++; 523552f7358SJed Brown } 524552f7358SJed Brown } 5257b59f5a9SMichael Lange 5267b59f5a9SMichael Lange /* Side 2 (Front) */ 5277b59f5a9SMichael Lange for (vz = 0; vz < faces[2]; vz++) { 5287b59f5a9SMichael Lange for (vx = 0; vx < faces[0]; vx++) { 5297b59f5a9SMichael Lange voffset = numFaces + vz*vertices[0]*vertices[1] + vx; 5307b59f5a9SMichael Lange cone[0] = voffset; cone[1] = voffset+1; cone[2] = voffset+vertices[0]*vertices[1]+1; cone[3] = voffset+vertices[0]*vertices[1]; 5317b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 532c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 533c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 534c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+1, 1);CHKERRQ(ierr); 535c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+0, 1);CHKERRQ(ierr); 536c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+1, 1);CHKERRQ(ierr); 5377b59f5a9SMichael Lange iface++; 538552f7358SJed Brown } 5397b59f5a9SMichael Lange } 5407b59f5a9SMichael Lange 5417b59f5a9SMichael Lange /* Side 3 (Back) */ 5427b59f5a9SMichael Lange for (vz = 0; vz < faces[2]; vz++) { 5437b59f5a9SMichael Lange for (vx = 0; vx < faces[0]; vx++) { 5447b59f5a9SMichael Lange voffset = numFaces + vz*vertices[0]*vertices[1] + vertices[0]*(vertices[1]-1) + vx; 5457b59f5a9SMichael Lange cone[0] = voffset+vertices[0]*vertices[1]; cone[1] = voffset+vertices[0]*vertices[1]+1; 5467b59f5a9SMichael Lange cone[2] = voffset+1; cone[3] = voffset; 5477b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 548c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 549c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 550c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+1, 1);CHKERRQ(ierr); 551c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+0, 1);CHKERRQ(ierr); 552c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+1, 1);CHKERRQ(ierr); 5537b59f5a9SMichael Lange iface++; 5547b59f5a9SMichael Lange } 5557b59f5a9SMichael Lange } 5567b59f5a9SMichael Lange 5577b59f5a9SMichael Lange /* Side 4 (Left) */ 5587b59f5a9SMichael Lange for (vz = 0; vz < faces[2]; vz++) { 5597b59f5a9SMichael Lange for (vy = 0; vy < faces[1]; vy++) { 5607b59f5a9SMichael Lange voffset = numFaces + vz*vertices[0]*vertices[1] + vy*vertices[0]; 5617b59f5a9SMichael Lange cone[0] = voffset; cone[1] = voffset+vertices[0]*vertices[1]; 5627b59f5a9SMichael Lange cone[2] = voffset+vertices[0]*vertices[1]+vertices[0]; cone[3] = voffset+vertices[0]; 5637b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 564c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 565c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 566c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+0, 1);CHKERRQ(ierr); 567c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[1]+0, 1);CHKERRQ(ierr); 568c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+vertices[0], 1);CHKERRQ(ierr); 5697b59f5a9SMichael Lange iface++; 5707b59f5a9SMichael Lange } 5717b59f5a9SMichael Lange } 5727b59f5a9SMichael Lange 5737b59f5a9SMichael Lange /* Side 5 (Right) */ 5747b59f5a9SMichael Lange for (vz = 0; vz < faces[2]; vz++) { 5757b59f5a9SMichael Lange for (vy = 0; vy < faces[1]; vy++) { 576aab5bcd8SJed Brown voffset = numFaces + vz*vertices[0]*vertices[1] + vy*vertices[0] + faces[0]; 5777b59f5a9SMichael Lange cone[0] = voffset+vertices[0]*vertices[1]; cone[1] = voffset; 5787b59f5a9SMichael Lange cone[2] = voffset+vertices[0]; cone[3] = voffset+vertices[0]*vertices[1]+vertices[0]; 5797b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 580c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 581c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 582c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+0, 1);CHKERRQ(ierr); 583c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+0, 1);CHKERRQ(ierr); 584c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+vertices[0], 1);CHKERRQ(ierr); 5857b59f5a9SMichael Lange iface++; 5867b59f5a9SMichael Lange } 587552f7358SJed Brown } 588552f7358SJed Brown } 589552f7358SJed Brown ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 590552f7358SJed Brown ierr = DMPlexStratify(dm);CHKERRQ(ierr); 591552f7358SJed Brown /* Build coordinates */ 5929596c6baSMatthew G. Knepley ierr = DMSetCoordinateDim(dm, 3);CHKERRQ(ierr); 593c2166f76SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 5949318fe57SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 595552f7358SJed Brown ierr = PetscSectionSetChart(coordSection, numFaces, numFaces + numVertices);CHKERRQ(ierr); 5969318fe57SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, 3);CHKERRQ(ierr); 597552f7358SJed Brown for (v = numFaces; v < numFaces+numVertices; ++v) { 598552f7358SJed Brown ierr = PetscSectionSetDof(coordSection, v, 3);CHKERRQ(ierr); 5999318fe57SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, 3);CHKERRQ(ierr); 600552f7358SJed Brown } 601552f7358SJed Brown ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 602552f7358SJed Brown ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 6038b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 604552f7358SJed Brown ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 605552f7358SJed Brown ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 6068b9ced59SLisandro Dalcin ierr = VecSetBlockSize(coordinates, 3);CHKERRQ(ierr); 6072eb5907fSJed Brown ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 608552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 609552f7358SJed Brown for (vz = 0; vz <= faces[2]; ++vz) { 610552f7358SJed Brown for (vy = 0; vy <= faces[1]; ++vy) { 611552f7358SJed Brown for (vx = 0; vx <= faces[0]; ++vx) { 612552f7358SJed Brown coords[((vz*(faces[1]+1)+vy)*(faces[0]+1)+vx)*3+0] = lower[0] + ((upper[0] - lower[0])/faces[0])*vx; 613552f7358SJed Brown coords[((vz*(faces[1]+1)+vy)*(faces[0]+1)+vx)*3+1] = lower[1] + ((upper[1] - lower[1])/faces[1])*vy; 614552f7358SJed Brown coords[((vz*(faces[1]+1)+vy)*(faces[0]+1)+vx)*3+2] = lower[2] + ((upper[2] - lower[2])/faces[2])*vz; 615552f7358SJed Brown } 616552f7358SJed Brown } 617552f7358SJed Brown } 618552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 619552f7358SJed Brown ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 620552f7358SJed Brown ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 621552f7358SJed Brown PetscFunctionReturn(0); 622552f7358SJed Brown } 623552f7358SJed Brown 6249318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxSurfaceMesh_Internal(DM dm, PetscInt dim, const PetscInt faces[], const PetscReal lower[], const PetscReal upper[], PetscBool interpolate) 6259318fe57SMatthew G. Knepley { 6269318fe57SMatthew G. Knepley PetscErrorCode ierr; 6279318fe57SMatthew G. Knepley 6289318fe57SMatthew G. Knepley PetscFunctionBegin; 6299318fe57SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 6309318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim-1);CHKERRQ(ierr); 6319318fe57SMatthew G. Knepley ierr = DMSetCoordinateDim(dm, dim);CHKERRQ(ierr); 6329318fe57SMatthew G. Knepley switch (dim) { 6339318fe57SMatthew G. Knepley case 1: ierr = DMPlexCreateBoxSurfaceMesh_Tensor_1D_Internal(dm, lower, upper, faces);CHKERRQ(ierr);break; 6349318fe57SMatthew G. Knepley case 2: ierr = DMPlexCreateBoxSurfaceMesh_Tensor_2D_Internal(dm, lower, upper, faces);CHKERRQ(ierr);break; 6359318fe57SMatthew G. Knepley case 3: ierr = DMPlexCreateBoxSurfaceMesh_Tensor_3D_Internal(dm, lower, upper, faces);CHKERRQ(ierr);break; 6369318fe57SMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Dimension not supported: %D", dim); 6379318fe57SMatthew G. Knepley } 6389318fe57SMatthew G. Knepley if (interpolate) {ierr = DMPlexInterpolateInPlace_Internal(dm);CHKERRQ(ierr);} 6399318fe57SMatthew G. Knepley PetscFunctionReturn(0); 6409318fe57SMatthew G. Knepley } 6419318fe57SMatthew G. Knepley 6429318fe57SMatthew G. Knepley /*@C 6439318fe57SMatthew G. Knepley DMPlexCreateBoxSurfaceMesh - Creates a mesh on the surface of the tensor product of unit intervals (box) using tensor cells (hexahedra). 6449318fe57SMatthew G. Knepley 6459318fe57SMatthew G. Knepley Collective 6469318fe57SMatthew G. Knepley 6479318fe57SMatthew G. Knepley Input Parameters: 6489318fe57SMatthew G. Knepley + comm - The communicator for the DM object 6499318fe57SMatthew G. Knepley . dim - The spatial dimension of the box, so the resulting mesh is has dimension dim-1 6509318fe57SMatthew G. Knepley . faces - Number of faces per dimension, or NULL for (1,) in 1D and (2, 2) in 2D and (1, 1, 1) in 3D 6519318fe57SMatthew G. Knepley . lower - The lower left corner, or NULL for (0, 0, 0) 6529318fe57SMatthew G. Knepley . upper - The upper right corner, or NULL for (1, 1, 1) 6539318fe57SMatthew G. Knepley - interpolate - Flag to create intermediate mesh pieces (edges, faces) 6549318fe57SMatthew G. Knepley 6559318fe57SMatthew G. Knepley Output Parameter: 6569318fe57SMatthew G. Knepley . dm - The DM object 6579318fe57SMatthew G. Knepley 6589318fe57SMatthew G. Knepley Level: beginner 6599318fe57SMatthew G. Knepley 6609318fe57SMatthew G. Knepley .seealso: DMSetFromOptions(), DMPlexCreateBoxMesh(), DMPlexCreateFromFile(), DMSetType(), DMCreate() 6619318fe57SMatthew G. Knepley @*/ 6629318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateBoxSurfaceMesh(MPI_Comm comm, PetscInt dim, const PetscInt faces[], const PetscReal lower[], const PetscReal upper[], PetscBool interpolate, DM *dm) 6639318fe57SMatthew G. Knepley { 6649318fe57SMatthew G. Knepley PetscInt fac[3] = {1, 1, 1}; 6659318fe57SMatthew G. Knepley PetscReal low[3] = {0, 0, 0}; 6669318fe57SMatthew G. Knepley PetscReal upp[3] = {1, 1, 1}; 6679318fe57SMatthew G. Knepley PetscErrorCode ierr; 6689318fe57SMatthew G. Knepley 6699318fe57SMatthew G. Knepley PetscFunctionBegin; 6709318fe57SMatthew G. Knepley ierr = DMCreate(comm,dm);CHKERRQ(ierr); 6719318fe57SMatthew G. Knepley ierr = DMSetType(*dm,DMPLEX);CHKERRQ(ierr); 6729318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxSurfaceMesh_Internal(*dm, dim, faces ? faces : fac, lower ? lower : low, upper ? upper : upp, interpolate);CHKERRQ(ierr); 6739318fe57SMatthew G. Knepley PetscFunctionReturn(0); 6749318fe57SMatthew G. Knepley } 6759318fe57SMatthew G. Knepley 6769318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateLineMesh_Internal(DM dm,PetscInt segments,PetscReal lower,PetscReal upper,DMBoundaryType bd) 677fdbf62faSLisandro Dalcin { 678fdbf62faSLisandro Dalcin PetscInt i,fStart,fEnd,numCells = 0,numVerts = 0; 679fdbf62faSLisandro Dalcin PetscInt numPoints[2],*coneSize,*cones,*coneOrientations; 680fdbf62faSLisandro Dalcin PetscScalar *vertexCoords; 681fdbf62faSLisandro Dalcin PetscReal L,maxCell; 682fdbf62faSLisandro Dalcin PetscBool markerSeparate = PETSC_FALSE; 683fdbf62faSLisandro Dalcin PetscInt markerLeft = 1, faceMarkerLeft = 1; 684fdbf62faSLisandro Dalcin PetscInt markerRight = 1, faceMarkerRight = 2; 685fdbf62faSLisandro Dalcin PetscBool wrap = (bd == DM_BOUNDARY_PERIODIC || bd == DM_BOUNDARY_TWIST) ? PETSC_TRUE : PETSC_FALSE; 686fdbf62faSLisandro Dalcin PetscMPIInt rank; 687fdbf62faSLisandro Dalcin PetscErrorCode ierr; 688fdbf62faSLisandro Dalcin 689fdbf62faSLisandro Dalcin PetscFunctionBegin; 6909318fe57SMatthew G. Knepley PetscValidPointer(dm,1); 691fdbf62faSLisandro Dalcin 6929318fe57SMatthew G. Knepley ierr = DMSetDimension(dm,1);CHKERRQ(ierr); 6939318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm,"marker");CHKERRQ(ierr); 6949318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm,"Face Sets");CHKERRQ(ierr); 695fdbf62faSLisandro Dalcin 6969318fe57SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm),&rank);CHKERRMPI(ierr); 697fdbf62faSLisandro Dalcin if (!rank) numCells = segments; 698fdbf62faSLisandro Dalcin if (!rank) numVerts = segments + (wrap ? 0 : 1); 699fdbf62faSLisandro Dalcin 700fdbf62faSLisandro Dalcin numPoints[0] = numVerts ; numPoints[1] = numCells; 701fdbf62faSLisandro Dalcin ierr = PetscMalloc4(numCells+numVerts,&coneSize,numCells*2,&cones,numCells+numVerts,&coneOrientations,numVerts,&vertexCoords);CHKERRQ(ierr); 702580bdb30SBarry Smith ierr = PetscArrayzero(coneOrientations,numCells+numVerts);CHKERRQ(ierr); 703fdbf62faSLisandro Dalcin for (i = 0; i < numCells; ++i) { coneSize[i] = 2; } 704fdbf62faSLisandro Dalcin for (i = 0; i < numVerts; ++i) { coneSize[numCells+i] = 0; } 705fdbf62faSLisandro Dalcin for (i = 0; i < numCells; ++i) { cones[2*i] = numCells + i%numVerts; cones[2*i+1] = numCells + (i+1)%numVerts; } 706fdbf62faSLisandro Dalcin for (i = 0; i < numVerts; ++i) { vertexCoords[i] = lower + (upper-lower)*((PetscReal)i/(PetscReal)numCells); } 7079318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm,1,numPoints,coneSize,cones,coneOrientations,vertexCoords);CHKERRQ(ierr); 708fdbf62faSLisandro Dalcin ierr = PetscFree4(coneSize,cones,coneOrientations,vertexCoords);CHKERRQ(ierr); 709fdbf62faSLisandro Dalcin 7109318fe57SMatthew G. Knepley ierr = PetscOptionsGetBool(((PetscObject)dm)->options,((PetscObject)dm)->prefix,"-dm_plex_separate_marker",&markerSeparate,NULL);CHKERRQ(ierr); 711fdbf62faSLisandro Dalcin if (markerSeparate) { markerLeft = faceMarkerLeft; markerRight = faceMarkerRight;} 712fdbf62faSLisandro Dalcin if (!wrap && !rank) { 7139318fe57SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm,1,&fStart,&fEnd);CHKERRQ(ierr); 7149318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm,"marker",fStart,markerLeft);CHKERRQ(ierr); 7159318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm,"marker",fEnd-1,markerRight);CHKERRQ(ierr); 7169318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm,"Face Sets",fStart,faceMarkerLeft);CHKERRQ(ierr); 7179318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm,"Face Sets",fEnd-1,faceMarkerRight);CHKERRQ(ierr); 718fdbf62faSLisandro Dalcin } 719fdbf62faSLisandro Dalcin if (wrap) { 720fdbf62faSLisandro Dalcin L = upper - lower; 721fdbf62faSLisandro Dalcin maxCell = (PetscReal)1.1*(L/(PetscReal)PetscMax(1,segments)); 7229318fe57SMatthew G. Knepley ierr = DMSetPeriodicity(dm,PETSC_TRUE,&maxCell,&L,&bd);CHKERRQ(ierr); 723fdbf62faSLisandro Dalcin } 7249318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr); 725fdbf62faSLisandro Dalcin PetscFunctionReturn(0); 726fdbf62faSLisandro Dalcin } 727fdbf62faSLisandro Dalcin 7289318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxMesh_Simplex_Internal(DM dm, PetscInt dim, const PetscInt faces[], const PetscReal lower[], const PetscReal upper[], const DMBoundaryType periodicity[], PetscBool interpolate) 729d6218766SMatthew G. Knepley { 7309318fe57SMatthew G. Knepley DM boundary, vol; 731768d5fceSMatthew G. Knepley PetscInt i; 732d6218766SMatthew G. Knepley PetscErrorCode ierr; 733d6218766SMatthew G. Knepley 734d6218766SMatthew G. Knepley PetscFunctionBegin; 7359318fe57SMatthew G. Knepley PetscValidPointer(dm, 1); 7369318fe57SMatthew G. Knepley for (i = 0; i < dim; ++i) if (periodicity[i] != DM_BOUNDARY_NONE) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Periodicity is not supported for simplex meshes"); 7379318fe57SMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject) dm), &boundary);CHKERRQ(ierr); 738d6218766SMatthew G. Knepley ierr = DMSetType(boundary, DMPLEX);CHKERRQ(ierr); 7399318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxSurfaceMesh_Internal(boundary, dim, faces, lower, upper, PETSC_FALSE);CHKERRQ(ierr); 7409318fe57SMatthew G. Knepley ierr = DMPlexGenerate(boundary, NULL, interpolate, &vol);CHKERRQ(ierr); 7419318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &vol);CHKERRQ(ierr); 742d6218766SMatthew G. Knepley ierr = DMDestroy(&boundary);CHKERRQ(ierr); 743d6218766SMatthew G. Knepley PetscFunctionReturn(0); 744d6218766SMatthew G. Knepley } 745d6218766SMatthew G. Knepley 7463dfda0b1SToby Isaac static PetscErrorCode DMPlexCreateCubeMesh_Internal(DM dm, const PetscReal lower[], const PetscReal upper[], const PetscInt edges[], DMBoundaryType bdX, DMBoundaryType bdY, DMBoundaryType bdZ) 7473dfda0b1SToby Isaac { 748ed0e4b50SMatthew G. Knepley DMLabel cutLabel = NULL; 749f4eb4c5dSMatthew G. Knepley PetscInt markerTop = 1, faceMarkerTop = 1; 750f4eb4c5dSMatthew G. Knepley PetscInt markerBottom = 1, faceMarkerBottom = 1; 751f4eb4c5dSMatthew G. Knepley PetscInt markerFront = 1, faceMarkerFront = 1; 752f4eb4c5dSMatthew G. Knepley PetscInt markerBack = 1, faceMarkerBack = 1; 753f4eb4c5dSMatthew G. Knepley PetscInt markerRight = 1, faceMarkerRight = 1; 754f4eb4c5dSMatthew G. Knepley PetscInt markerLeft = 1, faceMarkerLeft = 1; 7553dfda0b1SToby Isaac PetscInt dim; 756d8211ee3SMatthew G. Knepley PetscBool markerSeparate = PETSC_FALSE, cutMarker = PETSC_FALSE; 7573dfda0b1SToby Isaac PetscMPIInt rank; 7583dfda0b1SToby Isaac PetscErrorCode ierr; 7593dfda0b1SToby Isaac 7603dfda0b1SToby Isaac PetscFunctionBegin; 761f0226e14SMatthew G. Knepley ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 762ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 76350ae33c3SToby Isaac ierr = DMCreateLabel(dm,"marker");CHKERRQ(ierr); 76450ae33c3SToby Isaac ierr = DMCreateLabel(dm,"Face Sets");CHKERRQ(ierr); 7654c67ea77SStefano Zampini ierr = PetscOptionsGetBool(((PetscObject) dm)->options,((PetscObject) dm)->prefix, "-dm_plex_periodic_cut", &cutMarker, NULL);CHKERRQ(ierr); 766d8211ee3SMatthew G. Knepley if (bdX == DM_BOUNDARY_PERIODIC || bdX == DM_BOUNDARY_TWIST || 767d8211ee3SMatthew G. Knepley bdY == DM_BOUNDARY_PERIODIC || bdY == DM_BOUNDARY_TWIST || 768d8211ee3SMatthew G. Knepley bdZ == DM_BOUNDARY_PERIODIC || bdZ == DM_BOUNDARY_TWIST) { 7694c67ea77SStefano Zampini 770d1c88043SMatthew G. Knepley if (cutMarker) {ierr = DMCreateLabel(dm, "periodic_cut");CHKERRQ(ierr); ierr = DMGetLabel(dm, "periodic_cut", &cutLabel);CHKERRQ(ierr);} 771d8211ee3SMatthew G. Knepley } 7723dfda0b1SToby Isaac switch (dim) { 7733dfda0b1SToby Isaac case 2: 774f4eb4c5dSMatthew G. Knepley faceMarkerTop = 3; 775f4eb4c5dSMatthew G. Knepley faceMarkerBottom = 1; 776f4eb4c5dSMatthew G. Knepley faceMarkerRight = 2; 777f4eb4c5dSMatthew G. Knepley faceMarkerLeft = 4; 7783dfda0b1SToby Isaac break; 7793dfda0b1SToby Isaac case 3: 780f4eb4c5dSMatthew G. Knepley faceMarkerBottom = 1; 781f4eb4c5dSMatthew G. Knepley faceMarkerTop = 2; 782f4eb4c5dSMatthew G. Knepley faceMarkerFront = 3; 783f4eb4c5dSMatthew G. Knepley faceMarkerBack = 4; 784f4eb4c5dSMatthew G. Knepley faceMarkerRight = 5; 785f4eb4c5dSMatthew G. Knepley faceMarkerLeft = 6; 7863dfda0b1SToby Isaac break; 7873dfda0b1SToby Isaac default: 78889c010cfSBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Dimension %D not supported",dim); 7893dfda0b1SToby Isaac } 790c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject) dm)->options,((PetscObject) dm)->prefix, "-dm_plex_separate_marker", &markerSeparate, NULL);CHKERRQ(ierr); 791f4eb4c5dSMatthew G. Knepley if (markerSeparate) { 792f4eb4c5dSMatthew G. Knepley markerBottom = faceMarkerBottom; 793f4eb4c5dSMatthew G. Knepley markerTop = faceMarkerTop; 794f4eb4c5dSMatthew G. Knepley markerFront = faceMarkerFront; 795f4eb4c5dSMatthew G. Knepley markerBack = faceMarkerBack; 796f4eb4c5dSMatthew G. Knepley markerRight = faceMarkerRight; 797f4eb4c5dSMatthew G. Knepley markerLeft = faceMarkerLeft; 7983dfda0b1SToby Isaac } 7993dfda0b1SToby Isaac { 8003dfda0b1SToby Isaac const PetscInt numXEdges = !rank ? edges[0] : 0; 8013dfda0b1SToby Isaac const PetscInt numYEdges = !rank ? edges[1] : 0; 8023dfda0b1SToby Isaac const PetscInt numZEdges = !rank ? edges[2] : 0; 8033dfda0b1SToby Isaac const PetscInt numXVertices = !rank ? (bdX == DM_BOUNDARY_PERIODIC || bdX == DM_BOUNDARY_TWIST ? edges[0] : edges[0]+1) : 0; 8043dfda0b1SToby Isaac const PetscInt numYVertices = !rank ? (bdY == DM_BOUNDARY_PERIODIC || bdY == DM_BOUNDARY_TWIST ? edges[1] : edges[1]+1) : 0; 80542206facSLisandro Dalcin const PetscInt numZVertices = !rank ? (bdZ == DM_BOUNDARY_PERIODIC || bdZ == DM_BOUNDARY_TWIST ? edges[2] : edges[2]+1) : 0; 8063dfda0b1SToby Isaac const PetscInt numCells = numXEdges*numYEdges*numZEdges; 8073dfda0b1SToby Isaac const PetscInt numXFaces = numYEdges*numZEdges; 8083dfda0b1SToby Isaac const PetscInt numYFaces = numXEdges*numZEdges; 8093dfda0b1SToby Isaac const PetscInt numZFaces = numXEdges*numYEdges; 8103dfda0b1SToby Isaac const PetscInt numTotXFaces = numXVertices*numXFaces; 8113dfda0b1SToby Isaac const PetscInt numTotYFaces = numYVertices*numYFaces; 8123dfda0b1SToby Isaac const PetscInt numTotZFaces = numZVertices*numZFaces; 8133dfda0b1SToby Isaac const PetscInt numFaces = numTotXFaces + numTotYFaces + numTotZFaces; 8143dfda0b1SToby Isaac const PetscInt numTotXEdges = numXEdges*numYVertices*numZVertices; 8153dfda0b1SToby Isaac const PetscInt numTotYEdges = numYEdges*numXVertices*numZVertices; 8163dfda0b1SToby Isaac const PetscInt numTotZEdges = numZEdges*numXVertices*numYVertices; 8173dfda0b1SToby Isaac const PetscInt numVertices = numXVertices*numYVertices*numZVertices; 8183dfda0b1SToby Isaac const PetscInt numEdges = numTotXEdges + numTotYEdges + numTotZEdges; 8193dfda0b1SToby Isaac const PetscInt firstVertex = (dim == 2) ? numFaces : numCells; 8203dfda0b1SToby Isaac const PetscInt firstXFace = (dim == 2) ? 0 : numCells + numVertices; 8213dfda0b1SToby Isaac const PetscInt firstYFace = firstXFace + numTotXFaces; 8223dfda0b1SToby Isaac const PetscInt firstZFace = firstYFace + numTotYFaces; 8233dfda0b1SToby Isaac const PetscInt firstXEdge = numCells + numFaces + numVertices; 8243dfda0b1SToby Isaac const PetscInt firstYEdge = firstXEdge + numTotXEdges; 8253dfda0b1SToby Isaac const PetscInt firstZEdge = firstYEdge + numTotYEdges; 8263dfda0b1SToby Isaac Vec coordinates; 8273dfda0b1SToby Isaac PetscSection coordSection; 8283dfda0b1SToby Isaac PetscScalar *coords; 8293dfda0b1SToby Isaac PetscInt coordSize; 8303dfda0b1SToby Isaac PetscInt v, vx, vy, vz; 8313dfda0b1SToby Isaac PetscInt c, f, fx, fy, fz, e, ex, ey, ez; 8323dfda0b1SToby Isaac 8333dfda0b1SToby Isaac ierr = DMPlexSetChart(dm, 0, numCells+numFaces+numEdges+numVertices);CHKERRQ(ierr); 8343dfda0b1SToby Isaac for (c = 0; c < numCells; c++) { 8353dfda0b1SToby Isaac ierr = DMPlexSetConeSize(dm, c, 6);CHKERRQ(ierr); 8363dfda0b1SToby Isaac } 8373dfda0b1SToby Isaac for (f = firstXFace; f < firstXFace+numFaces; ++f) { 8383dfda0b1SToby Isaac ierr = DMPlexSetConeSize(dm, f, 4);CHKERRQ(ierr); 8393dfda0b1SToby Isaac } 8403dfda0b1SToby Isaac for (e = firstXEdge; e < firstXEdge+numEdges; ++e) { 8413dfda0b1SToby Isaac ierr = DMPlexSetConeSize(dm, e, 2);CHKERRQ(ierr); 8423dfda0b1SToby Isaac } 8433dfda0b1SToby Isaac ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 8443dfda0b1SToby Isaac /* Build cells */ 8453dfda0b1SToby Isaac for (fz = 0; fz < numZEdges; ++fz) { 8463dfda0b1SToby Isaac for (fy = 0; fy < numYEdges; ++fy) { 8473dfda0b1SToby Isaac for (fx = 0; fx < numXEdges; ++fx) { 8483dfda0b1SToby Isaac PetscInt cell = (fz*numYEdges + fy)*numXEdges + fx; 8493dfda0b1SToby Isaac PetscInt faceB = firstZFace + (fy*numXEdges+fx)*numZVertices + fz; 8503dfda0b1SToby Isaac PetscInt faceT = firstZFace + (fy*numXEdges+fx)*numZVertices + ((fz+1)%numZVertices); 8513dfda0b1SToby Isaac PetscInt faceF = firstYFace + (fz*numXEdges+fx)*numYVertices + fy; 8523dfda0b1SToby Isaac PetscInt faceK = firstYFace + (fz*numXEdges+fx)*numYVertices + ((fy+1)%numYVertices); 8533dfda0b1SToby Isaac PetscInt faceL = firstXFace + (fz*numYEdges+fy)*numXVertices + fx; 8543dfda0b1SToby Isaac PetscInt faceR = firstXFace + (fz*numYEdges+fy)*numXVertices + ((fx+1)%numXVertices); 8553dfda0b1SToby Isaac /* B, T, F, K, R, L */ 85642206facSLisandro Dalcin PetscInt ornt[6] = {-4, 0, 0, -1, 0, -4}; /* ??? */ 85742206facSLisandro Dalcin PetscInt cone[6]; 8583dfda0b1SToby Isaac 8593dfda0b1SToby Isaac /* no boundary twisting in 3D */ 8603dfda0b1SToby Isaac cone[0] = faceB; cone[1] = faceT; cone[2] = faceF; cone[3] = faceK; cone[4] = faceR; cone[5] = faceL; 8613dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, cell, cone);CHKERRQ(ierr); 8623dfda0b1SToby Isaac ierr = DMPlexSetConeOrientation(dm, cell, ornt);CHKERRQ(ierr); 8638a5b437dSMatthew G. Knepley if (bdX != DM_BOUNDARY_NONE && fx == numXEdges-1 && cutLabel) {ierr = DMLabelSetValue(cutLabel, cell, 2);CHKERRQ(ierr);} 8648a5b437dSMatthew G. Knepley if (bdY != DM_BOUNDARY_NONE && fy == numYEdges-1 && cutLabel) {ierr = DMLabelSetValue(cutLabel, cell, 2);CHKERRQ(ierr);} 8658a5b437dSMatthew G. Knepley if (bdZ != DM_BOUNDARY_NONE && fz == numZEdges-1 && cutLabel) {ierr = DMLabelSetValue(cutLabel, cell, 2);CHKERRQ(ierr);} 8663dfda0b1SToby Isaac } 8673dfda0b1SToby Isaac } 8683dfda0b1SToby Isaac } 8693dfda0b1SToby Isaac /* Build x faces */ 8703dfda0b1SToby Isaac for (fz = 0; fz < numZEdges; ++fz) { 8713dfda0b1SToby Isaac for (fy = 0; fy < numYEdges; ++fy) { 8723dfda0b1SToby Isaac for (fx = 0; fx < numXVertices; ++fx) { 8733dfda0b1SToby Isaac PetscInt face = firstXFace + (fz*numYEdges+fy) *numXVertices+fx; 8743dfda0b1SToby Isaac PetscInt edgeL = firstZEdge + (fy *numXVertices+fx)*numZEdges + fz; 8753dfda0b1SToby Isaac PetscInt edgeR = firstZEdge + (((fy+1)%numYVertices)*numXVertices+fx)*numZEdges + fz; 8763dfda0b1SToby Isaac PetscInt edgeB = firstYEdge + (fz *numXVertices+fx)*numYEdges + fy; 8773dfda0b1SToby Isaac PetscInt edgeT = firstYEdge + (((fz+1)%numZVertices)*numXVertices+fx)*numYEdges + fy; 8783dfda0b1SToby Isaac PetscInt ornt[4] = {0, 0, -2, -2}; 8793dfda0b1SToby Isaac PetscInt cone[4]; 8803dfda0b1SToby Isaac 8813dfda0b1SToby Isaac if (dim == 3) { 8823dfda0b1SToby Isaac /* markers */ 8833dfda0b1SToby Isaac if (bdX != DM_BOUNDARY_PERIODIC) { 8843dfda0b1SToby Isaac if (fx == numXVertices-1) { 885c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerRight);CHKERRQ(ierr); 886c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerRight);CHKERRQ(ierr); 8873dfda0b1SToby Isaac } 8883dfda0b1SToby Isaac else if (fx == 0) { 889c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerLeft);CHKERRQ(ierr); 890c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerLeft);CHKERRQ(ierr); 8913dfda0b1SToby Isaac } 8923dfda0b1SToby Isaac } 8933dfda0b1SToby Isaac } 8943dfda0b1SToby Isaac cone[0] = edgeB; cone[1] = edgeR; cone[2] = edgeT; cone[3] = edgeL; 8953dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, face, cone);CHKERRQ(ierr); 8963dfda0b1SToby Isaac ierr = DMPlexSetConeOrientation(dm, face, ornt);CHKERRQ(ierr); 8973dfda0b1SToby Isaac } 8983dfda0b1SToby Isaac } 8993dfda0b1SToby Isaac } 9003dfda0b1SToby Isaac /* Build y faces */ 9013dfda0b1SToby Isaac for (fz = 0; fz < numZEdges; ++fz) { 90242206facSLisandro Dalcin for (fx = 0; fx < numXEdges; ++fx) { 9033dfda0b1SToby Isaac for (fy = 0; fy < numYVertices; ++fy) { 9043dfda0b1SToby Isaac PetscInt face = firstYFace + (fz*numXEdges+fx)*numYVertices + fy; 9053dfda0b1SToby Isaac PetscInt edgeL = firstZEdge + (fy*numXVertices+ fx)*numZEdges + fz; 9063dfda0b1SToby Isaac PetscInt edgeR = firstZEdge + (fy*numXVertices+((fx+1)%numXVertices))*numZEdges + fz; 9073dfda0b1SToby Isaac PetscInt edgeB = firstXEdge + (fz *numYVertices+fy)*numXEdges + fx; 9083dfda0b1SToby Isaac PetscInt edgeT = firstXEdge + (((fz+1)%numZVertices)*numYVertices+fy)*numXEdges + fx; 9093dfda0b1SToby Isaac PetscInt ornt[4] = {0, 0, -2, -2}; 9103dfda0b1SToby Isaac PetscInt cone[4]; 9113dfda0b1SToby Isaac 9123dfda0b1SToby Isaac if (dim == 3) { 9133dfda0b1SToby Isaac /* markers */ 9143dfda0b1SToby Isaac if (bdY != DM_BOUNDARY_PERIODIC) { 9153dfda0b1SToby Isaac if (fy == numYVertices-1) { 916c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerBack);CHKERRQ(ierr); 917c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerBack);CHKERRQ(ierr); 9183dfda0b1SToby Isaac } 9193dfda0b1SToby Isaac else if (fy == 0) { 920c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerFront);CHKERRQ(ierr); 921c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerFront);CHKERRQ(ierr); 9223dfda0b1SToby Isaac } 9233dfda0b1SToby Isaac } 9243dfda0b1SToby Isaac } 9253dfda0b1SToby Isaac cone[0] = edgeB; cone[1] = edgeR; cone[2] = edgeT; cone[3] = edgeL; 9263dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, face, cone);CHKERRQ(ierr); 9273dfda0b1SToby Isaac ierr = DMPlexSetConeOrientation(dm, face, ornt);CHKERRQ(ierr); 9283dfda0b1SToby Isaac } 9293dfda0b1SToby Isaac } 9303dfda0b1SToby Isaac } 9313dfda0b1SToby Isaac /* Build z faces */ 9323dfda0b1SToby Isaac for (fy = 0; fy < numYEdges; ++fy) { 9333dfda0b1SToby Isaac for (fx = 0; fx < numXEdges; ++fx) { 9343dfda0b1SToby Isaac for (fz = 0; fz < numZVertices; fz++) { 9353dfda0b1SToby Isaac PetscInt face = firstZFace + (fy*numXEdges+fx)*numZVertices + fz; 9363dfda0b1SToby Isaac PetscInt edgeL = firstYEdge + (fz*numXVertices+ fx)*numYEdges + fy; 9373dfda0b1SToby Isaac PetscInt edgeR = firstYEdge + (fz*numXVertices+((fx+1)%numXVertices))*numYEdges + fy; 9383dfda0b1SToby Isaac PetscInt edgeB = firstXEdge + (fz*numYVertices+ fy)*numXEdges + fx; 9393dfda0b1SToby Isaac PetscInt edgeT = firstXEdge + (fz*numYVertices+((fy+1)%numYVertices))*numXEdges + fx; 9403dfda0b1SToby Isaac PetscInt ornt[4] = {0, 0, -2, -2}; 9413dfda0b1SToby Isaac PetscInt cone[4]; 9423dfda0b1SToby Isaac 9433dfda0b1SToby Isaac if (dim == 2) { 9443dfda0b1SToby Isaac if (bdX == DM_BOUNDARY_TWIST && fx == numXEdges-1) {edgeR += numYEdges-1-2*fy; ornt[1] = -2;} 9453dfda0b1SToby Isaac if (bdY == DM_BOUNDARY_TWIST && fy == numYEdges-1) {edgeT += numXEdges-1-2*fx; ornt[2] = 0;} 9468a5b437dSMatthew G. Knepley if (bdX != DM_BOUNDARY_NONE && fx == numXEdges-1 && cutLabel) {ierr = DMLabelSetValue(cutLabel, face, 2);CHKERRQ(ierr);} 9478a5b437dSMatthew G. Knepley if (bdY != DM_BOUNDARY_NONE && fy == numYEdges-1 && cutLabel) {ierr = DMLabelSetValue(cutLabel, face, 2);CHKERRQ(ierr);} 948d1c88043SMatthew G. Knepley } else { 9493dfda0b1SToby Isaac /* markers */ 9503dfda0b1SToby Isaac if (bdZ != DM_BOUNDARY_PERIODIC) { 9513dfda0b1SToby Isaac if (fz == numZVertices-1) { 952c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerTop);CHKERRQ(ierr); 953c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerTop);CHKERRQ(ierr); 9543dfda0b1SToby Isaac } 9553dfda0b1SToby Isaac else if (fz == 0) { 956c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerBottom);CHKERRQ(ierr); 957c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerBottom);CHKERRQ(ierr); 9583dfda0b1SToby Isaac } 9593dfda0b1SToby Isaac } 9603dfda0b1SToby Isaac } 9613dfda0b1SToby Isaac cone[0] = edgeB; cone[1] = edgeR; cone[2] = edgeT; cone[3] = edgeL; 9623dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, face, cone);CHKERRQ(ierr); 9633dfda0b1SToby Isaac ierr = DMPlexSetConeOrientation(dm, face, ornt);CHKERRQ(ierr); 9643dfda0b1SToby Isaac } 9653dfda0b1SToby Isaac } 9663dfda0b1SToby Isaac } 9673dfda0b1SToby Isaac /* Build Z edges*/ 9683dfda0b1SToby Isaac for (vy = 0; vy < numYVertices; vy++) { 9693dfda0b1SToby Isaac for (vx = 0; vx < numXVertices; vx++) { 9703dfda0b1SToby Isaac for (ez = 0; ez < numZEdges; ez++) { 9713dfda0b1SToby Isaac const PetscInt edge = firstZEdge + (vy*numXVertices+vx)*numZEdges + ez; 9723dfda0b1SToby Isaac const PetscInt vertexB = firstVertex + (ez *numYVertices+vy)*numXVertices + vx; 9733dfda0b1SToby Isaac const PetscInt vertexT = firstVertex + (((ez+1)%numZVertices)*numYVertices+vy)*numXVertices + vx; 9743dfda0b1SToby Isaac PetscInt cone[2]; 9753dfda0b1SToby Isaac 9763dfda0b1SToby Isaac if (dim == 3) { 9773dfda0b1SToby Isaac if (bdX != DM_BOUNDARY_PERIODIC) { 9783dfda0b1SToby Isaac if (vx == numXVertices-1) { 979c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerRight);CHKERRQ(ierr); 9803dfda0b1SToby Isaac } 9813dfda0b1SToby Isaac else if (vx == 0) { 982c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerLeft);CHKERRQ(ierr); 9833dfda0b1SToby Isaac } 9843dfda0b1SToby Isaac } 9853dfda0b1SToby Isaac if (bdY != DM_BOUNDARY_PERIODIC) { 9863dfda0b1SToby Isaac if (vy == numYVertices-1) { 987c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBack);CHKERRQ(ierr); 9883dfda0b1SToby Isaac } 9893dfda0b1SToby Isaac else if (vy == 0) { 990c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerFront);CHKERRQ(ierr); 9913dfda0b1SToby Isaac } 9923dfda0b1SToby Isaac } 9933dfda0b1SToby Isaac } 9943dfda0b1SToby Isaac cone[0] = vertexB; cone[1] = vertexT; 9953dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); 9963dfda0b1SToby Isaac } 9973dfda0b1SToby Isaac } 9983dfda0b1SToby Isaac } 9993dfda0b1SToby Isaac /* Build Y edges*/ 10003dfda0b1SToby Isaac for (vz = 0; vz < numZVertices; vz++) { 10013dfda0b1SToby Isaac for (vx = 0; vx < numXVertices; vx++) { 10023dfda0b1SToby Isaac for (ey = 0; ey < numYEdges; ey++) { 10033dfda0b1SToby Isaac const PetscInt nextv = (dim == 2 && bdY == DM_BOUNDARY_TWIST && ey == numYEdges-1) ? (numXVertices-vx-1) : (vz*numYVertices+((ey+1)%numYVertices))*numXVertices + vx; 10043dfda0b1SToby Isaac const PetscInt edge = firstYEdge + (vz*numXVertices+vx)*numYEdges + ey; 10053dfda0b1SToby Isaac const PetscInt vertexF = firstVertex + (vz*numYVertices+ey)*numXVertices + vx; 10063dfda0b1SToby Isaac const PetscInt vertexK = firstVertex + nextv; 10073dfda0b1SToby Isaac PetscInt cone[2]; 10083dfda0b1SToby Isaac 10093dfda0b1SToby Isaac cone[0] = vertexF; cone[1] = vertexK; 10103dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); 10113dfda0b1SToby Isaac if (dim == 2) { 10123dfda0b1SToby Isaac if ((bdX != DM_BOUNDARY_PERIODIC) && (bdX != DM_BOUNDARY_TWIST)) { 10133dfda0b1SToby Isaac if (vx == numXVertices-1) { 1014c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", edge, faceMarkerRight);CHKERRQ(ierr); 1015c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerRight);CHKERRQ(ierr); 1016c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerRight);CHKERRQ(ierr); 10173dfda0b1SToby Isaac if (ey == numYEdges-1) { 1018c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerRight);CHKERRQ(ierr); 10193dfda0b1SToby Isaac } 1020d8211ee3SMatthew G. Knepley } else if (vx == 0) { 1021c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", edge, faceMarkerLeft);CHKERRQ(ierr); 1022c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerLeft);CHKERRQ(ierr); 1023c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerLeft);CHKERRQ(ierr); 10243dfda0b1SToby Isaac if (ey == numYEdges-1) { 1025c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerLeft);CHKERRQ(ierr); 10263dfda0b1SToby Isaac } 10273dfda0b1SToby Isaac } 1028d8211ee3SMatthew G. Knepley } else { 10294c67ea77SStefano Zampini if (vx == 0 && cutLabel) { 1030d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, edge, 1);CHKERRQ(ierr); 1031d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, cone[0], 1);CHKERRQ(ierr); 1032d8211ee3SMatthew G. Knepley if (ey == numYEdges-1) { 1033d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, cone[1], 1);CHKERRQ(ierr); 10343dfda0b1SToby Isaac } 10353dfda0b1SToby Isaac } 1036d8211ee3SMatthew G. Knepley } 1037d8211ee3SMatthew G. Knepley } else { 10383dfda0b1SToby Isaac if (bdX != DM_BOUNDARY_PERIODIC) { 10393dfda0b1SToby Isaac if (vx == numXVertices-1) { 1040c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerRight);CHKERRQ(ierr); 1041d8211ee3SMatthew G. Knepley } else if (vx == 0) { 1042c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerLeft);CHKERRQ(ierr); 10433dfda0b1SToby Isaac } 10443dfda0b1SToby Isaac } 10453dfda0b1SToby Isaac if (bdZ != DM_BOUNDARY_PERIODIC) { 10463dfda0b1SToby Isaac if (vz == numZVertices-1) { 1047c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerTop);CHKERRQ(ierr); 1048d8211ee3SMatthew G. Knepley } else if (vz == 0) { 1049c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBottom);CHKERRQ(ierr); 10503dfda0b1SToby Isaac } 10513dfda0b1SToby Isaac } 10523dfda0b1SToby Isaac } 10533dfda0b1SToby Isaac } 10543dfda0b1SToby Isaac } 10553dfda0b1SToby Isaac } 10563dfda0b1SToby Isaac /* Build X edges*/ 10573dfda0b1SToby Isaac for (vz = 0; vz < numZVertices; vz++) { 10583dfda0b1SToby Isaac for (vy = 0; vy < numYVertices; vy++) { 10593dfda0b1SToby Isaac for (ex = 0; ex < numXEdges; ex++) { 10603dfda0b1SToby Isaac const PetscInt nextv = (dim == 2 && bdX == DM_BOUNDARY_TWIST && ex == numXEdges-1) ? (numYVertices-vy-1)*numXVertices : (vz*numYVertices+vy)*numXVertices + (ex+1)%numXVertices; 10613dfda0b1SToby Isaac const PetscInt edge = firstXEdge + (vz*numYVertices+vy)*numXEdges + ex; 10623dfda0b1SToby Isaac const PetscInt vertexL = firstVertex + (vz*numYVertices+vy)*numXVertices + ex; 10633dfda0b1SToby Isaac const PetscInt vertexR = firstVertex + nextv; 10643dfda0b1SToby Isaac PetscInt cone[2]; 10653dfda0b1SToby Isaac 10663dfda0b1SToby Isaac cone[0] = vertexL; cone[1] = vertexR; 10673dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); 10683dfda0b1SToby Isaac if (dim == 2) { 10693dfda0b1SToby Isaac if ((bdY != DM_BOUNDARY_PERIODIC) && (bdY != DM_BOUNDARY_TWIST)) { 10703dfda0b1SToby Isaac if (vy == numYVertices-1) { 1071c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", edge, faceMarkerTop);CHKERRQ(ierr); 1072c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerTop);CHKERRQ(ierr); 1073c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerTop);CHKERRQ(ierr); 10743dfda0b1SToby Isaac if (ex == numXEdges-1) { 1075c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerTop);CHKERRQ(ierr); 10763dfda0b1SToby Isaac } 1077d8211ee3SMatthew G. Knepley } else if (vy == 0) { 1078c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", edge, faceMarkerBottom);CHKERRQ(ierr); 1079c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBottom);CHKERRQ(ierr); 1080c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerBottom);CHKERRQ(ierr); 10813dfda0b1SToby Isaac if (ex == numXEdges-1) { 1082c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerBottom);CHKERRQ(ierr); 10833dfda0b1SToby Isaac } 10843dfda0b1SToby Isaac } 1085d8211ee3SMatthew G. Knepley } else { 10864c67ea77SStefano Zampini if (vy == 0 && cutLabel) { 1087d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, edge, 1);CHKERRQ(ierr); 1088d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, cone[0], 1);CHKERRQ(ierr); 1089d8211ee3SMatthew G. Knepley if (ex == numXEdges-1) { 1090d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, cone[1], 1);CHKERRQ(ierr); 10913dfda0b1SToby Isaac } 10923dfda0b1SToby Isaac } 1093d8211ee3SMatthew G. Knepley } 1094d8211ee3SMatthew G. Knepley } else { 10953dfda0b1SToby Isaac if (bdY != DM_BOUNDARY_PERIODIC) { 10963dfda0b1SToby Isaac if (vy == numYVertices-1) { 1097c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBack);CHKERRQ(ierr); 10983dfda0b1SToby Isaac } 10993dfda0b1SToby Isaac else if (vy == 0) { 1100c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerFront);CHKERRQ(ierr); 11013dfda0b1SToby Isaac } 11023dfda0b1SToby Isaac } 11033dfda0b1SToby Isaac if (bdZ != DM_BOUNDARY_PERIODIC) { 11043dfda0b1SToby Isaac if (vz == numZVertices-1) { 1105c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerTop);CHKERRQ(ierr); 11063dfda0b1SToby Isaac } 11073dfda0b1SToby Isaac else if (vz == 0) { 1108c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBottom);CHKERRQ(ierr); 11093dfda0b1SToby Isaac } 11103dfda0b1SToby Isaac } 11113dfda0b1SToby Isaac } 11123dfda0b1SToby Isaac } 11133dfda0b1SToby Isaac } 11143dfda0b1SToby Isaac } 11153dfda0b1SToby Isaac ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 11163dfda0b1SToby Isaac ierr = DMPlexStratify(dm);CHKERRQ(ierr); 11173dfda0b1SToby Isaac /* Build coordinates */ 11183dfda0b1SToby Isaac ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 11193dfda0b1SToby Isaac ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 11203dfda0b1SToby Isaac ierr = PetscSectionSetFieldComponents(coordSection, 0, dim);CHKERRQ(ierr); 11213dfda0b1SToby Isaac ierr = PetscSectionSetChart(coordSection, firstVertex, firstVertex+numVertices);CHKERRQ(ierr); 11223dfda0b1SToby Isaac for (v = firstVertex; v < firstVertex+numVertices; ++v) { 11233dfda0b1SToby Isaac ierr = PetscSectionSetDof(coordSection, v, dim);CHKERRQ(ierr); 11243dfda0b1SToby Isaac ierr = PetscSectionSetFieldDof(coordSection, v, 0, dim);CHKERRQ(ierr); 11253dfda0b1SToby Isaac } 11263dfda0b1SToby Isaac ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 11273dfda0b1SToby Isaac ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 11288b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 1129da16285aSMichael Lange ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 11303dfda0b1SToby Isaac ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 11318b9ced59SLisandro Dalcin ierr = VecSetBlockSize(coordinates, dim);CHKERRQ(ierr); 11323dfda0b1SToby Isaac ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 11333dfda0b1SToby Isaac ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 11343dfda0b1SToby Isaac for (vz = 0; vz < numZVertices; ++vz) { 11353dfda0b1SToby Isaac for (vy = 0; vy < numYVertices; ++vy) { 11363dfda0b1SToby Isaac for (vx = 0; vx < numXVertices; ++vx) { 11373dfda0b1SToby Isaac coords[((vz*numYVertices+vy)*numXVertices+vx)*dim+0] = lower[0] + ((upper[0] - lower[0])/numXEdges)*vx; 11383dfda0b1SToby Isaac coords[((vz*numYVertices+vy)*numXVertices+vx)*dim+1] = lower[1] + ((upper[1] - lower[1])/numYEdges)*vy; 11393dfda0b1SToby Isaac if (dim == 3) { 11403dfda0b1SToby Isaac coords[((vz*numYVertices+vy)*numXVertices+vx)*dim+2] = lower[2] + ((upper[2] - lower[2])/numZEdges)*vz; 11413dfda0b1SToby Isaac } 11423dfda0b1SToby Isaac } 11433dfda0b1SToby Isaac } 11443dfda0b1SToby Isaac } 11453dfda0b1SToby Isaac ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 11463dfda0b1SToby Isaac ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 11473dfda0b1SToby Isaac ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 11483dfda0b1SToby Isaac } 11493dfda0b1SToby Isaac PetscFunctionReturn(0); 11503dfda0b1SToby Isaac } 11513dfda0b1SToby Isaac 11529318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxMesh_Tensor_Internal(DM dm, PetscInt dim, const PetscInt faces[], const PetscReal lower[], const PetscReal upper[], const DMBoundaryType periodicity[]) 1153a6dfd86eSKarl Rupp { 11549318fe57SMatthew G. Knepley DMBoundaryType bdt[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE}; 11559318fe57SMatthew G. Knepley PetscInt fac[3] = {0, 0, 0}, d; 1156552f7358SJed Brown PetscErrorCode ierr; 1157552f7358SJed Brown 1158552f7358SJed Brown PetscFunctionBegin; 11599318fe57SMatthew G. Knepley PetscValidPointer(dm, 1); 11609318fe57SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 11619318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 11629318fe57SMatthew G. Knepley for (d = 0; d < dim; ++d) {fac[d] = faces[d]; bdt[d] = periodicity[d];} 11639318fe57SMatthew G. Knepley ierr = DMPlexCreateCubeMesh_Internal(dm, lower, upper, fac, bdt[0], bdt[1], bdt[2]);CHKERRQ(ierr); 1164768d5fceSMatthew G. Knepley if (periodicity[0] == DM_BOUNDARY_PERIODIC || periodicity[0] == DM_BOUNDARY_TWIST || 1165768d5fceSMatthew G. Knepley periodicity[1] == DM_BOUNDARY_PERIODIC || periodicity[1] == DM_BOUNDARY_TWIST || 1166768d5fceSMatthew G. Knepley (dim > 2 && (periodicity[2] == DM_BOUNDARY_PERIODIC || periodicity[2] == DM_BOUNDARY_TWIST))) { 1167768d5fceSMatthew G. Knepley PetscReal L[3]; 1168768d5fceSMatthew G. Knepley PetscReal maxCell[3]; 1169552f7358SJed Brown 11709318fe57SMatthew G. Knepley for (d = 0; d < dim; ++d) { 11719318fe57SMatthew G. Knepley L[d] = upper[d] - lower[d]; 11729318fe57SMatthew G. Knepley maxCell[d] = 1.1 * (L[d] / PetscMax(1, faces[d])); 1173768d5fceSMatthew G. Knepley } 11749318fe57SMatthew G. Knepley ierr = DMSetPeriodicity(dm, PETSC_TRUE, maxCell, L, periodicity);CHKERRQ(ierr); 1175768d5fceSMatthew G. Knepley } 11769318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr); 11779318fe57SMatthew G. Knepley PetscFunctionReturn(0); 11789318fe57SMatthew G. Knepley } 11799318fe57SMatthew G. Knepley 11809318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxMesh_Internal(DM dm, PetscInt dim, PetscBool simplex, const PetscInt faces[], const PetscReal lower[], const PetscReal upper[], const DMBoundaryType periodicity[], PetscBool interpolate) 11819318fe57SMatthew G. Knepley { 11829318fe57SMatthew G. Knepley PetscErrorCode ierr; 11839318fe57SMatthew G. Knepley 11849318fe57SMatthew G. Knepley PetscFunctionBegin; 11859318fe57SMatthew G. Knepley if (dim == 1) {ierr = DMPlexCreateLineMesh_Internal(dm, faces[0], lower[0], upper[0], periodicity[0]);CHKERRQ(ierr);} 11869318fe57SMatthew G. Knepley else if (simplex) {ierr = DMPlexCreateBoxMesh_Simplex_Internal(dm, dim, faces, lower, upper, periodicity, interpolate);CHKERRQ(ierr);} 11879318fe57SMatthew G. Knepley else {ierr = DMPlexCreateBoxMesh_Tensor_Internal(dm, dim, faces, lower, upper, periodicity);CHKERRQ(ierr);} 11889318fe57SMatthew G. Knepley if (!interpolate && dim > 1 && !simplex) { 1189768d5fceSMatthew G. Knepley DM udm; 1190768d5fceSMatthew G. Knepley 11919318fe57SMatthew G. Knepley ierr = DMPlexUninterpolate(dm, &udm);CHKERRQ(ierr); 11929318fe57SMatthew G. Knepley ierr = DMPlexCopyCoordinates(dm, udm);CHKERRQ(ierr); 11939318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &udm);CHKERRQ(ierr); 1194768d5fceSMatthew G. Knepley } 1195768d5fceSMatthew G. Knepley PetscFunctionReturn(0); 1196c8c68bd8SToby Isaac } 1197c8c68bd8SToby Isaac 1198768d5fceSMatthew G. Knepley /*@C 1199768d5fceSMatthew G. Knepley DMPlexCreateBoxMesh - Creates a mesh on the tensor product of unit intervals (box) using simplices or tensor cells (hexahedra). 1200768d5fceSMatthew G. Knepley 1201d083f849SBarry Smith Collective 1202768d5fceSMatthew G. Knepley 1203768d5fceSMatthew G. Knepley Input Parameters: 1204768d5fceSMatthew G. Knepley + comm - The communicator for the DM object 1205768d5fceSMatthew G. Knepley . dim - The spatial dimension 1206768d5fceSMatthew G. Knepley . simplex - PETSC_TRUE for simplices, PETSC_FALSE for tensor cells 1207fdbf62faSLisandro Dalcin . faces - Number of faces per dimension, or NULL for (1,) in 1D and (2, 2) in 2D and (1, 1, 1) in 3D 1208768d5fceSMatthew G. Knepley . lower - The lower left corner, or NULL for (0, 0, 0) 1209768d5fceSMatthew G. Knepley . upper - The upper right corner, or NULL for (1, 1, 1) 1210fdbf62faSLisandro Dalcin . periodicity - The boundary type for the X,Y,Z direction, or NULL for DM_BOUNDARY_NONE 1211768d5fceSMatthew G. Knepley - interpolate - Flag to create intermediate mesh pieces (edges, faces) 1212768d5fceSMatthew G. Knepley 1213768d5fceSMatthew G. Knepley Output Parameter: 1214768d5fceSMatthew G. Knepley . dm - The DM object 1215768d5fceSMatthew G. Knepley 12169318fe57SMatthew G. Knepley Note: If you want to customize this mesh using options, you just need to 12179318fe57SMatthew G. Knepley $ DMCreate(comm, &dm); 12189318fe57SMatthew G. Knepley $ DMSetType(dm, DMPLEX); 12199318fe57SMatthew G. Knepley $ DMSetFromOptions(dm); 12209318fe57SMatthew G. Knepley and use the options on the DMSetFromOptions() page. 12211367e252SJed Brown 12221367e252SJed Brown Here is the numbering returned for 2 faces in each direction for tensor cells: 1223768d5fceSMatthew G. Knepley $ 10---17---11---18----12 1224768d5fceSMatthew G. Knepley $ | | | 1225768d5fceSMatthew G. Knepley $ | | | 1226768d5fceSMatthew G. Knepley $ 20 2 22 3 24 1227768d5fceSMatthew G. Knepley $ | | | 1228768d5fceSMatthew G. Knepley $ | | | 1229768d5fceSMatthew G. Knepley $ 7---15----8---16----9 1230768d5fceSMatthew G. Knepley $ | | | 1231768d5fceSMatthew G. Knepley $ | | | 1232768d5fceSMatthew G. Knepley $ 19 0 21 1 23 1233768d5fceSMatthew G. Knepley $ | | | 1234768d5fceSMatthew G. Knepley $ | | | 1235768d5fceSMatthew G. Knepley $ 4---13----5---14----6 1236768d5fceSMatthew G. Knepley 1237768d5fceSMatthew G. Knepley and for simplicial cells 1238768d5fceSMatthew G. Knepley 1239768d5fceSMatthew G. Knepley $ 14----8---15----9----16 1240768d5fceSMatthew G. Knepley $ |\ 5 |\ 7 | 1241768d5fceSMatthew G. Knepley $ | \ | \ | 1242768d5fceSMatthew G. Knepley $ 13 2 14 3 15 1243768d5fceSMatthew G. Knepley $ | 4 \ | 6 \ | 1244768d5fceSMatthew G. Knepley $ | \ | \ | 1245768d5fceSMatthew G. Knepley $ 11----6---12----7----13 1246768d5fceSMatthew G. Knepley $ |\ |\ | 1247768d5fceSMatthew G. Knepley $ | \ 1 | \ 3 | 1248768d5fceSMatthew G. Knepley $ 10 0 11 1 12 1249768d5fceSMatthew G. Knepley $ | 0 \ | 2 \ | 1250768d5fceSMatthew G. Knepley $ | \ | \ | 1251768d5fceSMatthew G. Knepley $ 8----4----9----5----10 1252768d5fceSMatthew G. Knepley 1253768d5fceSMatthew G. Knepley Level: beginner 1254768d5fceSMatthew G. Knepley 12559318fe57SMatthew G. Knepley .seealso: DMSetFromOptions(), DMPlexCreateFromFile(), DMPlexCreateHexCylinderMesh(), DMSetType(), DMCreate() 1256768d5fceSMatthew G. Knepley @*/ 1257768d5fceSMatthew G. Knepley PetscErrorCode DMPlexCreateBoxMesh(MPI_Comm comm, PetscInt dim, PetscBool simplex, const PetscInt faces[], const PetscReal lower[], const PetscReal upper[], const DMBoundaryType periodicity[], PetscBool interpolate, DM *dm) 1258552f7358SJed Brown { 12599318fe57SMatthew G. Knepley PetscInt fac[3] = {1, 1, 1}; 1260fdbf62faSLisandro Dalcin PetscReal low[3] = {0, 0, 0}; 1261fdbf62faSLisandro Dalcin PetscReal upp[3] = {1, 1, 1}; 1262fdbf62faSLisandro Dalcin DMBoundaryType bdt[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE}; 1263768d5fceSMatthew G. Knepley PetscErrorCode ierr; 1264552f7358SJed Brown 1265768d5fceSMatthew G. Knepley PetscFunctionBegin; 12669318fe57SMatthew G. Knepley ierr = DMCreate(comm,dm);CHKERRQ(ierr); 12679318fe57SMatthew G. Knepley ierr = DMSetType(*dm,DMPLEX);CHKERRQ(ierr); 12689318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxMesh_Internal(*dm, dim, simplex, faces ? faces : fac, lower ? lower : low, upper ? upper : upp, periodicity ? periodicity : bdt, interpolate);CHKERRQ(ierr); 12699318fe57SMatthew G. Knepley PetscFunctionReturn(0); 12709318fe57SMatthew G. Knepley } 1271fdbf62faSLisandro Dalcin 12729318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateWedgeBoxMesh_Internal(DM dm, const PetscInt faces[], const PetscReal lower[], const PetscReal upper[], const DMBoundaryType periodicity[], PetscBool orderHeight, PetscBool interpolate) 12739318fe57SMatthew G. Knepley { 12749318fe57SMatthew G. Knepley DM bdm, vol; 12759318fe57SMatthew G. Knepley PetscReal normal[3] = {0., 0., 1.}; 12769318fe57SMatthew G. Knepley PetscInt i; 12779318fe57SMatthew G. Knepley PetscErrorCode ierr; 12789318fe57SMatthew G. Knepley 12799318fe57SMatthew G. Knepley PetscFunctionBegin; 12809318fe57SMatthew G. Knepley for (i = 0; i < 3; ++i) if (periodicity[i] != DM_BOUNDARY_NONE) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Periodicity not yet supported"); 12819318fe57SMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject) dm), &bdm);CHKERRQ(ierr); 12829318fe57SMatthew G. Knepley ierr = DMSetType(bdm, DMPLEX);CHKERRQ(ierr); 12839318fe57SMatthew G. Knepley ierr = DMSetDimension(bdm, 2);CHKERRQ(ierr); 12849318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxMesh_Simplex_Internal(bdm, 2, faces, lower, upper, periodicity, interpolate);CHKERRQ(ierr); 12859318fe57SMatthew G. Knepley ierr = DMPlexExtrude(bdm, faces[2], upper[2] - lower[2], orderHeight, normal, interpolate, &vol);CHKERRQ(ierr); 12869318fe57SMatthew G. Knepley ierr = DMDestroy(&bdm);CHKERRQ(ierr); 12879318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &vol);CHKERRQ(ierr); 12889318fe57SMatthew G. Knepley if (lower[2] != 0.0) { 12899318fe57SMatthew G. Knepley Vec v; 12909318fe57SMatthew G. Knepley PetscScalar *x; 12919318fe57SMatthew G. Knepley PetscInt cDim, n; 12929318fe57SMatthew G. Knepley 12939318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &v);CHKERRQ(ierr); 12949318fe57SMatthew G. Knepley ierr = VecGetBlockSize(v, &cDim);CHKERRQ(ierr); 12959318fe57SMatthew G. Knepley ierr = VecGetLocalSize(v, &n);CHKERRQ(ierr); 12969318fe57SMatthew G. Knepley ierr = VecGetArray(v, &x);CHKERRQ(ierr); 12979318fe57SMatthew G. Knepley x += cDim; 12989318fe57SMatthew G. Knepley for (i = 0; i < n; i += cDim) x[i] += lower[2]; 12999318fe57SMatthew G. Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 13009318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, v);CHKERRQ(ierr); 13019318fe57SMatthew G. Knepley } 1302552f7358SJed Brown PetscFunctionReturn(0); 1303552f7358SJed Brown } 1304552f7358SJed Brown 130500dabe28SStefano Zampini /*@ 130600dabe28SStefano Zampini DMPlexCreateWedgeBoxMesh - Creates a 3-D mesh tesselating the (x,y) plane and extruding in the third direction using wedge cells. 130700dabe28SStefano Zampini 1308d083f849SBarry Smith Collective 130900dabe28SStefano Zampini 131000dabe28SStefano Zampini Input Parameters: 131100dabe28SStefano Zampini + comm - The communicator for the DM object 131200dabe28SStefano Zampini . faces - Number of faces per dimension, or NULL for (1, 1, 1) 131300dabe28SStefano Zampini . lower - The lower left corner, or NULL for (0, 0, 0) 131400dabe28SStefano Zampini . upper - The upper right corner, or NULL for (1, 1, 1) 131500dabe28SStefano Zampini . periodicity - The boundary type for the X,Y,Z direction, or NULL for DM_BOUNDARY_NONE 1316d0fcb9c2SMatthew G. Knepley . orderHeight - If PETSC_TRUE, orders the extruded cells in the height first. Otherwise, orders the cell on the layers first 131700dabe28SStefano Zampini - interpolate - Flag to create intermediate mesh pieces (edges, faces) 131800dabe28SStefano Zampini 131900dabe28SStefano Zampini Output Parameter: 132000dabe28SStefano Zampini . dm - The DM object 132100dabe28SStefano Zampini 132200dabe28SStefano Zampini Level: beginner 132300dabe28SStefano Zampini 132400dabe28SStefano Zampini .seealso: DMPlexCreateHexCylinderMesh(), DMPlexCreateWedgeCylinderMesh(), DMPlexExtrude(), DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 132500dabe28SStefano Zampini @*/ 1326d0fcb9c2SMatthew G. Knepley PetscErrorCode DMPlexCreateWedgeBoxMesh(MPI_Comm comm, const PetscInt faces[], const PetscReal lower[], const PetscReal upper[], const DMBoundaryType periodicity[], PetscBool orderHeight, PetscBool interpolate, DM *dm) 132700dabe28SStefano Zampini { 13289318fe57SMatthew G. Knepley PetscInt fac[3] = {1, 1, 1}; 132900dabe28SStefano Zampini PetscReal low[3] = {0, 0, 0}; 133000dabe28SStefano Zampini PetscReal upp[3] = {1, 1, 1}; 133100dabe28SStefano Zampini DMBoundaryType bdt[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE}; 133200dabe28SStefano Zampini PetscErrorCode ierr; 133300dabe28SStefano Zampini 133400dabe28SStefano Zampini PetscFunctionBegin; 13359318fe57SMatthew G. Knepley ierr = DMCreate(comm,dm);CHKERRQ(ierr); 13369318fe57SMatthew G. Knepley ierr = DMSetType(*dm,DMPLEX);CHKERRQ(ierr); 13379318fe57SMatthew G. Knepley ierr = DMPlexCreateWedgeBoxMesh_Internal(*dm, faces ? faces : fac, lower ? lower : low, upper ? upper : upp, periodicity ? periodicity : bdt, orderHeight, interpolate);CHKERRQ(ierr); 133800dabe28SStefano Zampini PetscFunctionReturn(0); 133900dabe28SStefano Zampini } 134000dabe28SStefano Zampini 1341d0fcb9c2SMatthew G. Knepley /*@C 134200dabe28SStefano Zampini DMPlexExtrude - Creates a (d+1)-D mesh by extruding a d-D mesh in the normal direction using prismatic cells. 134300dabe28SStefano Zampini 134400dabe28SStefano Zampini Collective on idm 134500dabe28SStefano Zampini 134600dabe28SStefano Zampini Input Parameters: 1347d0fcb9c2SMatthew G. Knepley + idm - The mesh to be extruded 1348d0fcb9c2SMatthew G. Knepley . layers - The number of layers, or PETSC_DETERMINE to use the default 134909c71656SMatthew G. Knepley . height - The total height of the extrusion, or PETSC_DETERMINE to use the default 1350d0fcb9c2SMatthew G. Knepley . orderHeight - If PETSC_TRUE, orders the extruded cells in the height first. Otherwise, orders the cell on the layers first 1351d0fcb9c2SMatthew G. Knepley . extNormal - The normal direction in which the mesh should be extruded, or NULL to extrude using the surface normal 135200dabe28SStefano Zampini - interpolate - Flag to create intermediate mesh pieces (edges, faces) 135300dabe28SStefano Zampini 135400dabe28SStefano Zampini Output Parameter: 135500dabe28SStefano Zampini . dm - The DM object 135600dabe28SStefano Zampini 1357d0fcb9c2SMatthew G. Knepley Notes: 1358d0fcb9c2SMatthew G. Knepley The mesh created has prismatic cells, and the vertex ordering in the cone of the cell is that of the tensor prismatic cells. Not currently supported in Fortran. 1359d0fcb9c2SMatthew G. Knepley 1360d0fcb9c2SMatthew G. Knepley Options Database Keys: 13612479783cSJose E. Roman + -dm_plex_extrude_layers <k> - Sets the number of layers k 136209c71656SMatthew G. Knepley . -dm_plex_extrude_height <h> - Sets the total height of the extrusion 136309c71656SMatthew G. Knepley . -dm_plex_extrude_heights <h0,h1,...> - Sets the height of each layer 1364ee300463SSatish Balay . -dm_plex_extrude_order_height - If true, order cells by height first 1365ee300463SSatish Balay - -dm_plex_extrude_normal <n0,...,nd> - Sets the normal vector along which to extrude 136600dabe28SStefano Zampini 136700dabe28SStefano Zampini Level: advanced 136800dabe28SStefano Zampini 1369412e9a14SMatthew G. Knepley .seealso: DMPlexCreateWedgeCylinderMesh(), DMPlexCreateWedgeBoxMesh(), DMSetType(), DMCreate() 137000dabe28SStefano Zampini @*/ 1371d0fcb9c2SMatthew G. Knepley PetscErrorCode DMPlexExtrude(DM idm, PetscInt layers, PetscReal height, PetscBool orderHeight, const PetscReal extNormal[], PetscBool interpolate, DM* dm) 137200dabe28SStefano Zampini { 137300dabe28SStefano Zampini PetscScalar *coordsB; 137400dabe28SStefano Zampini const PetscScalar *coordsA; 137509c71656SMatthew G. Knepley PetscReal *normals = NULL, *heights = NULL; 1376d0fcb9c2SMatthew G. Knepley PetscReal clNormal[3]; 137700dabe28SStefano Zampini Vec coordinatesA, coordinatesB; 137800dabe28SStefano Zampini PetscSection coordSectionA, coordSectionB; 137909c71656SMatthew G. Knepley PetscInt dim, cDim, cDimB, c, l, v, coordSize, *newCone, nl; 138000dabe28SStefano Zampini PetscInt cStart, cEnd, vStart, vEnd, cellV, numCells, numVertices; 1381d0fcb9c2SMatthew G. Knepley const char *prefix; 138209c71656SMatthew G. Knepley PetscBool haveCLNormal, flg; 138300dabe28SStefano Zampini PetscErrorCode ierr; 138400dabe28SStefano Zampini 138500dabe28SStefano Zampini PetscFunctionBegin; 138600dabe28SStefano Zampini PetscValidHeaderSpecific(idm, DM_CLASSID, 1); 138700dabe28SStefano Zampini PetscValidLogicalCollectiveInt(idm, layers, 2); 138800dabe28SStefano Zampini PetscValidLogicalCollectiveReal(idm, height, 3); 1389064a246eSJacob Faibussowitsch PetscValidLogicalCollectiveBool(idm, interpolate, 6); 139000dabe28SStefano Zampini ierr = DMGetDimension(idm, &dim);CHKERRQ(ierr); 1391d0fcb9c2SMatthew G. Knepley ierr = DMGetCoordinateDim(idm, &cDim);CHKERRQ(ierr); 1392d0fcb9c2SMatthew G. Knepley cDimB = cDim == dim ? cDim+1 : cDim; 139300dabe28SStefano Zampini if (dim < 1 || dim > 3) SETERRQ1(PetscObjectComm((PetscObject)idm), PETSC_ERR_SUP, "Support for dimension %D not coded", dim); 139400dabe28SStefano Zampini 1395d0fcb9c2SMatthew G. Knepley ierr = PetscObjectGetOptionsPrefix((PetscObject) idm, &prefix);CHKERRQ(ierr); 1396d0fcb9c2SMatthew G. Knepley if (layers < 0) layers = 1; 1397d0fcb9c2SMatthew G. Knepley ierr = PetscOptionsGetInt(NULL, prefix, "-dm_plex_extrude_layers", &layers, NULL);CHKERRQ(ierr); 1398d0fcb9c2SMatthew G. Knepley if (layers <= 0) SETERRQ1(PetscObjectComm((PetscObject) idm), PETSC_ERR_ARG_OUTOFRANGE, "Number of layers %D must be positive", layers); 1399d0fcb9c2SMatthew G. Knepley if (height < 0.) height = 1.; 1400d0fcb9c2SMatthew G. Knepley ierr = PetscOptionsGetReal(NULL, prefix, "-dm_plex_extrude_height", &height, NULL);CHKERRQ(ierr); 1401d0fcb9c2SMatthew G. Knepley if (height <= 0.) SETERRQ1(PetscObjectComm((PetscObject) idm), PETSC_ERR_ARG_OUTOFRANGE, "Height of layers %g must be positive", (double) height); 140209c71656SMatthew G. Knepley ierr = PetscMalloc1(layers, &heights);CHKERRQ(ierr); 140309c71656SMatthew G. Knepley nl = layers; 140409c71656SMatthew G. Knepley ierr = PetscOptionsGetRealArray(NULL, prefix, "-dm_plex_extrude_heights", heights, &nl, &flg);CHKERRQ(ierr); 140509c71656SMatthew G. Knepley if (flg) { 140609c71656SMatthew G. Knepley if (!nl) SETERRQ(PetscObjectComm((PetscObject) idm), PETSC_ERR_ARG_OUTOFRANGE, "Must give at least one height for -dm_plex_extrude_heights"); 140709c71656SMatthew G. Knepley for (l = nl; l < layers; ++l) heights[l] = heights[l-1]; 140809c71656SMatthew G. Knepley for (l = 0; l < layers; ++l) if (heights[l] <= 0.) SETERRQ2(PetscObjectComm((PetscObject) idm), PETSC_ERR_ARG_OUTOFRANGE, "Height %g of layers %D must be positive", (double) heights[l], l); 140909c71656SMatthew G. Knepley } else { 141009c71656SMatthew G. Knepley for (l = 0; l < layers; ++l) heights[l] = height/layers; 141109c71656SMatthew G. Knepley } 1412d0fcb9c2SMatthew G. Knepley ierr = PetscOptionsGetBool(NULL, prefix, "-dm_plex_extrude_order_height", &orderHeight, NULL);CHKERRQ(ierr); 1413d0fcb9c2SMatthew G. Knepley c = 3; 1414d0fcb9c2SMatthew G. Knepley ierr = PetscOptionsGetRealArray(NULL, prefix, "-dm_plex_extrude_normal", clNormal, &c, &haveCLNormal);CHKERRQ(ierr); 1415d0fcb9c2SMatthew G. Knepley if (haveCLNormal && c != cDimB) SETERRQ2(PetscObjectComm((PetscObject)idm), PETSC_ERR_ARG_SIZ, "Input normal has size %D != %D extruded coordinate dimension", c, cDimB); 1416d0fcb9c2SMatthew G. Knepley 141700dabe28SStefano Zampini ierr = DMPlexGetHeightStratum(idm, 0, &cStart, &cEnd);CHKERRQ(ierr); 141800dabe28SStefano Zampini ierr = DMPlexGetDepthStratum(idm, 0, &vStart, &vEnd);CHKERRQ(ierr); 141900dabe28SStefano Zampini numCells = (cEnd - cStart)*layers; 142000dabe28SStefano Zampini numVertices = (vEnd - vStart)*(layers+1); 142100dabe28SStefano Zampini ierr = DMCreate(PetscObjectComm((PetscObject)idm), dm);CHKERRQ(ierr); 142200dabe28SStefano Zampini ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 142300dabe28SStefano Zampini ierr = DMSetDimension(*dm, dim+1);CHKERRQ(ierr); 142400dabe28SStefano Zampini ierr = DMPlexSetChart(*dm, 0, numCells+numVertices);CHKERRQ(ierr); 1425412e9a14SMatthew G. Knepley /* Must create the celltype label here so that we do not automatically try to compute the types */ 1426412e9a14SMatthew G. Knepley ierr = DMCreateLabel(*dm, "celltype");CHKERRQ(ierr); 142700dabe28SStefano Zampini for (c = cStart, cellV = 0; c < cEnd; ++c) { 1428412e9a14SMatthew G. Knepley DMPolytopeType ct, nct; 142900dabe28SStefano Zampini PetscInt *closure = NULL; 143000dabe28SStefano Zampini PetscInt closureSize, numCorners = 0; 143100dabe28SStefano Zampini 1432412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(idm, c, &ct);CHKERRQ(ierr); 1433412e9a14SMatthew G. Knepley switch (ct) { 1434412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: nct = DM_POLYTOPE_SEG_PRISM_TENSOR;break; 1435412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: nct = DM_POLYTOPE_TRI_PRISM_TENSOR;break; 1436412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: nct = DM_POLYTOPE_QUAD_PRISM_TENSOR;break; 1437412e9a14SMatthew G. Knepley default: nct = DM_POLYTOPE_UNKNOWN; 1438412e9a14SMatthew G. Knepley } 143900dabe28SStefano Zampini ierr = DMPlexGetTransitiveClosure(idm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 144000dabe28SStefano Zampini for (v = 0; v < closureSize*2; v += 2) if ((closure[v] >= vStart) && (closure[v] < vEnd)) numCorners++; 144100dabe28SStefano Zampini ierr = DMPlexRestoreTransitiveClosure(idm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 144200dabe28SStefano Zampini for (l = 0; l < layers; ++l) { 1443d0fcb9c2SMatthew G. Knepley const PetscInt cell = orderHeight ? layers*(c - cStart) + l : l*(cEnd - cStart) + c - cStart; 1444412e9a14SMatthew G. Knepley 1445412e9a14SMatthew G. Knepley ierr = DMPlexSetConeSize(*dm, cell, 2*numCorners);CHKERRQ(ierr); 1446412e9a14SMatthew G. Knepley ierr = DMPlexSetCellType(*dm, cell, nct);CHKERRQ(ierr); 144700dabe28SStefano Zampini } 144800dabe28SStefano Zampini cellV = PetscMax(numCorners,cellV); 144900dabe28SStefano Zampini } 145000dabe28SStefano Zampini ierr = DMSetUp(*dm);CHKERRQ(ierr); 145100dabe28SStefano Zampini 1452d0fcb9c2SMatthew G. Knepley if (dim != cDim && !(extNormal || haveCLNormal)) {ierr = PetscCalloc1(cDim*(vEnd - vStart), &normals);CHKERRQ(ierr);} 145300dabe28SStefano Zampini ierr = PetscMalloc1(3*cellV,&newCone);CHKERRQ(ierr); 145400dabe28SStefano Zampini for (c = cStart; c < cEnd; ++c) { 145500dabe28SStefano Zampini PetscInt *closure = NULL; 145600dabe28SStefano Zampini PetscInt closureSize, numCorners = 0, l; 145700dabe28SStefano Zampini PetscReal normal[3] = {0, 0, 0}; 145800dabe28SStefano Zampini 1459d0fcb9c2SMatthew G. Knepley if (normals) {ierr = DMPlexComputeCellGeometryFVM(idm, c, NULL, NULL, normal);CHKERRQ(ierr);} 146000dabe28SStefano Zampini ierr = DMPlexGetTransitiveClosure(idm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 146100dabe28SStefano Zampini for (v = 0; v < closureSize*2; v += 2) { 146200dabe28SStefano Zampini if ((closure[v] >= vStart) && (closure[v] < vEnd)) { 146300dabe28SStefano Zampini PetscInt d; 146400dabe28SStefano Zampini 146500dabe28SStefano Zampini newCone[numCorners++] = closure[v] - vStart; 146600dabe28SStefano Zampini if (normals) {for (d = 0; d < cDim; ++d) normals[cDim*(closure[v]-vStart)+d] += normal[d];} 146700dabe28SStefano Zampini } 146800dabe28SStefano Zampini } 146900dabe28SStefano Zampini ierr = DMPlexRestoreTransitiveClosure(idm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 147000dabe28SStefano Zampini for (l = 0; l < layers; ++l) { 147100dabe28SStefano Zampini PetscInt i; 147200dabe28SStefano Zampini 147300dabe28SStefano Zampini for (i = 0; i < numCorners; ++i) { 1474d0fcb9c2SMatthew G. Knepley newCone[ numCorners + i] = orderHeight ? (layers+1)*newCone[i] + l + numCells : l*(vEnd - vStart) + newCone[i] + numCells; 1475d0fcb9c2SMatthew G. Knepley newCone[2*numCorners + i] = orderHeight ? (layers+1)*newCone[i] + l + 1 + numCells : (l+1)*(vEnd - vStart) + newCone[i] + numCells; 147600dabe28SStefano Zampini } 1477d0fcb9c2SMatthew G. Knepley ierr = DMPlexSetCone(*dm, orderHeight ? layers*(c - cStart) + l : l*(cEnd - cStart) + c - cStart, newCone + numCorners);CHKERRQ(ierr); 147800dabe28SStefano Zampini } 147900dabe28SStefano Zampini } 148000dabe28SStefano Zampini ierr = DMPlexSymmetrize(*dm);CHKERRQ(ierr); 148100dabe28SStefano Zampini ierr = DMPlexStratify(*dm);CHKERRQ(ierr); 148200dabe28SStefano Zampini ierr = PetscFree(newCone);CHKERRQ(ierr); 148300dabe28SStefano Zampini 148400dabe28SStefano Zampini ierr = DMGetCoordinateSection(*dm, &coordSectionB);CHKERRQ(ierr); 148500dabe28SStefano Zampini ierr = PetscSectionSetNumFields(coordSectionB, 1);CHKERRQ(ierr); 148600dabe28SStefano Zampini ierr = PetscSectionSetFieldComponents(coordSectionB, 0, cDimB);CHKERRQ(ierr); 148700dabe28SStefano Zampini ierr = PetscSectionSetChart(coordSectionB, numCells, numCells+numVertices);CHKERRQ(ierr); 148800dabe28SStefano Zampini for (v = numCells; v < numCells+numVertices; ++v) { 148900dabe28SStefano Zampini ierr = PetscSectionSetDof(coordSectionB, v, cDimB);CHKERRQ(ierr); 149000dabe28SStefano Zampini ierr = PetscSectionSetFieldDof(coordSectionB, v, 0, cDimB);CHKERRQ(ierr); 1491412e9a14SMatthew G. Knepley ierr = DMPlexSetCellType(*dm, v, DM_POLYTOPE_POINT);CHKERRQ(ierr); 149200dabe28SStefano Zampini } 149300dabe28SStefano Zampini ierr = PetscSectionSetUp(coordSectionB);CHKERRQ(ierr); 149400dabe28SStefano Zampini ierr = PetscSectionGetStorageSize(coordSectionB, &coordSize);CHKERRQ(ierr); 149500dabe28SStefano Zampini ierr = VecCreate(PETSC_COMM_SELF, &coordinatesB);CHKERRQ(ierr); 149600dabe28SStefano Zampini ierr = PetscObjectSetName((PetscObject) coordinatesB, "coordinates");CHKERRQ(ierr); 149700dabe28SStefano Zampini ierr = VecSetSizes(coordinatesB, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 149800dabe28SStefano Zampini ierr = VecSetBlockSize(coordinatesB, cDimB);CHKERRQ(ierr); 149900dabe28SStefano Zampini ierr = VecSetType(coordinatesB,VECSTANDARD);CHKERRQ(ierr); 150000dabe28SStefano Zampini 150100dabe28SStefano Zampini ierr = DMGetCoordinateSection(idm, &coordSectionA);CHKERRQ(ierr); 150200dabe28SStefano Zampini ierr = DMGetCoordinatesLocal(idm, &coordinatesA);CHKERRQ(ierr); 150300dabe28SStefano Zampini ierr = VecGetArray(coordinatesB, &coordsB);CHKERRQ(ierr); 150400dabe28SStefano Zampini ierr = VecGetArrayRead(coordinatesA, &coordsA);CHKERRQ(ierr); 150500dabe28SStefano Zampini for (v = vStart; v < vEnd; ++v) { 150600dabe28SStefano Zampini const PetscScalar *cptr; 150700dabe28SStefano Zampini PetscReal ones2[2] = { 0., 1.}, ones3[3] = { 0., 0., 1.}; 1508d0fcb9c2SMatthew G. Knepley PetscReal normal[3]; 150909c71656SMatthew G. Knepley PetscReal norm; 151000dabe28SStefano Zampini PetscInt offA, d, cDimA = cDim; 151100dabe28SStefano Zampini 1512d0fcb9c2SMatthew G. Knepley if (normals) {for (d = 0; d < cDimB; ++d) normal[d] = normals[cDimB*(v - vStart)+d];} 1513d0fcb9c2SMatthew G. Knepley else if (haveCLNormal) {for (d = 0; d < cDimB; ++d) normal[d] = clNormal[d];} 1514d0fcb9c2SMatthew G. Knepley else if (extNormal) {for (d = 0; d < cDimB; ++d) normal[d] = extNormal[d];} 1515d0fcb9c2SMatthew G. Knepley else if (cDimB == 2) {for (d = 0; d < cDimB; ++d) normal[d] = ones2[d];} 1516d0fcb9c2SMatthew G. Knepley else if (cDimB == 3) {for (d = 0; d < cDimB; ++d) normal[d] = ones3[d];} 1517d0fcb9c2SMatthew G. Knepley else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unable to determine normal for extrusion"); 151800dabe28SStefano Zampini for (d = 0, norm = 0.0; d < cDimB; ++d) norm += normal[d]*normal[d]; 151900dabe28SStefano Zampini for (d = 0; d < cDimB; ++d) normal[d] *= 1./PetscSqrtReal(norm); 152000dabe28SStefano Zampini 152100dabe28SStefano Zampini ierr = PetscSectionGetOffset(coordSectionA, v, &offA);CHKERRQ(ierr); 152200dabe28SStefano Zampini cptr = coordsA + offA; 152309c71656SMatthew G. Knepley for (l = 0; l <= layers; ++l) { 152400dabe28SStefano Zampini PetscInt offB, d, newV; 152500dabe28SStefano Zampini 1526d0fcb9c2SMatthew G. Knepley newV = orderHeight ? (layers+1)*(v -vStart) + l + numCells : (vEnd -vStart)*l + (v -vStart) + numCells; 152700dabe28SStefano Zampini ierr = PetscSectionGetOffset(coordSectionB, newV, &offB);CHKERRQ(ierr); 152800dabe28SStefano Zampini for (d = 0; d < cDimA; ++d) { coordsB[offB+d] = cptr[d]; } 152909c71656SMatthew G. Knepley for (d = 0; d < cDimB; ++d) { coordsB[offB+d] += l ? normal[d]*heights[l-1] : 0.0; } 153000dabe28SStefano Zampini cptr = coordsB + offB; 153100dabe28SStefano Zampini cDimA = cDimB; 153200dabe28SStefano Zampini } 153300dabe28SStefano Zampini } 153400dabe28SStefano Zampini ierr = VecRestoreArrayRead(coordinatesA, &coordsA);CHKERRQ(ierr); 153500dabe28SStefano Zampini ierr = VecRestoreArray(coordinatesB, &coordsB);CHKERRQ(ierr); 153600dabe28SStefano Zampini ierr = DMSetCoordinatesLocal(*dm, coordinatesB);CHKERRQ(ierr); 153700dabe28SStefano Zampini ierr = VecDestroy(&coordinatesB);CHKERRQ(ierr); 153800dabe28SStefano Zampini ierr = PetscFree(normals);CHKERRQ(ierr); 153909c71656SMatthew G. Knepley ierr = PetscFree(heights);CHKERRQ(ierr); 154000dabe28SStefano Zampini if (interpolate) { 154100dabe28SStefano Zampini DM idm; 154200dabe28SStefano Zampini 154300dabe28SStefano Zampini ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 154400dabe28SStefano Zampini ierr = DMPlexCopyCoordinates(*dm, idm);CHKERRQ(ierr); 154500dabe28SStefano Zampini ierr = DMDestroy(dm);CHKERRQ(ierr); 154600dabe28SStefano Zampini *dm = idm; 154700dabe28SStefano Zampini } 154800dabe28SStefano Zampini PetscFunctionReturn(0); 154900dabe28SStefano Zampini } 155000dabe28SStefano Zampini 1551a9074c1eSMatthew G. Knepley /*@C 1552a9074c1eSMatthew G. Knepley DMPlexSetOptionsPrefix - Sets the prefix used for searching for all DM options in the database. 1553a9074c1eSMatthew G. Knepley 1554d083f849SBarry Smith Logically Collective on dm 1555a9074c1eSMatthew G. Knepley 1556a9074c1eSMatthew G. Knepley Input Parameters: 1557a9074c1eSMatthew G. Knepley + dm - the DM context 1558a9074c1eSMatthew G. Knepley - prefix - the prefix to prepend to all option names 1559a9074c1eSMatthew G. Knepley 1560a9074c1eSMatthew G. Knepley Notes: 1561a9074c1eSMatthew G. Knepley A hyphen (-) must NOT be given at the beginning of the prefix name. 1562a9074c1eSMatthew G. Knepley The first character of all runtime options is AUTOMATICALLY the hyphen. 1563a9074c1eSMatthew G. Knepley 1564a9074c1eSMatthew G. Knepley Level: advanced 1565a9074c1eSMatthew G. Knepley 1566a9074c1eSMatthew G. Knepley .seealso: SNESSetFromOptions() 1567a9074c1eSMatthew G. Knepley @*/ 1568a9074c1eSMatthew G. Knepley PetscErrorCode DMPlexSetOptionsPrefix(DM dm, const char prefix[]) 1569a9074c1eSMatthew G. Knepley { 1570a9074c1eSMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) dm->data; 1571a9074c1eSMatthew G. Knepley PetscErrorCode ierr; 1572a9074c1eSMatthew G. Knepley 1573a9074c1eSMatthew G. Knepley PetscFunctionBegin; 1574a9074c1eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1575a9074c1eSMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) dm, prefix);CHKERRQ(ierr); 1576a9074c1eSMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) mesh->partitioner, prefix);CHKERRQ(ierr); 1577a9074c1eSMatthew G. Knepley PetscFunctionReturn(0); 1578a9074c1eSMatthew G. Knepley } 1579a9074c1eSMatthew G. Knepley 15809318fe57SMatthew G. Knepley /* Remap geometry to cylinder 158161a622f3SMatthew G. Knepley TODO: This only works for a single refinement, then it is broken 158261a622f3SMatthew G. Knepley 15839318fe57SMatthew G. Knepley Interior square: Linear interpolation is correct 15849318fe57SMatthew G. Knepley The other cells all have vertices on rays from the origin. We want to uniformly expand the spacing 15859318fe57SMatthew G. Knepley such that the last vertex is on the unit circle. So the closest and farthest vertices are at distance 15860510c589SMatthew G. Knepley 15879318fe57SMatthew G. Knepley phi = arctan(y/x) 15889318fe57SMatthew G. Knepley d_close = sqrt(1/8 + 1/4 sin^2(phi)) 15899318fe57SMatthew G. Knepley d_far = sqrt(1/2 + sin^2(phi)) 15900510c589SMatthew G. Knepley 15919318fe57SMatthew G. Knepley so we remap them using 15920510c589SMatthew G. Knepley 15939318fe57SMatthew G. Knepley x_new = x_close + (x - x_close) (1 - d_close) / (d_far - d_close) 15949318fe57SMatthew G. Knepley y_new = y_close + (y - y_close) (1 - d_close) / (d_far - d_close) 15950510c589SMatthew G. Knepley 15969318fe57SMatthew G. Knepley If pi/4 < phi < 3pi/4 or -3pi/4 < phi < -pi/4, then we switch x and y. 15979318fe57SMatthew G. Knepley */ 15989318fe57SMatthew G. Knepley static void snapToCylinder(PetscInt dim, PetscInt Nf, PetscInt NfAux, 15999318fe57SMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 16009318fe57SMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 16019318fe57SMatthew G. Knepley PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 16029318fe57SMatthew G. Knepley { 16039318fe57SMatthew G. Knepley const PetscReal dis = 1.0/PetscSqrtReal(2.0); 16049318fe57SMatthew G. Knepley const PetscReal ds2 = 0.5*dis; 160522cc497dSMatthew G. Knepley 16069318fe57SMatthew G. Knepley if ((PetscAbsScalar(u[0]) <= ds2) && (PetscAbsScalar(u[1]) <= ds2)) { 16079318fe57SMatthew G. Knepley f0[0] = u[0]; 16089318fe57SMatthew G. Knepley f0[1] = u[1]; 16099318fe57SMatthew G. Knepley } else { 16109318fe57SMatthew G. Knepley PetscReal phi, sinp, cosp, dc, df, x, y, xc, yc; 16110510c589SMatthew G. Knepley 16129318fe57SMatthew G. Knepley x = PetscRealPart(u[0]); 16139318fe57SMatthew G. Knepley y = PetscRealPart(u[1]); 16149318fe57SMatthew G. Knepley phi = PetscAtan2Real(y, x); 16159318fe57SMatthew G. Knepley sinp = PetscSinReal(phi); 16169318fe57SMatthew G. Knepley cosp = PetscCosReal(phi); 16179318fe57SMatthew G. Knepley if ((PetscAbsReal(phi) > PETSC_PI/4.0) && (PetscAbsReal(phi) < 3.0*PETSC_PI/4.0)) { 16189318fe57SMatthew G. Knepley dc = PetscAbsReal(ds2/sinp); 16199318fe57SMatthew G. Knepley df = PetscAbsReal(dis/sinp); 16209318fe57SMatthew G. Knepley xc = ds2*x/PetscAbsReal(y); 16219318fe57SMatthew G. Knepley yc = ds2*PetscSignReal(y); 16229318fe57SMatthew G. Knepley } else { 16239318fe57SMatthew G. Knepley dc = PetscAbsReal(ds2/cosp); 16249318fe57SMatthew G. Knepley df = PetscAbsReal(dis/cosp); 16259318fe57SMatthew G. Knepley xc = ds2*PetscSignReal(x); 16269318fe57SMatthew G. Knepley yc = ds2*y/PetscAbsReal(x); 16279318fe57SMatthew G. Knepley } 16289318fe57SMatthew G. Knepley f0[0] = xc + (u[0] - xc)*(1.0 - dc)/(df - dc); 16299318fe57SMatthew G. Knepley f0[1] = yc + (u[1] - yc)*(1.0 - dc)/(df - dc); 16309318fe57SMatthew G. Knepley } 16319318fe57SMatthew G. Knepley f0[2] = u[2]; 16329318fe57SMatthew G. Knepley } 16330510c589SMatthew G. Knepley 16349318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateHexCylinderMesh_Internal(DM dm, DMBoundaryType periodicZ) 16350510c589SMatthew G. Knepley { 16360510c589SMatthew G. Knepley const PetscInt dim = 3; 16379318fe57SMatthew G. Knepley PetscInt numCells, numVertices; 1638d8c47e87SMatthew G. Knepley PetscMPIInt rank; 16390510c589SMatthew G. Knepley PetscErrorCode ierr; 16400510c589SMatthew G. Knepley 16410510c589SMatthew G. Knepley PetscFunctionBegin; 16429318fe57SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 16439318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 16440510c589SMatthew G. Knepley /* Create topology */ 16450510c589SMatthew G. Knepley { 16460510c589SMatthew G. Knepley PetscInt cone[8], c; 16470510c589SMatthew G. Knepley 1648d8c47e87SMatthew G. Knepley numCells = !rank ? 5 : 0; 1649d8c47e87SMatthew G. Knepley numVertices = !rank ? 16 : 0; 1650006a8963SMatthew G. Knepley if (periodicZ == DM_BOUNDARY_PERIODIC) { 1651ae8bcbbbSMatthew G. Knepley numCells *= 3; 1652d8c47e87SMatthew G. Knepley numVertices = !rank ? 24 : 0; 1653006a8963SMatthew G. Knepley } 16549318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVertices);CHKERRQ(ierr); 16559318fe57SMatthew G. Knepley for (c = 0; c < numCells; c++) {ierr = DMPlexSetConeSize(dm, c, 8);CHKERRQ(ierr);} 16569318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); 1657d8c47e87SMatthew G. Knepley if (!rank) { 1658006a8963SMatthew G. Knepley if (periodicZ == DM_BOUNDARY_PERIODIC) { 1659ae8bcbbbSMatthew G. Knepley cone[0] = 15; cone[1] = 18; cone[2] = 17; cone[3] = 16; 1660ae8bcbbbSMatthew G. Knepley cone[4] = 31; cone[5] = 32; cone[6] = 33; cone[7] = 34; 16619318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 0, cone);CHKERRQ(ierr); 1662ae8bcbbbSMatthew G. Knepley cone[0] = 16; cone[1] = 17; cone[2] = 24; cone[3] = 23; 1663ae8bcbbbSMatthew G. Knepley cone[4] = 32; cone[5] = 36; cone[6] = 37; cone[7] = 33; /* 22 25 26 21 */ 16649318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 1, cone);CHKERRQ(ierr); 1665ae8bcbbbSMatthew G. Knepley cone[0] = 18; cone[1] = 27; cone[2] = 24; cone[3] = 17; 1666ae8bcbbbSMatthew G. Knepley cone[4] = 34; cone[5] = 33; cone[6] = 37; cone[7] = 38; 16679318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 2, cone);CHKERRQ(ierr); 1668ae8bcbbbSMatthew G. Knepley cone[0] = 29; cone[1] = 27; cone[2] = 18; cone[3] = 15; 1669ae8bcbbbSMatthew G. Knepley cone[4] = 35; cone[5] = 31; cone[6] = 34; cone[7] = 38; 16709318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 3, cone);CHKERRQ(ierr); 1671ae8bcbbbSMatthew G. Knepley cone[0] = 29; cone[1] = 15; cone[2] = 16; cone[3] = 23; 1672ae8bcbbbSMatthew G. Knepley cone[4] = 35; cone[5] = 36; cone[6] = 32; cone[7] = 31; 16739318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 4, cone);CHKERRQ(ierr); 1674006a8963SMatthew G. Knepley 1675ae8bcbbbSMatthew G. Knepley cone[0] = 31; cone[1] = 34; cone[2] = 33; cone[3] = 32; 1676ae8bcbbbSMatthew G. Knepley cone[4] = 19; cone[5] = 22; cone[6] = 21; cone[7] = 20; 16779318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 5, cone);CHKERRQ(ierr); 1678ae8bcbbbSMatthew G. Knepley cone[0] = 32; cone[1] = 33; cone[2] = 37; cone[3] = 36; 1679ae8bcbbbSMatthew G. Knepley cone[4] = 22; cone[5] = 25; cone[6] = 26; cone[7] = 21; 16809318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 6, cone);CHKERRQ(ierr); 1681ae8bcbbbSMatthew G. Knepley cone[0] = 34; cone[1] = 38; cone[2] = 37; cone[3] = 33; 1682ae8bcbbbSMatthew G. Knepley cone[4] = 20; cone[5] = 21; cone[6] = 26; cone[7] = 28; 16839318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 7, cone);CHKERRQ(ierr); 1684ae8bcbbbSMatthew G. Knepley cone[0] = 35; cone[1] = 38; cone[2] = 34; cone[3] = 31; 1685ae8bcbbbSMatthew G. Knepley cone[4] = 30; cone[5] = 19; cone[6] = 20; cone[7] = 28; 16869318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 8, cone);CHKERRQ(ierr); 1687ae8bcbbbSMatthew G. Knepley cone[0] = 35; cone[1] = 31; cone[2] = 32; cone[3] = 36; 1688ae8bcbbbSMatthew G. Knepley cone[4] = 30; cone[5] = 25; cone[6] = 22; cone[7] = 19; 16899318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 9, cone);CHKERRQ(ierr); 1690ae8bcbbbSMatthew G. Knepley 1691ae8bcbbbSMatthew G. Knepley cone[0] = 19; cone[1] = 20; cone[2] = 21; cone[3] = 22; 1692ae8bcbbbSMatthew G. Knepley cone[4] = 15; cone[5] = 16; cone[6] = 17; cone[7] = 18; 16939318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 10, cone);CHKERRQ(ierr); 1694ae8bcbbbSMatthew G. Knepley cone[0] = 22; cone[1] = 21; cone[2] = 26; cone[3] = 25; 1695ae8bcbbbSMatthew G. Knepley cone[4] = 16; cone[5] = 23; cone[6] = 24; cone[7] = 17; 16969318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 11, cone);CHKERRQ(ierr); 1697ae8bcbbbSMatthew G. Knepley cone[0] = 20; cone[1] = 28; cone[2] = 26; cone[3] = 21; 1698ae8bcbbbSMatthew G. Knepley cone[4] = 18; cone[5] = 17; cone[6] = 24; cone[7] = 27; 16999318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 12, cone);CHKERRQ(ierr); 1700ae8bcbbbSMatthew G. Knepley cone[0] = 30; cone[1] = 28; cone[2] = 20; cone[3] = 19; 1701ae8bcbbbSMatthew G. Knepley cone[4] = 29; cone[5] = 15; cone[6] = 18; cone[7] = 27; 17029318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 13, cone);CHKERRQ(ierr); 1703ae8bcbbbSMatthew G. Knepley cone[0] = 30; cone[1] = 19; cone[2] = 22; cone[3] = 25; 1704ae8bcbbbSMatthew G. Knepley cone[4] = 29; cone[5] = 23; cone[6] = 16; cone[7] = 15; 17059318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 14, cone);CHKERRQ(ierr); 1706006a8963SMatthew G. Knepley } else { 170710c6f908SMatthew G. Knepley cone[0] = 5; cone[1] = 8; cone[2] = 7; cone[3] = 6; 170810c6f908SMatthew G. Knepley cone[4] = 9; cone[5] = 12; cone[6] = 11; cone[7] = 10; 17099318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 0, cone);CHKERRQ(ierr); 171010c6f908SMatthew G. Knepley cone[0] = 6; cone[1] = 7; cone[2] = 14; cone[3] = 13; 171110c6f908SMatthew G. Knepley cone[4] = 12; cone[5] = 15; cone[6] = 16; cone[7] = 11; 17129318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 1, cone);CHKERRQ(ierr); 171310c6f908SMatthew G. Knepley cone[0] = 8; cone[1] = 17; cone[2] = 14; cone[3] = 7; 171410c6f908SMatthew G. Knepley cone[4] = 10; cone[5] = 11; cone[6] = 16; cone[7] = 18; 17159318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 2, cone);CHKERRQ(ierr); 171610c6f908SMatthew G. Knepley cone[0] = 19; cone[1] = 17; cone[2] = 8; cone[3] = 5; 171710c6f908SMatthew G. Knepley cone[4] = 20; cone[5] = 9; cone[6] = 10; cone[7] = 18; 17189318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 3, cone);CHKERRQ(ierr); 171910c6f908SMatthew G. Knepley cone[0] = 19; cone[1] = 5; cone[2] = 6; cone[3] = 13; 172010c6f908SMatthew G. Knepley cone[4] = 20; cone[5] = 15; cone[6] = 12; cone[7] = 9; 17219318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 4, cone);CHKERRQ(ierr); 1722006a8963SMatthew G. Knepley } 1723d8c47e87SMatthew G. Knepley } 17249318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 17259318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 17260510c589SMatthew G. Knepley } 1727dbc1dc17SMatthew G. Knepley /* Create cube geometry */ 17280510c589SMatthew G. Knepley { 17290510c589SMatthew G. Knepley Vec coordinates; 17300510c589SMatthew G. Knepley PetscSection coordSection; 17310510c589SMatthew G. Knepley PetscScalar *coords; 17320510c589SMatthew G. Knepley PetscInt coordSize, v; 17330510c589SMatthew G. Knepley const PetscReal dis = 1.0/PetscSqrtReal(2.0); 17340510c589SMatthew G. Knepley const PetscReal ds2 = dis/2.0; 17350510c589SMatthew G. Knepley 17360510c589SMatthew G. Knepley /* Build coordinates */ 17379318fe57SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 17380510c589SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 17390510c589SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, dim);CHKERRQ(ierr); 17400510c589SMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, numCells, numCells+numVertices);CHKERRQ(ierr); 17410510c589SMatthew G. Knepley for (v = numCells; v < numCells+numVertices; ++v) { 17420510c589SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, dim);CHKERRQ(ierr); 17430510c589SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, dim);CHKERRQ(ierr); 17440510c589SMatthew G. Knepley } 17450510c589SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 17460510c589SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 17470510c589SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 17480510c589SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 17490510c589SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 17500510c589SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, dim);CHKERRQ(ierr); 17510510c589SMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 17520510c589SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 1753d8c47e87SMatthew G. Knepley if (!rank) { 17540510c589SMatthew G. Knepley coords[0*dim+0] = -ds2; coords[0*dim+1] = -ds2; coords[0*dim+2] = 0.0; 17550510c589SMatthew G. Knepley coords[1*dim+0] = ds2; coords[1*dim+1] = -ds2; coords[1*dim+2] = 0.0; 17560510c589SMatthew G. Knepley coords[2*dim+0] = ds2; coords[2*dim+1] = ds2; coords[2*dim+2] = 0.0; 17570510c589SMatthew G. Knepley coords[3*dim+0] = -ds2; coords[3*dim+1] = ds2; coords[3*dim+2] = 0.0; 17580510c589SMatthew G. Knepley coords[4*dim+0] = -ds2; coords[4*dim+1] = -ds2; coords[4*dim+2] = 1.0; 17590510c589SMatthew G. Knepley coords[5*dim+0] = -ds2; coords[5*dim+1] = ds2; coords[5*dim+2] = 1.0; 17600510c589SMatthew G. Knepley coords[6*dim+0] = ds2; coords[6*dim+1] = ds2; coords[6*dim+2] = 1.0; 17610510c589SMatthew G. Knepley coords[7*dim+0] = ds2; coords[7*dim+1] = -ds2; coords[7*dim+2] = 1.0; 17620510c589SMatthew G. Knepley coords[ 8*dim+0] = dis; coords[ 8*dim+1] = -dis; coords[ 8*dim+2] = 0.0; 17630510c589SMatthew G. Knepley coords[ 9*dim+0] = dis; coords[ 9*dim+1] = dis; coords[ 9*dim+2] = 0.0; 17640510c589SMatthew G. Knepley coords[10*dim+0] = dis; coords[10*dim+1] = -dis; coords[10*dim+2] = 1.0; 17650510c589SMatthew G. Knepley coords[11*dim+0] = dis; coords[11*dim+1] = dis; coords[11*dim+2] = 1.0; 17660510c589SMatthew G. Knepley coords[12*dim+0] = -dis; coords[12*dim+1] = dis; coords[12*dim+2] = 0.0; 17670510c589SMatthew G. Knepley coords[13*dim+0] = -dis; coords[13*dim+1] = dis; coords[13*dim+2] = 1.0; 17680510c589SMatthew G. Knepley coords[14*dim+0] = -dis; coords[14*dim+1] = -dis; coords[14*dim+2] = 0.0; 17690510c589SMatthew G. Knepley coords[15*dim+0] = -dis; coords[15*dim+1] = -dis; coords[15*dim+2] = 1.0; 1770ae8bcbbbSMatthew G. Knepley if (periodicZ == DM_BOUNDARY_PERIODIC) { 1771ae8bcbbbSMatthew G. Knepley /* 15 31 19 */ coords[16*dim+0] = -ds2; coords[16*dim+1] = -ds2; coords[16*dim+2] = 0.5; 1772ae8bcbbbSMatthew G. Knepley /* 16 32 22 */ coords[17*dim+0] = ds2; coords[17*dim+1] = -ds2; coords[17*dim+2] = 0.5; 1773ae8bcbbbSMatthew G. Knepley /* 17 33 21 */ coords[18*dim+0] = ds2; coords[18*dim+1] = ds2; coords[18*dim+2] = 0.5; 1774ae8bcbbbSMatthew G. Knepley /* 18 34 20 */ coords[19*dim+0] = -ds2; coords[19*dim+1] = ds2; coords[19*dim+2] = 0.5; 1775ae8bcbbbSMatthew G. Knepley /* 29 35 30 */ coords[20*dim+0] = -dis; coords[20*dim+1] = -dis; coords[20*dim+2] = 0.5; 1776ae8bcbbbSMatthew G. Knepley /* 23 36 25 */ coords[21*dim+0] = dis; coords[21*dim+1] = -dis; coords[21*dim+2] = 0.5; 1777ae8bcbbbSMatthew G. Knepley /* 24 37 26 */ coords[22*dim+0] = dis; coords[22*dim+1] = dis; coords[22*dim+2] = 0.5; 1778ae8bcbbbSMatthew G. Knepley /* 27 38 28 */ coords[23*dim+0] = -dis; coords[23*dim+1] = dis; coords[23*dim+2] = 0.5; 1779ae8bcbbbSMatthew G. Knepley } 1780d8c47e87SMatthew G. Knepley } 17810510c589SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 17829318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 17830510c589SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 17840510c589SMatthew G. Knepley } 1785006a8963SMatthew G. Knepley /* Create periodicity */ 1786006a8963SMatthew G. Knepley if (periodicZ == DM_BOUNDARY_PERIODIC || periodicZ == DM_BOUNDARY_TWIST) { 1787006a8963SMatthew G. Knepley PetscReal L[3]; 1788006a8963SMatthew G. Knepley PetscReal maxCell[3]; 1789006a8963SMatthew G. Knepley DMBoundaryType bdType[3]; 1790006a8963SMatthew G. Knepley PetscReal lower[3] = {0.0, 0.0, 0.0}; 1791ae8bcbbbSMatthew G. Knepley PetscReal upper[3] = {1.0, 1.0, 1.5}; 1792ae8bcbbbSMatthew G. Knepley PetscInt i, numZCells = 3; 1793006a8963SMatthew G. Knepley 1794006a8963SMatthew G. Knepley bdType[0] = DM_BOUNDARY_NONE; 1795006a8963SMatthew G. Knepley bdType[1] = DM_BOUNDARY_NONE; 1796006a8963SMatthew G. Knepley bdType[2] = periodicZ; 1797006a8963SMatthew G. Knepley for (i = 0; i < dim; i++) { 1798006a8963SMatthew G. Knepley L[i] = upper[i] - lower[i]; 1799006a8963SMatthew G. Knepley maxCell[i] = 1.1 * (L[i] / numZCells); 1800006a8963SMatthew G. Knepley } 18019318fe57SMatthew G. Knepley ierr = DMSetPeriodicity(dm, PETSC_TRUE, maxCell, L, bdType);CHKERRQ(ierr); 1802006a8963SMatthew G. Knepley } 1803dbc1dc17SMatthew G. Knepley { 18049318fe57SMatthew G. Knepley DM cdm; 18059318fe57SMatthew G. Knepley PetscDS cds; 18069318fe57SMatthew G. Knepley PetscScalar c[2] = {1.0, 1.0}; 1807dbc1dc17SMatthew G. Knepley 18089318fe57SMatthew G. Knepley ierr = DMPlexCreateCoordinateSpace(dm, 1, snapToCylinder);CHKERRQ(ierr); 18099318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 18109318fe57SMatthew G. Knepley ierr = DMGetDS(cdm, &cds);CHKERRQ(ierr); 18119318fe57SMatthew G. Knepley ierr = PetscDSSetConstants(cds, 2, c);CHKERRQ(ierr); 1812dbc1dc17SMatthew G. Knepley } 18139318fe57SMatthew G. Knepley /* Wait for coordinate creation before doing in-place modification */ 18149318fe57SMatthew G. Knepley ierr = DMPlexInterpolateInPlace_Internal(dm);CHKERRQ(ierr); 18150510c589SMatthew G. Knepley PetscFunctionReturn(0); 18160510c589SMatthew G. Knepley } 18170510c589SMatthew G. Knepley 181824119c2aSMatthew G. Knepley /*@ 18199318fe57SMatthew G. Knepley DMPlexCreateHexCylinderMesh - Creates a mesh on the tensor product of the unit interval with the circle (cylinder) using hexahedra. 182024119c2aSMatthew G. Knepley 1821d083f849SBarry Smith Collective 182224119c2aSMatthew G. Knepley 182324119c2aSMatthew G. Knepley Input Parameters: 182424119c2aSMatthew G. Knepley + comm - The communicator for the DM object 18259318fe57SMatthew G. Knepley - periodicZ - The boundary type for the Z direction 182624119c2aSMatthew G. Knepley 182724119c2aSMatthew G. Knepley Output Parameter: 182824119c2aSMatthew G. Knepley . dm - The DM object 182924119c2aSMatthew G. Knepley 18309318fe57SMatthew G. Knepley Note: 18319318fe57SMatthew G. Knepley Here is the output numbering looking from the bottom of the cylinder: 18329318fe57SMatthew G. Knepley $ 17-----14 18339318fe57SMatthew G. Knepley $ | | 18349318fe57SMatthew G. Knepley $ | 2 | 18359318fe57SMatthew G. Knepley $ | | 18369318fe57SMatthew G. Knepley $ 17-----8-----7-----14 18379318fe57SMatthew G. Knepley $ | | | | 18389318fe57SMatthew G. Knepley $ | 3 | 0 | 1 | 18399318fe57SMatthew G. Knepley $ | | | | 18409318fe57SMatthew G. Knepley $ 19-----5-----6-----13 18419318fe57SMatthew G. Knepley $ | | 18429318fe57SMatthew G. Knepley $ | 4 | 18439318fe57SMatthew G. Knepley $ | | 18449318fe57SMatthew G. Knepley $ 19-----13 18459318fe57SMatthew G. Knepley $ 18469318fe57SMatthew G. Knepley $ and up through the top 18479318fe57SMatthew G. Knepley $ 18489318fe57SMatthew G. Knepley $ 18-----16 18499318fe57SMatthew G. Knepley $ | | 18509318fe57SMatthew G. Knepley $ | 2 | 18519318fe57SMatthew G. Knepley $ | | 18529318fe57SMatthew G. Knepley $ 18----10----11-----16 18539318fe57SMatthew G. Knepley $ | | | | 18549318fe57SMatthew G. Knepley $ | 3 | 0 | 1 | 18559318fe57SMatthew G. Knepley $ | | | | 18569318fe57SMatthew G. Knepley $ 20-----9----12-----15 18579318fe57SMatthew G. Knepley $ | | 18589318fe57SMatthew G. Knepley $ | 4 | 18599318fe57SMatthew G. Knepley $ | | 18609318fe57SMatthew G. Knepley $ 20-----15 18619318fe57SMatthew G. Knepley 186224119c2aSMatthew G. Knepley Level: beginner 186324119c2aSMatthew G. Knepley 18649318fe57SMatthew G. Knepley .seealso: DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 186524119c2aSMatthew G. Knepley @*/ 18669318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateHexCylinderMesh(MPI_Comm comm, DMBoundaryType periodicZ, DM *dm) 18679318fe57SMatthew G. Knepley { 18689318fe57SMatthew G. Knepley PetscErrorCode ierr; 18699318fe57SMatthew G. Knepley 18709318fe57SMatthew G. Knepley PetscFunctionBegin; 18719318fe57SMatthew G. Knepley PetscValidPointer(dm, 3); 18729318fe57SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 18739318fe57SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 18749318fe57SMatthew G. Knepley ierr = DMPlexCreateHexCylinderMesh_Internal(*dm, periodicZ);CHKERRQ(ierr); 18759318fe57SMatthew G. Knepley PetscFunctionReturn(0); 18769318fe57SMatthew G. Knepley } 18779318fe57SMatthew G. Knepley 18789318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateWedgeCylinderMesh_Internal(DM dm, PetscInt n, PetscBool interpolate) 187924119c2aSMatthew G. Knepley { 188024119c2aSMatthew G. Knepley const PetscInt dim = 3; 1881412e9a14SMatthew G. Knepley PetscInt numCells, numVertices, v; 18829fe9f049SMatthew G. Knepley PetscMPIInt rank; 188324119c2aSMatthew G. Knepley PetscErrorCode ierr; 188424119c2aSMatthew G. Knepley 188524119c2aSMatthew G. Knepley PetscFunctionBegin; 18869318fe57SMatthew G. Knepley if (n < 0) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Number of wedges %D cannot be negative", n); 18879318fe57SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 18889318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 1889412e9a14SMatthew G. Knepley /* Must create the celltype label here so that we do not automatically try to compute the types */ 18909318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm, "celltype");CHKERRQ(ierr); 189124119c2aSMatthew G. Knepley /* Create topology */ 189224119c2aSMatthew G. Knepley { 189324119c2aSMatthew G. Knepley PetscInt cone[6], c; 189424119c2aSMatthew G. Knepley 18959fe9f049SMatthew G. Knepley numCells = !rank ? n : 0; 18969fe9f049SMatthew G. Knepley numVertices = !rank ? 2*(n+1) : 0; 18979318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVertices);CHKERRQ(ierr); 18989318fe57SMatthew G. Knepley for (c = 0; c < numCells; c++) {ierr = DMPlexSetConeSize(dm, c, 6);CHKERRQ(ierr);} 18999318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); 190024119c2aSMatthew G. Knepley for (c = 0; c < numCells; c++) { 190124119c2aSMatthew G. Knepley cone[0] = c+n*1; cone[1] = (c+1)%n+n*1; cone[2] = 0+3*n; 190224119c2aSMatthew G. Knepley cone[3] = c+n*2; cone[4] = (c+1)%n+n*2; cone[5] = 1+3*n; 19039318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, c, cone);CHKERRQ(ierr); 19049318fe57SMatthew G. Knepley ierr = DMPlexSetCellType(dm, c, DM_POLYTOPE_TRI_PRISM_TENSOR);CHKERRQ(ierr); 190524119c2aSMatthew G. Knepley } 19069318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 19079318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 190824119c2aSMatthew G. Knepley } 1909412e9a14SMatthew G. Knepley for (v = numCells; v < numCells+numVertices; ++v) { 19109318fe57SMatthew G. Knepley ierr = DMPlexSetCellType(dm, v, DM_POLYTOPE_POINT);CHKERRQ(ierr); 191124119c2aSMatthew G. Knepley } 191224119c2aSMatthew G. Knepley /* Create cylinder geometry */ 191324119c2aSMatthew G. Knepley { 191424119c2aSMatthew G. Knepley Vec coordinates; 191524119c2aSMatthew G. Knepley PetscSection coordSection; 191624119c2aSMatthew G. Knepley PetscScalar *coords; 1917412e9a14SMatthew G. Knepley PetscInt coordSize, c; 191824119c2aSMatthew G. Knepley 191924119c2aSMatthew G. Knepley /* Build coordinates */ 19209318fe57SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 192124119c2aSMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 192224119c2aSMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, dim);CHKERRQ(ierr); 192324119c2aSMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, numCells, numCells+numVertices);CHKERRQ(ierr); 192424119c2aSMatthew G. Knepley for (v = numCells; v < numCells+numVertices; ++v) { 192524119c2aSMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, dim);CHKERRQ(ierr); 192624119c2aSMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, dim);CHKERRQ(ierr); 192724119c2aSMatthew G. Knepley } 192824119c2aSMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 192924119c2aSMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 193024119c2aSMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 193124119c2aSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 193224119c2aSMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 193324119c2aSMatthew G. Knepley ierr = VecSetBlockSize(coordinates, dim);CHKERRQ(ierr); 193424119c2aSMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 193524119c2aSMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 193624119c2aSMatthew G. Knepley for (c = 0; c < numCells; c++) { 193724119c2aSMatthew G. Knepley coords[(c+0*n)*dim+0] = PetscCosReal(2.0*c*PETSC_PI/n); coords[(c+0*n)*dim+1] = PetscSinReal(2.0*c*PETSC_PI/n); coords[(c+0*n)*dim+2] = 1.0; 193824119c2aSMatthew G. Knepley coords[(c+1*n)*dim+0] = PetscCosReal(2.0*c*PETSC_PI/n); coords[(c+1*n)*dim+1] = PetscSinReal(2.0*c*PETSC_PI/n); coords[(c+1*n)*dim+2] = 0.0; 193924119c2aSMatthew G. Knepley } 19409fe9f049SMatthew G. Knepley if (!rank) { 194124119c2aSMatthew G. Knepley coords[(2*n+0)*dim+0] = 0.0; coords[(2*n+0)*dim+1] = 0.0; coords[(2*n+0)*dim+2] = 1.0; 194224119c2aSMatthew G. Knepley coords[(2*n+1)*dim+0] = 0.0; coords[(2*n+1)*dim+1] = 0.0; coords[(2*n+1)*dim+2] = 0.0; 19439fe9f049SMatthew G. Knepley } 194424119c2aSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 19459318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 194624119c2aSMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 194724119c2aSMatthew G. Knepley } 19489318fe57SMatthew G. Knepley /* Interpolate */ 19499318fe57SMatthew G. Knepley if (interpolate) {ierr = DMPlexInterpolateInPlace_Internal(dm);CHKERRQ(ierr);} 19509318fe57SMatthew G. Knepley PetscFunctionReturn(0); 19519318fe57SMatthew G. Knepley } 19529318fe57SMatthew G. Knepley 19539318fe57SMatthew G. Knepley /*@ 19549318fe57SMatthew G. Knepley DMPlexCreateWedgeCylinderMesh - Creates a mesh on the tensor product of the unit interval with the circle (cylinder) using wedges. 19559318fe57SMatthew G. Knepley 19569318fe57SMatthew G. Knepley Collective 19579318fe57SMatthew G. Knepley 19589318fe57SMatthew G. Knepley Input Parameters: 19599318fe57SMatthew G. Knepley + comm - The communicator for the DM object 19609318fe57SMatthew G. Knepley . n - The number of wedges around the origin 19619318fe57SMatthew G. Knepley - interpolate - Create edges and faces 19629318fe57SMatthew G. Knepley 19639318fe57SMatthew G. Knepley Output Parameter: 19649318fe57SMatthew G. Knepley . dm - The DM object 19659318fe57SMatthew G. Knepley 19669318fe57SMatthew G. Knepley Level: beginner 19679318fe57SMatthew G. Knepley 19689318fe57SMatthew G. Knepley .seealso: DMPlexCreateHexCylinderMesh(), DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 19699318fe57SMatthew G. Knepley @*/ 19709318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateWedgeCylinderMesh(MPI_Comm comm, PetscInt n, PetscBool interpolate, DM *dm) 19719318fe57SMatthew G. Knepley { 19729318fe57SMatthew G. Knepley PetscErrorCode ierr; 19739318fe57SMatthew G. Knepley 19749318fe57SMatthew G. Knepley PetscFunctionBegin; 19759318fe57SMatthew G. Knepley PetscValidPointer(dm, 4); 19769318fe57SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 19779318fe57SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 19789318fe57SMatthew G. Knepley ierr = DMPlexCreateWedgeCylinderMesh_Internal(*dm, n, interpolate);CHKERRQ(ierr); 197924119c2aSMatthew G. Knepley PetscFunctionReturn(0); 198024119c2aSMatthew G. Knepley } 198124119c2aSMatthew G. Knepley 198265a81367SMatthew G. Knepley PETSC_STATIC_INLINE PetscReal DiffNormReal(PetscInt dim, const PetscReal x[], const PetscReal y[]) 198365a81367SMatthew G. Knepley { 198465a81367SMatthew G. Knepley PetscReal prod = 0.0; 198565a81367SMatthew G. Knepley PetscInt i; 198665a81367SMatthew G. Knepley for (i = 0; i < dim; ++i) prod += PetscSqr(x[i] - y[i]); 198765a81367SMatthew G. Knepley return PetscSqrtReal(prod); 198865a81367SMatthew G. Knepley } 198965a81367SMatthew G. Knepley PETSC_STATIC_INLINE PetscReal DotReal(PetscInt dim, const PetscReal x[], const PetscReal y[]) 199065a81367SMatthew G. Knepley { 199165a81367SMatthew G. Knepley PetscReal prod = 0.0; 199265a81367SMatthew G. Knepley PetscInt i; 199365a81367SMatthew G. Knepley for (i = 0; i < dim; ++i) prod += x[i]*y[i]; 199465a81367SMatthew G. Knepley return prod; 199565a81367SMatthew G. Knepley } 199665a81367SMatthew G. Knepley 199751a74b61SMatthew G. Knepley /* The first constant is the sphere radius */ 199851a74b61SMatthew G. Knepley static void snapToSphere(PetscInt dim, PetscInt Nf, PetscInt NfAux, 199951a74b61SMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 200051a74b61SMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 200151a74b61SMatthew G. Knepley PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 200251a74b61SMatthew G. Knepley { 200351a74b61SMatthew G. Knepley PetscReal r = PetscRealPart(constants[0]); 200451a74b61SMatthew G. Knepley PetscReal norm2 = 0.0, fac; 200551a74b61SMatthew G. Knepley PetscInt n = uOff[1] - uOff[0], d; 200651a74b61SMatthew G. Knepley 200751a74b61SMatthew G. Knepley for (d = 0; d < n; ++d) norm2 += PetscSqr(PetscRealPart(u[d])); 200851a74b61SMatthew G. Knepley fac = r/PetscSqrtReal(norm2); 200951a74b61SMatthew G. Knepley for (d = 0; d < n; ++d) f0[d] = u[d]*fac; 201051a74b61SMatthew G. Knepley } 201151a74b61SMatthew G. Knepley 20129318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateSphereMesh_Internal(DM dm, PetscInt dim, PetscBool simplex, PetscReal R) 20132829fed8SMatthew G. Knepley { 201465a81367SMatthew G. Knepley const PetscInt embedDim = dim+1; 201565a81367SMatthew G. Knepley PetscSection coordSection; 201665a81367SMatthew G. Knepley Vec coordinates; 201765a81367SMatthew G. Knepley PetscScalar *coords; 201865a81367SMatthew G. Knepley PetscReal *coordsIn; 201965a81367SMatthew G. Knepley PetscInt numCells, numEdges, numVerts, firstVertex, v, firstEdge, coordSize, d, c, e; 202065a81367SMatthew G. Knepley PetscMPIInt rank; 202165a81367SMatthew G. Knepley PetscErrorCode ierr; 202265a81367SMatthew G. Knepley 202365a81367SMatthew G. Knepley PetscFunctionBegin; 20249318fe57SMatthew G. Knepley PetscValidLogicalCollectiveBool(dm, simplex, 3); 20259318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 20269318fe57SMatthew G. Knepley ierr = DMSetCoordinateDim(dm, dim+1);CHKERRQ(ierr); 20279318fe57SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 202865a81367SMatthew G. Knepley switch (dim) { 202965a81367SMatthew G. Knepley case 2: 203065a81367SMatthew G. Knepley if (simplex) { 203151a74b61SMatthew G. Knepley const PetscReal radius = PetscSqrtReal(1 + PETSC_PHI*PETSC_PHI)/(1.0 + PETSC_PHI); 203251a74b61SMatthew G. Knepley const PetscReal edgeLen = 2.0/(1.0 + PETSC_PHI) * (R/radius); 203365a81367SMatthew G. Knepley const PetscInt degree = 5; 203451a74b61SMatthew G. Knepley PetscReal vertex[3] = {0.0, 1.0/(1.0 + PETSC_PHI), PETSC_PHI/(1.0 + PETSC_PHI)}; 203565a81367SMatthew G. Knepley PetscInt s[3] = {1, 1, 1}; 203665a81367SMatthew G. Knepley PetscInt cone[3]; 203765a81367SMatthew G. Knepley PetscInt *graph, p, i, j, k; 203865a81367SMatthew G. Knepley 203951a74b61SMatthew G. Knepley vertex[0] *= R/radius; vertex[1] *= R/radius; vertex[2] *= R/radius; 204065a81367SMatthew G. Knepley numCells = !rank ? 20 : 0; 204165a81367SMatthew G. Knepley numVerts = !rank ? 12 : 0; 204265a81367SMatthew G. Knepley firstVertex = numCells; 204351a74b61SMatthew G. Knepley /* Use icosahedron, which for a R-sphere has coordinates which are all cyclic permutations of 204465a81367SMatthew G. Knepley 204565a81367SMatthew G. Knepley (0, \pm 1/\phi+1, \pm \phi/\phi+1) 204665a81367SMatthew G. Knepley 204765a81367SMatthew G. Knepley where \phi^2 - \phi - 1 = 0, meaning \phi is the golden ratio \frac{1 + \sqrt{5}}{2}. The edge 204851a74b61SMatthew G. Knepley length is then given by 2/(1+\phi) = 2 * 0.38197 = 0.76393. 204965a81367SMatthew G. Knepley */ 205065a81367SMatthew G. Knepley /* Construct vertices */ 205165a81367SMatthew G. Knepley ierr = PetscCalloc1(numVerts * embedDim, &coordsIn);CHKERRQ(ierr); 205245da822fSValeria Barra if (!rank) { 205365a81367SMatthew G. Knepley for (p = 0, i = 0; p < embedDim; ++p) { 205465a81367SMatthew G. Knepley for (s[1] = -1; s[1] < 2; s[1] += 2) { 205565a81367SMatthew G. Knepley for (s[2] = -1; s[2] < 2; s[2] += 2) { 205665a81367SMatthew G. Knepley for (d = 0; d < embedDim; ++d) coordsIn[i*embedDim+d] = s[(d+p)%embedDim]*vertex[(d+p)%embedDim]; 205765a81367SMatthew G. Knepley ++i; 205865a81367SMatthew G. Knepley } 205965a81367SMatthew G. Knepley } 206065a81367SMatthew G. Knepley } 206145da822fSValeria Barra } 206265a81367SMatthew G. Knepley /* Construct graph */ 206365a81367SMatthew G. Knepley ierr = PetscCalloc1(numVerts * numVerts, &graph);CHKERRQ(ierr); 206465a81367SMatthew G. Knepley for (i = 0; i < numVerts; ++i) { 206565a81367SMatthew G. Knepley for (j = 0, k = 0; j < numVerts; ++j) { 206665a81367SMatthew G. Knepley if (PetscAbsReal(DiffNormReal(embedDim, &coordsIn[i*embedDim], &coordsIn[j*embedDim]) - edgeLen) < PETSC_SMALL) {graph[i*numVerts+j] = 1; ++k;} 206765a81367SMatthew G. Knepley } 20689318fe57SMatthew G. Knepley if (k != degree) SETERRQ3(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid icosahedron, vertex %D degree %D != %D", i, k, degree); 206965a81367SMatthew G. Knepley } 207065a81367SMatthew G. Knepley /* Build Topology */ 20719318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVerts);CHKERRQ(ierr); 207265a81367SMatthew G. Knepley for (c = 0; c < numCells; c++) { 20739318fe57SMatthew G. Knepley ierr = DMPlexSetConeSize(dm, c, embedDim);CHKERRQ(ierr); 207465a81367SMatthew G. Knepley } 20759318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 207665a81367SMatthew G. Knepley /* Cells */ 207765a81367SMatthew G. Knepley for (i = 0, c = 0; i < numVerts; ++i) { 207865a81367SMatthew G. Knepley for (j = 0; j < i; ++j) { 207965a81367SMatthew G. Knepley for (k = 0; k < j; ++k) { 208065a81367SMatthew G. Knepley if (graph[i*numVerts+j] && graph[j*numVerts+k] && graph[k*numVerts+i]) { 208165a81367SMatthew G. Knepley cone[0] = firstVertex+i; cone[1] = firstVertex+j; cone[2] = firstVertex+k; 208265a81367SMatthew G. Knepley /* Check orientation */ 208365a81367SMatthew G. Knepley { 208465a81367SMatthew G. Knepley const PetscInt epsilon[3][3][3] = {{{0, 0, 0}, {0, 0, 1}, {0, -1, 0}}, {{0, 0, -1}, {0, 0, 0}, {1, 0, 0}}, {{0, 1, 0}, {-1, 0, 0}, {0, 0, 0}}}; 208565a81367SMatthew G. Knepley PetscReal normal[3]; 208665a81367SMatthew G. Knepley PetscInt e, f; 208765a81367SMatthew G. Knepley 208865a81367SMatthew G. Knepley for (d = 0; d < embedDim; ++d) { 208965a81367SMatthew G. Knepley normal[d] = 0.0; 209065a81367SMatthew G. Knepley for (e = 0; e < embedDim; ++e) { 209165a81367SMatthew G. Knepley for (f = 0; f < embedDim; ++f) { 209265a81367SMatthew G. Knepley normal[d] += epsilon[d][e][f]*(coordsIn[j*embedDim+e] - coordsIn[i*embedDim+e])*(coordsIn[k*embedDim+f] - coordsIn[i*embedDim+f]); 209365a81367SMatthew G. Knepley } 209465a81367SMatthew G. Knepley } 209565a81367SMatthew G. Knepley } 209665a81367SMatthew G. Knepley if (DotReal(embedDim, normal, &coordsIn[i*embedDim]) < 0) {PetscInt tmp = cone[1]; cone[1] = cone[2]; cone[2] = tmp;} 209765a81367SMatthew G. Knepley } 20989318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, c++, cone);CHKERRQ(ierr); 209965a81367SMatthew G. Knepley } 210065a81367SMatthew G. Knepley } 210165a81367SMatthew G. Knepley } 210265a81367SMatthew G. Knepley } 21039318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 21049318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 210565a81367SMatthew G. Knepley ierr = PetscFree(graph);CHKERRQ(ierr); 210665a81367SMatthew G. Knepley } else { 21072829fed8SMatthew G. Knepley /* 21082829fed8SMatthew G. Knepley 12-21--13 21092829fed8SMatthew G. Knepley | | 21102829fed8SMatthew G. Knepley 25 4 24 21112829fed8SMatthew G. Knepley | | 21122829fed8SMatthew G. Knepley 12-25--9-16--8-24--13 21132829fed8SMatthew G. Knepley | | | | 21142829fed8SMatthew G. Knepley 23 5 17 0 15 3 22 21152829fed8SMatthew G. Knepley | | | | 21162829fed8SMatthew G. Knepley 10-20--6-14--7-19--11 21172829fed8SMatthew G. Knepley | | 21182829fed8SMatthew G. Knepley 20 1 19 21192829fed8SMatthew G. Knepley | | 21202829fed8SMatthew G. Knepley 10-18--11 21212829fed8SMatthew G. Knepley | | 21222829fed8SMatthew G. Knepley 23 2 22 21232829fed8SMatthew G. Knepley | | 21242829fed8SMatthew G. Knepley 12-21--13 21252829fed8SMatthew G. Knepley */ 21262829fed8SMatthew G. Knepley PetscInt cone[4], ornt[4]; 21272829fed8SMatthew G. Knepley 212865a81367SMatthew G. Knepley numCells = !rank ? 6 : 0; 212965a81367SMatthew G. Knepley numEdges = !rank ? 12 : 0; 213065a81367SMatthew G. Knepley numVerts = !rank ? 8 : 0; 213165a81367SMatthew G. Knepley firstVertex = numCells; 213265a81367SMatthew G. Knepley firstEdge = numCells + numVerts; 21332829fed8SMatthew G. Knepley /* Build Topology */ 21349318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numEdges+numVerts);CHKERRQ(ierr); 21352829fed8SMatthew G. Knepley for (c = 0; c < numCells; c++) { 21369318fe57SMatthew G. Knepley ierr = DMPlexSetConeSize(dm, c, 4);CHKERRQ(ierr); 21372829fed8SMatthew G. Knepley } 21382829fed8SMatthew G. Knepley for (e = firstEdge; e < firstEdge+numEdges; ++e) { 21399318fe57SMatthew G. Knepley ierr = DMPlexSetConeSize(dm, e, 2);CHKERRQ(ierr); 21402829fed8SMatthew G. Knepley } 21419318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 214245da822fSValeria Barra if (!rank) { 21432829fed8SMatthew G. Knepley /* Cell 0 */ 21442829fed8SMatthew G. Knepley cone[0] = 14; cone[1] = 15; cone[2] = 16; cone[3] = 17; 21459318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 0, cone);CHKERRQ(ierr); 21462829fed8SMatthew G. Knepley ornt[0] = 0; ornt[1] = 0; ornt[2] = 0; ornt[3] = 0; 21479318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 0, ornt);CHKERRQ(ierr); 21482829fed8SMatthew G. Knepley /* Cell 1 */ 21492829fed8SMatthew G. Knepley cone[0] = 18; cone[1] = 19; cone[2] = 14; cone[3] = 20; 21509318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 1, cone);CHKERRQ(ierr); 21512829fed8SMatthew G. Knepley ornt[0] = 0; ornt[1] = 0; ornt[2] = -2; ornt[3] = 0; 21529318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 1, ornt);CHKERRQ(ierr); 21532829fed8SMatthew G. Knepley /* Cell 2 */ 21542829fed8SMatthew G. Knepley cone[0] = 21; cone[1] = 22; cone[2] = 18; cone[3] = 23; 21559318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 2, cone);CHKERRQ(ierr); 21562829fed8SMatthew G. Knepley ornt[0] = 0; ornt[1] = 0; ornt[2] = -2; ornt[3] = 0; 21579318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 2, ornt);CHKERRQ(ierr); 21582829fed8SMatthew G. Knepley /* Cell 3 */ 21592829fed8SMatthew G. Knepley cone[0] = 19; cone[1] = 22; cone[2] = 24; cone[3] = 15; 21609318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 3, cone);CHKERRQ(ierr); 21612829fed8SMatthew G. Knepley ornt[0] = -2; ornt[1] = -2; ornt[2] = 0; ornt[3] = -2; 21629318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 3, ornt);CHKERRQ(ierr); 21632829fed8SMatthew G. Knepley /* Cell 4 */ 21642829fed8SMatthew G. Knepley cone[0] = 16; cone[1] = 24; cone[2] = 21; cone[3] = 25; 21659318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 4, cone);CHKERRQ(ierr); 21662829fed8SMatthew G. Knepley ornt[0] = -2; ornt[1] = -2; ornt[2] = -2; ornt[3] = 0; 21679318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 4, ornt);CHKERRQ(ierr); 21682829fed8SMatthew G. Knepley /* Cell 5 */ 21692829fed8SMatthew G. Knepley cone[0] = 20; cone[1] = 17; cone[2] = 25; cone[3] = 23; 21709318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 5, cone);CHKERRQ(ierr); 21712829fed8SMatthew G. Knepley ornt[0] = -2; ornt[1] = -2; ornt[2] = -2; ornt[3] = -2; 21729318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 5, ornt);CHKERRQ(ierr); 21732829fed8SMatthew G. Knepley /* Edges */ 21742829fed8SMatthew G. Knepley cone[0] = 6; cone[1] = 7; 21759318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 14, cone);CHKERRQ(ierr); 21762829fed8SMatthew G. Knepley cone[0] = 7; cone[1] = 8; 21779318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 15, cone);CHKERRQ(ierr); 21782829fed8SMatthew G. Knepley cone[0] = 8; cone[1] = 9; 21799318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 16, cone);CHKERRQ(ierr); 21802829fed8SMatthew G. Knepley cone[0] = 9; cone[1] = 6; 21819318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 17, cone);CHKERRQ(ierr); 21822829fed8SMatthew G. Knepley cone[0] = 10; cone[1] = 11; 21839318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 18, cone);CHKERRQ(ierr); 21842829fed8SMatthew G. Knepley cone[0] = 11; cone[1] = 7; 21859318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 19, cone);CHKERRQ(ierr); 21862829fed8SMatthew G. Knepley cone[0] = 6; cone[1] = 10; 21879318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 20, cone);CHKERRQ(ierr); 21882829fed8SMatthew G. Knepley cone[0] = 12; cone[1] = 13; 21899318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 21, cone);CHKERRQ(ierr); 21902829fed8SMatthew G. Knepley cone[0] = 13; cone[1] = 11; 21919318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 22, cone);CHKERRQ(ierr); 21922829fed8SMatthew G. Knepley cone[0] = 10; cone[1] = 12; 21939318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 23, cone);CHKERRQ(ierr); 21942829fed8SMatthew G. Knepley cone[0] = 13; cone[1] = 8; 21959318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 24, cone);CHKERRQ(ierr); 21962829fed8SMatthew G. Knepley cone[0] = 12; cone[1] = 9; 21979318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 25, cone);CHKERRQ(ierr); 219845da822fSValeria Barra } 21999318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 22009318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 22012829fed8SMatthew G. Knepley /* Build coordinates */ 220265a81367SMatthew G. Knepley ierr = PetscCalloc1(numVerts * embedDim, &coordsIn);CHKERRQ(ierr); 220345da822fSValeria Barra if (!rank) { 220451a74b61SMatthew G. Knepley coordsIn[0*embedDim+0] = -R; coordsIn[0*embedDim+1] = R; coordsIn[0*embedDim+2] = -R; 220551a74b61SMatthew G. Knepley coordsIn[1*embedDim+0] = R; coordsIn[1*embedDim+1] = R; coordsIn[1*embedDim+2] = -R; 220651a74b61SMatthew G. Knepley coordsIn[2*embedDim+0] = R; coordsIn[2*embedDim+1] = -R; coordsIn[2*embedDim+2] = -R; 220751a74b61SMatthew G. Knepley coordsIn[3*embedDim+0] = -R; coordsIn[3*embedDim+1] = -R; coordsIn[3*embedDim+2] = -R; 220851a74b61SMatthew G. Knepley coordsIn[4*embedDim+0] = -R; coordsIn[4*embedDim+1] = R; coordsIn[4*embedDim+2] = R; 220951a74b61SMatthew G. Knepley coordsIn[5*embedDim+0] = R; coordsIn[5*embedDim+1] = R; coordsIn[5*embedDim+2] = R; 221051a74b61SMatthew G. Knepley coordsIn[6*embedDim+0] = -R; coordsIn[6*embedDim+1] = -R; coordsIn[6*embedDim+2] = R; 221151a74b61SMatthew G. Knepley coordsIn[7*embedDim+0] = R; coordsIn[7*embedDim+1] = -R; coordsIn[7*embedDim+2] = R; 221265a81367SMatthew G. Knepley } 221345da822fSValeria Barra } 221465a81367SMatthew G. Knepley break; 221565a81367SMatthew G. Knepley case 3: 2216116ded15SMatthew G. Knepley if (simplex) { 2217116ded15SMatthew G. Knepley const PetscReal edgeLen = 1.0/PETSC_PHI; 221851a74b61SMatthew G. Knepley PetscReal vertexA[4] = {0.5, 0.5, 0.5, 0.5}; 221951a74b61SMatthew G. Knepley PetscReal vertexB[4] = {1.0, 0.0, 0.0, 0.0}; 222051a74b61SMatthew G. Knepley PetscReal vertexC[4] = {0.5, 0.5*PETSC_PHI, 0.5/PETSC_PHI, 0.0}; 2221116ded15SMatthew G. Knepley const PetscInt degree = 12; 2222116ded15SMatthew G. Knepley PetscInt s[4] = {1, 1, 1}; 2223116ded15SMatthew G. Knepley PetscInt evenPerm[12][4] = {{0, 1, 2, 3}, {0, 2, 3, 1}, {0, 3, 1, 2}, {1, 0, 3, 2}, {1, 2, 0, 3}, {1, 3, 2, 0}, 2224116ded15SMatthew G. Knepley {2, 0, 1, 3}, {2, 1, 3, 0}, {2, 3, 0, 1}, {3, 0, 2, 1}, {3, 1, 0, 2}, {3, 2, 1, 0}}; 2225116ded15SMatthew G. Knepley PetscInt cone[4]; 2226116ded15SMatthew G. Knepley PetscInt *graph, p, i, j, k, l; 2227116ded15SMatthew G. Knepley 222851a74b61SMatthew G. Knepley vertexA[0] *= R; vertexA[1] *= R; vertexA[2] *= R; vertexA[3] *= R; 222951a74b61SMatthew G. Knepley vertexB[0] *= R; vertexB[1] *= R; vertexB[2] *= R; vertexB[3] *= R; 223051a74b61SMatthew G. Knepley vertexC[0] *= R; vertexC[1] *= R; vertexC[2] *= R; vertexC[3] *= R; 2231116ded15SMatthew G. Knepley numCells = !rank ? 600 : 0; 2232116ded15SMatthew G. Knepley numVerts = !rank ? 120 : 0; 2233116ded15SMatthew G. Knepley firstVertex = numCells; 2234116ded15SMatthew G. Knepley /* Use the 600-cell, which for a unit sphere has coordinates which are 2235116ded15SMatthew G. Knepley 2236116ded15SMatthew G. Knepley 1/2 (\pm 1, \pm 1, \pm 1, \pm 1) 16 2237116ded15SMatthew G. Knepley (\pm 1, 0, 0, 0) all cyclic permutations 8 2238116ded15SMatthew G. Knepley 1/2 (\pm 1, \pm phi, \pm 1/phi, 0) all even permutations 96 2239116ded15SMatthew G. Knepley 2240116ded15SMatthew G. Knepley where \phi^2 - \phi - 1 = 0, meaning \phi is the golden ratio \frac{1 + \sqrt{5}}{2}. The edge 22416333ae4fSvaleriabarra length is then given by 1/\phi = 0.61803. 2242116ded15SMatthew G. Knepley 2243116ded15SMatthew G. Knepley http://buzzard.pugetsound.edu/sage-practice/ch03s03.html 2244116ded15SMatthew G. Knepley http://mathworld.wolfram.com/600-Cell.html 2245116ded15SMatthew G. Knepley */ 2246116ded15SMatthew G. Knepley /* Construct vertices */ 2247116ded15SMatthew G. Knepley ierr = PetscCalloc1(numVerts * embedDim, &coordsIn);CHKERRQ(ierr); 2248116ded15SMatthew G. Knepley i = 0; 224945da822fSValeria Barra if (!rank) { 2250116ded15SMatthew G. Knepley for (s[0] = -1; s[0] < 2; s[0] += 2) { 2251116ded15SMatthew G. Knepley for (s[1] = -1; s[1] < 2; s[1] += 2) { 2252116ded15SMatthew G. Knepley for (s[2] = -1; s[2] < 2; s[2] += 2) { 2253116ded15SMatthew G. Knepley for (s[3] = -1; s[3] < 2; s[3] += 2) { 2254116ded15SMatthew G. Knepley for (d = 0; d < embedDim; ++d) coordsIn[i*embedDim+d] = s[d]*vertexA[d]; 2255116ded15SMatthew G. Knepley ++i; 2256116ded15SMatthew G. Knepley } 2257116ded15SMatthew G. Knepley } 2258116ded15SMatthew G. Knepley } 2259116ded15SMatthew G. Knepley } 2260116ded15SMatthew G. Knepley for (p = 0; p < embedDim; ++p) { 2261116ded15SMatthew G. Knepley s[1] = s[2] = s[3] = 1; 2262116ded15SMatthew G. Knepley for (s[0] = -1; s[0] < 2; s[0] += 2) { 2263116ded15SMatthew G. Knepley for (d = 0; d < embedDim; ++d) coordsIn[i*embedDim+d] = s[(d+p)%embedDim]*vertexB[(d+p)%embedDim]; 2264116ded15SMatthew G. Knepley ++i; 2265116ded15SMatthew G. Knepley } 2266116ded15SMatthew G. Knepley } 2267116ded15SMatthew G. Knepley for (p = 0; p < 12; ++p) { 2268116ded15SMatthew G. Knepley s[3] = 1; 2269116ded15SMatthew G. Knepley for (s[0] = -1; s[0] < 2; s[0] += 2) { 2270116ded15SMatthew G. Knepley for (s[1] = -1; s[1] < 2; s[1] += 2) { 2271116ded15SMatthew G. Knepley for (s[2] = -1; s[2] < 2; s[2] += 2) { 2272116ded15SMatthew G. Knepley for (d = 0; d < embedDim; ++d) coordsIn[i*embedDim+d] = s[evenPerm[p][d]]*vertexC[evenPerm[p][d]]; 2273116ded15SMatthew G. Knepley ++i; 2274116ded15SMatthew G. Knepley } 2275116ded15SMatthew G. Knepley } 2276116ded15SMatthew G. Knepley } 2277116ded15SMatthew G. Knepley } 227845da822fSValeria Barra } 22799318fe57SMatthew G. Knepley if (i != numVerts) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid 600-cell, vertices %D != %D", i, numVerts); 2280116ded15SMatthew G. Knepley /* Construct graph */ 2281116ded15SMatthew G. Knepley ierr = PetscCalloc1(numVerts * numVerts, &graph);CHKERRQ(ierr); 2282116ded15SMatthew G. Knepley for (i = 0; i < numVerts; ++i) { 2283116ded15SMatthew G. Knepley for (j = 0, k = 0; j < numVerts; ++j) { 2284116ded15SMatthew G. Knepley if (PetscAbsReal(DiffNormReal(embedDim, &coordsIn[i*embedDim], &coordsIn[j*embedDim]) - edgeLen) < PETSC_SMALL) {graph[i*numVerts+j] = 1; ++k;} 2285116ded15SMatthew G. Knepley } 22869318fe57SMatthew G. Knepley if (k != degree) SETERRQ3(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid 600-cell, vertex %D degree %D != %D", i, k, degree); 2287116ded15SMatthew G. Knepley } 2288116ded15SMatthew G. Knepley /* Build Topology */ 22899318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVerts);CHKERRQ(ierr); 2290116ded15SMatthew G. Knepley for (c = 0; c < numCells; c++) { 22919318fe57SMatthew G. Knepley ierr = DMPlexSetConeSize(dm, c, embedDim);CHKERRQ(ierr); 2292116ded15SMatthew G. Knepley } 22939318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 2294116ded15SMatthew G. Knepley /* Cells */ 229545da822fSValeria Barra if (!rank) { 2296116ded15SMatthew G. Knepley for (i = 0, c = 0; i < numVerts; ++i) { 2297116ded15SMatthew G. Knepley for (j = 0; j < i; ++j) { 2298116ded15SMatthew G. Knepley for (k = 0; k < j; ++k) { 2299116ded15SMatthew G. Knepley for (l = 0; l < k; ++l) { 2300116ded15SMatthew G. Knepley if (graph[i*numVerts+j] && graph[j*numVerts+k] && graph[k*numVerts+i] && 2301116ded15SMatthew G. Knepley graph[l*numVerts+i] && graph[l*numVerts+j] && graph[l*numVerts+k]) { 2302116ded15SMatthew G. Knepley cone[0] = firstVertex+i; cone[1] = firstVertex+j; cone[2] = firstVertex+k; cone[3] = firstVertex+l; 2303116ded15SMatthew G. Knepley /* Check orientation: https://ef.gy/linear-algebra:normal-vectors-in-higher-dimensional-spaces */ 2304116ded15SMatthew G. Knepley { 2305116ded15SMatthew G. Knepley const PetscInt epsilon[4][4][4][4] = {{{{0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}}, 2306116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 1}, { 0, 0, -1, 0}}, 2307116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 0, -1}, { 0, 0, 0, 0}, { 0, 1, 0, 0}}, 2308116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 1, 0}, { 0, -1, 0, 0}, { 0, 0, 0, 0}}}, 2309116ded15SMatthew G. Knepley 2310116ded15SMatthew G. Knepley {{{0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, -1}, { 0, 0, 1, 0}}, 2311116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}}, 2312116ded15SMatthew G. Knepley {{0, 0, 0, 1}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, {-1, 0, 0, 0}}, 2313116ded15SMatthew G. Knepley {{0, 0, -1, 0}, { 0, 0, 0, 0}, { 1, 0, 0, 0}, { 0, 0, 0, 0}}}, 2314116ded15SMatthew G. Knepley 2315116ded15SMatthew G. Knepley {{{0, 0, 0, 0}, { 0, 0, 0, 1}, { 0, 0, 0, 0}, { 0, -1, 0, 0}}, 2316116ded15SMatthew G. Knepley {{0, 0, 0, -1}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 1, 0, 0, 0}}, 2317116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}}, 2318116ded15SMatthew G. Knepley {{0, 1, 0, 0}, {-1, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}}}, 2319116ded15SMatthew G. Knepley 2320116ded15SMatthew G. Knepley {{{0, 0, 0, 0}, { 0, 0, -1, 0}, { 0, 1, 0, 0}, { 0, 0, 0, 0}}, 2321116ded15SMatthew G. Knepley {{0, 0, 1, 0}, { 0, 0, 0, 0}, {-1, 0, 0, 0}, { 0, 0, 0, 0}}, 2322116ded15SMatthew G. Knepley {{0, -1, 0, 0}, { 1, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}}, 2323116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}}}}; 2324116ded15SMatthew G. Knepley PetscReal normal[4]; 2325116ded15SMatthew G. Knepley PetscInt e, f, g; 2326116ded15SMatthew G. Knepley 2327116ded15SMatthew G. Knepley for (d = 0; d < embedDim; ++d) { 2328116ded15SMatthew G. Knepley normal[d] = 0.0; 2329116ded15SMatthew G. Knepley for (e = 0; e < embedDim; ++e) { 2330116ded15SMatthew G. Knepley for (f = 0; f < embedDim; ++f) { 2331116ded15SMatthew G. Knepley for (g = 0; g < embedDim; ++g) { 2332116ded15SMatthew G. Knepley normal[d] += epsilon[d][e][f][g]*(coordsIn[j*embedDim+e] - coordsIn[i*embedDim+e])*(coordsIn[k*embedDim+f] - coordsIn[i*embedDim+f])*(coordsIn[l*embedDim+f] - coordsIn[i*embedDim+f]); 2333116ded15SMatthew G. Knepley } 2334116ded15SMatthew G. Knepley } 2335116ded15SMatthew G. Knepley } 2336116ded15SMatthew G. Knepley } 2337116ded15SMatthew G. Knepley if (DotReal(embedDim, normal, &coordsIn[i*embedDim]) < 0) {PetscInt tmp = cone[1]; cone[1] = cone[2]; cone[2] = tmp;} 2338116ded15SMatthew G. Knepley } 23399318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, c++, cone);CHKERRQ(ierr); 2340116ded15SMatthew G. Knepley } 2341116ded15SMatthew G. Knepley } 2342116ded15SMatthew G. Knepley } 2343116ded15SMatthew G. Knepley } 2344116ded15SMatthew G. Knepley } 234545da822fSValeria Barra } 23469318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 23479318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 2348116ded15SMatthew G. Knepley ierr = PetscFree(graph);CHKERRQ(ierr); 2349116ded15SMatthew G. Knepley break; 2350116ded15SMatthew G. Knepley } 23519318fe57SMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Unsupported dimension for sphere: %D", dim); 235265a81367SMatthew G. Knepley } 235365a81367SMatthew G. Knepley /* Create coordinates */ 23549318fe57SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 23552829fed8SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 23562829fed8SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, embedDim);CHKERRQ(ierr); 23572829fed8SMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, firstVertex, firstVertex+numVerts);CHKERRQ(ierr); 23582829fed8SMatthew G. Knepley for (v = firstVertex; v < firstVertex+numVerts; ++v) { 23592829fed8SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, embedDim);CHKERRQ(ierr); 23602829fed8SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, embedDim);CHKERRQ(ierr); 23612829fed8SMatthew G. Knepley } 23622829fed8SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 23632829fed8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 23642829fed8SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 23652829fed8SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, embedDim);CHKERRQ(ierr); 23662829fed8SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 23672829fed8SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 23682829fed8SMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 23692829fed8SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 237065a81367SMatthew G. Knepley for (v = 0; v < numVerts; ++v) for (d = 0; d < embedDim; ++d) {coords[v*embedDim+d] = coordsIn[v*embedDim+d];} 23712829fed8SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 23729318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 23732829fed8SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 237465a81367SMatthew G. Knepley ierr = PetscFree(coordsIn);CHKERRQ(ierr); 237551a74b61SMatthew G. Knepley { 237651a74b61SMatthew G. Knepley DM cdm; 237751a74b61SMatthew G. Knepley PetscDS cds; 23789318fe57SMatthew G. Knepley PetscScalar c = R; 237951a74b61SMatthew G. Knepley 23809318fe57SMatthew G. Knepley ierr = DMPlexCreateCoordinateSpace(dm, 1, snapToSphere);CHKERRQ(ierr); 23819318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 238251a74b61SMatthew G. Knepley ierr = DMGetDS(cdm, &cds);CHKERRQ(ierr); 23839318fe57SMatthew G. Knepley ierr = PetscDSSetConstants(cds, 1, &c);CHKERRQ(ierr); 238451a74b61SMatthew G. Knepley } 23859318fe57SMatthew G. Knepley /* Wait for coordinate creation before doing in-place modification */ 23869318fe57SMatthew G. Knepley if (simplex) {ierr = DMPlexInterpolateInPlace_Internal(dm);CHKERRQ(ierr);} 23879318fe57SMatthew G. Knepley PetscFunctionReturn(0); 23889318fe57SMatthew G. Knepley } 23899318fe57SMatthew G. Knepley 23909318fe57SMatthew G. Knepley /*@ 23919318fe57SMatthew G. Knepley DMPlexCreateSphereMesh - Creates a mesh on the d-dimensional sphere, S^d. 23929318fe57SMatthew G. Knepley 23939318fe57SMatthew G. Knepley Collective 23949318fe57SMatthew G. Knepley 23959318fe57SMatthew G. Knepley Input Parameters: 23969318fe57SMatthew G. Knepley + comm - The communicator for the DM object 23979318fe57SMatthew G. Knepley . dim - The dimension 23989318fe57SMatthew G. Knepley . simplex - Use simplices, or tensor product cells 23999318fe57SMatthew G. Knepley - R - The radius 24009318fe57SMatthew G. Knepley 24019318fe57SMatthew G. Knepley Output Parameter: 24029318fe57SMatthew G. Knepley . dm - The DM object 24039318fe57SMatthew G. Knepley 24049318fe57SMatthew G. Knepley Level: beginner 24059318fe57SMatthew G. Knepley 24069318fe57SMatthew G. Knepley .seealso: DMPlexCreateBallMesh(), DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 24079318fe57SMatthew G. Knepley @*/ 24089318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateSphereMesh(MPI_Comm comm, PetscInt dim, PetscBool simplex, PetscReal R, DM *dm) 24099318fe57SMatthew G. Knepley { 24109318fe57SMatthew G. Knepley PetscErrorCode ierr; 24119318fe57SMatthew G. Knepley 24129318fe57SMatthew G. Knepley PetscFunctionBegin; 24139318fe57SMatthew G. Knepley PetscValidPointer(dm, 5); 24149318fe57SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 24159318fe57SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 24169318fe57SMatthew G. Knepley ierr = DMPlexCreateSphereMesh_Internal(*dm, dim, simplex, R);CHKERRQ(ierr); 24179318fe57SMatthew G. Knepley PetscFunctionReturn(0); 24189318fe57SMatthew G. Knepley } 24199318fe57SMatthew G. Knepley 24209318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBallMesh_Internal(DM dm, PetscInt dim, PetscReal R) 24219318fe57SMatthew G. Knepley { 24229318fe57SMatthew G. Knepley DM sdm, vol; 24239318fe57SMatthew G. Knepley DMLabel bdlabel; 24249318fe57SMatthew G. Knepley PetscErrorCode ierr; 24259318fe57SMatthew G. Knepley 24269318fe57SMatthew G. Knepley PetscFunctionBegin; 24279318fe57SMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject) dm), &sdm);CHKERRQ(ierr); 24289318fe57SMatthew G. Knepley ierr = DMSetType(sdm, DMPLEX);CHKERRQ(ierr); 24299318fe57SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) sdm, "bd_");CHKERRQ(ierr); 24309318fe57SMatthew G. Knepley ierr = DMPlexCreateSphereMesh_Internal(sdm, dim-1, PETSC_TRUE, R);CHKERRQ(ierr); 24319318fe57SMatthew G. Knepley ierr = DMSetFromOptions(sdm);CHKERRQ(ierr); 24329318fe57SMatthew G. Knepley ierr = DMViewFromOptions(sdm, NULL, "-dm_view");CHKERRQ(ierr); 24339318fe57SMatthew G. Knepley ierr = DMPlexGenerate(sdm, NULL, PETSC_TRUE, &vol);CHKERRQ(ierr); 24349318fe57SMatthew G. Knepley ierr = DMDestroy(&sdm);CHKERRQ(ierr); 24359318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &vol);CHKERRQ(ierr); 24369318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm, "marker");CHKERRQ(ierr); 24379318fe57SMatthew G. Knepley ierr = DMGetLabel(dm, "marker", &bdlabel);CHKERRQ(ierr); 24389318fe57SMatthew G. Knepley ierr = DMPlexMarkBoundaryFaces(dm, PETSC_DETERMINE, bdlabel);CHKERRQ(ierr); 24399318fe57SMatthew G. Knepley ierr = DMPlexLabelComplete(dm, bdlabel);CHKERRQ(ierr); 244051a74b61SMatthew G. Knepley PetscFunctionReturn(0); 244151a74b61SMatthew G. Knepley } 244251a74b61SMatthew G. Knepley 244351a74b61SMatthew G. Knepley /*@ 244451a74b61SMatthew G. Knepley DMPlexCreateBallMesh - Creates a simplex mesh on the d-dimensional ball, B^d. 244551a74b61SMatthew G. Knepley 244651a74b61SMatthew G. Knepley Collective 244751a74b61SMatthew G. Knepley 244851a74b61SMatthew G. Knepley Input Parameters: 244951a74b61SMatthew G. Knepley + comm - The communicator for the DM object 245051a74b61SMatthew G. Knepley . dim - The dimension 245151a74b61SMatthew G. Knepley - R - The radius 245251a74b61SMatthew G. Knepley 245351a74b61SMatthew G. Knepley Output Parameter: 245451a74b61SMatthew G. Knepley . dm - The DM object 245551a74b61SMatthew G. Knepley 245651a74b61SMatthew G. Knepley Options Database Keys: 245751a74b61SMatthew G. Knepley - bd_dm_refine - This will refine the surface mesh preserving the sphere geometry 245851a74b61SMatthew G. Knepley 245951a74b61SMatthew G. Knepley Level: beginner 246051a74b61SMatthew G. Knepley 246151a74b61SMatthew G. Knepley .seealso: DMPlexCreateSphereMesh(), DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 246251a74b61SMatthew G. Knepley @*/ 246351a74b61SMatthew G. Knepley PetscErrorCode DMPlexCreateBallMesh(MPI_Comm comm, PetscInt dim, PetscReal R, DM *dm) 246451a74b61SMatthew G. Knepley { 246551a74b61SMatthew G. Knepley PetscErrorCode ierr; 246651a74b61SMatthew G. Knepley 246751a74b61SMatthew G. Knepley PetscFunctionBegin; 24689318fe57SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 24699318fe57SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 24709318fe57SMatthew G. Knepley ierr = DMPlexCreateBallMesh_Internal(*dm, dim, R);CHKERRQ(ierr); 24712829fed8SMatthew G. Knepley PetscFunctionReturn(0); 24722829fed8SMatthew G. Knepley } 24732829fed8SMatthew G. Knepley 24749318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateReferenceCell_Internal(DM rdm, DMPolytopeType ct) 24750a6ba040SMatthew G. Knepley { 24760a6ba040SMatthew G. Knepley PetscErrorCode ierr; 24770a6ba040SMatthew G. Knepley 24780a6ba040SMatthew G. Knepley PetscFunctionBegin; 24799318fe57SMatthew G. Knepley switch (ct) { 24809318fe57SMatthew G. Knepley case DM_POLYTOPE_POINT: 24819318fe57SMatthew G. Knepley { 24829318fe57SMatthew G. Knepley PetscInt numPoints[1] = {1}; 24839318fe57SMatthew G. Knepley PetscInt coneSize[1] = {0}; 24849318fe57SMatthew G. Knepley PetscInt cones[1] = {0}; 24859318fe57SMatthew G. Knepley PetscInt coneOrientations[1] = {0}; 24869318fe57SMatthew G. Knepley PetscScalar vertexCoords[1] = {0.0}; 24879318fe57SMatthew G. Knepley 24889318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 0);CHKERRQ(ierr); 24899318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 0, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 24909318fe57SMatthew G. Knepley } 24919318fe57SMatthew G. Knepley break; 24929318fe57SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 24939318fe57SMatthew G. Knepley { 24949318fe57SMatthew G. Knepley PetscInt numPoints[2] = {2, 1}; 24959318fe57SMatthew G. Knepley PetscInt coneSize[3] = {2, 0, 0}; 24969318fe57SMatthew G. Knepley PetscInt cones[2] = {1, 2}; 24979318fe57SMatthew G. Knepley PetscInt coneOrientations[2] = {0, 0}; 24989318fe57SMatthew G. Knepley PetscScalar vertexCoords[2] = {-1.0, 1.0}; 24999318fe57SMatthew G. Knepley 25009318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 1);CHKERRQ(ierr); 25019318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 25029318fe57SMatthew G. Knepley } 25039318fe57SMatthew G. Knepley break; 25049318fe57SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 25059318fe57SMatthew G. Knepley { 25069318fe57SMatthew G. Knepley PetscInt numPoints[2] = {3, 1}; 25079318fe57SMatthew G. Knepley PetscInt coneSize[4] = {3, 0, 0, 0}; 25089318fe57SMatthew G. Knepley PetscInt cones[3] = {1, 2, 3}; 25099318fe57SMatthew G. Knepley PetscInt coneOrientations[3] = {0, 0, 0}; 25109318fe57SMatthew G. Knepley PetscScalar vertexCoords[6] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0}; 25119318fe57SMatthew G. Knepley 25129318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 2);CHKERRQ(ierr); 25139318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 25149318fe57SMatthew G. Knepley } 25159318fe57SMatthew G. Knepley break; 25169318fe57SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 25179318fe57SMatthew G. Knepley { 25189318fe57SMatthew G. Knepley PetscInt numPoints[2] = {4, 1}; 25199318fe57SMatthew G. Knepley PetscInt coneSize[5] = {4, 0, 0, 0, 0}; 25209318fe57SMatthew G. Knepley PetscInt cones[4] = {1, 2, 3, 4}; 25219318fe57SMatthew G. Knepley PetscInt coneOrientations[4] = {0, 0, 0, 0}; 25229318fe57SMatthew G. Knepley PetscScalar vertexCoords[8] = {-1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0}; 25239318fe57SMatthew G. Knepley 25249318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 2);CHKERRQ(ierr); 25259318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 25269318fe57SMatthew G. Knepley } 25279318fe57SMatthew G. Knepley break; 25289318fe57SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 25299318fe57SMatthew G. Knepley { 25309318fe57SMatthew G. Knepley PetscInt numPoints[2] = {4, 1}; 25319318fe57SMatthew G. Knepley PetscInt coneSize[5] = {4, 0, 0, 0, 0}; 25329318fe57SMatthew G. Knepley PetscInt cones[4] = {1, 2, 3, 4}; 25339318fe57SMatthew G. Knepley PetscInt coneOrientations[4] = {0, 0, 0, 0}; 25349318fe57SMatthew G. Knepley PetscScalar vertexCoords[8] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0}; 25359318fe57SMatthew G. Knepley 25369318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 2);CHKERRQ(ierr); 25379318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 25389318fe57SMatthew G. Knepley } 25399318fe57SMatthew G. Knepley break; 25409318fe57SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 25419318fe57SMatthew G. Knepley { 25429318fe57SMatthew G. Knepley PetscInt numPoints[2] = {4, 1}; 25439318fe57SMatthew G. Knepley PetscInt coneSize[5] = {4, 0, 0, 0, 0}; 25449318fe57SMatthew G. Knepley PetscInt cones[4] = {1, 3, 2, 4}; 25459318fe57SMatthew G. Knepley PetscInt coneOrientations[4] = {0, 0, 0, 0}; 25469318fe57SMatthew G. Knepley PetscScalar vertexCoords[12] = {-1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0}; 25479318fe57SMatthew G. Knepley 25489318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 25499318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 25509318fe57SMatthew G. Knepley } 25519318fe57SMatthew G. Knepley break; 25529318fe57SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 25539318fe57SMatthew G. Knepley { 25549318fe57SMatthew G. Knepley PetscInt numPoints[2] = {8, 1}; 25559318fe57SMatthew G. Knepley PetscInt coneSize[9] = {8, 0, 0, 0, 0, 0, 0, 0, 0}; 25569318fe57SMatthew G. Knepley PetscInt cones[8] = {1, 4, 3, 2, 5, 6, 7, 8}; 25579318fe57SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 25589318fe57SMatthew G. Knepley PetscScalar vertexCoords[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, 25599318fe57SMatthew G. Knepley -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0}; 25609318fe57SMatthew G. Knepley 25619318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 25629318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 25639318fe57SMatthew G. Knepley } 25649318fe57SMatthew G. Knepley break; 25659318fe57SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 25669318fe57SMatthew G. Knepley { 25679318fe57SMatthew G. Knepley PetscInt numPoints[2] = {6, 1}; 25689318fe57SMatthew G. Knepley PetscInt coneSize[7] = {6, 0, 0, 0, 0, 0, 0}; 25699318fe57SMatthew G. Knepley PetscInt cones[6] = {1, 3, 2, 4, 5, 6}; 25709318fe57SMatthew G. Knepley PetscInt coneOrientations[6] = {0, 0, 0, 0, 0, 0}; 25719318fe57SMatthew G. Knepley PetscScalar vertexCoords[18] = {-1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 25729318fe57SMatthew G. Knepley -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0}; 25739318fe57SMatthew G. Knepley 25749318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 25759318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 25769318fe57SMatthew G. Knepley } 25779318fe57SMatthew G. Knepley break; 25789318fe57SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 25799318fe57SMatthew G. Knepley { 25809318fe57SMatthew G. Knepley PetscInt numPoints[2] = {6, 1}; 25819318fe57SMatthew G. Knepley PetscInt coneSize[7] = {6, 0, 0, 0, 0, 0, 0}; 25829318fe57SMatthew G. Knepley PetscInt cones[6] = {1, 2, 3, 4, 5, 6}; 25839318fe57SMatthew G. Knepley PetscInt coneOrientations[6] = {0, 0, 0, 0, 0, 0}; 25849318fe57SMatthew G. Knepley PetscScalar vertexCoords[18] = {-1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 25859318fe57SMatthew G. Knepley -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0}; 25869318fe57SMatthew G. Knepley 25879318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 25889318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 25899318fe57SMatthew G. Knepley } 25909318fe57SMatthew G. Knepley break; 25919318fe57SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 25929318fe57SMatthew G. Knepley { 25939318fe57SMatthew G. Knepley PetscInt numPoints[2] = {8, 1}; 25949318fe57SMatthew G. Knepley PetscInt coneSize[9] = {8, 0, 0, 0, 0, 0, 0, 0, 0}; 25959318fe57SMatthew G. Knepley PetscInt cones[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 25969318fe57SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 25979318fe57SMatthew G. Knepley PetscScalar vertexCoords[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, 25989318fe57SMatthew G. Knepley -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0}; 25999318fe57SMatthew G. Knepley 26009318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 26019318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 26029318fe57SMatthew G. Knepley } 26039318fe57SMatthew G. Knepley break; 26049318fe57SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 26059318fe57SMatthew G. Knepley { 26069318fe57SMatthew G. Knepley PetscInt numPoints[2] = {5, 1}; 26079318fe57SMatthew G. Knepley PetscInt coneSize[6] = {5, 0, 0, 0, 0, 0}; 26089318fe57SMatthew G. Knepley PetscInt cones[5] = {1, 4, 3, 2, 5}; 26099318fe57SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 26109318fe57SMatthew G. Knepley PetscScalar vertexCoords[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, 26119318fe57SMatthew G. Knepley 0.0, 0.0, 1.0}; 26129318fe57SMatthew G. Knepley 26139318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 26149318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 26159318fe57SMatthew G. Knepley } 26169318fe57SMatthew G. Knepley break; 26179318fe57SMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) rdm), PETSC_ERR_ARG_WRONG, "Cannot create reference cell for cell type %s", DMPolytopeTypes[ct]); 26189318fe57SMatthew G. Knepley } 26199318fe57SMatthew G. Knepley { 26209318fe57SMatthew G. Knepley PetscInt Nv, v; 26219318fe57SMatthew G. Knepley 26229318fe57SMatthew G. Knepley /* Must create the celltype label here so that we do not automatically try to compute the types */ 26239318fe57SMatthew G. Knepley ierr = DMCreateLabel(rdm, "celltype");CHKERRQ(ierr); 26249318fe57SMatthew G. Knepley ierr = DMPlexSetCellType(rdm, 0, ct);CHKERRQ(ierr); 26259318fe57SMatthew G. Knepley ierr = DMPlexGetChart(rdm, NULL, &Nv);CHKERRQ(ierr); 26269318fe57SMatthew G. Knepley for (v = 1; v < Nv; ++v) {ierr = DMPlexSetCellType(rdm, v, DM_POLYTOPE_POINT);CHKERRQ(ierr);} 26279318fe57SMatthew G. Knepley } 26289318fe57SMatthew G. Knepley ierr = DMPlexInterpolateInPlace_Internal(rdm);CHKERRQ(ierr); 2629*b7f6ffafSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) rdm, DMPolytopeTypes[ct]);CHKERRQ(ierr); 26300a6ba040SMatthew G. Knepley PetscFunctionReturn(0); 26310a6ba040SMatthew G. Knepley } 26320a6ba040SMatthew G. Knepley 26339318fe57SMatthew G. Knepley /*@ 26349318fe57SMatthew G. Knepley DMPlexCreateReferenceCell - Create a DMPLEX with the appropriate FEM reference cell 26359318fe57SMatthew G. Knepley 26369318fe57SMatthew G. Knepley Collective 26379318fe57SMatthew G. Knepley 26389318fe57SMatthew G. Knepley Input Parameters: 26399318fe57SMatthew G. Knepley + comm - The communicator 26409318fe57SMatthew G. Knepley - ct - The cell type of the reference cell 26419318fe57SMatthew G. Knepley 26429318fe57SMatthew G. Knepley Output Parameter: 26439318fe57SMatthew G. Knepley . refdm - The reference cell 26449318fe57SMatthew G. Knepley 26459318fe57SMatthew G. Knepley Level: intermediate 26469318fe57SMatthew G. Knepley 26479318fe57SMatthew G. Knepley .seealso: DMPlexCreateReferenceCell(), DMPlexCreateBoxMesh() 26489318fe57SMatthew G. Knepley @*/ 26499318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateReferenceCell(MPI_Comm comm, DMPolytopeType ct, DM *refdm) 26500a6ba040SMatthew G. Knepley { 26510a6ba040SMatthew G. Knepley PetscErrorCode ierr; 26520a6ba040SMatthew G. Knepley 26530a6ba040SMatthew G. Knepley PetscFunctionBegin; 26549318fe57SMatthew G. Knepley ierr = DMCreate(comm, refdm);CHKERRQ(ierr); 26559318fe57SMatthew G. Knepley ierr = DMSetType(*refdm, DMPLEX);CHKERRQ(ierr); 26569318fe57SMatthew G. Knepley ierr = DMPlexCreateReferenceCell_Internal(*refdm, ct);CHKERRQ(ierr); 26579318fe57SMatthew G. Knepley PetscFunctionReturn(0); 26589318fe57SMatthew G. Knepley } 265979a015ccSMatthew G. Knepley 26609318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoundaryLabel_Private(DM dm, const char name[]) 26619318fe57SMatthew G. Knepley { 26629318fe57SMatthew G. Knepley DM plex; 26639318fe57SMatthew G. Knepley DMLabel label; 26649318fe57SMatthew G. Knepley PetscBool hasLabel; 26659318fe57SMatthew G. Knepley PetscErrorCode ierr; 26660a6ba040SMatthew G. Knepley 26679318fe57SMatthew G. Knepley PetscFunctionBeginUser; 26689318fe57SMatthew G. Knepley ierr = DMHasLabel(dm, name, &hasLabel);CHKERRQ(ierr); 26699318fe57SMatthew G. Knepley if (hasLabel) PetscFunctionReturn(0); 26709318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm, name);CHKERRQ(ierr); 26719318fe57SMatthew G. Knepley ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 26729318fe57SMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 26739318fe57SMatthew G. Knepley ierr = DMPlexMarkBoundaryFaces(plex, 1, label);CHKERRQ(ierr); 26749318fe57SMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 26759318fe57SMatthew G. Knepley PetscFunctionReturn(0); 26769318fe57SMatthew G. Knepley } 2677acdc6f61SToby Isaac 26789318fe57SMatthew G. Knepley const char * const DMPlexShapes[] = {"box", "box_surface", "ball", "sphere", "cylinder", "unknown", "DMPlexShape", "DM_SHAPE_", NULL}; 26799318fe57SMatthew G. Knepley 268061a622f3SMatthew G. Knepley static PetscErrorCode DMPlexCreateFromOptions_Internal(PetscOptionItems *PetscOptionsObject, PetscBool *useCoordSpace, DM dm) 26819318fe57SMatthew G. Knepley { 26829318fe57SMatthew G. Knepley DMPlexShape shape = DM_SHAPE_BOX; 26839318fe57SMatthew G. Knepley DMPolytopeType cell = DM_POLYTOPE_TRIANGLE; 26849318fe57SMatthew G. Knepley PetscInt dim = 2; 26859318fe57SMatthew G. Knepley PetscBool simplex = PETSC_TRUE, interpolate = PETSC_TRUE, adjCone = PETSC_FALSE, adjClosure = PETSC_TRUE, refDomain = PETSC_FALSE; 26869318fe57SMatthew G. Knepley PetscBool flg, flg2, fflg, bdfflg; 26879318fe57SMatthew G. Knepley MPI_Comm comm; 26889318fe57SMatthew G. Knepley char filename[PETSC_MAX_PATH_LEN], bdFilename[PETSC_MAX_PATH_LEN]; 26899318fe57SMatthew G. Knepley PetscErrorCode ierr; 26909318fe57SMatthew G. Knepley 26919318fe57SMatthew G. Knepley PetscFunctionBegin; 26929318fe57SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 26939318fe57SMatthew G. Knepley /* TODO Turn this into a registration interface */ 26949318fe57SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_filename", "File containing a mesh", "DMPlexCreateFromFile", filename, filename, sizeof(filename), &fflg);CHKERRQ(ierr); 26959318fe57SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_boundary_filename", "File containing a mesh boundary", "DMPlexCreateFromFile", bdFilename, bdFilename, sizeof(bdFilename), &bdfflg);CHKERRQ(ierr); 26969318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_cell", "Cell shape", "", DMPolytopeTypes, (PetscEnum) cell, (PetscEnum *) &cell, NULL);CHKERRQ(ierr); 26979318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_reference_cell_domain", "Use a reference cell domain", "", refDomain, &refDomain, NULL);CHKERRQ(ierr); 26989318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_shape", "Shape for built-in mesh", "", DMPlexShapes, (PetscEnum) shape, (PetscEnum *) &shape, &flg);CHKERRQ(ierr); 26999318fe57SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_plex_dim", "Topological dimension of the mesh", "DMGetDimension", dim, &dim, &flg, 0);CHKERRQ(ierr); 27009318fe57SMatthew G. Knepley if ((dim < 0) || (dim > 3)) SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Dimension %D should be in [1, 3]", dim); 27019318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_simplex", "Mesh cell shape", "", simplex, &simplex, &flg);CHKERRQ(ierr); 27029318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_interpolate", "Flag to create edges and faces automatically", "", interpolate, &interpolate, &flg);CHKERRQ(ierr); 27039318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_adj_cone", "Set adjacency direction", "DMSetBasicAdjacency", adjCone, &adjCone, &flg);CHKERRQ(ierr); 27049318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_adj_closure", "Set adjacency size", "DMSetBasicAdjacency", adjClosure, &adjClosure, &flg2);CHKERRQ(ierr); 27059318fe57SMatthew G. Knepley if (flg || flg2) {ierr = DMSetBasicAdjacency(dm, adjCone, adjClosure);CHKERRQ(ierr);} 27069318fe57SMatthew G. Knepley 270761a622f3SMatthew G. Knepley switch (cell) { 270861a622f3SMatthew G. Knepley case DM_POLYTOPE_POINT: 270961a622f3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 271061a622f3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 271161a622f3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 271261a622f3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 271361a622f3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 271461a622f3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 271561a622f3SMatthew G. Knepley *useCoordSpace = PETSC_TRUE;break; 271661a622f3SMatthew G. Knepley default: *useCoordSpace = PETSC_FALSE;break; 271761a622f3SMatthew G. Knepley } 271861a622f3SMatthew G. Knepley 27199318fe57SMatthew G. Knepley if (fflg) { 27209318fe57SMatthew G. Knepley DM dmnew; 27219318fe57SMatthew G. Knepley 27229318fe57SMatthew G. Knepley ierr = DMPlexCreateFromFile(PetscObjectComm((PetscObject) dm), filename, interpolate, &dmnew);CHKERRQ(ierr); 27239318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &dmnew);CHKERRQ(ierr); 27249318fe57SMatthew G. Knepley } else if (refDomain) { 27259318fe57SMatthew G. Knepley ierr = DMPlexCreateReferenceCell_Internal(dm, cell);CHKERRQ(ierr); 27269318fe57SMatthew G. Knepley } else if (bdfflg) { 27279318fe57SMatthew G. Knepley DM bdm, dmnew; 27289318fe57SMatthew G. Knepley 27299318fe57SMatthew G. Knepley ierr = DMPlexCreateFromFile(PetscObjectComm((PetscObject) dm), bdFilename, interpolate, &bdm);CHKERRQ(ierr); 27309318fe57SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) bdm, "bd_");CHKERRQ(ierr); 27319318fe57SMatthew G. Knepley ierr = DMSetFromOptions(bdm);CHKERRQ(ierr); 27329318fe57SMatthew G. Knepley ierr = DMPlexGenerate(bdm, NULL, interpolate, &dmnew);CHKERRQ(ierr); 27339318fe57SMatthew G. Knepley ierr = DMDestroy(&bdm);CHKERRQ(ierr); 27349318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &dmnew);CHKERRQ(ierr); 27359318fe57SMatthew G. Knepley } else { 27369318fe57SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) dm, DMPlexShapes[shape]);CHKERRQ(ierr); 27379318fe57SMatthew G. Knepley switch (shape) { 27389318fe57SMatthew G. Knepley case DM_SHAPE_BOX: 27399318fe57SMatthew G. Knepley { 27409318fe57SMatthew G. Knepley PetscInt faces[3] = {0, 0, 0}; 27419318fe57SMatthew G. Knepley PetscReal lower[3] = {0, 0, 0}; 27429318fe57SMatthew G. Knepley PetscReal upper[3] = {1, 1, 1}; 27439318fe57SMatthew G. Knepley DMBoundaryType bdt[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE}; 27449318fe57SMatthew G. Knepley PetscInt i, n; 27459318fe57SMatthew G. Knepley 27469318fe57SMatthew G. Knepley n = dim; 27479318fe57SMatthew G. Knepley for (i = 0; i < dim; ++i) faces[i] = (dim == 1 ? 1 : 4-dim); 27489318fe57SMatthew G. Knepley ierr = PetscOptionsIntArray("-dm_plex_box_faces", "Number of faces along each dimension", "", faces, &n, &flg);CHKERRQ(ierr); 27499318fe57SMatthew G. Knepley n = 3; 27509318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_lower", "Lower left corner of box", "", lower, &n, &flg);CHKERRQ(ierr); 27519318fe57SMatthew G. Knepley if (flg && (n != dim)) SETERRQ2(comm, PETSC_ERR_ARG_SIZ, "Lower box point had %D values, should have been %D", n, dim); 27529318fe57SMatthew G. Knepley n = 3; 27539318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_upper", "Upper right corner of box", "", upper, &n, &flg);CHKERRQ(ierr); 27549318fe57SMatthew G. Knepley if (flg && (n != dim)) SETERRQ2(comm, PETSC_ERR_ARG_SIZ, "Upper box point had %D values, should have been %D", n, dim); 27559318fe57SMatthew G. Knepley n = 3; 27569318fe57SMatthew G. Knepley ierr = PetscOptionsEnumArray("-dm_plex_box_bd", "Boundary type for each dimension", "", DMBoundaryTypes, (PetscEnum *) bdt, &n, &flg);CHKERRQ(ierr); 27579318fe57SMatthew G. Knepley if (flg && (n != dim)) SETERRQ2(comm, PETSC_ERR_ARG_SIZ, "Box boundary types had %D values, should have been %D", n, dim); 27589318fe57SMatthew G. Knepley switch (cell) { 275961a622f3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 27609318fe57SMatthew G. Knepley ierr = DMPlexCreateWedgeBoxMesh_Internal(dm, faces, lower, upper, bdt, PETSC_FALSE, interpolate);CHKERRQ(ierr); 27619318fe57SMatthew G. Knepley break; 27629318fe57SMatthew G. Knepley default: 27639318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxMesh_Internal(dm, dim, simplex, faces, lower, upper, bdt, interpolate);CHKERRQ(ierr); 27649318fe57SMatthew G. Knepley break; 27659318fe57SMatthew G. Knepley } 27669318fe57SMatthew G. Knepley } 27679318fe57SMatthew G. Knepley break; 27689318fe57SMatthew G. Knepley case DM_SHAPE_BOX_SURFACE: 27699318fe57SMatthew G. Knepley { 27709318fe57SMatthew G. Knepley PetscInt faces[3] = {0, 0, 0}; 27719318fe57SMatthew G. Knepley PetscReal lower[3] = {0, 0, 0}; 27729318fe57SMatthew G. Knepley PetscReal upper[3] = {1, 1, 1}; 27739318fe57SMatthew G. Knepley PetscInt i, n; 27749318fe57SMatthew G. Knepley 27759318fe57SMatthew G. Knepley n = dim+1; 27769318fe57SMatthew G. Knepley for (i = 0; i < dim+1; ++i) faces[i] = (dim+1 == 1 ? 1 : 4-(dim+1)); 27779318fe57SMatthew G. Knepley ierr = PetscOptionsIntArray("-dm_plex_box_faces", "Number of faces along each dimension", "", faces, &n, &flg);CHKERRQ(ierr); 27789318fe57SMatthew G. Knepley n = 3; 27799318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_lower", "Lower left corner of box", "", lower, &n, &flg);CHKERRQ(ierr); 27809318fe57SMatthew G. Knepley if (flg && (n != dim+1)) SETERRQ2(comm, PETSC_ERR_ARG_SIZ, "Lower box point had %D values, should have been %D", n, dim+1); 27819318fe57SMatthew G. Knepley n = 3; 27829318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_upper", "Upper right corner of box", "", upper, &n, &flg);CHKERRQ(ierr); 27839318fe57SMatthew G. Knepley if (flg && (n != dim+1)) SETERRQ2(comm, PETSC_ERR_ARG_SIZ, "Upper box point had %D values, should have been %D", n, dim+1); 27849318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxSurfaceMesh_Internal(dm, dim+1, faces, lower, upper, interpolate);CHKERRQ(ierr); 27859318fe57SMatthew G. Knepley } 27869318fe57SMatthew G. Knepley break; 27879318fe57SMatthew G. Knepley case DM_SHAPE_SPHERE: 27889318fe57SMatthew G. Knepley { 27899318fe57SMatthew G. Knepley PetscReal R = 1.0; 27909318fe57SMatthew G. Knepley 27919318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_sphere_radius", "Radius of the sphere", "", R, &R, &flg);CHKERRQ(ierr); 27929318fe57SMatthew G. Knepley ierr = DMPlexCreateSphereMesh_Internal(dm, dim, simplex, R);CHKERRQ(ierr); 27939318fe57SMatthew G. Knepley } 27949318fe57SMatthew G. Knepley break; 27959318fe57SMatthew G. Knepley case DM_SHAPE_BALL: 27969318fe57SMatthew G. Knepley { 27979318fe57SMatthew G. Knepley PetscReal R = 1.0; 27989318fe57SMatthew G. Knepley 27999318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_ball_radius", "Radius of the ball", "", R, &R, &flg);CHKERRQ(ierr); 28009318fe57SMatthew G. Knepley ierr = DMPlexCreateBallMesh_Internal(dm, dim, R);CHKERRQ(ierr); 28019318fe57SMatthew G. Knepley } 28029318fe57SMatthew G. Knepley break; 28039318fe57SMatthew G. Knepley case DM_SHAPE_CYLINDER: 28049318fe57SMatthew G. Knepley { 28059318fe57SMatthew G. Knepley DMBoundaryType bdt = DM_BOUNDARY_NONE; 28069318fe57SMatthew G. Knepley PetscInt Nw = 6; 28079318fe57SMatthew G. Knepley 28089318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_cylinder_bd", "Boundary type in the z direction", "", DMBoundaryTypes, (PetscEnum) bdt, (PetscEnum *) &bdt, NULL);CHKERRQ(ierr); 280961a622f3SMatthew G. Knepley ierr = PetscOptionsInt("-dm_plex_cylinder_num_wedges", "Number of wedges around the cylinder", "", Nw, &Nw, NULL);CHKERRQ(ierr); 28109318fe57SMatthew G. Knepley switch (cell) { 281161a622f3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 28129318fe57SMatthew G. Knepley ierr = DMPlexCreateWedgeCylinderMesh_Internal(dm, Nw, interpolate);CHKERRQ(ierr); 28139318fe57SMatthew G. Knepley break; 28149318fe57SMatthew G. Knepley default: 28159318fe57SMatthew G. Knepley ierr = DMPlexCreateHexCylinderMesh_Internal(dm, bdt);CHKERRQ(ierr); 28169318fe57SMatthew G. Knepley break; 28179318fe57SMatthew G. Knepley } 28189318fe57SMatthew G. Knepley } 28199318fe57SMatthew G. Knepley break; 28209318fe57SMatthew G. Knepley default: SETERRQ1(comm, PETSC_ERR_SUP, "Domain shape %s is unsupported", DMPlexShapes[shape]); 28219318fe57SMatthew G. Knepley } 28229318fe57SMatthew G. Knepley } 28239318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr); 28240a6ba040SMatthew G. Knepley PetscFunctionReturn(0); 28250a6ba040SMatthew G. Knepley } 28260a6ba040SMatthew G. Knepley 282747920aaeSMatthew G. Knepley PetscErrorCode DMSetFromOptions_NonRefinement_Plex(PetscOptionItems *PetscOptionsObject, DM dm) 28280a6ba040SMatthew G. Knepley { 28290a6ba040SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 2830c0f0dcc3SMatthew G. Knepley PetscBool flg; 28319318fe57SMatthew G. Knepley char bdLabel[PETSC_MAX_PATH_LEN]; 28320a6ba040SMatthew G. Knepley PetscErrorCode ierr; 28330a6ba040SMatthew G. Knepley 28340a6ba040SMatthew G. Knepley PetscFunctionBegin; 28350a6ba040SMatthew G. Knepley /* Handle viewing */ 28360c77aedcSMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_print_set_values", "Output all set values info", "DMPlexMatSetClosure", PETSC_FALSE, &mesh->printSetValues, NULL);CHKERRQ(ierr); 28375a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_plex_print_fem", "Debug output level all fem computations", "DMPlexSNESComputeResidualFEM", 0, &mesh->printFEM, NULL,0);CHKERRQ(ierr); 28380c77aedcSMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_print_tol", "Tolerance for FEM output", "DMPlexSNESComputeResidualFEM", mesh->printTol, &mesh->printTol, NULL);CHKERRQ(ierr); 28395a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_plex_print_l2", "Debug output level all L2 diff computations", "DMComputeL2Diff", 0, &mesh->printL2, NULL,0);CHKERRQ(ierr); 2840c0f0dcc3SMatthew G. Knepley ierr = DMMonitorSetFromOptions(dm, "-dm_plex_monitor_throughput", "Monitor the simulation throughput", "DMPlexMonitorThroughput", DMPlexMonitorThroughput, NULL, &flg);CHKERRQ(ierr); 2841c0f0dcc3SMatthew G. Knepley if (flg) {ierr = PetscLogDefaultBegin();CHKERRQ(ierr);} 28429318fe57SMatthew G. Knepley /* Labeling */ 28439318fe57SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_boundary_label", "Label to mark the mesh boundary", "", bdLabel, bdLabel, sizeof(bdLabel), &flg);CHKERRQ(ierr); 28449318fe57SMatthew G. Knepley if (flg) {ierr = DMPlexCreateBoundaryLabel_Private(dm, bdLabel);CHKERRQ(ierr);} 2845953fc75cSMatthew G. Knepley /* Point Location */ 28460c77aedcSMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_hash_location", "Use grid hashing for point location", "DMInterpolate", PETSC_FALSE, &mesh->useHashLocation, NULL);CHKERRQ(ierr); 28470848f4b5SMatthew G. Knepley /* Partitioning and distribution */ 284898ba2d7fSLawrence Mitchell ierr = PetscOptionsBool("-dm_plex_partition_balance", "Attempt to evenly divide points on partition boundary between processes", "DMPlexSetPartitionBalance", PETSC_FALSE, &mesh->partitionBalance, NULL);CHKERRQ(ierr); 28492e62ab5aSMatthew G. Knepley /* Generation and remeshing */ 28500c77aedcSMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_remesh_bd", "Allow changes to the boundary on remeshing", "DMAdapt", PETSC_FALSE, &mesh->remeshBd, NULL);CHKERRQ(ierr); 2851b29cfa1cSToby Isaac /* Projection behavior */ 28525a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_plex_max_projection_height", "Maxmimum mesh point height used to project locally", "DMPlexSetMaxProjectionHeight", 0, &mesh->maxProjectionHeight, NULL,0);CHKERRQ(ierr); 285364141f95SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_regular_refinement", "Use special nested projection algorithm for regular refinement", "DMPlexSetRegularRefinement", mesh->regularRefinement, &mesh->regularRefinement, NULL);CHKERRQ(ierr); 28549318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_cell_refiner", "Strategy for cell refinment", "", DMPlexCellRefinerTypes, (PetscEnum) mesh->cellRefiner, (PetscEnum *) &mesh->cellRefiner, NULL);CHKERRQ(ierr); 2855f12cf164SMatthew G. Knepley /* Checking structure */ 2856f12cf164SMatthew G. Knepley { 2857e902f1eaSVaclav Hapla PetscBool flg = PETSC_FALSE, flg2 = PETSC_FALSE, all = PETSC_FALSE; 2858f12cf164SMatthew G. Knepley 2859e902f1eaSVaclav Hapla ierr = PetscOptionsBool("-dm_plex_check_all", "Perform all checks", NULL, PETSC_FALSE, &all, &flg2);CHKERRQ(ierr); 2860f12cf164SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_check_symmetry", "Check that the adjacency information in the mesh is symmetric", "DMPlexCheckSymmetry", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 2861e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckSymmetry(dm);CHKERRQ(ierr);} 286225c50c26SVaclav Hapla ierr = PetscOptionsBool("-dm_plex_check_skeleton", "Check that each cell has the correct number of vertices (only for homogeneous simplex or tensor meshes)", "DMPlexCheckSkeleton", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 2863e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckSkeleton(dm, 0);CHKERRQ(ierr);} 286425c50c26SVaclav Hapla ierr = PetscOptionsBool("-dm_plex_check_faces", "Check that the faces of each cell give a vertex order this is consistent with what we expect from the cell type", "DMPlexCheckFaces", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 2865e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckFaces(dm, 0);CHKERRQ(ierr);} 2866f12cf164SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_check_geometry", "Check that cells have positive volume", "DMPlexCheckGeometry", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 2867e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckGeometry(dm);CHKERRQ(ierr);} 286875ebff7aSVaclav Hapla ierr = PetscOptionsBool("-dm_plex_check_pointsf", "Check some necessary conditions for PointSF", "DMPlexCheckPointSF", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 2869e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckPointSF(dm);CHKERRQ(ierr);} 287075ebff7aSVaclav Hapla ierr = PetscOptionsBool("-dm_plex_check_interface_cones", "Check points on inter-partition interfaces have conforming order of cone points", "DMPlexCheckInterfaceCones", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 2871e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckInterfaceCones(dm);CHKERRQ(ierr);} 2872412e9a14SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_check_cell_shape", "Check cell shape", "DMPlexCheckCellShape", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 2873412e9a14SMatthew G. Knepley if (flg && flg2) {ierr = DMPlexCheckCellShape(dm, PETSC_TRUE, PETSC_DETERMINE);CHKERRQ(ierr);} 2874f12cf164SMatthew G. Knepley } 28759318fe57SMatthew G. Knepley { 28769318fe57SMatthew G. Knepley PetscReal scale = 1.0; 28774f3833eaSMatthew G. Knepley 28789318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_scale", "Scale factor for mesh coordinates", "DMPlexScale", scale, &scale, &flg);CHKERRQ(ierr); 28799318fe57SMatthew G. Knepley if (flg) { 28809318fe57SMatthew G. Knepley Vec coordinates, coordinatesLocal; 28819318fe57SMatthew G. Knepley 28829318fe57SMatthew G. Knepley ierr = DMGetCoordinates(dm, &coordinates);CHKERRQ(ierr); 28839318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinatesLocal);CHKERRQ(ierr); 28849318fe57SMatthew G. Knepley ierr = VecScale(coordinates, scale);CHKERRQ(ierr); 28859318fe57SMatthew G. Knepley ierr = VecScale(coordinatesLocal, scale);CHKERRQ(ierr); 28869318fe57SMatthew G. Knepley } 28879318fe57SMatthew G. Knepley } 28884f3833eaSMatthew G. Knepley ierr = PetscPartitionerSetFromOptions(mesh->partitioner);CHKERRQ(ierr); 288968d4fef7SMatthew G. Knepley PetscFunctionReturn(0); 289068d4fef7SMatthew G. Knepley } 289168d4fef7SMatthew G. Knepley 289246fa42a0SMatthew G. Knepley static PetscErrorCode DMSetFromOptions_Plex(PetscOptionItems *PetscOptionsObject,DM dm) 289368d4fef7SMatthew G. Knepley { 28949318fe57SMatthew G. Knepley PetscReal volume = -1.0, extThickness = 1.0; 28959318fe57SMatthew G. Knepley PetscInt prerefine = 0, refine = 0, r, coarsen = 0, overlap = 0, extLayers = 0, dim; 2896c1cad2e7SMatthew G. Knepley PetscBool uniformOrig, created = PETSC_FALSE, uniform = PETSC_TRUE, distribute = PETSC_FALSE, interpolate = PETSC_TRUE, extColOrder = PETSC_TRUE, coordSpace = PETSC_TRUE, remap = PETSC_TRUE, ghostCells = PETSC_FALSE, isHierarchy, ignoreModel = PETSC_FALSE, flg; 289768d4fef7SMatthew G. Knepley PetscErrorCode ierr; 289868d4fef7SMatthew G. Knepley 289968d4fef7SMatthew G. Knepley PetscFunctionBegin; 2900064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 29011a1499c8SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"DMPlex Options");CHKERRQ(ierr); 29029318fe57SMatthew G. Knepley /* Handle automatic creation */ 29039318fe57SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 290461a622f3SMatthew G. Knepley if (dim < 0) {ierr = DMPlexCreateFromOptions_Internal(PetscOptionsObject, &coordSpace, dm);CHKERRQ(ierr);created = PETSC_TRUE;} 29059b44eab4SMatthew G. Knepley /* Handle DMPlex refinement before distribution */ 2906c1cad2e7SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_ignore_model", "Flag to ignore the geometry model when refining", "DMCreate", ignoreModel, &ignoreModel, &flg);CHKERRQ(ierr); 2907c1cad2e7SMatthew G. Knepley if (flg) {((DM_Plex *) dm->data)->ignoreModel = ignoreModel;} 2908250712c9SMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &uniformOrig);CHKERRQ(ierr); 29099318fe57SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_refine_pre", "The number of refinements before distribution", "DMCreate", prerefine, &prerefine, NULL,0);CHKERRQ(ierr); 291061a622f3SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_remap_pre", "Flag to control coordinate remapping", "DMCreate", remap, &remap, NULL);CHKERRQ(ierr); 2911250712c9SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_uniform_pre", "Flag for uniform refinement before distribution", "DMCreate", uniform, &uniform, &flg);CHKERRQ(ierr); 2912250712c9SMatthew G. Knepley if (flg) {ierr = DMPlexSetRefinementUniform(dm, uniform);CHKERRQ(ierr);} 2913250712c9SMatthew G. Knepley ierr = PetscOptionsReal("-dm_refine_volume_limit_pre", "The maximum cell volume after refinement before distribution", "DMCreate", volume, &volume, &flg);CHKERRQ(ierr); 29149318fe57SMatthew G. Knepley if (flg) { 29159318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, PETSC_FALSE);CHKERRQ(ierr); 29169318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementLimit(dm, volume);CHKERRQ(ierr); 29179318fe57SMatthew G. Knepley prerefine = PetscMax(prerefine, 1); 29189318fe57SMatthew G. Knepley } 29199b44eab4SMatthew G. Knepley for (r = 0; r < prerefine; ++r) { 29209b44eab4SMatthew G. Knepley DM rdm; 29219b44eab4SMatthew G. Knepley PetscPointFunc coordFunc = ((DM_Plex*) dm->data)->coordFunc; 29229b44eab4SMatthew G. Knepley 29239b44eab4SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 29249b44eab4SMatthew G. Knepley ierr = DMRefine(dm, PetscObjectComm((PetscObject) dm), &rdm);CHKERRQ(ierr); 29259318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &rdm);CHKERRQ(ierr); 29269b44eab4SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 292761a622f3SMatthew G. Knepley if (coordFunc && remap) { 29289b44eab4SMatthew G. Knepley ierr = DMPlexRemapGeometry(dm, 0.0, coordFunc);CHKERRQ(ierr); 29299b44eab4SMatthew G. Knepley ((DM_Plex*) dm->data)->coordFunc = coordFunc; 29309b44eab4SMatthew G. Knepley } 29319b44eab4SMatthew G. Knepley } 2932250712c9SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, uniformOrig);CHKERRQ(ierr); 29339318fe57SMatthew G. Knepley /* Handle DMPlex extrusion before distribution */ 29349318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_interpolate", "Flag to create edges and faces automatically", "", interpolate, &interpolate, NULL);CHKERRQ(ierr); 29359318fe57SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_extrude_layers", "The number of layers to extrude", "", extLayers, &extLayers, NULL, 0);CHKERRQ(ierr); 29369318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_extrude_thickness", "The thickness of the layer to be extruded", "", extThickness, &extThickness, NULL);CHKERRQ(ierr); 29379318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_extrude_column_first", "Order the cells in a vertical column first", "", extColOrder, &extColOrder, NULL);CHKERRQ(ierr); 29389318fe57SMatthew G. Knepley if (extLayers) { 29399318fe57SMatthew G. Knepley DM edm; 29409318fe57SMatthew G. Knepley 29419318fe57SMatthew G. Knepley ierr = DMPlexExtrude(dm, extLayers, extThickness, extColOrder, NULL, interpolate, &edm);CHKERRQ(ierr); 29429318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &edm);CHKERRQ(ierr); 29439318fe57SMatthew G. Knepley } 29449b44eab4SMatthew G. Knepley /* Handle DMPlex distribution */ 29459b44eab4SMatthew G. Knepley ierr = PetscOptionsBool("-dm_distribute", "Flag to redistribute a mesh among processes", "DMCreate", distribute, &distribute, NULL);CHKERRQ(ierr); 29469b44eab4SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_distribute_overlap", "The size of the overlap halo", "DMCreate", overlap, &overlap, NULL, 0);CHKERRQ(ierr); 29479b44eab4SMatthew G. Knepley if (distribute) { 29489b44eab4SMatthew G. Knepley DM pdm = NULL; 29499b44eab4SMatthew G. Knepley PetscPartitioner part; 29509b44eab4SMatthew G. Knepley 29519b44eab4SMatthew G. Knepley ierr = DMPlexGetPartitioner(dm, &part);CHKERRQ(ierr); 29529b44eab4SMatthew G. Knepley ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); 29539b44eab4SMatthew G. Knepley ierr = DMPlexDistribute(dm, overlap, NULL, &pdm);CHKERRQ(ierr); 29549b44eab4SMatthew G. Knepley if (pdm) { 29559318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &pdm);CHKERRQ(ierr); 29569b44eab4SMatthew G. Knepley } 29579b44eab4SMatthew G. Knepley } 29589318fe57SMatthew G. Knepley /* Create coordinate space */ 29599318fe57SMatthew G. Knepley if (created) { 296061a622f3SMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) dm->data; 29619318fe57SMatthew G. Knepley PetscInt degree = 1; 296261a622f3SMatthew G. Knepley PetscBool periodic, flg; 29639318fe57SMatthew G. Knepley 296461a622f3SMatthew G. Knepley ierr = PetscOptionsBool("-dm_coord_space", "Use an FEM space for coordinates", "", coordSpace, &coordSpace, &flg);CHKERRQ(ierr); 29659318fe57SMatthew G. Knepley ierr = PetscOptionsInt("-dm_coord_petscspace_degree", "FEM degree for coordinate space", "", degree, °ree, NULL);CHKERRQ(ierr); 296661a622f3SMatthew G. Knepley if (coordSpace) {ierr = DMPlexCreateCoordinateSpace(dm, degree, mesh->coordFunc);CHKERRQ(ierr);} 296761a622f3SMatthew G. Knepley if (flg && !coordSpace) { 296861a622f3SMatthew G. Knepley DM cdm; 296961a622f3SMatthew G. Knepley PetscDS cds; 297061a622f3SMatthew G. Knepley PetscObject obj; 297161a622f3SMatthew G. Knepley PetscClassId id; 297261a622f3SMatthew G. Knepley 297361a622f3SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 297461a622f3SMatthew G. Knepley ierr = DMGetDS(cdm, &cds);CHKERRQ(ierr); 297561a622f3SMatthew G. Knepley ierr = PetscDSGetDiscretization(cds, 0, &obj);CHKERRQ(ierr); 297661a622f3SMatthew G. Knepley ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 297761a622f3SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 297861a622f3SMatthew G. Knepley PetscContainer dummy; 297961a622f3SMatthew G. Knepley 298061a622f3SMatthew G. Knepley ierr = PetscContainerCreate(PETSC_COMM_SELF, &dummy);CHKERRQ(ierr); 298161a622f3SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) dummy, "coordinates");CHKERRQ(ierr); 298261a622f3SMatthew G. Knepley ierr = DMSetField(cdm, 0, NULL, (PetscObject) dummy);CHKERRQ(ierr); 298361a622f3SMatthew G. Knepley ierr = PetscContainerDestroy(&dummy);CHKERRQ(ierr); 298461a622f3SMatthew G. Knepley ierr = DMClearDS(cdm);CHKERRQ(ierr); 298561a622f3SMatthew G. Knepley } 298661a622f3SMatthew G. Knepley mesh->coordFunc = NULL; 298761a622f3SMatthew G. Knepley } 29889318fe57SMatthew G. Knepley ierr = DMLocalizeCoordinates(dm);CHKERRQ(ierr); 298961a622f3SMatthew G. Knepley ierr = DMGetPeriodicity(dm, &periodic, NULL, NULL, NULL);CHKERRQ(ierr); 299061a622f3SMatthew G. Knepley if (periodic) {ierr = DMSetPeriodicity(dm, PETSC_TRUE, NULL, NULL, NULL);CHKERRQ(ierr);} 29919318fe57SMatthew G. Knepley } 299268d4fef7SMatthew G. Knepley /* Handle DMPlex refinement */ 299361a622f3SMatthew G. Knepley remap = PETSC_TRUE; 29945a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_refine", "The number of uniform refinements", "DMCreate", refine, &refine, NULL,0);CHKERRQ(ierr); 299561a622f3SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_remap", "Flag to control coordinate remapping", "DMCreate", remap, &remap, NULL);CHKERRQ(ierr); 29965a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_refine_hierarchy", "The number of uniform refinements", "DMCreate", refine, &refine, &isHierarchy,0);CHKERRQ(ierr); 2997b6a0289aSMatthew G. Knepley if (refine) {ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr);} 299868d4fef7SMatthew G. Knepley if (refine && isHierarchy) { 2999acdc6f61SToby Isaac DM *dms, coarseDM; 300068d4fef7SMatthew G. Knepley 3001acdc6f61SToby Isaac ierr = DMGetCoarseDM(dm, &coarseDM);CHKERRQ(ierr); 3002acdc6f61SToby Isaac ierr = PetscObjectReference((PetscObject)coarseDM);CHKERRQ(ierr); 300368d4fef7SMatthew G. Knepley ierr = PetscMalloc1(refine,&dms);CHKERRQ(ierr); 300468d4fef7SMatthew G. Knepley ierr = DMRefineHierarchy(dm, refine, dms);CHKERRQ(ierr); 300568d4fef7SMatthew G. Knepley /* Total hack since we do not pass in a pointer */ 300668d4fef7SMatthew G. Knepley ierr = DMPlexSwap_Static(dm, dms[refine-1]);CHKERRQ(ierr); 300768d4fef7SMatthew G. Knepley if (refine == 1) { 3008a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dm, dms[0]);CHKERRQ(ierr); 30090aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dm, PETSC_TRUE);CHKERRQ(ierr); 301068d4fef7SMatthew G. Knepley } else { 3011a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dm, dms[refine-2]);CHKERRQ(ierr); 30120aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dm, PETSC_TRUE);CHKERRQ(ierr); 3013a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dms[0], dms[refine-1]);CHKERRQ(ierr); 30140aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dms[0], PETSC_TRUE);CHKERRQ(ierr); 301568d4fef7SMatthew G. Knepley } 3016acdc6f61SToby Isaac ierr = DMSetCoarseDM(dms[refine-1], coarseDM);CHKERRQ(ierr); 3017acdc6f61SToby Isaac ierr = PetscObjectDereference((PetscObject)coarseDM);CHKERRQ(ierr); 301868d4fef7SMatthew G. Knepley /* Free DMs */ 301968d4fef7SMatthew G. Knepley for (r = 0; r < refine; ++r) { 3020547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dms[r]);CHKERRQ(ierr); 302168d4fef7SMatthew G. Knepley ierr = DMDestroy(&dms[r]);CHKERRQ(ierr); 302268d4fef7SMatthew G. Knepley } 302368d4fef7SMatthew G. Knepley ierr = PetscFree(dms);CHKERRQ(ierr); 302468d4fef7SMatthew G. Knepley } else { 302568d4fef7SMatthew G. Knepley for (r = 0; r < refine; ++r) { 30269318fe57SMatthew G. Knepley DM rdm; 302751a74b61SMatthew G. Knepley PetscPointFunc coordFunc = ((DM_Plex*) dm->data)->coordFunc; 302868d4fef7SMatthew G. Knepley 30291a1499c8SBarry Smith ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 30309318fe57SMatthew G. Knepley ierr = DMRefine(dm, PetscObjectComm((PetscObject) dm), &rdm);CHKERRQ(ierr); 303168d4fef7SMatthew G. Knepley /* Total hack since we do not pass in a pointer */ 30329318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &rdm);CHKERRQ(ierr); 3033547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 303461a622f3SMatthew G. Knepley if (coordFunc && remap) { 303551a74b61SMatthew G. Knepley ierr = DMPlexRemapGeometry(dm, 0.0, coordFunc);CHKERRQ(ierr); 303651a74b61SMatthew G. Knepley ((DM_Plex*) dm->data)->coordFunc = coordFunc; 303751a74b61SMatthew G. Knepley } 303868d4fef7SMatthew G. Knepley } 303968d4fef7SMatthew G. Knepley } 30403cf6fe12SMatthew G. Knepley /* Handle DMPlex coarsening */ 30415a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_coarsen", "Coarsen the mesh", "DMCreate", coarsen, &coarsen, NULL,0);CHKERRQ(ierr); 30425a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_coarsen_hierarchy", "The number of coarsenings", "DMCreate", coarsen, &coarsen, &isHierarchy,0);CHKERRQ(ierr); 3043b653a561SMatthew G. Knepley if (coarsen && isHierarchy) { 3044b653a561SMatthew G. Knepley DM *dms; 3045b653a561SMatthew G. Knepley 3046b653a561SMatthew G. Knepley ierr = PetscMalloc1(coarsen, &dms);CHKERRQ(ierr); 3047b653a561SMatthew G. Knepley ierr = DMCoarsenHierarchy(dm, coarsen, dms);CHKERRQ(ierr); 3048b653a561SMatthew G. Knepley /* Free DMs */ 3049b653a561SMatthew G. Knepley for (r = 0; r < coarsen; ++r) { 3050547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dms[r]);CHKERRQ(ierr); 3051b653a561SMatthew G. Knepley ierr = DMDestroy(&dms[r]);CHKERRQ(ierr); 3052b653a561SMatthew G. Knepley } 3053b653a561SMatthew G. Knepley ierr = PetscFree(dms);CHKERRQ(ierr); 3054b653a561SMatthew G. Knepley } else { 3055b653a561SMatthew G. Knepley for (r = 0; r < coarsen; ++r) { 30569318fe57SMatthew G. Knepley DM cdm; 30579318fe57SMatthew G. Knepley PetscPointFunc coordFunc = ((DM_Plex*) dm->data)->coordFunc; 30583cf6fe12SMatthew G. Knepley 30593cf6fe12SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 30609318fe57SMatthew G. Knepley ierr = DMCoarsen(dm, PetscObjectComm((PetscObject) dm), &cdm);CHKERRQ(ierr); 30613cf6fe12SMatthew G. Knepley /* Total hack since we do not pass in a pointer */ 30629318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &cdm);CHKERRQ(ierr); 3063547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 30649318fe57SMatthew G. Knepley if (coordFunc) { 30659318fe57SMatthew G. Knepley ierr = DMPlexRemapGeometry(dm, 0.0, coordFunc);CHKERRQ(ierr); 30669318fe57SMatthew G. Knepley ((DM_Plex*) dm->data)->coordFunc = coordFunc; 30679318fe57SMatthew G. Knepley } 30683cf6fe12SMatthew G. Knepley } 3069b653a561SMatthew G. Knepley } 3070909dfd52SMatthew G. Knepley /* Handle ghost cells */ 3071909dfd52SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_create_fv_ghost_cells", "Flag to create finite volume ghost cells on the boundary", "DMCreate", ghostCells, &ghostCells, NULL);CHKERRQ(ierr); 3072909dfd52SMatthew G. Knepley if (ghostCells) { 3073909dfd52SMatthew G. Knepley DM gdm; 3074909dfd52SMatthew G. Knepley char lname[PETSC_MAX_PATH_LEN]; 3075909dfd52SMatthew G. Knepley 3076909dfd52SMatthew G. Knepley lname[0] = '\0'; 3077909dfd52SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_fv_ghost_cells_label", "Label name for ghost cells boundary", "DMCreate", lname, lname, sizeof(lname), &flg);CHKERRQ(ierr); 3078909dfd52SMatthew G. Knepley ierr = DMPlexConstructGhostCells(dm, flg ? lname : NULL, NULL, &gdm);CHKERRQ(ierr); 3079909dfd52SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &gdm);CHKERRQ(ierr); 3080909dfd52SMatthew G. Knepley } 30813cf6fe12SMatthew G. Knepley /* Handle */ 30821a1499c8SBarry Smith ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 30830a6ba040SMatthew G. Knepley ierr = PetscOptionsTail();CHKERRQ(ierr); 30840a6ba040SMatthew G. Knepley PetscFunctionReturn(0); 30850a6ba040SMatthew G. Knepley } 30860a6ba040SMatthew G. Knepley 3087552f7358SJed Brown static PetscErrorCode DMCreateGlobalVector_Plex(DM dm,Vec *vec) 3088552f7358SJed Brown { 3089552f7358SJed Brown PetscErrorCode ierr; 3090552f7358SJed Brown 3091552f7358SJed Brown PetscFunctionBegin; 3092552f7358SJed Brown ierr = DMCreateGlobalVector_Section_Private(dm,vec);CHKERRQ(ierr); 3093552f7358SJed Brown /* ierr = VecSetOperation(*vec, VECOP_DUPLICATE, (void(*)(void)) VecDuplicate_MPI_DM);CHKERRQ(ierr); */ 3094552f7358SJed Brown ierr = VecSetOperation(*vec, VECOP_VIEW, (void (*)(void)) VecView_Plex);CHKERRQ(ierr); 3095d930f514SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_VIEWNATIVE, (void (*)(void)) VecView_Plex_Native);CHKERRQ(ierr); 30962c40f234SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_LOAD, (void (*)(void)) VecLoad_Plex);CHKERRQ(ierr); 3097d930f514SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_LOADNATIVE, (void (*)(void)) VecLoad_Plex_Native);CHKERRQ(ierr); 3098552f7358SJed Brown PetscFunctionReturn(0); 3099552f7358SJed Brown } 3100552f7358SJed Brown 3101552f7358SJed Brown static PetscErrorCode DMCreateLocalVector_Plex(DM dm,Vec *vec) 3102552f7358SJed Brown { 3103552f7358SJed Brown PetscErrorCode ierr; 3104552f7358SJed Brown 3105552f7358SJed Brown PetscFunctionBegin; 3106552f7358SJed Brown ierr = DMCreateLocalVector_Section_Private(dm,vec);CHKERRQ(ierr); 3107552f7358SJed Brown ierr = VecSetOperation(*vec, VECOP_VIEW, (void (*)(void)) VecView_Plex_Local);CHKERRQ(ierr); 31082c40f234SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_LOAD, (void (*)(void)) VecLoad_Plex_Local);CHKERRQ(ierr); 3109552f7358SJed Brown PetscFunctionReturn(0); 3110552f7358SJed Brown } 3111552f7358SJed Brown 3112793f3fe5SMatthew G. Knepley static PetscErrorCode DMGetDimPoints_Plex(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 3113793f3fe5SMatthew G. Knepley { 3114793f3fe5SMatthew G. Knepley PetscInt depth, d; 3115793f3fe5SMatthew G. Knepley PetscErrorCode ierr; 3116793f3fe5SMatthew G. Knepley 3117793f3fe5SMatthew G. Knepley PetscFunctionBegin; 3118793f3fe5SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3119793f3fe5SMatthew G. Knepley if (depth == 1) { 3120793f3fe5SMatthew G. Knepley ierr = DMGetDimension(dm, &d);CHKERRQ(ierr); 3121793f3fe5SMatthew G. Knepley if (dim == 0) {ierr = DMPlexGetDepthStratum(dm, dim, pStart, pEnd);CHKERRQ(ierr);} 3122793f3fe5SMatthew G. Knepley else if (dim == d) {ierr = DMPlexGetDepthStratum(dm, 1, pStart, pEnd);CHKERRQ(ierr);} 3123793f3fe5SMatthew G. Knepley else {*pStart = 0; *pEnd = 0;} 3124793f3fe5SMatthew G. Knepley } else { 3125793f3fe5SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, dim, pStart, pEnd);CHKERRQ(ierr); 3126793f3fe5SMatthew G. Knepley } 3127793f3fe5SMatthew G. Knepley PetscFunctionReturn(0); 3128793f3fe5SMatthew G. Knepley } 3129793f3fe5SMatthew G. Knepley 313028d58a37SPierre Jolivet static PetscErrorCode DMGetNeighbors_Plex(DM dm, PetscInt *nranks, const PetscMPIInt *ranks[]) 3131502a2867SDave May { 3132502a2867SDave May PetscSF sf; 31330a19bb7dSprj- PetscInt niranks, njranks, n; 31340a19bb7dSprj- const PetscMPIInt *iranks, *jranks; 31350a19bb7dSprj- DM_Plex *data = (DM_Plex*) dm->data; 31362f356facSMatthew G. Knepley PetscErrorCode ierr; 3137502a2867SDave May 31382f356facSMatthew G. Knepley PetscFunctionBegin; 3139502a2867SDave May ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 31400a19bb7dSprj- if (!data->neighbors) { 314107a779feSPierre Jolivet ierr = PetscSFSetUp(sf);CHKERRQ(ierr); 31420a19bb7dSprj- ierr = PetscSFGetRootRanks(sf, &njranks, &jranks, NULL, NULL, NULL);CHKERRQ(ierr); 31430a19bb7dSprj- ierr = PetscSFGetLeafRanks(sf, &niranks, &iranks, NULL, NULL);CHKERRQ(ierr); 31440a19bb7dSprj- ierr = PetscMalloc1(njranks + niranks + 1, &data->neighbors);CHKERRQ(ierr); 31450a19bb7dSprj- ierr = PetscArraycpy(data->neighbors + 1, jranks, njranks);CHKERRQ(ierr); 31460a19bb7dSprj- ierr = PetscArraycpy(data->neighbors + njranks + 1, iranks, niranks);CHKERRQ(ierr); 31470a19bb7dSprj- n = njranks + niranks; 31480a19bb7dSprj- ierr = PetscSortRemoveDupsMPIInt(&n, data->neighbors + 1);CHKERRQ(ierr); 31490a19bb7dSprj- /* The following cast should never fail: can't have more neighbors than PETSC_MPI_INT_MAX */ 31500a19bb7dSprj- ierr = PetscMPIIntCast(n, data->neighbors);CHKERRQ(ierr); 31510a19bb7dSprj- } 31520a19bb7dSprj- if (nranks) *nranks = data->neighbors[0]; 31530a19bb7dSprj- if (ranks) { 31540a19bb7dSprj- if (data->neighbors[0]) *ranks = data->neighbors + 1; 31550a19bb7dSprj- else *ranks = NULL; 31560a19bb7dSprj- } 3157502a2867SDave May PetscFunctionReturn(0); 3158502a2867SDave May } 3159502a2867SDave May 31601eb70e55SToby Isaac PETSC_INTERN PetscErrorCode DMInterpolateSolution_Plex(DM, DM, Mat, Vec, Vec); 31611eb70e55SToby Isaac 316246fa42a0SMatthew G. Knepley static PetscErrorCode DMInitialize_Plex(DM dm) 3163552f7358SJed Brown { 3164713918a9SToby Isaac PetscErrorCode ierr; 3165713918a9SToby Isaac 3166552f7358SJed Brown PetscFunctionBegin; 3167552f7358SJed Brown dm->ops->view = DMView_Plex; 31682c40f234SMatthew G. Knepley dm->ops->load = DMLoad_Plex; 3169552f7358SJed Brown dm->ops->setfromoptions = DMSetFromOptions_Plex; 317038221697SMatthew G. Knepley dm->ops->clone = DMClone_Plex; 3171552f7358SJed Brown dm->ops->setup = DMSetUp_Plex; 31721bb6d2a8SBarry Smith dm->ops->createlocalsection = DMCreateLocalSection_Plex; 317366ad2231SToby Isaac dm->ops->createdefaultconstraints = DMCreateDefaultConstraints_Plex; 3174552f7358SJed Brown dm->ops->createglobalvector = DMCreateGlobalVector_Plex; 3175552f7358SJed Brown dm->ops->createlocalvector = DMCreateLocalVector_Plex; 3176184d77edSJed Brown dm->ops->getlocaltoglobalmapping = NULL; 31770298fd71SBarry Smith dm->ops->createfieldis = NULL; 3178552f7358SJed Brown dm->ops->createcoordinatedm = DMCreateCoordinateDM_Plex; 3179f19dbd58SToby Isaac dm->ops->createcoordinatefield = DMCreateCoordinateField_Plex; 31800a6ba040SMatthew G. Knepley dm->ops->getcoloring = NULL; 3181552f7358SJed Brown dm->ops->creatematrix = DMCreateMatrix_Plex; 3182bceba477SMatthew G. Knepley dm->ops->createinterpolation = DMCreateInterpolation_Plex; 3183bd041c0cSMatthew G. Knepley dm->ops->createmassmatrix = DMCreateMassMatrix_Plex; 31845a84ad33SLisandro Dalcin dm->ops->createinjection = DMCreateInjection_Plex; 3185552f7358SJed Brown dm->ops->refine = DMRefine_Plex; 31860a6ba040SMatthew G. Knepley dm->ops->coarsen = DMCoarsen_Plex; 31870a6ba040SMatthew G. Knepley dm->ops->refinehierarchy = DMRefineHierarchy_Plex; 3188b653a561SMatthew G. Knepley dm->ops->coarsenhierarchy = DMCoarsenHierarchy_Plex; 31890d1cd5e0SMatthew G. Knepley dm->ops->adaptlabel = DMAdaptLabel_Plex; 31900d1cd5e0SMatthew G. Knepley dm->ops->adaptmetric = DMAdaptMetric_Plex; 31910298fd71SBarry Smith dm->ops->globaltolocalbegin = NULL; 31920298fd71SBarry Smith dm->ops->globaltolocalend = NULL; 31930298fd71SBarry Smith dm->ops->localtoglobalbegin = NULL; 31940298fd71SBarry Smith dm->ops->localtoglobalend = NULL; 3195552f7358SJed Brown dm->ops->destroy = DMDestroy_Plex; 3196552f7358SJed Brown dm->ops->createsubdm = DMCreateSubDM_Plex; 31972adcc780SMatthew G. Knepley dm->ops->createsuperdm = DMCreateSuperDM_Plex; 3198793f3fe5SMatthew G. Knepley dm->ops->getdimpoints = DMGetDimPoints_Plex; 3199552f7358SJed Brown dm->ops->locatepoints = DMLocatePoints_Plex; 32000709b2feSToby Isaac dm->ops->projectfunctionlocal = DMProjectFunctionLocal_Plex; 32010709b2feSToby Isaac dm->ops->projectfunctionlabellocal = DMProjectFunctionLabelLocal_Plex; 3202bfc4295aSToby Isaac dm->ops->projectfieldlocal = DMProjectFieldLocal_Plex; 32038c6c5593SMatthew G. Knepley dm->ops->projectfieldlabellocal = DMProjectFieldLabelLocal_Plex; 3204ece3a9fcSMatthew G. Knepley dm->ops->projectbdfieldlabellocal = DMProjectBdFieldLabelLocal_Plex; 32050709b2feSToby Isaac dm->ops->computel2diff = DMComputeL2Diff_Plex; 3206b698f381SToby Isaac dm->ops->computel2gradientdiff = DMComputeL2GradientDiff_Plex; 32072a16baeaSToby Isaac dm->ops->computel2fielddiff = DMComputeL2FieldDiff_Plex; 320828d58a37SPierre Jolivet dm->ops->getneighbors = DMGetNeighbors_Plex; 3209f1d73a7aSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexInsertBoundaryValues_C",DMPlexInsertBoundaryValues_Plex);CHKERRQ(ierr); 321056cf3b9cSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexInsertTimeDerviativeBoundaryValues_C",DMPlexInsertTimeDerivativeBoundaryValues_Plex);CHKERRQ(ierr); 32118135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMSetUpGLVisViewer_C",DMSetUpGLVisViewer_Plex);CHKERRQ(ierr); 321228d58a37SPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)dm,"DMCreateNeumannOverlap_C",DMCreateNeumannOverlap_Plex);CHKERRQ(ierr); 3213cb54e036SVaclav Hapla ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexGetOverlap_C",DMPlexGetOverlap_Plex);CHKERRQ(ierr); 32141eb70e55SToby Isaac ierr = PetscObjectComposeFunction((PetscObject)dm,"DMInterpolateSolution_C",DMInterpolateSolution_Plex);CHKERRQ(ierr); 3215552f7358SJed Brown PetscFunctionReturn(0); 3216552f7358SJed Brown } 3217552f7358SJed Brown 321846fa42a0SMatthew G. Knepley PETSC_INTERN PetscErrorCode DMClone_Plex(DM dm, DM *newdm) 321963a16f15SMatthew G. Knepley { 322063a16f15SMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) dm->data; 322163a16f15SMatthew G. Knepley PetscErrorCode ierr; 322263a16f15SMatthew G. Knepley 322363a16f15SMatthew G. Knepley PetscFunctionBegin; 322463a16f15SMatthew G. Knepley mesh->refct++; 322563a16f15SMatthew G. Knepley (*newdm)->data = mesh; 322663a16f15SMatthew G. Knepley ierr = PetscObjectChangeTypeName((PetscObject) *newdm, DMPLEX);CHKERRQ(ierr); 322763a16f15SMatthew G. Knepley ierr = DMInitialize_Plex(*newdm);CHKERRQ(ierr); 322863a16f15SMatthew G. Knepley PetscFunctionReturn(0); 322963a16f15SMatthew G. Knepley } 323063a16f15SMatthew G. Knepley 32318818961aSMatthew G Knepley /*MC 32328818961aSMatthew G Knepley DMPLEX = "plex" - A DM object that encapsulates an unstructured mesh, or CW Complex, which can be expressed using a Hasse Diagram. 32338818961aSMatthew G Knepley In the local representation, Vecs contain all unknowns in the interior and shared boundary. This is 32348818961aSMatthew G Knepley specified by a PetscSection object. Ownership in the global representation is determined by 32358818961aSMatthew G Knepley ownership of the underlying DMPlex points. This is specified by another PetscSection object. 32368818961aSMatthew G Knepley 3237e5893cccSMatthew G. Knepley Options Database Keys: 3238250712c9SMatthew G. Knepley + -dm_refine_pre - Refine mesh before distribution 3239250712c9SMatthew G. Knepley + -dm_refine_uniform_pre - Choose uniform or generator-based refinement 3240250712c9SMatthew G. Knepley + -dm_refine_volume_limit_pre - Cell volume limit after pre-refinement using generator 3241250712c9SMatthew G. Knepley . -dm_distribute - Distribute mesh across processes 3242250712c9SMatthew G. Knepley . -dm_distribute_overlap - Number of cells to overlap for distribution 3243250712c9SMatthew G. Knepley . -dm_refine - Refine mesh after distribution 3244250712c9SMatthew G. Knepley . -dm_plex_hash_location - Use grid hashing for point location 3245f12cf164SMatthew G. Knepley . -dm_plex_partition_balance - Attempt to evenly divide points on partition boundary between processes 3246f12cf164SMatthew G. Knepley . -dm_plex_remesh_bd - Allow changes to the boundary on remeshing 3247f12cf164SMatthew G. Knepley . -dm_plex_max_projection_height - Maxmimum mesh point height used to project locally 3248f12cf164SMatthew G. Knepley . -dm_plex_regular_refinement - Use special nested projection algorithm for regular refinement 3249250712c9SMatthew G. Knepley . -dm_plex_check_all - Perform all shecks below 3250f12cf164SMatthew G. Knepley . -dm_plex_check_symmetry - Check that the adjacency information in the mesh is symmetric 3251f12cf164SMatthew G. Knepley . -dm_plex_check_skeleton <celltype> - Check that each cell has the correct number of vertices 3252f12cf164SMatthew G. Knepley . -dm_plex_check_faces <celltype> - Check that the faces of each cell give a vertex order this is consistent with what we expect from the cell type 3253f12cf164SMatthew G. Knepley . -dm_plex_check_geometry - Check that cells have positive volume 3254f12cf164SMatthew G. Knepley . -dm_view :mesh.tex:ascii_latex - View the mesh in LaTeX/TikZ 3255e5893cccSMatthew G. Knepley . -dm_plex_view_scale <num> - Scale the TikZ 3256e5893cccSMatthew G. Knepley - -dm_plex_print_fem <num> - View FEM assembly information, such as element vectors and matrices 3257e5893cccSMatthew G. Knepley 32588818961aSMatthew G Knepley Level: intermediate 32598818961aSMatthew G Knepley 32608818961aSMatthew G Knepley .seealso: DMType, DMPlexCreate(), DMCreate(), DMSetType() 32618818961aSMatthew G Knepley M*/ 32628818961aSMatthew G Knepley 32638cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Plex(DM dm) 3264552f7358SJed Brown { 3265552f7358SJed Brown DM_Plex *mesh; 3266412e9a14SMatthew G. Knepley PetscInt unit; 3267552f7358SJed Brown PetscErrorCode ierr; 3268552f7358SJed Brown 3269552f7358SJed Brown PetscFunctionBegin; 3270552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3271b00a9115SJed Brown ierr = PetscNewLog(dm,&mesh);CHKERRQ(ierr); 3272552f7358SJed Brown dm->data = mesh; 3273552f7358SJed Brown 3274552f7358SJed Brown mesh->refct = 1; 327582f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &mesh->coneSection);CHKERRQ(ierr); 3276552f7358SJed Brown mesh->maxConeSize = 0; 32770298fd71SBarry Smith mesh->cones = NULL; 32780298fd71SBarry Smith mesh->coneOrientations = NULL; 327982f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &mesh->supportSection);CHKERRQ(ierr); 3280552f7358SJed Brown mesh->maxSupportSize = 0; 32810298fd71SBarry Smith mesh->supports = NULL; 3282552f7358SJed Brown mesh->refinementUniform = PETSC_TRUE; 3283552f7358SJed Brown mesh->refinementLimit = -1.0; 32847d0f5628SVaclav Hapla mesh->interpolated = DMPLEX_INTERPOLATED_INVALID; 32857d0f5628SVaclav Hapla mesh->interpolatedCollective = DMPLEX_INTERPOLATED_INVALID; 3286552f7358SJed Brown 32870298fd71SBarry Smith mesh->facesTmp = NULL; 3288552f7358SJed Brown 3289d9deefdfSMatthew G. Knepley mesh->tetgenOpts = NULL; 3290d9deefdfSMatthew G. Knepley mesh->triangleOpts = NULL; 329177623264SMatthew G. Knepley ierr = PetscPartitionerCreate(PetscObjectComm((PetscObject)dm), &mesh->partitioner);CHKERRQ(ierr); 32922e62ab5aSMatthew G. Knepley mesh->remeshBd = PETSC_FALSE; 3293d9deefdfSMatthew G. Knepley 32940298fd71SBarry Smith mesh->subpointMap = NULL; 3295552f7358SJed Brown 32968865f1eaSKarl Rupp for (unit = 0; unit < NUM_PETSC_UNITS; ++unit) mesh->scale[unit] = 1.0; 3297552f7358SJed Brown 32980aef6b92SMatthew G. Knepley mesh->regularRefinement = PETSC_FALSE; 3299df0420ecSMatthew G. Knepley mesh->depthState = -1; 3300ba2698f1SMatthew G. Knepley mesh->celltypeState = -1; 33010298fd71SBarry Smith mesh->globalVertexNumbers = NULL; 33020298fd71SBarry Smith mesh->globalCellNumbers = NULL; 3303a68b90caSToby Isaac mesh->anchorSection = NULL; 3304a68b90caSToby Isaac mesh->anchorIS = NULL; 330541e6d900SToby Isaac mesh->createanchors = NULL; 3306fa73a4e1SToby Isaac mesh->computeanchormatrix = NULL; 3307d961a43aSToby Isaac mesh->parentSection = NULL; 3308d961a43aSToby Isaac mesh->parents = NULL; 3309d961a43aSToby Isaac mesh->childIDs = NULL; 3310d961a43aSToby Isaac mesh->childSection = NULL; 3311d961a43aSToby Isaac mesh->children = NULL; 3312d6a7ad0dSToby Isaac mesh->referenceTree = NULL; 3313dcbd3bf7SToby Isaac mesh->getchildsymmetry = NULL; 3314552f7358SJed Brown mesh->vtkCellHeight = 0; 3315e228b242SToby Isaac mesh->useAnchors = PETSC_FALSE; 3316552f7358SJed Brown 3317b29cfa1cSToby Isaac mesh->maxProjectionHeight = 0; 3318b29cfa1cSToby Isaac 33190a19bb7dSprj- mesh->neighbors = NULL; 33200a19bb7dSprj- 3321552f7358SJed Brown mesh->printSetValues = PETSC_FALSE; 3322552f7358SJed Brown mesh->printFEM = 0; 33236113b454SMatthew G. Knepley mesh->printTol = 1.0e-10; 3324552f7358SJed Brown 3325552f7358SJed Brown ierr = DMInitialize_Plex(dm);CHKERRQ(ierr); 3326552f7358SJed Brown PetscFunctionReturn(0); 3327552f7358SJed Brown } 3328552f7358SJed Brown 3329552f7358SJed Brown /*@ 3330552f7358SJed Brown DMPlexCreate - Creates a DMPlex object, which encapsulates an unstructured mesh, or CW complex, which can be expressed using a Hasse Diagram. 3331552f7358SJed Brown 3332d083f849SBarry Smith Collective 3333552f7358SJed Brown 3334552f7358SJed Brown Input Parameter: 3335552f7358SJed Brown . comm - The communicator for the DMPlex object 3336552f7358SJed Brown 3337552f7358SJed Brown Output Parameter: 3338552f7358SJed Brown . mesh - The DMPlex object 3339552f7358SJed Brown 3340552f7358SJed Brown Level: beginner 3341552f7358SJed Brown 3342552f7358SJed Brown @*/ 3343552f7358SJed Brown PetscErrorCode DMPlexCreate(MPI_Comm comm, DM *mesh) 3344552f7358SJed Brown { 3345552f7358SJed Brown PetscErrorCode ierr; 3346552f7358SJed Brown 3347552f7358SJed Brown PetscFunctionBegin; 3348552f7358SJed Brown PetscValidPointer(mesh,2); 3349552f7358SJed Brown ierr = DMCreate(comm, mesh);CHKERRQ(ierr); 3350552f7358SJed Brown ierr = DMSetType(*mesh, DMPLEX);CHKERRQ(ierr); 3351552f7358SJed Brown PetscFunctionReturn(0); 3352552f7358SJed Brown } 3353552f7358SJed Brown 3354b09969d6SVaclav Hapla /*@C 3355b09969d6SVaclav Hapla DMPlexBuildFromCellListParallel - Build distributed DMPLEX topology from a list of vertices for each cell (common mesh generator output) 3356b09969d6SVaclav Hapla 3357b09969d6SVaclav Hapla Input Parameters: 3358b09969d6SVaclav Hapla + dm - The DM 3359b09969d6SVaclav Hapla . numCells - The number of cells owned by this process 336025b6865aSVaclav Hapla . numVertices - The number of vertices owned by this process, or PETSC_DECIDE 336125b6865aSVaclav Hapla . NVertices - The global number of vertices, or PETSC_DECIDE 3362b09969d6SVaclav Hapla . numCorners - The number of vertices for each cell 33635e488331SVaclav Hapla - cells - An array of numCells*numCorners numbers, the global vertex numbers for each cell 3364b09969d6SVaclav Hapla 3365b09969d6SVaclav Hapla Output Parameter: 33668ddadb14SVaclav Hapla . vertexSF - (Optional) SF describing complete vertex ownership 3367b09969d6SVaclav Hapla 3368b09969d6SVaclav Hapla Notes: 3369b09969d6SVaclav Hapla Two triangles sharing a face 3370b09969d6SVaclav Hapla $ 3371b09969d6SVaclav Hapla $ 2 3372b09969d6SVaclav Hapla $ / | \ 3373b09969d6SVaclav Hapla $ / | \ 3374b09969d6SVaclav Hapla $ / | \ 3375b09969d6SVaclav Hapla $ 0 0 | 1 3 3376b09969d6SVaclav Hapla $ \ | / 3377b09969d6SVaclav Hapla $ \ | / 3378b09969d6SVaclav Hapla $ \ | / 3379b09969d6SVaclav Hapla $ 1 3380b09969d6SVaclav Hapla would have input 3381b09969d6SVaclav Hapla $ numCells = 2, numVertices = 4 3382b09969d6SVaclav Hapla $ cells = [0 1 2 1 3 2] 3383b09969d6SVaclav Hapla $ 3384b09969d6SVaclav Hapla which would result in the DMPlex 3385b09969d6SVaclav Hapla $ 3386b09969d6SVaclav Hapla $ 4 3387b09969d6SVaclav Hapla $ / | \ 3388b09969d6SVaclav Hapla $ / | \ 3389b09969d6SVaclav Hapla $ / | \ 3390b09969d6SVaclav Hapla $ 2 0 | 1 5 3391b09969d6SVaclav Hapla $ \ | / 3392b09969d6SVaclav Hapla $ \ | / 3393b09969d6SVaclav Hapla $ \ | / 3394b09969d6SVaclav Hapla $ 3 3395b09969d6SVaclav Hapla 339625b6865aSVaclav Hapla Vertices are implicitly numbered consecutively 0,...,NVertices. 339725b6865aSVaclav Hapla Each rank owns a chunk of numVertices consecutive vertices. 339825b6865aSVaclav Hapla If numVertices is PETSC_DECIDE, PETSc will distribute them as evenly as possible using PetscLayout. 339925b6865aSVaclav Hapla If both NVertices and numVertices are PETSC_DECIDE, NVertices is computed by PETSc as the maximum vertex index in cells + 1. 340025b6865aSVaclav Hapla If only NVertices is PETSC_DECIDE, it is computed as the sum of numVertices over all ranks. 340125b6865aSVaclav Hapla 3402b09969d6SVaclav Hapla The cell distribution is arbitrary non-overlapping, independent of the vertex distribution. 3403b09969d6SVaclav Hapla 3404b09969d6SVaclav Hapla Not currently supported in Fortran. 3405b09969d6SVaclav Hapla 3406b09969d6SVaclav Hapla Level: advanced 3407b09969d6SVaclav Hapla 3408b09969d6SVaclav Hapla .seealso: DMPlexBuildFromCellList(), DMPlexCreateFromCellListParallelPetsc(), DMPlexBuildCoordinatesFromCellListParallel() 3409b09969d6SVaclav Hapla @*/ 341025b6865aSVaclav Hapla PetscErrorCode DMPlexBuildFromCellListParallel(DM dm, PetscInt numCells, PetscInt numVertices, PetscInt NVertices, PetscInt numCorners, const PetscInt cells[], PetscSF *vertexSF) 3411a47d0d45SMatthew G. Knepley { 34122464107aSksagiyam PetscSF sfPoint; 34132464107aSksagiyam PetscLayout layout; 34142464107aSksagiyam PetscInt numVerticesAdj, *verticesAdj, *cones, c, p, dim; 34159852e123SBarry Smith PetscMPIInt rank, size; 3416a47d0d45SMatthew G. Knepley PetscErrorCode ierr; 3417a47d0d45SMatthew G. Knepley 3418a47d0d45SMatthew G. Knepley PetscFunctionBegin; 341925b6865aSVaclav Hapla PetscValidLogicalCollectiveInt(dm,NVertices,4); 3420b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 3421ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 3422ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRMPI(ierr); 34236cbf6523SVaclav Hapla ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 342425b6865aSVaclav Hapla /* Get/check global number of vertices */ 342525b6865aSVaclav Hapla { 342625b6865aSVaclav Hapla PetscInt NVerticesInCells, i; 342725b6865aSVaclav Hapla const PetscInt len = numCells * numCorners; 342825b6865aSVaclav Hapla 342925b6865aSVaclav Hapla /* NVerticesInCells = max(cells) + 1 */ 343025b6865aSVaclav Hapla NVerticesInCells = PETSC_MIN_INT; 343125b6865aSVaclav Hapla for (i=0; i<len; i++) if (cells[i] > NVerticesInCells) NVerticesInCells = cells[i]; 343225b6865aSVaclav Hapla ++NVerticesInCells; 3433ffc4695bSBarry Smith ierr = MPI_Allreduce(MPI_IN_PLACE, &NVerticesInCells, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 343425b6865aSVaclav Hapla 343525b6865aSVaclav Hapla if (numVertices == PETSC_DECIDE && NVertices == PETSC_DECIDE) NVertices = NVerticesInCells; 343625b6865aSVaclav Hapla else if (NVertices != PETSC_DECIDE && NVertices < NVerticesInCells) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Specified global number of vertices %D must be greater than or equal to the number of vertices in cells %D",NVertices,NVerticesInCells); 343725b6865aSVaclav Hapla } 34389079aca8SVaclav Hapla /* Count locally unique vertices */ 34399079aca8SVaclav Hapla { 34409079aca8SVaclav Hapla PetscHSetI vhash; 34419079aca8SVaclav Hapla PetscInt off = 0; 34429079aca8SVaclav Hapla 3443e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&vhash);CHKERRQ(ierr); 3444a47d0d45SMatthew G. Knepley for (c = 0; c < numCells; ++c) { 3445a47d0d45SMatthew G. Knepley for (p = 0; p < numCorners; ++p) { 3446e8f14785SLisandro Dalcin ierr = PetscHSetIAdd(vhash, cells[c*numCorners+p]);CHKERRQ(ierr); 3447a47d0d45SMatthew G. Knepley } 3448a47d0d45SMatthew G. Knepley } 3449e8f14785SLisandro Dalcin ierr = PetscHSetIGetSize(vhash, &numVerticesAdj);CHKERRQ(ierr); 3450a47d0d45SMatthew G. Knepley ierr = PetscMalloc1(numVerticesAdj, &verticesAdj);CHKERRQ(ierr); 3451e8f14785SLisandro Dalcin ierr = PetscHSetIGetElems(vhash, &off, verticesAdj);CHKERRQ(ierr); 3452e8f14785SLisandro Dalcin ierr = PetscHSetIDestroy(&vhash);CHKERRQ(ierr); 3453a47d0d45SMatthew G. Knepley if (off != numVerticesAdj) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid number of local vertices %D should be %D", off, numVerticesAdj); 3454a47d0d45SMatthew G. Knepley } 34559079aca8SVaclav Hapla ierr = PetscSortInt(numVerticesAdj, verticesAdj);CHKERRQ(ierr); 3456a47d0d45SMatthew G. Knepley /* Create cones */ 3457a47d0d45SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVerticesAdj);CHKERRQ(ierr); 3458a47d0d45SMatthew G. Knepley for (c = 0; c < numCells; ++c) {ierr = DMPlexSetConeSize(dm, c, numCorners);CHKERRQ(ierr);} 3459a47d0d45SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); 3460961cfab0SVaclav Hapla ierr = DMPlexGetCones(dm,&cones);CHKERRQ(ierr); 3461a47d0d45SMatthew G. Knepley for (c = 0; c < numCells; ++c) { 3462a47d0d45SMatthew G. Knepley for (p = 0; p < numCorners; ++p) { 3463a47d0d45SMatthew G. Knepley const PetscInt gv = cells[c*numCorners+p]; 3464a47d0d45SMatthew G. Knepley PetscInt lv; 3465a47d0d45SMatthew G. Knepley 34669079aca8SVaclav Hapla /* Positions within verticesAdj form 0-based local vertex numbering; 34679079aca8SVaclav Hapla we need to shift it by numCells to get correct DAG points (cells go first) */ 3468a47d0d45SMatthew G. Knepley ierr = PetscFindInt(gv, numVerticesAdj, verticesAdj, &lv);CHKERRQ(ierr); 3469a47d0d45SMatthew G. Knepley if (lv < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not find global vertex %D in local connectivity", gv); 3470961cfab0SVaclav Hapla cones[c*numCorners+p] = lv+numCells; 3471a47d0d45SMatthew G. Knepley } 3472a47d0d45SMatthew G. Knepley } 34732464107aSksagiyam /* Build point sf */ 34742464107aSksagiyam ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)dm), &layout);CHKERRQ(ierr); 34752464107aSksagiyam ierr = PetscLayoutSetSize(layout, NVertices);CHKERRQ(ierr); 34762464107aSksagiyam ierr = PetscLayoutSetLocalSize(layout, numVertices);CHKERRQ(ierr); 34772464107aSksagiyam ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr); 34782464107aSksagiyam ierr = PetscSFCreateByMatchingIndices(layout, numVerticesAdj, verticesAdj, NULL, numCells, numVerticesAdj, verticesAdj, NULL, numCells, vertexSF, &sfPoint);CHKERRQ(ierr); 34792464107aSksagiyam ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 3480a47d0d45SMatthew G. Knepley ierr = PetscFree(verticesAdj);CHKERRQ(ierr); 3481a47d0d45SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) sfPoint, "point SF");CHKERRQ(ierr); 34822464107aSksagiyam if (dm->sf) { 34832464107aSksagiyam const char *prefix; 34842464107aSksagiyam 34852464107aSksagiyam ierr = PetscObjectGetOptionsPrefix((PetscObject)dm->sf, &prefix);CHKERRQ(ierr); 34862464107aSksagiyam ierr = PetscObjectSetOptionsPrefix((PetscObject)sfPoint, prefix);CHKERRQ(ierr); 34872464107aSksagiyam } 34882464107aSksagiyam ierr = DMSetPointSF(dm, sfPoint);CHKERRQ(ierr); 34892464107aSksagiyam ierr = PetscSFDestroy(&sfPoint);CHKERRQ(ierr); 34902464107aSksagiyam if (vertexSF) {ierr = PetscObjectSetName((PetscObject)(*vertexSF), "Vertex Ownership SF");CHKERRQ(ierr);} 3491a47d0d45SMatthew G. Knepley /* Fill in the rest of the topology structure */ 3492a47d0d45SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 3493a47d0d45SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 3494b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 3495a47d0d45SMatthew G. Knepley PetscFunctionReturn(0); 3496a47d0d45SMatthew G. Knepley } 3497a47d0d45SMatthew G. Knepley 3498b09969d6SVaclav Hapla /*@C 3499b09969d6SVaclav Hapla DMPlexBuildCoordinatesFromCellListParallel - Build DM coordinates from a list of coordinates for each owned vertex (common mesh generator output) 3500b09969d6SVaclav Hapla 3501b09969d6SVaclav Hapla Input Parameters: 3502b09969d6SVaclav Hapla + dm - The DM 3503b09969d6SVaclav Hapla . spaceDim - The spatial dimension used for coordinates 3504b09969d6SVaclav Hapla . sfVert - SF describing complete vertex ownership 3505b09969d6SVaclav Hapla - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 3506b09969d6SVaclav Hapla 3507b09969d6SVaclav Hapla Level: advanced 3508b09969d6SVaclav Hapla 3509b09969d6SVaclav Hapla Notes: 3510b09969d6SVaclav Hapla Not currently supported in Fortran. 3511b09969d6SVaclav Hapla 3512b09969d6SVaclav Hapla .seealso: DMPlexBuildCoordinatesFromCellList(), DMPlexCreateFromCellListParallelPetsc(), DMPlexBuildFromCellListParallel() 3513b09969d6SVaclav Hapla @*/ 35141edcf0b2SVaclav Hapla PetscErrorCode DMPlexBuildCoordinatesFromCellListParallel(DM dm, PetscInt spaceDim, PetscSF sfVert, const PetscReal vertexCoords[]) 3515a47d0d45SMatthew G. Knepley { 3516a47d0d45SMatthew G. Knepley PetscSection coordSection; 3517a47d0d45SMatthew G. Knepley Vec coordinates; 3518a47d0d45SMatthew G. Knepley PetscScalar *coords; 35191edcf0b2SVaclav Hapla PetscInt numVertices, numVerticesAdj, coordSize, v, vStart, vEnd; 3520a47d0d45SMatthew G. Knepley PetscErrorCode ierr; 3521a47d0d45SMatthew G. Knepley 3522a47d0d45SMatthew G. Knepley PetscFunctionBegin; 3523b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 35241edcf0b2SVaclav Hapla ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 35251edcf0b2SVaclav Hapla if (vStart < 0 || vEnd < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "DM is not set up properly. DMPlexBuildFromCellList() should be called first."); 35269596c6baSMatthew G. Knepley ierr = DMSetCoordinateDim(dm, spaceDim);CHKERRQ(ierr); 3527a47d0d45SMatthew G. Knepley ierr = PetscSFGetGraph(sfVert, &numVertices, &numVerticesAdj, NULL, NULL);CHKERRQ(ierr); 35281edcf0b2SVaclav Hapla if (vEnd - vStart != numVerticesAdj) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Supplied sfVert has wrong number of leaves = %D != %D = vEnd - vStart",numVerticesAdj,vEnd - vStart); 3529a47d0d45SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 3530a47d0d45SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 3531a47d0d45SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, spaceDim);CHKERRQ(ierr); 35321edcf0b2SVaclav Hapla ierr = PetscSectionSetChart(coordSection, vStart, vEnd);CHKERRQ(ierr); 35331edcf0b2SVaclav Hapla for (v = vStart; v < vEnd; ++v) { 3534a47d0d45SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, spaceDim);CHKERRQ(ierr); 3535a47d0d45SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, spaceDim);CHKERRQ(ierr); 3536a47d0d45SMatthew G. Knepley } 3537a47d0d45SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 3538a47d0d45SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 3539a47d0d45SMatthew G. Knepley ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinates);CHKERRQ(ierr); 3540a47d0d45SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, spaceDim);CHKERRQ(ierr); 3541a47d0d45SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 3542a47d0d45SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 3543a47d0d45SMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 3544a47d0d45SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 3545a47d0d45SMatthew G. Knepley { 3546a47d0d45SMatthew G. Knepley MPI_Datatype coordtype; 3547a47d0d45SMatthew G. Knepley 3548a47d0d45SMatthew G. Knepley /* Need a temp buffer for coords if we have complex/single */ 3549ffc4695bSBarry Smith ierr = MPI_Type_contiguous(spaceDim, MPIU_SCALAR, &coordtype);CHKERRMPI(ierr); 3550ffc4695bSBarry Smith ierr = MPI_Type_commit(&coordtype);CHKERRMPI(ierr); 355121016a8bSBarry Smith #if defined(PETSC_USE_COMPLEX) 355221016a8bSBarry Smith { 355321016a8bSBarry Smith PetscScalar *svertexCoords; 355421016a8bSBarry Smith PetscInt i; 35553612f820SVaclav Hapla ierr = PetscMalloc1(numVertices*spaceDim,&svertexCoords);CHKERRQ(ierr); 35563612f820SVaclav Hapla for (i=0; i<numVertices*spaceDim; i++) svertexCoords[i] = vertexCoords[i]; 3557ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sfVert, coordtype, svertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 3558ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sfVert, coordtype, svertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 355921016a8bSBarry Smith ierr = PetscFree(svertexCoords);CHKERRQ(ierr); 356021016a8bSBarry Smith } 356121016a8bSBarry Smith #else 3562ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sfVert, coordtype, vertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 3563ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sfVert, coordtype, vertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 356421016a8bSBarry Smith #endif 3565ffc4695bSBarry Smith ierr = MPI_Type_free(&coordtype);CHKERRMPI(ierr); 3566a47d0d45SMatthew G. Knepley } 3567a47d0d45SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 3568a47d0d45SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 3569a47d0d45SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 3570b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 3571a47d0d45SMatthew G. Knepley PetscFunctionReturn(0); 3572a47d0d45SMatthew G. Knepley } 3573a47d0d45SMatthew G. Knepley 3574c3edce3dSSatish Balay /*@ 3575b09969d6SVaclav Hapla DMPlexCreateFromCellListParallelPetsc - Create distributed DMPLEX from a list of vertices for each cell (common mesh generator output) 3576a47d0d45SMatthew G. Knepley 3577a47d0d45SMatthew G. Knepley Input Parameters: 3578a47d0d45SMatthew G. Knepley + comm - The communicator 3579a47d0d45SMatthew G. Knepley . dim - The topological dimension of the mesh 3580a47d0d45SMatthew G. Knepley . numCells - The number of cells owned by this process 358125b6865aSVaclav Hapla . numVertices - The number of vertices owned by this process, or PETSC_DECIDE 358225b6865aSVaclav Hapla . NVertices - The global number of vertices, or PETSC_DECIDE 3583a47d0d45SMatthew G. Knepley . numCorners - The number of vertices for each cell 3584a47d0d45SMatthew G. Knepley . interpolate - Flag indicating that intermediate mesh entities (faces, edges) should be created automatically 3585a47d0d45SMatthew G. Knepley . cells - An array of numCells*numCorners numbers, the global vertex numbers for each cell 3586a47d0d45SMatthew G. Knepley . spaceDim - The spatial dimension used for coordinates 3587a47d0d45SMatthew G. Knepley - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 3588a47d0d45SMatthew G. Knepley 3589a47d0d45SMatthew G. Knepley Output Parameter: 359018d54ad4SMichael Lange + dm - The DM 3591b09969d6SVaclav Hapla - vertexSF - (Optional) SF describing complete vertex ownership 3592a47d0d45SMatthew G. Knepley 3593b09969d6SVaclav Hapla Notes: 3594b09969d6SVaclav Hapla This function is just a convenient sequence of DMCreate(), DMSetType(), DMSetDimension(), 3595b09969d6SVaclav Hapla DMPlexBuildFromCellListParallel(), DMPlexInterpolate(), DMPlexBuildCoordinatesFromCellListParallel() 3596a47d0d45SMatthew G. Knepley 359725b6865aSVaclav Hapla See DMPlexBuildFromCellListParallel() for an example and details about the topology-related parameters. 359825b6865aSVaclav Hapla See DMPlexBuildCoordinatesFromCellListParallel() for details about the geometry-related parameters. 359925b6865aSVaclav Hapla 3600b09969d6SVaclav Hapla Level: intermediate 3601a47d0d45SMatthew G. Knepley 3602b09969d6SVaclav Hapla .seealso: DMPlexCreateFromCellListPetsc(), DMPlexBuildFromCellListParallel(), DMPlexBuildCoordinatesFromCellListParallel(), DMPlexCreateFromDAG(), DMPlexCreate() 3603a47d0d45SMatthew G. Knepley @*/ 360425b6865aSVaclav Hapla PetscErrorCode DMPlexCreateFromCellListParallelPetsc(MPI_Comm comm, PetscInt dim, PetscInt numCells, PetscInt numVertices, PetscInt NVertices, PetscInt numCorners, PetscBool interpolate, const PetscInt cells[], PetscInt spaceDim, const PetscReal vertexCoords[], PetscSF *vertexSF, DM *dm) 3605a47d0d45SMatthew G. Knepley { 3606a47d0d45SMatthew G. Knepley PetscSF sfVert; 3607a47d0d45SMatthew G. Knepley PetscErrorCode ierr; 3608a47d0d45SMatthew G. Knepley 3609a47d0d45SMatthew G. Knepley PetscFunctionBegin; 3610a47d0d45SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 3611a47d0d45SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 3612a47d0d45SMatthew G. Knepley PetscValidLogicalCollectiveInt(*dm, dim, 2); 3613064a246eSJacob Faibussowitsch PetscValidLogicalCollectiveInt(*dm, spaceDim, 9); 3614a47d0d45SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 361525b6865aSVaclav Hapla ierr = DMPlexBuildFromCellListParallel(*dm, numCells, numVertices, NVertices, numCorners, cells, &sfVert);CHKERRQ(ierr); 3616a47d0d45SMatthew G. Knepley if (interpolate) { 36175fd9971aSMatthew G. Knepley DM idm; 3618a47d0d45SMatthew G. Knepley 3619a47d0d45SMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 3620a47d0d45SMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 3621a47d0d45SMatthew G. Knepley *dm = idm; 3622a47d0d45SMatthew G. Knepley } 36231edcf0b2SVaclav Hapla ierr = DMPlexBuildCoordinatesFromCellListParallel(*dm, spaceDim, sfVert, vertexCoords);CHKERRQ(ierr); 362418d54ad4SMichael Lange if (vertexSF) *vertexSF = sfVert; 3625fba955ccSBarry Smith else {ierr = PetscSFDestroy(&sfVert);CHKERRQ(ierr);} 3626a47d0d45SMatthew G. Knepley PetscFunctionReturn(0); 3627a47d0d45SMatthew G. Knepley } 3628a47d0d45SMatthew G. Knepley 3629a4a685f2SJacob Faibussowitsch /*@ 3630a4a685f2SJacob Faibussowitsch DMPlexCreateFromCellListParallel - Deprecated, use DMPlexCreateFromCellListParallelPetsc() 3631a4a685f2SJacob Faibussowitsch 3632a4a685f2SJacob Faibussowitsch Level: deprecated 3633a4a685f2SJacob Faibussowitsch 3634a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromCellListParallelPetsc() 3635a4a685f2SJacob Faibussowitsch @*/ 3636a4a685f2SJacob Faibussowitsch PetscErrorCode DMPlexCreateFromCellListParallel(MPI_Comm comm, PetscInt dim, PetscInt numCells, PetscInt numVertices, PetscInt numCorners, PetscBool interpolate, const int cells[], PetscInt spaceDim, const PetscReal vertexCoords[], PetscSF *vertexSF, DM *dm) 3637a4a685f2SJacob Faibussowitsch { 3638a4a685f2SJacob Faibussowitsch PetscErrorCode ierr; 3639a4a685f2SJacob Faibussowitsch PetscInt i; 3640a4a685f2SJacob Faibussowitsch PetscInt *pintCells; 3641a4a685f2SJacob Faibussowitsch 3642a4a685f2SJacob Faibussowitsch PetscFunctionBegin; 3643a4a685f2SJacob Faibussowitsch if (sizeof(int) > sizeof(PetscInt)) SETERRQ2(comm, PETSC_ERR_ARG_SIZ, "Size of int %zd greater than size of PetscInt %zd. Reconfigure PETSc --with-64-bit-indices=1", sizeof(int), sizeof(PetscInt)); 3644a4a685f2SJacob Faibussowitsch if (sizeof(int) == sizeof(PetscInt)) { 3645a4a685f2SJacob Faibussowitsch pintCells = (PetscInt *) cells; 3646a4a685f2SJacob Faibussowitsch } else { 3647a4a685f2SJacob Faibussowitsch ierr = PetscMalloc1(numCells*numCorners, &pintCells);CHKERRQ(ierr); 3648a4a685f2SJacob Faibussowitsch for (i = 0; i < numCells*numCorners; i++) { 3649a4a685f2SJacob Faibussowitsch pintCells[i] = (PetscInt) cells[i]; 3650a4a685f2SJacob Faibussowitsch } 3651a4a685f2SJacob Faibussowitsch } 365225b6865aSVaclav Hapla ierr = DMPlexCreateFromCellListParallelPetsc(comm, dim, numCells, numVertices, PETSC_DECIDE, numCorners, interpolate, pintCells, spaceDim, vertexCoords, vertexSF, dm);CHKERRQ(ierr); 3653a4a685f2SJacob Faibussowitsch if (sizeof(int) != sizeof(PetscInt)) { 3654a4a685f2SJacob Faibussowitsch ierr = PetscFree(pintCells);CHKERRQ(ierr); 3655a4a685f2SJacob Faibussowitsch } 3656a4a685f2SJacob Faibussowitsch PetscFunctionReturn(0); 3657a4a685f2SJacob Faibussowitsch } 3658a4a685f2SJacob Faibussowitsch 3659b09969d6SVaclav Hapla /*@C 3660b09969d6SVaclav Hapla DMPlexBuildFromCellList - Build DMPLEX topology from a list of vertices for each cell (common mesh generator output) 36619298eaa6SMatthew G Knepley 36629298eaa6SMatthew G Knepley Input Parameters: 3663b09969d6SVaclav Hapla + dm - The DM 3664b09969d6SVaclav Hapla . numCells - The number of cells owned by this process 366525b6865aSVaclav Hapla . numVertices - The number of vertices owned by this process, or PETSC_DECIDE 36669298eaa6SMatthew G Knepley . numCorners - The number of vertices for each cell 36675e488331SVaclav Hapla - cells - An array of numCells*numCorners numbers, the global vertex numbers for each cell 36689298eaa6SMatthew G Knepley 3669b09969d6SVaclav Hapla Level: advanced 36709298eaa6SMatthew G Knepley 3671b09969d6SVaclav Hapla Notes: 3672b09969d6SVaclav Hapla Two triangles sharing a face 36739298eaa6SMatthew G Knepley $ 36749298eaa6SMatthew G Knepley $ 2 36759298eaa6SMatthew G Knepley $ / | \ 36769298eaa6SMatthew G Knepley $ / | \ 36779298eaa6SMatthew G Knepley $ / | \ 36789298eaa6SMatthew G Knepley $ 0 0 | 1 3 36799298eaa6SMatthew G Knepley $ \ | / 36809298eaa6SMatthew G Knepley $ \ | / 36819298eaa6SMatthew G Knepley $ \ | / 36829298eaa6SMatthew G Knepley $ 1 36839298eaa6SMatthew G Knepley would have input 36849298eaa6SMatthew G Knepley $ numCells = 2, numVertices = 4 36859298eaa6SMatthew G Knepley $ cells = [0 1 2 1 3 2] 36869298eaa6SMatthew G Knepley $ 36879298eaa6SMatthew G Knepley which would result in the DMPlex 36889298eaa6SMatthew G Knepley $ 36899298eaa6SMatthew G Knepley $ 4 36909298eaa6SMatthew G Knepley $ / | \ 36919298eaa6SMatthew G Knepley $ / | \ 36929298eaa6SMatthew G Knepley $ / | \ 36939298eaa6SMatthew G Knepley $ 2 0 | 1 5 36949298eaa6SMatthew G Knepley $ \ | / 36959298eaa6SMatthew G Knepley $ \ | / 36969298eaa6SMatthew G Knepley $ \ | / 36979298eaa6SMatthew G Knepley $ 3 36989298eaa6SMatthew G Knepley 369925b6865aSVaclav Hapla If numVertices is PETSC_DECIDE, it is computed by PETSc as the maximum vertex index in cells + 1. 370025b6865aSVaclav Hapla 3701b09969d6SVaclav Hapla Not currently supported in Fortran. 37029298eaa6SMatthew G Knepley 3703b09969d6SVaclav Hapla .seealso: DMPlexBuildFromCellListParallel(), DMPlexBuildCoordinatesFromCellList(), DMPlexCreateFromCellListPetsc() 3704b09969d6SVaclav Hapla @*/ 37055e488331SVaclav Hapla PetscErrorCode DMPlexBuildFromCellList(DM dm, PetscInt numCells, PetscInt numVertices, PetscInt numCorners, const PetscInt cells[]) 3706b09969d6SVaclav Hapla { 3707961cfab0SVaclav Hapla PetscInt *cones, c, p, dim; 3708b09969d6SVaclav Hapla PetscErrorCode ierr; 3709b09969d6SVaclav Hapla 3710b09969d6SVaclav Hapla PetscFunctionBegin; 3711b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 3712b09969d6SVaclav Hapla ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 371325b6865aSVaclav Hapla /* Get/check global number of vertices */ 371425b6865aSVaclav Hapla { 371525b6865aSVaclav Hapla PetscInt NVerticesInCells, i; 371625b6865aSVaclav Hapla const PetscInt len = numCells * numCorners; 371725b6865aSVaclav Hapla 371825b6865aSVaclav Hapla /* NVerticesInCells = max(cells) + 1 */ 371925b6865aSVaclav Hapla NVerticesInCells = PETSC_MIN_INT; 372025b6865aSVaclav Hapla for (i=0; i<len; i++) if (cells[i] > NVerticesInCells) NVerticesInCells = cells[i]; 372125b6865aSVaclav Hapla ++NVerticesInCells; 372225b6865aSVaclav Hapla 372325b6865aSVaclav Hapla if (numVertices == PETSC_DECIDE) numVertices = NVerticesInCells; 372425b6865aSVaclav Hapla else if (numVertices < NVerticesInCells) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Specified number of vertices %D must be greater than or equal to the number of vertices in cells %D",numVertices,NVerticesInCells); 372525b6865aSVaclav Hapla } 3726b09969d6SVaclav Hapla ierr = DMPlexSetChart(dm, 0, numCells+numVertices);CHKERRQ(ierr); 3727b09969d6SVaclav Hapla for (c = 0; c < numCells; ++c) { 3728b09969d6SVaclav Hapla ierr = DMPlexSetConeSize(dm, c, numCorners);CHKERRQ(ierr); 3729b09969d6SVaclav Hapla } 3730b09969d6SVaclav Hapla ierr = DMSetUp(dm);CHKERRQ(ierr); 3731961cfab0SVaclav Hapla ierr = DMPlexGetCones(dm,&cones);CHKERRQ(ierr); 3732b09969d6SVaclav Hapla for (c = 0; c < numCells; ++c) { 3733b09969d6SVaclav Hapla for (p = 0; p < numCorners; ++p) { 3734961cfab0SVaclav Hapla cones[c*numCorners+p] = cells[c*numCorners+p]+numCells; 3735b09969d6SVaclav Hapla } 3736b09969d6SVaclav Hapla } 3737b09969d6SVaclav Hapla ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 3738b09969d6SVaclav Hapla ierr = DMPlexStratify(dm);CHKERRQ(ierr); 3739b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 3740b09969d6SVaclav Hapla PetscFunctionReturn(0); 3741b09969d6SVaclav Hapla } 3742b09969d6SVaclav Hapla 3743b09969d6SVaclav Hapla /*@C 3744b09969d6SVaclav Hapla DMPlexBuildCoordinatesFromCellList - Build DM coordinates from a list of coordinates for each owned vertex (common mesh generator output) 3745b09969d6SVaclav Hapla 3746b09969d6SVaclav Hapla Input Parameters: 3747b09969d6SVaclav Hapla + dm - The DM 3748b09969d6SVaclav Hapla . spaceDim - The spatial dimension used for coordinates 3749b09969d6SVaclav Hapla - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 3750b09969d6SVaclav Hapla 3751b09969d6SVaclav Hapla Level: advanced 3752b09969d6SVaclav Hapla 3753b09969d6SVaclav Hapla Notes: 3754b09969d6SVaclav Hapla Not currently supported in Fortran. 3755b09969d6SVaclav Hapla 3756b09969d6SVaclav Hapla .seealso: DMPlexBuildCoordinatesFromCellListParallel(), DMPlexCreateFromCellListPetsc(), DMPlexBuildFromCellList() 3757b09969d6SVaclav Hapla @*/ 37581edcf0b2SVaclav Hapla PetscErrorCode DMPlexBuildCoordinatesFromCellList(DM dm, PetscInt spaceDim, const PetscReal vertexCoords[]) 3759b09969d6SVaclav Hapla { 3760b09969d6SVaclav Hapla PetscSection coordSection; 3761b09969d6SVaclav Hapla Vec coordinates; 3762b09969d6SVaclav Hapla DM cdm; 3763b09969d6SVaclav Hapla PetscScalar *coords; 37641edcf0b2SVaclav Hapla PetscInt v, vStart, vEnd, d; 3765b09969d6SVaclav Hapla PetscErrorCode ierr; 3766b09969d6SVaclav Hapla 3767b09969d6SVaclav Hapla PetscFunctionBegin; 3768b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 37691edcf0b2SVaclav Hapla ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 37701edcf0b2SVaclav Hapla if (vStart < 0 || vEnd < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "DM is not set up properly. DMPlexBuildFromCellList() should be called first."); 3771b09969d6SVaclav Hapla ierr = DMSetCoordinateDim(dm, spaceDim);CHKERRQ(ierr); 3772b09969d6SVaclav Hapla ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 3773b09969d6SVaclav Hapla ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 3774b09969d6SVaclav Hapla ierr = PetscSectionSetFieldComponents(coordSection, 0, spaceDim);CHKERRQ(ierr); 37751edcf0b2SVaclav Hapla ierr = PetscSectionSetChart(coordSection, vStart, vEnd);CHKERRQ(ierr); 37761edcf0b2SVaclav Hapla for (v = vStart; v < vEnd; ++v) { 3777b09969d6SVaclav Hapla ierr = PetscSectionSetDof(coordSection, v, spaceDim);CHKERRQ(ierr); 3778b09969d6SVaclav Hapla ierr = PetscSectionSetFieldDof(coordSection, v, 0, spaceDim);CHKERRQ(ierr); 3779b09969d6SVaclav Hapla } 3780b09969d6SVaclav Hapla ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 3781b09969d6SVaclav Hapla 3782b09969d6SVaclav Hapla ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 3783b09969d6SVaclav Hapla ierr = DMCreateLocalVector(cdm, &coordinates);CHKERRQ(ierr); 3784b09969d6SVaclav Hapla ierr = VecSetBlockSize(coordinates, spaceDim);CHKERRQ(ierr); 3785b09969d6SVaclav Hapla ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 378699946890SBarry Smith ierr = VecGetArrayWrite(coordinates, &coords);CHKERRQ(ierr); 37871edcf0b2SVaclav Hapla for (v = 0; v < vEnd-vStart; ++v) { 3788b09969d6SVaclav Hapla for (d = 0; d < spaceDim; ++d) { 3789b09969d6SVaclav Hapla coords[v*spaceDim+d] = vertexCoords[v*spaceDim+d]; 3790b09969d6SVaclav Hapla } 3791b09969d6SVaclav Hapla } 379299946890SBarry Smith ierr = VecRestoreArrayWrite(coordinates, &coords);CHKERRQ(ierr); 3793b09969d6SVaclav Hapla ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 3794b09969d6SVaclav Hapla ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 3795b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 3796b09969d6SVaclav Hapla PetscFunctionReturn(0); 3797b09969d6SVaclav Hapla } 3798b09969d6SVaclav Hapla 3799b09969d6SVaclav Hapla /*@ 3800b09969d6SVaclav Hapla DMPlexCreateFromCellListPetsc - Create DMPLEX from a list of vertices for each cell (common mesh generator output) 3801b09969d6SVaclav Hapla 3802b09969d6SVaclav Hapla Input Parameters: 3803b09969d6SVaclav Hapla + comm - The communicator 3804b09969d6SVaclav Hapla . dim - The topological dimension of the mesh 3805b09969d6SVaclav Hapla . numCells - The number of cells 380625b6865aSVaclav Hapla . numVertices - The number of vertices owned by this process, or PETSC_DECIDE 3807b09969d6SVaclav Hapla . numCorners - The number of vertices for each cell 3808b09969d6SVaclav Hapla . interpolate - Flag indicating that intermediate mesh entities (faces, edges) should be created automatically 3809b09969d6SVaclav Hapla . cells - An array of numCells*numCorners numbers, the vertices for each cell 3810b09969d6SVaclav Hapla . spaceDim - The spatial dimension used for coordinates 3811b09969d6SVaclav Hapla - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 3812b09969d6SVaclav Hapla 3813b09969d6SVaclav Hapla Output Parameter: 3814b09969d6SVaclav Hapla . dm - The DM 3815b09969d6SVaclav Hapla 3816b09969d6SVaclav Hapla Notes: 3817b09969d6SVaclav Hapla This function is just a convenient sequence of DMCreate(), DMSetType(), DMSetDimension(), DMPlexBuildFromCellList(), 3818b09969d6SVaclav Hapla DMPlexInterpolate(), DMPlexBuildCoordinatesFromCellList() 3819b09969d6SVaclav Hapla 382025b6865aSVaclav Hapla See DMPlexBuildFromCellList() for an example and details about the topology-related parameters. 382125b6865aSVaclav Hapla See DMPlexBuildCoordinatesFromCellList() for details about the geometry-related parameters. 382225b6865aSVaclav Hapla 3823b09969d6SVaclav Hapla Level: intermediate 3824b09969d6SVaclav Hapla 3825b09969d6SVaclav Hapla .seealso: DMPlexCreateFromCellListParallelPetsc(), DMPlexBuildFromCellList(), DMPlexBuildCoordinatesFromCellList(), DMPlexCreateFromDAG(), DMPlexCreate() 38269298eaa6SMatthew G Knepley @*/ 3827a4a685f2SJacob Faibussowitsch PetscErrorCode DMPlexCreateFromCellListPetsc(MPI_Comm comm, PetscInt dim, PetscInt numCells, PetscInt numVertices, PetscInt numCorners, PetscBool interpolate, const PetscInt cells[], PetscInt spaceDim, const PetscReal vertexCoords[], DM *dm) 38289298eaa6SMatthew G Knepley { 38299298eaa6SMatthew G Knepley PetscErrorCode ierr; 38309298eaa6SMatthew G Knepley 38319298eaa6SMatthew G Knepley PetscFunctionBegin; 38325fd8819aSMatthew Knepley if (!dim) SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "This is not appropriate for 0-dimensional meshes. Consider either creating the DM using DMPlexCreateFromDAG(), by hand, or using DMSwarm."); 38339298eaa6SMatthew G Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 38349298eaa6SMatthew G Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 3835c73cfb54SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 38365e488331SVaclav Hapla ierr = DMPlexBuildFromCellList(*dm, numCells, numVertices, numCorners, cells);CHKERRQ(ierr); 38379298eaa6SMatthew G Knepley if (interpolate) { 38385fd9971aSMatthew G. Knepley DM idm; 38399298eaa6SMatthew G Knepley 38409298eaa6SMatthew G Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 38419298eaa6SMatthew G Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 38429298eaa6SMatthew G Knepley *dm = idm; 38439298eaa6SMatthew G Knepley } 38441edcf0b2SVaclav Hapla ierr = DMPlexBuildCoordinatesFromCellList(*dm, spaceDim, vertexCoords);CHKERRQ(ierr); 38459298eaa6SMatthew G Knepley PetscFunctionReturn(0); 38469298eaa6SMatthew G Knepley } 38479298eaa6SMatthew G Knepley 3848939f6067SMatthew G. Knepley /*@ 3849a4a685f2SJacob Faibussowitsch DMPlexCreateFromCellList - Deprecated, use DMPlexCreateFromCellListPetsc() 3850a4a685f2SJacob Faibussowitsch 3851a4a685f2SJacob Faibussowitsch Level: deprecated 3852a4a685f2SJacob Faibussowitsch 3853a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromCellListPetsc() 3854a4a685f2SJacob Faibussowitsch @*/ 3855a4a685f2SJacob Faibussowitsch PetscErrorCode DMPlexCreateFromCellList(MPI_Comm comm, PetscInt dim, PetscInt numCells, PetscInt numVertices, PetscInt numCorners, PetscBool interpolate, const int cells[], PetscInt spaceDim, const double vertexCoords[], DM *dm) 3856a4a685f2SJacob Faibussowitsch { 3857a4a685f2SJacob Faibussowitsch PetscErrorCode ierr; 3858a4a685f2SJacob Faibussowitsch PetscInt i; 3859a4a685f2SJacob Faibussowitsch PetscInt *pintCells; 3860a4a685f2SJacob Faibussowitsch PetscReal *prealVC; 3861a4a685f2SJacob Faibussowitsch 3862a4a685f2SJacob Faibussowitsch PetscFunctionBegin; 3863a4a685f2SJacob Faibussowitsch if (sizeof(int) > sizeof(PetscInt)) SETERRQ2(comm, PETSC_ERR_ARG_SIZ, "Size of int %zd greater than size of PetscInt %zd. Reconfigure PETSc --with-64-bit-indices=1", sizeof(int), sizeof(PetscInt)); 3864a4a685f2SJacob Faibussowitsch if (sizeof(int) == sizeof(PetscInt)) { 3865a4a685f2SJacob Faibussowitsch pintCells = (PetscInt *) cells; 3866a4a685f2SJacob Faibussowitsch } else { 3867a4a685f2SJacob Faibussowitsch ierr = PetscMalloc1(numCells*numCorners, &pintCells);CHKERRQ(ierr); 3868a4a685f2SJacob Faibussowitsch for (i = 0; i < numCells*numCorners; i++) { 3869a4a685f2SJacob Faibussowitsch pintCells[i] = (PetscInt) cells[i]; 3870a4a685f2SJacob Faibussowitsch } 3871a4a685f2SJacob Faibussowitsch } 3872a4a685f2SJacob Faibussowitsch if (sizeof(double) > sizeof(PetscReal)) SETERRQ2(comm, PETSC_ERR_ARG_SIZ, "Size of double %zd greater than size of PetscReal %zd. Reconfigure PETSc --with-precision=<higher precision>.", sizeof(double), sizeof(PetscReal)); 3873a4a685f2SJacob Faibussowitsch if (sizeof(double) == sizeof(PetscReal)) { 3874a4a685f2SJacob Faibussowitsch prealVC = (PetscReal *) vertexCoords; 3875a4a685f2SJacob Faibussowitsch } else { 3876a4a685f2SJacob Faibussowitsch ierr = PetscMalloc1(numVertices*spaceDim, &prealVC);CHKERRQ(ierr); 3877a4a685f2SJacob Faibussowitsch for (i = 0; i < numVertices*spaceDim; i++) { 3878a4a685f2SJacob Faibussowitsch prealVC[i] = (PetscReal) vertexCoords[i]; 3879a4a685f2SJacob Faibussowitsch } 3880a4a685f2SJacob Faibussowitsch } 3881a4a685f2SJacob Faibussowitsch ierr = DMPlexCreateFromCellListPetsc(comm, dim, numCells, numVertices, numCorners, interpolate, pintCells, spaceDim, prealVC, dm);CHKERRQ(ierr); 3882a4a685f2SJacob Faibussowitsch if (sizeof(int) != sizeof(PetscInt)) { 3883a4a685f2SJacob Faibussowitsch ierr = PetscFree(pintCells);CHKERRQ(ierr); 3884a4a685f2SJacob Faibussowitsch } 3885a4a685f2SJacob Faibussowitsch if (sizeof(double) != sizeof(PetscReal)) { 3886a4a685f2SJacob Faibussowitsch ierr = PetscFree(prealVC);CHKERRQ(ierr); 3887a4a685f2SJacob Faibussowitsch } 3888a4a685f2SJacob Faibussowitsch PetscFunctionReturn(0); 3889a4a685f2SJacob Faibussowitsch } 3890a4a685f2SJacob Faibussowitsch 3891a4a685f2SJacob Faibussowitsch /*@ 3892939f6067SMatthew G. Knepley DMPlexCreateFromDAG - This takes as input the adjacency-list representation of the Directed Acyclic Graph (Hasse Diagram) encoding a mesh, and produces a DM 3893939f6067SMatthew G. Knepley 3894939f6067SMatthew G. Knepley Input Parameters: 3895c73cfb54SMatthew G. Knepley + dm - The empty DM object, usually from DMCreate() and DMSetDimension() 3896939f6067SMatthew G. Knepley . depth - The depth of the DAG 3897367003a6SStefano Zampini . numPoints - Array of size depth + 1 containing the number of points at each depth 3898939f6067SMatthew G. Knepley . coneSize - The cone size of each point 3899939f6067SMatthew G. Knepley . cones - The concatenation of the cone points for each point, the cone list must be oriented correctly for each point 3900939f6067SMatthew G. Knepley . coneOrientations - The orientation of each cone point 3901367003a6SStefano Zampini - vertexCoords - An array of numPoints[0]*spacedim numbers representing the coordinates of each vertex, with spacedim the value set via DMSetCoordinateDim() 3902939f6067SMatthew G. Knepley 3903939f6067SMatthew G. Knepley Output Parameter: 3904939f6067SMatthew G. Knepley . dm - The DM 3905939f6067SMatthew G. Knepley 3906939f6067SMatthew G. Knepley Note: Two triangles sharing a face would have input 3907939f6067SMatthew G. Knepley $ depth = 1, numPoints = [4 2], coneSize = [3 3 0 0 0 0] 3908939f6067SMatthew G. Knepley $ cones = [2 3 4 3 5 4], coneOrientations = [0 0 0 0 0 0] 3909939f6067SMatthew G. Knepley $ vertexCoords = [-1.0 0.0 0.0 -1.0 0.0 1.0 1.0 0.0] 3910939f6067SMatthew G. Knepley $ 3911939f6067SMatthew G. Knepley which would result in the DMPlex 3912939f6067SMatthew G. Knepley $ 3913939f6067SMatthew G. Knepley $ 4 3914939f6067SMatthew G. Knepley $ / | \ 3915939f6067SMatthew G. Knepley $ / | \ 3916939f6067SMatthew G. Knepley $ / | \ 3917939f6067SMatthew G. Knepley $ 2 0 | 1 5 3918939f6067SMatthew G. Knepley $ \ | / 3919939f6067SMatthew G. Knepley $ \ | / 3920939f6067SMatthew G. Knepley $ \ | / 3921939f6067SMatthew G. Knepley $ 3 3922939f6067SMatthew G. Knepley $ 3923a4a685f2SJacob Faibussowitsch $ Notice that all points are numbered consecutively, unlike DMPlexCreateFromCellListPetsc() 3924939f6067SMatthew G. Knepley 3925939f6067SMatthew G. Knepley Level: advanced 3926939f6067SMatthew G. Knepley 3927a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromCellListPetsc(), DMPlexCreate() 3928939f6067SMatthew G. Knepley @*/ 39299298eaa6SMatthew G Knepley PetscErrorCode DMPlexCreateFromDAG(DM dm, PetscInt depth, const PetscInt numPoints[], const PetscInt coneSize[], const PetscInt cones[], const PetscInt coneOrientations[], const PetscScalar vertexCoords[]) 39309298eaa6SMatthew G Knepley { 39319298eaa6SMatthew G Knepley Vec coordinates; 39329298eaa6SMatthew G Knepley PetscSection coordSection; 39339298eaa6SMatthew G Knepley PetscScalar *coords; 3934811e8653SToby Isaac PetscInt coordSize, firstVertex = -1, pStart = 0, pEnd = 0, p, v, dim, dimEmbed, d, off; 39359298eaa6SMatthew G Knepley PetscErrorCode ierr; 39369298eaa6SMatthew G Knepley 39379298eaa6SMatthew G Knepley PetscFunctionBegin; 3938c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 3939811e8653SToby Isaac ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr); 394089c010cfSBarry Smith if (dimEmbed < dim) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Embedding dimension %D cannot be less than intrinsic dimension %d",dimEmbed,dim); 39419298eaa6SMatthew G Knepley for (d = 0; d <= depth; ++d) pEnd += numPoints[d]; 39429298eaa6SMatthew G Knepley ierr = DMPlexSetChart(dm, pStart, pEnd);CHKERRQ(ierr); 39439298eaa6SMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 39449298eaa6SMatthew G Knepley ierr = DMPlexSetConeSize(dm, p, coneSize[p-pStart]);CHKERRQ(ierr); 394597e052ccSToby Isaac if (firstVertex < 0 && !coneSize[p - pStart]) { 394697e052ccSToby Isaac firstVertex = p - pStart; 39479298eaa6SMatthew G Knepley } 394897e052ccSToby Isaac } 394989c010cfSBarry Smith if (firstVertex < 0 && numPoints[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Expected %D vertices but could not find any", numPoints[0]); 39509298eaa6SMatthew G Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 39519298eaa6SMatthew G Knepley for (p = pStart, off = 0; p < pEnd; off += coneSize[p-pStart], ++p) { 39529298eaa6SMatthew G Knepley ierr = DMPlexSetCone(dm, p, &cones[off]);CHKERRQ(ierr); 39539298eaa6SMatthew G Knepley ierr = DMPlexSetConeOrientation(dm, p, &coneOrientations[off]);CHKERRQ(ierr); 39549298eaa6SMatthew G Knepley } 39559298eaa6SMatthew G Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 39569298eaa6SMatthew G Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 39579298eaa6SMatthew G Knepley /* Build coordinates */ 3958c2166f76SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 39599298eaa6SMatthew G Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 3960811e8653SToby Isaac ierr = PetscSectionSetFieldComponents(coordSection, 0, dimEmbed);CHKERRQ(ierr); 39619298eaa6SMatthew G Knepley ierr = PetscSectionSetChart(coordSection, firstVertex, firstVertex+numPoints[0]);CHKERRQ(ierr); 39629298eaa6SMatthew G Knepley for (v = firstVertex; v < firstVertex+numPoints[0]; ++v) { 3963811e8653SToby Isaac ierr = PetscSectionSetDof(coordSection, v, dimEmbed);CHKERRQ(ierr); 3964811e8653SToby Isaac ierr = PetscSectionSetFieldDof(coordSection, v, 0, dimEmbed);CHKERRQ(ierr); 39659298eaa6SMatthew G Knepley } 39669298eaa6SMatthew G Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 39679298eaa6SMatthew G Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 39688b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 39696f8cbbeeSMatthew G Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 39709298eaa6SMatthew G Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 39718b9ced59SLisandro Dalcin ierr = VecSetBlockSize(coordinates, dimEmbed);CHKERRQ(ierr); 39722eb5907fSJed Brown ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 39739318fe57SMatthew G. Knepley if (vertexCoords) { 39749298eaa6SMatthew G Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 39759298eaa6SMatthew G Knepley for (v = 0; v < numPoints[0]; ++v) { 39769298eaa6SMatthew G Knepley PetscInt off; 39779298eaa6SMatthew G Knepley 39789298eaa6SMatthew G Knepley ierr = PetscSectionGetOffset(coordSection, v+firstVertex, &off);CHKERRQ(ierr); 3979811e8653SToby Isaac for (d = 0; d < dimEmbed; ++d) { 3980811e8653SToby Isaac coords[off+d] = vertexCoords[v*dimEmbed+d]; 39819298eaa6SMatthew G Knepley } 39829298eaa6SMatthew G Knepley } 39839318fe57SMatthew G. Knepley } 39849298eaa6SMatthew G Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 39859298eaa6SMatthew G Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 39869298eaa6SMatthew G Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 39879298eaa6SMatthew G Knepley PetscFunctionReturn(0); 39889298eaa6SMatthew G Knepley } 39898415267dSToby Isaac 3990ca522641SMatthew G. Knepley /*@C 39918ca92349SMatthew G. Knepley DMPlexCreateCellVertexFromFile - Create a DMPlex mesh from a simple cell-vertex file. 39928ca92349SMatthew G. Knepley 39938ca92349SMatthew G. Knepley + comm - The MPI communicator 39948ca92349SMatthew G. Knepley . filename - Name of the .dat file 39958ca92349SMatthew G. Knepley - interpolate - Create faces and edges in the mesh 39968ca92349SMatthew G. Knepley 39978ca92349SMatthew G. Knepley Output Parameter: 39988ca92349SMatthew G. Knepley . dm - The DM object representing the mesh 39998ca92349SMatthew G. Knepley 40008ca92349SMatthew G. Knepley Note: The format is the simplest possible: 40018ca92349SMatthew G. Knepley $ Ne 40028ca92349SMatthew G. Knepley $ v0 v1 ... vk 40038ca92349SMatthew G. Knepley $ Nv 40048ca92349SMatthew G. Knepley $ x y z marker 40058ca92349SMatthew G. Knepley 40068ca92349SMatthew G. Knepley Level: beginner 40078ca92349SMatthew G. Knepley 40088ca92349SMatthew G. Knepley .seealso: DMPlexCreateFromFile(), DMPlexCreateMedFromFile(), DMPlexCreateGmsh(), DMPlexCreate() 40098ca92349SMatthew G. Knepley @*/ 40108ca92349SMatthew G. Knepley PetscErrorCode DMPlexCreateCellVertexFromFile(MPI_Comm comm, const char filename[], PetscBool interpolate, DM *dm) 40118ca92349SMatthew G. Knepley { 40128ca92349SMatthew G. Knepley DMLabel marker; 40138ca92349SMatthew G. Knepley PetscViewer viewer; 40148ca92349SMatthew G. Knepley Vec coordinates; 40158ca92349SMatthew G. Knepley PetscSection coordSection; 40168ca92349SMatthew G. Knepley PetscScalar *coords; 40178ca92349SMatthew G. Knepley char line[PETSC_MAX_PATH_LEN]; 40188ca92349SMatthew G. Knepley PetscInt dim = 3, cdim = 3, coordSize, v, c, d; 40198ca92349SMatthew G. Knepley PetscMPIInt rank; 40208ca92349SMatthew G. Knepley int snum, Nv, Nc; 40218ca92349SMatthew G. Knepley PetscErrorCode ierr; 40228ca92349SMatthew G. Knepley 40238ca92349SMatthew G. Knepley PetscFunctionBegin; 4024ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 40258ca92349SMatthew G. Knepley ierr = PetscViewerCreate(comm, &viewer);CHKERRQ(ierr); 40268ca92349SMatthew G. Knepley ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr); 40278ca92349SMatthew G. Knepley ierr = PetscViewerFileSetMode(viewer, FILE_MODE_READ);CHKERRQ(ierr); 40288ca92349SMatthew G. Knepley ierr = PetscViewerFileSetName(viewer, filename);CHKERRQ(ierr); 40298ca92349SMatthew G. Knepley if (!rank) { 40308ca92349SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 2, NULL, PETSC_STRING);CHKERRQ(ierr); 40318ca92349SMatthew G. Knepley snum = sscanf(line, "%d %d", &Nc, &Nv); 40328ca92349SMatthew G. Knepley if (snum != 2) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 403325ce1634SJed Brown } else { 403425ce1634SJed Brown Nc = Nv = 0; 40358ca92349SMatthew G. Knepley } 40368ca92349SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 40378ca92349SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 40388ca92349SMatthew G. Knepley ierr = DMPlexSetChart(*dm, 0, Nc+Nv);CHKERRQ(ierr); 40398ca92349SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 40408ca92349SMatthew G. Knepley ierr = DMSetCoordinateDim(*dm, cdim);CHKERRQ(ierr); 40418ca92349SMatthew G. Knepley /* Read topology */ 40428ca92349SMatthew G. Knepley if (!rank) { 40438ca92349SMatthew G. Knepley PetscInt cone[8], corners = 8; 40448ca92349SMatthew G. Knepley int vbuf[8], v; 40458ca92349SMatthew G. Knepley 40468ca92349SMatthew G. Knepley for (c = 0; c < Nc; ++c) {ierr = DMPlexSetConeSize(*dm, c, corners);CHKERRQ(ierr);} 40478ca92349SMatthew G. Knepley ierr = DMSetUp(*dm);CHKERRQ(ierr); 40488ca92349SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 40498ca92349SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, corners, NULL, PETSC_STRING);CHKERRQ(ierr); 40508ca92349SMatthew G. Knepley snum = sscanf(line, "%d %d %d %d %d %d %d %d", &vbuf[0], &vbuf[1], &vbuf[2], &vbuf[3], &vbuf[4], &vbuf[5], &vbuf[6], &vbuf[7]); 40518ca92349SMatthew G. Knepley if (snum != corners) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 40528ca92349SMatthew G. Knepley for (v = 0; v < corners; ++v) cone[v] = vbuf[v] + Nc; 40538ca92349SMatthew G. Knepley /* Hexahedra are inverted */ 40548ca92349SMatthew G. Knepley { 40558ca92349SMatthew G. Knepley PetscInt tmp = cone[1]; 40568ca92349SMatthew G. Knepley cone[1] = cone[3]; 40578ca92349SMatthew G. Knepley cone[3] = tmp; 40588ca92349SMatthew G. Knepley } 40598ca92349SMatthew G. Knepley ierr = DMPlexSetCone(*dm, c, cone);CHKERRQ(ierr); 40608ca92349SMatthew G. Knepley } 40618ca92349SMatthew G. Knepley } 40628ca92349SMatthew G. Knepley ierr = DMPlexSymmetrize(*dm);CHKERRQ(ierr); 40638ca92349SMatthew G. Knepley ierr = DMPlexStratify(*dm);CHKERRQ(ierr); 40648ca92349SMatthew G. Knepley /* Read coordinates */ 40658ca92349SMatthew G. Knepley ierr = DMGetCoordinateSection(*dm, &coordSection);CHKERRQ(ierr); 40668ca92349SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 40678ca92349SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, cdim);CHKERRQ(ierr); 40688ca92349SMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, Nc, Nc + Nv);CHKERRQ(ierr); 40698ca92349SMatthew G. Knepley for (v = Nc; v < Nc+Nv; ++v) { 40708ca92349SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, cdim);CHKERRQ(ierr); 40718ca92349SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, cdim);CHKERRQ(ierr); 40728ca92349SMatthew G. Knepley } 40738ca92349SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 40748ca92349SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 40758ca92349SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 40768ca92349SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 40778ca92349SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 40788ca92349SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, cdim);CHKERRQ(ierr); 40798ca92349SMatthew G. Knepley ierr = VecSetType(coordinates, VECSTANDARD);CHKERRQ(ierr); 40808ca92349SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 40818ca92349SMatthew G. Knepley if (!rank) { 40828ca92349SMatthew G. Knepley double x[3]; 40838ca92349SMatthew G. Knepley int val; 40848ca92349SMatthew G. Knepley 40858ca92349SMatthew G. Knepley ierr = DMCreateLabel(*dm, "marker");CHKERRQ(ierr); 40868ca92349SMatthew G. Knepley ierr = DMGetLabel(*dm, "marker", &marker);CHKERRQ(ierr); 40878ca92349SMatthew G. Knepley for (v = 0; v < Nv; ++v) { 40888ca92349SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 4, NULL, PETSC_STRING);CHKERRQ(ierr); 40898ca92349SMatthew G. Knepley snum = sscanf(line, "%lg %lg %lg %d", &x[0], &x[1], &x[2], &val); 40908ca92349SMatthew G. Knepley if (snum != 4) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 40918ca92349SMatthew G. Knepley for (d = 0; d < cdim; ++d) coords[v*cdim+d] = x[d]; 40928ca92349SMatthew G. Knepley if (val) {ierr = DMLabelSetValue(marker, v+Nc, val);CHKERRQ(ierr);} 40938ca92349SMatthew G. Knepley } 40948ca92349SMatthew G. Knepley } 40958ca92349SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 40968ca92349SMatthew G. Knepley ierr = DMSetCoordinatesLocal(*dm, coordinates);CHKERRQ(ierr); 40978ca92349SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 40988ca92349SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 40998ca92349SMatthew G. Knepley if (interpolate) { 41008ca92349SMatthew G. Knepley DM idm; 41018ca92349SMatthew G. Knepley DMLabel bdlabel; 41028ca92349SMatthew G. Knepley 41038ca92349SMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 41048ca92349SMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 41058ca92349SMatthew G. Knepley *dm = idm; 41068ca92349SMatthew G. Knepley 41078ca92349SMatthew G. Knepley ierr = DMGetLabel(*dm, "marker", &bdlabel);CHKERRQ(ierr); 41088ca92349SMatthew G. Knepley ierr = DMPlexMarkBoundaryFaces(*dm, PETSC_DETERMINE, bdlabel);CHKERRQ(ierr); 41098ca92349SMatthew G. Knepley ierr = DMPlexLabelComplete(*dm, bdlabel);CHKERRQ(ierr); 41108ca92349SMatthew G. Knepley } 41118ca92349SMatthew G. Knepley PetscFunctionReturn(0); 41128ca92349SMatthew G. Knepley } 41138ca92349SMatthew G. Knepley 41148ca92349SMatthew G. Knepley /*@C 4115ca522641SMatthew G. Knepley DMPlexCreateFromFile - This takes a filename and produces a DM 4116ca522641SMatthew G. Knepley 4117ca522641SMatthew G. Knepley Input Parameters: 4118ca522641SMatthew G. Knepley + comm - The communicator 4119ca522641SMatthew G. Knepley . filename - A file name 4120ca522641SMatthew G. Knepley - interpolate - Flag to create intermediate mesh pieces (edges, faces) 4121ca522641SMatthew G. Knepley 4122ca522641SMatthew G. Knepley Output Parameter: 4123ca522641SMatthew G. Knepley . dm - The DM 4124ca522641SMatthew G. Knepley 412502ef0d99SVaclav Hapla Options Database Keys: 412602ef0d99SVaclav Hapla . -dm_plex_create_from_hdf5_xdmf - use the PETSC_VIEWER_HDF5_XDMF format for reading HDF5 412702ef0d99SVaclav Hapla 4128bca97951SVaclav Hapla Use -dm_plex_create_ prefix to pass options to the internal PetscViewer, e.g. 4129bca97951SVaclav Hapla $ -dm_plex_create_viewer_hdf5_collective 4130bca97951SVaclav Hapla 4131ca522641SMatthew G. Knepley Level: beginner 4132ca522641SMatthew G. Knepley 4133a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromDAG(), DMPlexCreateFromCellListPetsc(), DMPlexCreate() 4134ca522641SMatthew G. Knepley @*/ 4135ca522641SMatthew G. Knepley PetscErrorCode DMPlexCreateFromFile(MPI_Comm comm, const char filename[], PetscBool interpolate, DM *dm) 4136ca522641SMatthew G. Knepley { 4137ca522641SMatthew G. Knepley const char *extGmsh = ".msh"; 4138de78e4feSLisandro Dalcin const char *extGmsh2 = ".msh2"; 4139de78e4feSLisandro Dalcin const char *extGmsh4 = ".msh4"; 4140ca522641SMatthew G. Knepley const char *extCGNS = ".cgns"; 4141ca522641SMatthew G. Knepley const char *extExodus = ".exo"; 414290c68965SMatthew G. Knepley const char *extGenesis = ".gen"; 41432f0bd6dcSMichael Lange const char *extFluent = ".cas"; 4144cc2f8f65SMatthew G. Knepley const char *extHDF5 = ".h5"; 4145707dd687SMichael Lange const char *extMed = ".med"; 4146f2801cd6SMatthew G. Knepley const char *extPLY = ".ply"; 4147c1cad2e7SMatthew G. Knepley const char *extEGADSLite = ".egadslite"; 4148c1cad2e7SMatthew G. Knepley const char *extEGADS = ".egads"; 4149c1cad2e7SMatthew G. Knepley const char *extIGES = ".igs"; 4150c1cad2e7SMatthew G. Knepley const char *extSTEP = ".stp"; 41518ca92349SMatthew G. Knepley const char *extCV = ".dat"; 4152ca522641SMatthew G. Knepley size_t len; 4153c1cad2e7SMatthew G. Knepley PetscBool isGmsh, isGmsh2, isGmsh4, isCGNS, isExodus, isGenesis, isFluent, isHDF5, isMed, isPLY, isEGADSLite, isEGADS, isIGES, isSTEP, isCV; 4154ca522641SMatthew G. Knepley PetscMPIInt rank; 4155ca522641SMatthew G. Knepley PetscErrorCode ierr; 4156ca522641SMatthew G. Knepley 4157ca522641SMatthew G. Knepley PetscFunctionBegin; 41585d80c0bfSVaclav Hapla PetscValidCharPointer(filename, 2); 4159ca522641SMatthew G. Knepley PetscValidPointer(dm, 4); 4160f1f45c63SVaclav Hapla ierr = DMInitializePackage();CHKERRQ(ierr); 4161f1f45c63SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_CreateFromFile,0,0,0,0);CHKERRQ(ierr); 4162ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 4163ca522641SMatthew G. Knepley ierr = PetscStrlen(filename, &len);CHKERRQ(ierr); 4164ca522641SMatthew G. Knepley if (!len) SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Filename must be a valid path"); 4165ca522641SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extGmsh, 4, &isGmsh);CHKERRQ(ierr); 4166de78e4feSLisandro Dalcin ierr = PetscStrncmp(&filename[PetscMax(0,len-5)], extGmsh2, 5, &isGmsh2);CHKERRQ(ierr); 4167de78e4feSLisandro Dalcin ierr = PetscStrncmp(&filename[PetscMax(0,len-5)], extGmsh4, 5, &isGmsh4);CHKERRQ(ierr); 4168ca522641SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-5)], extCGNS, 5, &isCGNS);CHKERRQ(ierr); 4169ca522641SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extExodus, 4, &isExodus);CHKERRQ(ierr); 417090c68965SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extGenesis, 4, &isGenesis);CHKERRQ(ierr); 41712f0bd6dcSMichael Lange ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extFluent, 4, &isFluent);CHKERRQ(ierr); 4172cc2f8f65SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-3)], extHDF5, 3, &isHDF5);CHKERRQ(ierr); 4173707dd687SMichael Lange ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extMed, 4, &isMed);CHKERRQ(ierr); 4174f2801cd6SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extPLY, 4, &isPLY);CHKERRQ(ierr); 4175c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-10)], extEGADSLite, 10, &isEGADSLite);CHKERRQ(ierr); 4176c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-6)], extEGADS, 6, &isEGADS);CHKERRQ(ierr); 4177c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extIGES, 4, &isIGES);CHKERRQ(ierr); 4178c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extSTEP, 4, &isSTEP);CHKERRQ(ierr); 41798ca92349SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extCV, 4, &isCV);CHKERRQ(ierr); 4180de78e4feSLisandro Dalcin if (isGmsh || isGmsh2 || isGmsh4) { 41817d282ae0SMichael Lange ierr = DMPlexCreateGmshFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4182ca522641SMatthew G. Knepley } else if (isCGNS) { 4183ca522641SMatthew G. Knepley ierr = DMPlexCreateCGNSFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 418490c68965SMatthew G. Knepley } else if (isExodus || isGenesis) { 4185ca522641SMatthew G. Knepley ierr = DMPlexCreateExodusFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 41862f0bd6dcSMichael Lange } else if (isFluent) { 41872f0bd6dcSMichael Lange ierr = DMPlexCreateFluentFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4188cc2f8f65SMatthew G. Knepley } else if (isHDF5) { 41899c48423bSVaclav Hapla PetscBool load_hdf5_xdmf = PETSC_FALSE; 4190cc2f8f65SMatthew G. Knepley PetscViewer viewer; 4191cc2f8f65SMatthew G. Knepley 419243b242b4SVaclav Hapla /* PETSC_VIEWER_HDF5_XDMF is used if the filename ends with .xdmf.h5, or if -dm_plex_create_from_hdf5_xdmf option is present */ 419343b242b4SVaclav Hapla ierr = PetscStrncmp(&filename[PetscMax(0,len-8)], ".xdmf", 5, &load_hdf5_xdmf);CHKERRQ(ierr); 41949c48423bSVaclav Hapla ierr = PetscOptionsGetBool(NULL, NULL, "-dm_plex_create_from_hdf5_xdmf", &load_hdf5_xdmf, NULL);CHKERRQ(ierr); 4195cc2f8f65SMatthew G. Knepley ierr = PetscViewerCreate(comm, &viewer);CHKERRQ(ierr); 4196cc2f8f65SMatthew G. Knepley ierr = PetscViewerSetType(viewer, PETSCVIEWERHDF5);CHKERRQ(ierr); 4197bca97951SVaclav Hapla ierr = PetscViewerSetOptionsPrefix(viewer, "dm_plex_create_");CHKERRQ(ierr); 4198bca97951SVaclav Hapla ierr = PetscViewerSetFromOptions(viewer);CHKERRQ(ierr); 4199cc2f8f65SMatthew G. Knepley ierr = PetscViewerFileSetMode(viewer, FILE_MODE_READ);CHKERRQ(ierr); 4200cc2f8f65SMatthew G. Knepley ierr = PetscViewerFileSetName(viewer, filename);CHKERRQ(ierr); 4201cc2f8f65SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 4202cc2f8f65SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 42039c48423bSVaclav Hapla if (load_hdf5_xdmf) {ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_HDF5_XDMF);CHKERRQ(ierr);} 4204cc2f8f65SMatthew G. Knepley ierr = DMLoad(*dm, viewer);CHKERRQ(ierr); 42059c48423bSVaclav Hapla if (load_hdf5_xdmf) {ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);} 4206cc2f8f65SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 42075fd9971aSMatthew G. Knepley 42085fd9971aSMatthew G. Knepley if (interpolate) { 42095fd9971aSMatthew G. Knepley DM idm; 42105fd9971aSMatthew G. Knepley 42115fd9971aSMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 42125fd9971aSMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 42135fd9971aSMatthew G. Knepley *dm = idm; 42145fd9971aSMatthew G. Knepley } 4215707dd687SMichael Lange } else if (isMed) { 4216707dd687SMichael Lange ierr = DMPlexCreateMedFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4217f2801cd6SMatthew G. Knepley } else if (isPLY) { 4218f2801cd6SMatthew G. Knepley ierr = DMPlexCreatePLYFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4219c1cad2e7SMatthew G. Knepley } else if (isEGADSLite || isEGADS || isIGES || isSTEP) { 4220c1cad2e7SMatthew G. Knepley if (isEGADSLite) {ierr = DMPlexCreateEGADSLiteFromFile(comm, filename, dm);CHKERRQ(ierr);} 4221c1cad2e7SMatthew G. Knepley else {ierr = DMPlexCreateEGADSFromFile(comm, filename, dm);CHKERRQ(ierr);} 42227bee2925SMatthew Knepley if (!interpolate) { 42237bee2925SMatthew Knepley DM udm; 42247bee2925SMatthew Knepley 42257bee2925SMatthew Knepley ierr = DMPlexUninterpolate(*dm, &udm);CHKERRQ(ierr); 42267bee2925SMatthew Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 42277bee2925SMatthew Knepley *dm = udm; 42287bee2925SMatthew Knepley } 42298ca92349SMatthew G. Knepley } else if (isCV) { 42308ca92349SMatthew G. Knepley ierr = DMPlexCreateCellVertexFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4231ca522641SMatthew G. Knepley } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot load file %s: unrecognized extension", filename); 4232f1f45c63SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_CreateFromFile,0,0,0,0);CHKERRQ(ierr); 4233ca522641SMatthew G. Knepley PetscFunctionReturn(0); 4234ca522641SMatthew G. Knepley } 4235