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 */ 856b5a892a1SMatthew G. Knepley PetscInt ornt[6] = {-2, 0, 0, -3, 0, -2}; /* ??? */ 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; 878b5a892a1SMatthew G. Knepley PetscInt ornt[4] = {0, 0, -1, -1}; 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; 909b5a892a1SMatthew G. Knepley PetscInt ornt[4] = {0, 0, -1, -1}; 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; 940b5a892a1SMatthew G. Knepley PetscInt ornt[4] = {0, 0, -1, -1}; 9413dfda0b1SToby Isaac PetscInt cone[4]; 9423dfda0b1SToby Isaac 9433dfda0b1SToby Isaac if (dim == 2) { 944b5a892a1SMatthew G. Knepley if (bdX == DM_BOUNDARY_TWIST && fx == numXEdges-1) {edgeR += numYEdges-1-2*fy; ornt[1] = -1;} 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); 2151b5a892a1SMatthew G. Knepley ornt[0] = 0; ornt[1] = 0; ornt[2] = -1; 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); 2156b5a892a1SMatthew G. Knepley ornt[0] = 0; ornt[1] = 0; ornt[2] = -1; 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); 2161b5a892a1SMatthew G. Knepley ornt[0] = -1; ornt[1] = -1; ornt[2] = 0; ornt[3] = -1; 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); 2166b5a892a1SMatthew G. Knepley ornt[0] = -1; ornt[1] = -1; ornt[2] = -1; 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); 2171b5a892a1SMatthew G. Knepley ornt[0] = -1; ornt[1] = -1; ornt[2] = -1; ornt[3] = -1; 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; 2504b5a892a1SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 2505b5a892a1SMatthew G. Knepley { 2506b5a892a1SMatthew G. Knepley PetscInt numPoints[2] = {2, 1}; 2507b5a892a1SMatthew G. Knepley PetscInt coneSize[3] = {2, 0, 0}; 2508b5a892a1SMatthew G. Knepley PetscInt cones[2] = {1, 2}; 2509b5a892a1SMatthew G. Knepley PetscInt coneOrientations[2] = {0, 0}; 2510b5a892a1SMatthew G. Knepley PetscScalar vertexCoords[2] = {-1.0, 1.0}; 2511b5a892a1SMatthew G. Knepley 2512b5a892a1SMatthew G. Knepley ierr = DMSetDimension(rdm, 1);CHKERRQ(ierr); 2513b5a892a1SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 2514b5a892a1SMatthew G. Knepley } 2515b5a892a1SMatthew G. Knepley break; 25169318fe57SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 25179318fe57SMatthew G. Knepley { 25189318fe57SMatthew G. Knepley PetscInt numPoints[2] = {3, 1}; 25199318fe57SMatthew G. Knepley PetscInt coneSize[4] = {3, 0, 0, 0}; 25209318fe57SMatthew G. Knepley PetscInt cones[3] = {1, 2, 3}; 25219318fe57SMatthew G. Knepley PetscInt coneOrientations[3] = {0, 0, 0}; 25229318fe57SMatthew G. Knepley PetscScalar vertexCoords[6] = {-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_QUADRILATERAL: 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_SEG_PRISM_TENSOR: 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, 2, 3, 4}; 25459318fe57SMatthew G. Knepley PetscInt coneOrientations[4] = {0, 0, 0, 0}; 25469318fe57SMatthew G. Knepley PetscScalar vertexCoords[8] = {-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, 2);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_TETRAHEDRON: 25539318fe57SMatthew G. Knepley { 25549318fe57SMatthew G. Knepley PetscInt numPoints[2] = {4, 1}; 25559318fe57SMatthew G. Knepley PetscInt coneSize[5] = {4, 0, 0, 0, 0}; 2556f0edb160SMatthew G. Knepley PetscInt cones[4] = {1, 2, 3, 4}; 25579318fe57SMatthew G. Knepley PetscInt coneOrientations[4] = {0, 0, 0, 0}; 2558f0edb160SMatthew 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}; 25599318fe57SMatthew G. Knepley 25609318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 25619318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 25629318fe57SMatthew G. Knepley } 25639318fe57SMatthew G. Knepley break; 25649318fe57SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 25659318fe57SMatthew G. Knepley { 25669318fe57SMatthew G. Knepley PetscInt numPoints[2] = {8, 1}; 25679318fe57SMatthew G. Knepley PetscInt coneSize[9] = {8, 0, 0, 0, 0, 0, 0, 0, 0}; 2568f0edb160SMatthew G. Knepley PetscInt cones[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 25699318fe57SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 2570f0edb160SMatthew 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, 25719318fe57SMatthew 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}; 25729318fe57SMatthew G. Knepley 25739318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 25749318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 25759318fe57SMatthew G. Knepley } 25769318fe57SMatthew G. Knepley break; 25779318fe57SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 25789318fe57SMatthew G. Knepley { 25799318fe57SMatthew G. Knepley PetscInt numPoints[2] = {6, 1}; 25809318fe57SMatthew G. Knepley PetscInt coneSize[7] = {6, 0, 0, 0, 0, 0, 0}; 2581f0edb160SMatthew G. Knepley PetscInt cones[6] = {1, 2, 3, 4, 5, 6}; 25829318fe57SMatthew G. Knepley PetscInt coneOrientations[6] = {0, 0, 0, 0, 0, 0}; 2583f0edb160SMatthew G. Knepley PetscScalar vertexCoords[18] = {-1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 25849318fe57SMatthew G. Knepley -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0}; 25859318fe57SMatthew G. Knepley 25869318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 25879318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 25889318fe57SMatthew G. Knepley } 25899318fe57SMatthew G. Knepley break; 25909318fe57SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 25919318fe57SMatthew G. Knepley { 25929318fe57SMatthew G. Knepley PetscInt numPoints[2] = {6, 1}; 25939318fe57SMatthew G. Knepley PetscInt coneSize[7] = {6, 0, 0, 0, 0, 0, 0}; 25949318fe57SMatthew G. Knepley PetscInt cones[6] = {1, 2, 3, 4, 5, 6}; 25959318fe57SMatthew G. Knepley PetscInt coneOrientations[6] = {0, 0, 0, 0, 0, 0}; 25969318fe57SMatthew G. Knepley PetscScalar vertexCoords[18] = {-1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 25979318fe57SMatthew G. Knepley -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0}; 25989318fe57SMatthew G. Knepley 25999318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 26009318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 26019318fe57SMatthew G. Knepley } 26029318fe57SMatthew G. Knepley break; 26039318fe57SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 26049318fe57SMatthew G. Knepley { 26059318fe57SMatthew G. Knepley PetscInt numPoints[2] = {8, 1}; 26069318fe57SMatthew G. Knepley PetscInt coneSize[9] = {8, 0, 0, 0, 0, 0, 0, 0, 0}; 26079318fe57SMatthew G. Knepley PetscInt cones[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 26089318fe57SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 26099318fe57SMatthew 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, 26109318fe57SMatthew 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}; 26119318fe57SMatthew G. Knepley 26129318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 26139318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 26149318fe57SMatthew G. Knepley } 26159318fe57SMatthew G. Knepley break; 26169318fe57SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 26179318fe57SMatthew G. Knepley { 26189318fe57SMatthew G. Knepley PetscInt numPoints[2] = {5, 1}; 26199318fe57SMatthew G. Knepley PetscInt coneSize[6] = {5, 0, 0, 0, 0, 0}; 2620f0edb160SMatthew G. Knepley PetscInt cones[5] = {1, 2, 3, 4, 5}; 26219318fe57SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 2622f0edb160SMatthew 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, 26239318fe57SMatthew G. Knepley 0.0, 0.0, 1.0}; 26249318fe57SMatthew G. Knepley 26259318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 26269318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 26279318fe57SMatthew G. Knepley } 26289318fe57SMatthew G. Knepley break; 26299318fe57SMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) rdm), PETSC_ERR_ARG_WRONG, "Cannot create reference cell for cell type %s", DMPolytopeTypes[ct]); 26309318fe57SMatthew G. Knepley } 26319318fe57SMatthew G. Knepley { 26329318fe57SMatthew G. Knepley PetscInt Nv, v; 26339318fe57SMatthew G. Knepley 26349318fe57SMatthew G. Knepley /* Must create the celltype label here so that we do not automatically try to compute the types */ 26359318fe57SMatthew G. Knepley ierr = DMCreateLabel(rdm, "celltype");CHKERRQ(ierr); 26369318fe57SMatthew G. Knepley ierr = DMPlexSetCellType(rdm, 0, ct);CHKERRQ(ierr); 26379318fe57SMatthew G. Knepley ierr = DMPlexGetChart(rdm, NULL, &Nv);CHKERRQ(ierr); 26389318fe57SMatthew G. Knepley for (v = 1; v < Nv; ++v) {ierr = DMPlexSetCellType(rdm, v, DM_POLYTOPE_POINT);CHKERRQ(ierr);} 26399318fe57SMatthew G. Knepley } 26409318fe57SMatthew G. Knepley ierr = DMPlexInterpolateInPlace_Internal(rdm);CHKERRQ(ierr); 2641b7f6ffafSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) rdm, DMPolytopeTypes[ct]);CHKERRQ(ierr); 26420a6ba040SMatthew G. Knepley PetscFunctionReturn(0); 26430a6ba040SMatthew G. Knepley } 26440a6ba040SMatthew G. Knepley 26459318fe57SMatthew G. Knepley /*@ 26469318fe57SMatthew G. Knepley DMPlexCreateReferenceCell - Create a DMPLEX with the appropriate FEM reference cell 26479318fe57SMatthew G. Knepley 26489318fe57SMatthew G. Knepley Collective 26499318fe57SMatthew G. Knepley 26509318fe57SMatthew G. Knepley Input Parameters: 26519318fe57SMatthew G. Knepley + comm - The communicator 26529318fe57SMatthew G. Knepley - ct - The cell type of the reference cell 26539318fe57SMatthew G. Knepley 26549318fe57SMatthew G. Knepley Output Parameter: 26559318fe57SMatthew G. Knepley . refdm - The reference cell 26569318fe57SMatthew G. Knepley 26579318fe57SMatthew G. Knepley Level: intermediate 26589318fe57SMatthew G. Knepley 26599318fe57SMatthew G. Knepley .seealso: DMPlexCreateReferenceCell(), DMPlexCreateBoxMesh() 26609318fe57SMatthew G. Knepley @*/ 26619318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateReferenceCell(MPI_Comm comm, DMPolytopeType ct, DM *refdm) 26620a6ba040SMatthew G. Knepley { 26630a6ba040SMatthew G. Knepley PetscErrorCode ierr; 26640a6ba040SMatthew G. Knepley 26650a6ba040SMatthew G. Knepley PetscFunctionBegin; 26669318fe57SMatthew G. Knepley ierr = DMCreate(comm, refdm);CHKERRQ(ierr); 26679318fe57SMatthew G. Knepley ierr = DMSetType(*refdm, DMPLEX);CHKERRQ(ierr); 26689318fe57SMatthew G. Knepley ierr = DMPlexCreateReferenceCell_Internal(*refdm, ct);CHKERRQ(ierr); 26699318fe57SMatthew G. Knepley PetscFunctionReturn(0); 26709318fe57SMatthew G. Knepley } 267179a015ccSMatthew G. Knepley 26729318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoundaryLabel_Private(DM dm, const char name[]) 26739318fe57SMatthew G. Knepley { 26749318fe57SMatthew G. Knepley DM plex; 26759318fe57SMatthew G. Knepley DMLabel label; 26769318fe57SMatthew G. Knepley PetscBool hasLabel; 26779318fe57SMatthew G. Knepley PetscErrorCode ierr; 26780a6ba040SMatthew G. Knepley 26799318fe57SMatthew G. Knepley PetscFunctionBeginUser; 26809318fe57SMatthew G. Knepley ierr = DMHasLabel(dm, name, &hasLabel);CHKERRQ(ierr); 26819318fe57SMatthew G. Knepley if (hasLabel) PetscFunctionReturn(0); 26829318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm, name);CHKERRQ(ierr); 26839318fe57SMatthew G. Knepley ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 26849318fe57SMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 26859318fe57SMatthew G. Knepley ierr = DMPlexMarkBoundaryFaces(plex, 1, label);CHKERRQ(ierr); 26869318fe57SMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 26879318fe57SMatthew G. Knepley PetscFunctionReturn(0); 26889318fe57SMatthew G. Knepley } 2689acdc6f61SToby Isaac 26909318fe57SMatthew G. Knepley const char * const DMPlexShapes[] = {"box", "box_surface", "ball", "sphere", "cylinder", "unknown", "DMPlexShape", "DM_SHAPE_", NULL}; 26919318fe57SMatthew G. Knepley 269261a622f3SMatthew G. Knepley static PetscErrorCode DMPlexCreateFromOptions_Internal(PetscOptionItems *PetscOptionsObject, PetscBool *useCoordSpace, DM dm) 26939318fe57SMatthew G. Knepley { 26949318fe57SMatthew G. Knepley DMPlexShape shape = DM_SHAPE_BOX; 26959318fe57SMatthew G. Knepley DMPolytopeType cell = DM_POLYTOPE_TRIANGLE; 26969318fe57SMatthew G. Knepley PetscInt dim = 2; 26979318fe57SMatthew G. Knepley PetscBool simplex = PETSC_TRUE, interpolate = PETSC_TRUE, adjCone = PETSC_FALSE, adjClosure = PETSC_TRUE, refDomain = PETSC_FALSE; 26989318fe57SMatthew G. Knepley PetscBool flg, flg2, fflg, bdfflg; 26999318fe57SMatthew G. Knepley MPI_Comm comm; 27009318fe57SMatthew G. Knepley char filename[PETSC_MAX_PATH_LEN], bdFilename[PETSC_MAX_PATH_LEN]; 27019318fe57SMatthew G. Knepley PetscErrorCode ierr; 27029318fe57SMatthew G. Knepley 27039318fe57SMatthew G. Knepley PetscFunctionBegin; 27049318fe57SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 27059318fe57SMatthew G. Knepley /* TODO Turn this into a registration interface */ 27069318fe57SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_filename", "File containing a mesh", "DMPlexCreateFromFile", filename, filename, sizeof(filename), &fflg);CHKERRQ(ierr); 27079318fe57SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_boundary_filename", "File containing a mesh boundary", "DMPlexCreateFromFile", bdFilename, bdFilename, sizeof(bdFilename), &bdfflg);CHKERRQ(ierr); 27089318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_cell", "Cell shape", "", DMPolytopeTypes, (PetscEnum) cell, (PetscEnum *) &cell, NULL);CHKERRQ(ierr); 27099318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_reference_cell_domain", "Use a reference cell domain", "", refDomain, &refDomain, NULL);CHKERRQ(ierr); 27109318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_shape", "Shape for built-in mesh", "", DMPlexShapes, (PetscEnum) shape, (PetscEnum *) &shape, &flg);CHKERRQ(ierr); 27119318fe57SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_plex_dim", "Topological dimension of the mesh", "DMGetDimension", dim, &dim, &flg, 0);CHKERRQ(ierr); 27129318fe57SMatthew G. Knepley if ((dim < 0) || (dim > 3)) SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Dimension %D should be in [1, 3]", dim); 27139318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_simplex", "Mesh cell shape", "", simplex, &simplex, &flg);CHKERRQ(ierr); 27149318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_interpolate", "Flag to create edges and faces automatically", "", interpolate, &interpolate, &flg);CHKERRQ(ierr); 27159318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_adj_cone", "Set adjacency direction", "DMSetBasicAdjacency", adjCone, &adjCone, &flg);CHKERRQ(ierr); 27169318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_adj_closure", "Set adjacency size", "DMSetBasicAdjacency", adjClosure, &adjClosure, &flg2);CHKERRQ(ierr); 27179318fe57SMatthew G. Knepley if (flg || flg2) {ierr = DMSetBasicAdjacency(dm, adjCone, adjClosure);CHKERRQ(ierr);} 27189318fe57SMatthew G. Knepley 271961a622f3SMatthew G. Knepley switch (cell) { 272061a622f3SMatthew G. Knepley case DM_POLYTOPE_POINT: 272161a622f3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 272261a622f3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 272361a622f3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 272461a622f3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 272561a622f3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 272661a622f3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 272761a622f3SMatthew G. Knepley *useCoordSpace = PETSC_TRUE;break; 272861a622f3SMatthew G. Knepley default: *useCoordSpace = PETSC_FALSE;break; 272961a622f3SMatthew G. Knepley } 273061a622f3SMatthew G. Knepley 27319318fe57SMatthew G. Knepley if (fflg) { 27329318fe57SMatthew G. Knepley DM dmnew; 27339318fe57SMatthew G. Knepley 27349318fe57SMatthew G. Knepley ierr = DMPlexCreateFromFile(PetscObjectComm((PetscObject) dm), filename, interpolate, &dmnew);CHKERRQ(ierr); 27359318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &dmnew);CHKERRQ(ierr); 27369318fe57SMatthew G. Knepley } else if (refDomain) { 27379318fe57SMatthew G. Knepley ierr = DMPlexCreateReferenceCell_Internal(dm, cell);CHKERRQ(ierr); 27389318fe57SMatthew G. Knepley } else if (bdfflg) { 27399318fe57SMatthew G. Knepley DM bdm, dmnew; 27409318fe57SMatthew G. Knepley 27419318fe57SMatthew G. Knepley ierr = DMPlexCreateFromFile(PetscObjectComm((PetscObject) dm), bdFilename, interpolate, &bdm);CHKERRQ(ierr); 27429318fe57SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) bdm, "bd_");CHKERRQ(ierr); 27439318fe57SMatthew G. Knepley ierr = DMSetFromOptions(bdm);CHKERRQ(ierr); 27449318fe57SMatthew G. Knepley ierr = DMPlexGenerate(bdm, NULL, interpolate, &dmnew);CHKERRQ(ierr); 27459318fe57SMatthew G. Knepley ierr = DMDestroy(&bdm);CHKERRQ(ierr); 27469318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &dmnew);CHKERRQ(ierr); 27479318fe57SMatthew G. Knepley } else { 27489318fe57SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) dm, DMPlexShapes[shape]);CHKERRQ(ierr); 27499318fe57SMatthew G. Knepley switch (shape) { 27509318fe57SMatthew G. Knepley case DM_SHAPE_BOX: 27519318fe57SMatthew G. Knepley { 27529318fe57SMatthew G. Knepley PetscInt faces[3] = {0, 0, 0}; 27539318fe57SMatthew G. Knepley PetscReal lower[3] = {0, 0, 0}; 27549318fe57SMatthew G. Knepley PetscReal upper[3] = {1, 1, 1}; 27559318fe57SMatthew G. Knepley DMBoundaryType bdt[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE}; 27569318fe57SMatthew G. Knepley PetscInt i, n; 27579318fe57SMatthew G. Knepley 27589318fe57SMatthew G. Knepley n = dim; 27599318fe57SMatthew G. Knepley for (i = 0; i < dim; ++i) faces[i] = (dim == 1 ? 1 : 4-dim); 27609318fe57SMatthew G. Knepley ierr = PetscOptionsIntArray("-dm_plex_box_faces", "Number of faces along each dimension", "", faces, &n, &flg);CHKERRQ(ierr); 27619318fe57SMatthew G. Knepley n = 3; 27629318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_lower", "Lower left corner of box", "", lower, &n, &flg);CHKERRQ(ierr); 27639318fe57SMatthew G. Knepley if (flg && (n != dim)) SETERRQ2(comm, PETSC_ERR_ARG_SIZ, "Lower box point had %D values, should have been %D", n, dim); 27649318fe57SMatthew G. Knepley n = 3; 27659318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_upper", "Upper right corner of box", "", upper, &n, &flg);CHKERRQ(ierr); 27669318fe57SMatthew G. Knepley if (flg && (n != dim)) SETERRQ2(comm, PETSC_ERR_ARG_SIZ, "Upper box point had %D values, should have been %D", n, dim); 27679318fe57SMatthew G. Knepley n = 3; 27689318fe57SMatthew G. Knepley ierr = PetscOptionsEnumArray("-dm_plex_box_bd", "Boundary type for each dimension", "", DMBoundaryTypes, (PetscEnum *) bdt, &n, &flg);CHKERRQ(ierr); 27699318fe57SMatthew G. Knepley if (flg && (n != dim)) SETERRQ2(comm, PETSC_ERR_ARG_SIZ, "Box boundary types had %D values, should have been %D", n, dim); 27709318fe57SMatthew G. Knepley switch (cell) { 277161a622f3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 27729318fe57SMatthew G. Knepley ierr = DMPlexCreateWedgeBoxMesh_Internal(dm, faces, lower, upper, bdt, PETSC_FALSE, interpolate);CHKERRQ(ierr); 27739318fe57SMatthew G. Knepley break; 27749318fe57SMatthew G. Knepley default: 27759318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxMesh_Internal(dm, dim, simplex, faces, lower, upper, bdt, interpolate);CHKERRQ(ierr); 27769318fe57SMatthew G. Knepley break; 27779318fe57SMatthew G. Knepley } 27789318fe57SMatthew G. Knepley } 27799318fe57SMatthew G. Knepley break; 27809318fe57SMatthew G. Knepley case DM_SHAPE_BOX_SURFACE: 27819318fe57SMatthew G. Knepley { 27829318fe57SMatthew G. Knepley PetscInt faces[3] = {0, 0, 0}; 27839318fe57SMatthew G. Knepley PetscReal lower[3] = {0, 0, 0}; 27849318fe57SMatthew G. Knepley PetscReal upper[3] = {1, 1, 1}; 27859318fe57SMatthew G. Knepley PetscInt i, n; 27869318fe57SMatthew G. Knepley 27879318fe57SMatthew G. Knepley n = dim+1; 27889318fe57SMatthew G. Knepley for (i = 0; i < dim+1; ++i) faces[i] = (dim+1 == 1 ? 1 : 4-(dim+1)); 27899318fe57SMatthew G. Knepley ierr = PetscOptionsIntArray("-dm_plex_box_faces", "Number of faces along each dimension", "", faces, &n, &flg);CHKERRQ(ierr); 27909318fe57SMatthew G. Knepley n = 3; 27919318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_lower", "Lower left corner of box", "", lower, &n, &flg);CHKERRQ(ierr); 27929318fe57SMatthew 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); 27939318fe57SMatthew G. Knepley n = 3; 27949318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_upper", "Upper right corner of box", "", upper, &n, &flg);CHKERRQ(ierr); 27959318fe57SMatthew 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); 27969318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxSurfaceMesh_Internal(dm, dim+1, faces, lower, upper, interpolate);CHKERRQ(ierr); 27979318fe57SMatthew G. Knepley } 27989318fe57SMatthew G. Knepley break; 27999318fe57SMatthew G. Knepley case DM_SHAPE_SPHERE: 28009318fe57SMatthew G. Knepley { 28019318fe57SMatthew G. Knepley PetscReal R = 1.0; 28029318fe57SMatthew G. Knepley 28039318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_sphere_radius", "Radius of the sphere", "", R, &R, &flg);CHKERRQ(ierr); 28049318fe57SMatthew G. Knepley ierr = DMPlexCreateSphereMesh_Internal(dm, dim, simplex, R);CHKERRQ(ierr); 28059318fe57SMatthew G. Knepley } 28069318fe57SMatthew G. Knepley break; 28079318fe57SMatthew G. Knepley case DM_SHAPE_BALL: 28089318fe57SMatthew G. Knepley { 28099318fe57SMatthew G. Knepley PetscReal R = 1.0; 28109318fe57SMatthew G. Knepley 28119318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_ball_radius", "Radius of the ball", "", R, &R, &flg);CHKERRQ(ierr); 28129318fe57SMatthew G. Knepley ierr = DMPlexCreateBallMesh_Internal(dm, dim, R);CHKERRQ(ierr); 28139318fe57SMatthew G. Knepley } 28149318fe57SMatthew G. Knepley break; 28159318fe57SMatthew G. Knepley case DM_SHAPE_CYLINDER: 28169318fe57SMatthew G. Knepley { 28179318fe57SMatthew G. Knepley DMBoundaryType bdt = DM_BOUNDARY_NONE; 28189318fe57SMatthew G. Knepley PetscInt Nw = 6; 28199318fe57SMatthew G. Knepley 28209318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_cylinder_bd", "Boundary type in the z direction", "", DMBoundaryTypes, (PetscEnum) bdt, (PetscEnum *) &bdt, NULL);CHKERRQ(ierr); 282161a622f3SMatthew G. Knepley ierr = PetscOptionsInt("-dm_plex_cylinder_num_wedges", "Number of wedges around the cylinder", "", Nw, &Nw, NULL);CHKERRQ(ierr); 28229318fe57SMatthew G. Knepley switch (cell) { 282361a622f3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 28249318fe57SMatthew G. Knepley ierr = DMPlexCreateWedgeCylinderMesh_Internal(dm, Nw, interpolate);CHKERRQ(ierr); 28259318fe57SMatthew G. Knepley break; 28269318fe57SMatthew G. Knepley default: 28279318fe57SMatthew G. Knepley ierr = DMPlexCreateHexCylinderMesh_Internal(dm, bdt);CHKERRQ(ierr); 28289318fe57SMatthew G. Knepley break; 28299318fe57SMatthew G. Knepley } 28309318fe57SMatthew G. Knepley } 28319318fe57SMatthew G. Knepley break; 28329318fe57SMatthew G. Knepley default: SETERRQ1(comm, PETSC_ERR_SUP, "Domain shape %s is unsupported", DMPlexShapes[shape]); 28339318fe57SMatthew G. Knepley } 28349318fe57SMatthew G. Knepley } 28359318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr); 28360a6ba040SMatthew G. Knepley PetscFunctionReturn(0); 28370a6ba040SMatthew G. Knepley } 28380a6ba040SMatthew G. Knepley 283947920aaeSMatthew G. Knepley PetscErrorCode DMSetFromOptions_NonRefinement_Plex(PetscOptionItems *PetscOptionsObject, DM dm) 28400a6ba040SMatthew G. Knepley { 28410a6ba040SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 2842c0f0dcc3SMatthew G. Knepley PetscBool flg; 28439318fe57SMatthew G. Knepley char bdLabel[PETSC_MAX_PATH_LEN]; 28440a6ba040SMatthew G. Knepley PetscErrorCode ierr; 28450a6ba040SMatthew G. Knepley 28460a6ba040SMatthew G. Knepley PetscFunctionBegin; 28470a6ba040SMatthew G. Knepley /* Handle viewing */ 28480c77aedcSMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_print_set_values", "Output all set values info", "DMPlexMatSetClosure", PETSC_FALSE, &mesh->printSetValues, NULL);CHKERRQ(ierr); 28495a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_plex_print_fem", "Debug output level all fem computations", "DMPlexSNESComputeResidualFEM", 0, &mesh->printFEM, NULL,0);CHKERRQ(ierr); 28500c77aedcSMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_print_tol", "Tolerance for FEM output", "DMPlexSNESComputeResidualFEM", mesh->printTol, &mesh->printTol, NULL);CHKERRQ(ierr); 28515a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_plex_print_l2", "Debug output level all L2 diff computations", "DMComputeL2Diff", 0, &mesh->printL2, NULL,0);CHKERRQ(ierr); 2852c0f0dcc3SMatthew G. Knepley ierr = DMMonitorSetFromOptions(dm, "-dm_plex_monitor_throughput", "Monitor the simulation throughput", "DMPlexMonitorThroughput", DMPlexMonitorThroughput, NULL, &flg);CHKERRQ(ierr); 2853c0f0dcc3SMatthew G. Knepley if (flg) {ierr = PetscLogDefaultBegin();CHKERRQ(ierr);} 28549318fe57SMatthew G. Knepley /* Labeling */ 28559318fe57SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_boundary_label", "Label to mark the mesh boundary", "", bdLabel, bdLabel, sizeof(bdLabel), &flg);CHKERRQ(ierr); 28569318fe57SMatthew G. Knepley if (flg) {ierr = DMPlexCreateBoundaryLabel_Private(dm, bdLabel);CHKERRQ(ierr);} 2857953fc75cSMatthew G. Knepley /* Point Location */ 28580c77aedcSMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_hash_location", "Use grid hashing for point location", "DMInterpolate", PETSC_FALSE, &mesh->useHashLocation, NULL);CHKERRQ(ierr); 28590848f4b5SMatthew G. Knepley /* Partitioning and distribution */ 286098ba2d7fSLawrence 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); 28612e62ab5aSMatthew G. Knepley /* Generation and remeshing */ 28620c77aedcSMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_remesh_bd", "Allow changes to the boundary on remeshing", "DMAdapt", PETSC_FALSE, &mesh->remeshBd, NULL);CHKERRQ(ierr); 2863b29cfa1cSToby Isaac /* Projection behavior */ 28645a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_plex_max_projection_height", "Maxmimum mesh point height used to project locally", "DMPlexSetMaxProjectionHeight", 0, &mesh->maxProjectionHeight, NULL,0);CHKERRQ(ierr); 286564141f95SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_regular_refinement", "Use special nested projection algorithm for regular refinement", "DMPlexSetRegularRefinement", mesh->regularRefinement, &mesh->regularRefinement, NULL);CHKERRQ(ierr); 28669318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_cell_refiner", "Strategy for cell refinment", "", DMPlexCellRefinerTypes, (PetscEnum) mesh->cellRefiner, (PetscEnum *) &mesh->cellRefiner, NULL);CHKERRQ(ierr); 2867f12cf164SMatthew G. Knepley /* Checking structure */ 2868f12cf164SMatthew G. Knepley { 2869e902f1eaSVaclav Hapla PetscBool flg = PETSC_FALSE, flg2 = PETSC_FALSE, all = PETSC_FALSE; 2870f12cf164SMatthew G. Knepley 2871e902f1eaSVaclav Hapla ierr = PetscOptionsBool("-dm_plex_check_all", "Perform all checks", NULL, PETSC_FALSE, &all, &flg2);CHKERRQ(ierr); 2872f12cf164SMatthew 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); 2873e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckSymmetry(dm);CHKERRQ(ierr);} 287425c50c26SVaclav 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); 2875e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckSkeleton(dm, 0);CHKERRQ(ierr);} 287625c50c26SVaclav 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); 2877e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckFaces(dm, 0);CHKERRQ(ierr);} 2878f12cf164SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_check_geometry", "Check that cells have positive volume", "DMPlexCheckGeometry", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 2879e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckGeometry(dm);CHKERRQ(ierr);} 288075ebff7aSVaclav Hapla ierr = PetscOptionsBool("-dm_plex_check_pointsf", "Check some necessary conditions for PointSF", "DMPlexCheckPointSF", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 2881e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckPointSF(dm);CHKERRQ(ierr);} 288275ebff7aSVaclav 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); 2883e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckInterfaceCones(dm);CHKERRQ(ierr);} 2884412e9a14SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_check_cell_shape", "Check cell shape", "DMPlexCheckCellShape", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 2885412e9a14SMatthew G. Knepley if (flg && flg2) {ierr = DMPlexCheckCellShape(dm, PETSC_TRUE, PETSC_DETERMINE);CHKERRQ(ierr);} 2886f12cf164SMatthew G. Knepley } 28879318fe57SMatthew G. Knepley { 28889318fe57SMatthew G. Knepley PetscReal scale = 1.0; 28894f3833eaSMatthew G. Knepley 28909318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_scale", "Scale factor for mesh coordinates", "DMPlexScale", scale, &scale, &flg);CHKERRQ(ierr); 28919318fe57SMatthew G. Knepley if (flg) { 28929318fe57SMatthew G. Knepley Vec coordinates, coordinatesLocal; 28939318fe57SMatthew G. Knepley 28949318fe57SMatthew G. Knepley ierr = DMGetCoordinates(dm, &coordinates);CHKERRQ(ierr); 28959318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinatesLocal);CHKERRQ(ierr); 28969318fe57SMatthew G. Knepley ierr = VecScale(coordinates, scale);CHKERRQ(ierr); 28979318fe57SMatthew G. Knepley ierr = VecScale(coordinatesLocal, scale);CHKERRQ(ierr); 28989318fe57SMatthew G. Knepley } 28999318fe57SMatthew G. Knepley } 29004f3833eaSMatthew G. Knepley ierr = PetscPartitionerSetFromOptions(mesh->partitioner);CHKERRQ(ierr); 290168d4fef7SMatthew G. Knepley PetscFunctionReturn(0); 290268d4fef7SMatthew G. Knepley } 290368d4fef7SMatthew G. Knepley 290446fa42a0SMatthew G. Knepley static PetscErrorCode DMSetFromOptions_Plex(PetscOptionItems *PetscOptionsObject,DM dm) 290568d4fef7SMatthew G. Knepley { 29069318fe57SMatthew G. Knepley PetscReal volume = -1.0, extThickness = 1.0; 29079318fe57SMatthew G. Knepley PetscInt prerefine = 0, refine = 0, r, coarsen = 0, overlap = 0, extLayers = 0, dim; 2908c1cad2e7SMatthew 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; 290968d4fef7SMatthew G. Knepley PetscErrorCode ierr; 291068d4fef7SMatthew G. Knepley 291168d4fef7SMatthew G. Knepley PetscFunctionBegin; 2912064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 29131a1499c8SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"DMPlex Options");CHKERRQ(ierr); 29149318fe57SMatthew G. Knepley /* Handle automatic creation */ 29159318fe57SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 291661a622f3SMatthew G. Knepley if (dim < 0) {ierr = DMPlexCreateFromOptions_Internal(PetscOptionsObject, &coordSpace, dm);CHKERRQ(ierr);created = PETSC_TRUE;} 2917*d89e6e46SMatthew G. Knepley /* Handle interpolation before distribution */ 2918*d89e6e46SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_interpolate_pre", "Flag to interpolate mesh before distribution", "", interpolate, &interpolate, &flg);CHKERRQ(ierr); 2919*d89e6e46SMatthew G. Knepley if (flg) { 2920*d89e6e46SMatthew G. Knepley DMPlexInterpolatedFlag interpolated; 2921*d89e6e46SMatthew G. Knepley 2922*d89e6e46SMatthew G. Knepley ierr = DMPlexIsInterpolated(dm, &interpolated);CHKERRQ(ierr); 2923*d89e6e46SMatthew G. Knepley if (interpolated == DMPLEX_INTERPOLATED_FULL && !interpolate) { 2924*d89e6e46SMatthew G. Knepley DM udm; 2925*d89e6e46SMatthew G. Knepley 2926*d89e6e46SMatthew G. Knepley ierr = DMPlexUninterpolate(dm, &udm);CHKERRQ(ierr); 2927*d89e6e46SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &udm);CHKERRQ(ierr); 2928*d89e6e46SMatthew G. Knepley } else if (interpolated != DMPLEX_INTERPOLATED_FULL && interpolate) { 2929*d89e6e46SMatthew G. Knepley DM idm; 2930*d89e6e46SMatthew G. Knepley 2931*d89e6e46SMatthew G. Knepley ierr = DMPlexInterpolate(dm, &idm);CHKERRQ(ierr); 2932*d89e6e46SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &idm);CHKERRQ(ierr); 2933*d89e6e46SMatthew G. Knepley } 2934*d89e6e46SMatthew G. Knepley } 29359b44eab4SMatthew G. Knepley /* Handle DMPlex refinement before distribution */ 2936c1cad2e7SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_ignore_model", "Flag to ignore the geometry model when refining", "DMCreate", ignoreModel, &ignoreModel, &flg);CHKERRQ(ierr); 2937c1cad2e7SMatthew G. Knepley if (flg) {((DM_Plex *) dm->data)->ignoreModel = ignoreModel;} 2938250712c9SMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &uniformOrig);CHKERRQ(ierr); 29399318fe57SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_refine_pre", "The number of refinements before distribution", "DMCreate", prerefine, &prerefine, NULL,0);CHKERRQ(ierr); 294061a622f3SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_remap_pre", "Flag to control coordinate remapping", "DMCreate", remap, &remap, NULL);CHKERRQ(ierr); 2941250712c9SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_uniform_pre", "Flag for uniform refinement before distribution", "DMCreate", uniform, &uniform, &flg);CHKERRQ(ierr); 2942250712c9SMatthew G. Knepley if (flg) {ierr = DMPlexSetRefinementUniform(dm, uniform);CHKERRQ(ierr);} 2943250712c9SMatthew G. Knepley ierr = PetscOptionsReal("-dm_refine_volume_limit_pre", "The maximum cell volume after refinement before distribution", "DMCreate", volume, &volume, &flg);CHKERRQ(ierr); 29449318fe57SMatthew G. Knepley if (flg) { 29459318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, PETSC_FALSE);CHKERRQ(ierr); 29469318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementLimit(dm, volume);CHKERRQ(ierr); 29479318fe57SMatthew G. Knepley prerefine = PetscMax(prerefine, 1); 29489318fe57SMatthew G. Knepley } 29499b44eab4SMatthew G. Knepley for (r = 0; r < prerefine; ++r) { 29509b44eab4SMatthew G. Knepley DM rdm; 29519b44eab4SMatthew G. Knepley PetscPointFunc coordFunc = ((DM_Plex*) dm->data)->coordFunc; 29529b44eab4SMatthew G. Knepley 29539b44eab4SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 29549b44eab4SMatthew G. Knepley ierr = DMRefine(dm, PetscObjectComm((PetscObject) dm), &rdm);CHKERRQ(ierr); 29559318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &rdm);CHKERRQ(ierr); 29569b44eab4SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 295761a622f3SMatthew G. Knepley if (coordFunc && remap) { 29589b44eab4SMatthew G. Knepley ierr = DMPlexRemapGeometry(dm, 0.0, coordFunc);CHKERRQ(ierr); 29599b44eab4SMatthew G. Knepley ((DM_Plex*) dm->data)->coordFunc = coordFunc; 29609b44eab4SMatthew G. Knepley } 29619b44eab4SMatthew G. Knepley } 2962250712c9SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, uniformOrig);CHKERRQ(ierr); 29639318fe57SMatthew G. Knepley /* Handle DMPlex extrusion before distribution */ 29649318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_interpolate", "Flag to create edges and faces automatically", "", interpolate, &interpolate, NULL);CHKERRQ(ierr); 29659318fe57SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_extrude_layers", "The number of layers to extrude", "", extLayers, &extLayers, NULL, 0);CHKERRQ(ierr); 29669318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_extrude_thickness", "The thickness of the layer to be extruded", "", extThickness, &extThickness, NULL);CHKERRQ(ierr); 29679318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_extrude_column_first", "Order the cells in a vertical column first", "", extColOrder, &extColOrder, NULL);CHKERRQ(ierr); 29689318fe57SMatthew G. Knepley if (extLayers) { 29699318fe57SMatthew G. Knepley DM edm; 29709318fe57SMatthew G. Knepley 29719318fe57SMatthew G. Knepley ierr = DMPlexExtrude(dm, extLayers, extThickness, extColOrder, NULL, interpolate, &edm);CHKERRQ(ierr); 29729318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &edm);CHKERRQ(ierr); 29739318fe57SMatthew G. Knepley } 29749b44eab4SMatthew G. Knepley /* Handle DMPlex distribution */ 29759b44eab4SMatthew G. Knepley ierr = PetscOptionsBool("-dm_distribute", "Flag to redistribute a mesh among processes", "DMCreate", distribute, &distribute, NULL);CHKERRQ(ierr); 29769b44eab4SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_distribute_overlap", "The size of the overlap halo", "DMCreate", overlap, &overlap, NULL, 0);CHKERRQ(ierr); 29779b44eab4SMatthew G. Knepley if (distribute) { 29789b44eab4SMatthew G. Knepley DM pdm = NULL; 29799b44eab4SMatthew G. Knepley PetscPartitioner part; 29809b44eab4SMatthew G. Knepley 29819b44eab4SMatthew G. Knepley ierr = DMPlexGetPartitioner(dm, &part);CHKERRQ(ierr); 29829b44eab4SMatthew G. Knepley ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); 29839b44eab4SMatthew G. Knepley ierr = DMPlexDistribute(dm, overlap, NULL, &pdm);CHKERRQ(ierr); 29849b44eab4SMatthew G. Knepley if (pdm) { 29859318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &pdm);CHKERRQ(ierr); 29869b44eab4SMatthew G. Knepley } 29879b44eab4SMatthew G. Knepley } 29889318fe57SMatthew G. Knepley /* Create coordinate space */ 29899318fe57SMatthew G. Knepley if (created) { 299061a622f3SMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) dm->data; 29919318fe57SMatthew G. Knepley PetscInt degree = 1; 299261a622f3SMatthew G. Knepley PetscBool periodic, flg; 29939318fe57SMatthew G. Knepley 299461a622f3SMatthew G. Knepley ierr = PetscOptionsBool("-dm_coord_space", "Use an FEM space for coordinates", "", coordSpace, &coordSpace, &flg);CHKERRQ(ierr); 29959318fe57SMatthew G. Knepley ierr = PetscOptionsInt("-dm_coord_petscspace_degree", "FEM degree for coordinate space", "", degree, °ree, NULL);CHKERRQ(ierr); 299661a622f3SMatthew G. Knepley if (coordSpace) {ierr = DMPlexCreateCoordinateSpace(dm, degree, mesh->coordFunc);CHKERRQ(ierr);} 299761a622f3SMatthew G. Knepley if (flg && !coordSpace) { 299861a622f3SMatthew G. Knepley DM cdm; 299961a622f3SMatthew G. Knepley PetscDS cds; 300061a622f3SMatthew G. Knepley PetscObject obj; 300161a622f3SMatthew G. Knepley PetscClassId id; 300261a622f3SMatthew G. Knepley 300361a622f3SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 300461a622f3SMatthew G. Knepley ierr = DMGetDS(cdm, &cds);CHKERRQ(ierr); 300561a622f3SMatthew G. Knepley ierr = PetscDSGetDiscretization(cds, 0, &obj);CHKERRQ(ierr); 300661a622f3SMatthew G. Knepley ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 300761a622f3SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 300861a622f3SMatthew G. Knepley PetscContainer dummy; 300961a622f3SMatthew G. Knepley 301061a622f3SMatthew G. Knepley ierr = PetscContainerCreate(PETSC_COMM_SELF, &dummy);CHKERRQ(ierr); 301161a622f3SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) dummy, "coordinates");CHKERRQ(ierr); 301261a622f3SMatthew G. Knepley ierr = DMSetField(cdm, 0, NULL, (PetscObject) dummy);CHKERRQ(ierr); 301361a622f3SMatthew G. Knepley ierr = PetscContainerDestroy(&dummy);CHKERRQ(ierr); 301461a622f3SMatthew G. Knepley ierr = DMClearDS(cdm);CHKERRQ(ierr); 301561a622f3SMatthew G. Knepley } 301661a622f3SMatthew G. Knepley mesh->coordFunc = NULL; 301761a622f3SMatthew G. Knepley } 30189318fe57SMatthew G. Knepley ierr = DMLocalizeCoordinates(dm);CHKERRQ(ierr); 301961a622f3SMatthew G. Knepley ierr = DMGetPeriodicity(dm, &periodic, NULL, NULL, NULL);CHKERRQ(ierr); 302061a622f3SMatthew G. Knepley if (periodic) {ierr = DMSetPeriodicity(dm, PETSC_TRUE, NULL, NULL, NULL);CHKERRQ(ierr);} 30219318fe57SMatthew G. Knepley } 302268d4fef7SMatthew G. Knepley /* Handle DMPlex refinement */ 302361a622f3SMatthew G. Knepley remap = PETSC_TRUE; 30245a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_refine", "The number of uniform refinements", "DMCreate", refine, &refine, NULL,0);CHKERRQ(ierr); 302561a622f3SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_remap", "Flag to control coordinate remapping", "DMCreate", remap, &remap, NULL);CHKERRQ(ierr); 30265a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_refine_hierarchy", "The number of uniform refinements", "DMCreate", refine, &refine, &isHierarchy,0);CHKERRQ(ierr); 3027b6a0289aSMatthew G. Knepley if (refine) {ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr);} 302868d4fef7SMatthew G. Knepley if (refine && isHierarchy) { 3029acdc6f61SToby Isaac DM *dms, coarseDM; 303068d4fef7SMatthew G. Knepley 3031acdc6f61SToby Isaac ierr = DMGetCoarseDM(dm, &coarseDM);CHKERRQ(ierr); 3032acdc6f61SToby Isaac ierr = PetscObjectReference((PetscObject)coarseDM);CHKERRQ(ierr); 303368d4fef7SMatthew G. Knepley ierr = PetscMalloc1(refine,&dms);CHKERRQ(ierr); 303468d4fef7SMatthew G. Knepley ierr = DMRefineHierarchy(dm, refine, dms);CHKERRQ(ierr); 303568d4fef7SMatthew G. Knepley /* Total hack since we do not pass in a pointer */ 303668d4fef7SMatthew G. Knepley ierr = DMPlexSwap_Static(dm, dms[refine-1]);CHKERRQ(ierr); 303768d4fef7SMatthew G. Knepley if (refine == 1) { 3038a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dm, dms[0]);CHKERRQ(ierr); 30390aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dm, PETSC_TRUE);CHKERRQ(ierr); 304068d4fef7SMatthew G. Knepley } else { 3041a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dm, dms[refine-2]);CHKERRQ(ierr); 30420aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dm, PETSC_TRUE);CHKERRQ(ierr); 3043a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dms[0], dms[refine-1]);CHKERRQ(ierr); 30440aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dms[0], PETSC_TRUE);CHKERRQ(ierr); 304568d4fef7SMatthew G. Knepley } 3046acdc6f61SToby Isaac ierr = DMSetCoarseDM(dms[refine-1], coarseDM);CHKERRQ(ierr); 3047acdc6f61SToby Isaac ierr = PetscObjectDereference((PetscObject)coarseDM);CHKERRQ(ierr); 304868d4fef7SMatthew G. Knepley /* Free DMs */ 304968d4fef7SMatthew G. Knepley for (r = 0; r < refine; ++r) { 3050547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dms[r]);CHKERRQ(ierr); 305168d4fef7SMatthew G. Knepley ierr = DMDestroy(&dms[r]);CHKERRQ(ierr); 305268d4fef7SMatthew G. Knepley } 305368d4fef7SMatthew G. Knepley ierr = PetscFree(dms);CHKERRQ(ierr); 305468d4fef7SMatthew G. Knepley } else { 305568d4fef7SMatthew G. Knepley for (r = 0; r < refine; ++r) { 30569318fe57SMatthew G. Knepley DM rdm; 305751a74b61SMatthew G. Knepley PetscPointFunc coordFunc = ((DM_Plex*) dm->data)->coordFunc; 305868d4fef7SMatthew G. Knepley 30591a1499c8SBarry Smith ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 30609318fe57SMatthew G. Knepley ierr = DMRefine(dm, PetscObjectComm((PetscObject) dm), &rdm);CHKERRQ(ierr); 306168d4fef7SMatthew G. Knepley /* Total hack since we do not pass in a pointer */ 30629318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &rdm);CHKERRQ(ierr); 3063547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 306461a622f3SMatthew G. Knepley if (coordFunc && remap) { 306551a74b61SMatthew G. Knepley ierr = DMPlexRemapGeometry(dm, 0.0, coordFunc);CHKERRQ(ierr); 306651a74b61SMatthew G. Knepley ((DM_Plex*) dm->data)->coordFunc = coordFunc; 306751a74b61SMatthew G. Knepley } 306868d4fef7SMatthew G. Knepley } 306968d4fef7SMatthew G. Knepley } 30703cf6fe12SMatthew G. Knepley /* Handle DMPlex coarsening */ 30715a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_coarsen", "Coarsen the mesh", "DMCreate", coarsen, &coarsen, NULL,0);CHKERRQ(ierr); 30725a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_coarsen_hierarchy", "The number of coarsenings", "DMCreate", coarsen, &coarsen, &isHierarchy,0);CHKERRQ(ierr); 3073b653a561SMatthew G. Knepley if (coarsen && isHierarchy) { 3074b653a561SMatthew G. Knepley DM *dms; 3075b653a561SMatthew G. Knepley 3076b653a561SMatthew G. Knepley ierr = PetscMalloc1(coarsen, &dms);CHKERRQ(ierr); 3077b653a561SMatthew G. Knepley ierr = DMCoarsenHierarchy(dm, coarsen, dms);CHKERRQ(ierr); 3078b653a561SMatthew G. Knepley /* Free DMs */ 3079b653a561SMatthew G. Knepley for (r = 0; r < coarsen; ++r) { 3080547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dms[r]);CHKERRQ(ierr); 3081b653a561SMatthew G. Knepley ierr = DMDestroy(&dms[r]);CHKERRQ(ierr); 3082b653a561SMatthew G. Knepley } 3083b653a561SMatthew G. Knepley ierr = PetscFree(dms);CHKERRQ(ierr); 3084b653a561SMatthew G. Knepley } else { 3085b653a561SMatthew G. Knepley for (r = 0; r < coarsen; ++r) { 30869318fe57SMatthew G. Knepley DM cdm; 30879318fe57SMatthew G. Knepley PetscPointFunc coordFunc = ((DM_Plex*) dm->data)->coordFunc; 30883cf6fe12SMatthew G. Knepley 30893cf6fe12SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 30909318fe57SMatthew G. Knepley ierr = DMCoarsen(dm, PetscObjectComm((PetscObject) dm), &cdm);CHKERRQ(ierr); 30913cf6fe12SMatthew G. Knepley /* Total hack since we do not pass in a pointer */ 30929318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &cdm);CHKERRQ(ierr); 3093547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 30949318fe57SMatthew G. Knepley if (coordFunc) { 30959318fe57SMatthew G. Knepley ierr = DMPlexRemapGeometry(dm, 0.0, coordFunc);CHKERRQ(ierr); 30969318fe57SMatthew G. Knepley ((DM_Plex*) dm->data)->coordFunc = coordFunc; 30979318fe57SMatthew G. Knepley } 30983cf6fe12SMatthew G. Knepley } 3099b653a561SMatthew G. Knepley } 3100909dfd52SMatthew G. Knepley /* Handle ghost cells */ 3101909dfd52SMatthew 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); 3102909dfd52SMatthew G. Knepley if (ghostCells) { 3103909dfd52SMatthew G. Knepley DM gdm; 3104909dfd52SMatthew G. Knepley char lname[PETSC_MAX_PATH_LEN]; 3105909dfd52SMatthew G. Knepley 3106909dfd52SMatthew G. Knepley lname[0] = '\0'; 3107909dfd52SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_fv_ghost_cells_label", "Label name for ghost cells boundary", "DMCreate", lname, lname, sizeof(lname), &flg);CHKERRQ(ierr); 3108909dfd52SMatthew G. Knepley ierr = DMPlexConstructGhostCells(dm, flg ? lname : NULL, NULL, &gdm);CHKERRQ(ierr); 3109909dfd52SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &gdm);CHKERRQ(ierr); 3110909dfd52SMatthew G. Knepley } 31113cf6fe12SMatthew G. Knepley /* Handle */ 31121a1499c8SBarry Smith ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 31130a6ba040SMatthew G. Knepley ierr = PetscOptionsTail();CHKERRQ(ierr); 31140a6ba040SMatthew G. Knepley PetscFunctionReturn(0); 31150a6ba040SMatthew G. Knepley } 31160a6ba040SMatthew G. Knepley 3117552f7358SJed Brown static PetscErrorCode DMCreateGlobalVector_Plex(DM dm,Vec *vec) 3118552f7358SJed Brown { 3119552f7358SJed Brown PetscErrorCode ierr; 3120552f7358SJed Brown 3121552f7358SJed Brown PetscFunctionBegin; 3122552f7358SJed Brown ierr = DMCreateGlobalVector_Section_Private(dm,vec);CHKERRQ(ierr); 3123552f7358SJed Brown /* ierr = VecSetOperation(*vec, VECOP_DUPLICATE, (void(*)(void)) VecDuplicate_MPI_DM);CHKERRQ(ierr); */ 3124552f7358SJed Brown ierr = VecSetOperation(*vec, VECOP_VIEW, (void (*)(void)) VecView_Plex);CHKERRQ(ierr); 3125d930f514SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_VIEWNATIVE, (void (*)(void)) VecView_Plex_Native);CHKERRQ(ierr); 31262c40f234SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_LOAD, (void (*)(void)) VecLoad_Plex);CHKERRQ(ierr); 3127d930f514SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_LOADNATIVE, (void (*)(void)) VecLoad_Plex_Native);CHKERRQ(ierr); 3128552f7358SJed Brown PetscFunctionReturn(0); 3129552f7358SJed Brown } 3130552f7358SJed Brown 3131552f7358SJed Brown static PetscErrorCode DMCreateLocalVector_Plex(DM dm,Vec *vec) 3132552f7358SJed Brown { 3133552f7358SJed Brown PetscErrorCode ierr; 3134552f7358SJed Brown 3135552f7358SJed Brown PetscFunctionBegin; 3136552f7358SJed Brown ierr = DMCreateLocalVector_Section_Private(dm,vec);CHKERRQ(ierr); 3137552f7358SJed Brown ierr = VecSetOperation(*vec, VECOP_VIEW, (void (*)(void)) VecView_Plex_Local);CHKERRQ(ierr); 31382c40f234SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_LOAD, (void (*)(void)) VecLoad_Plex_Local);CHKERRQ(ierr); 3139552f7358SJed Brown PetscFunctionReturn(0); 3140552f7358SJed Brown } 3141552f7358SJed Brown 3142793f3fe5SMatthew G. Knepley static PetscErrorCode DMGetDimPoints_Plex(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 3143793f3fe5SMatthew G. Knepley { 3144793f3fe5SMatthew G. Knepley PetscInt depth, d; 3145793f3fe5SMatthew G. Knepley PetscErrorCode ierr; 3146793f3fe5SMatthew G. Knepley 3147793f3fe5SMatthew G. Knepley PetscFunctionBegin; 3148793f3fe5SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3149793f3fe5SMatthew G. Knepley if (depth == 1) { 3150793f3fe5SMatthew G. Knepley ierr = DMGetDimension(dm, &d);CHKERRQ(ierr); 3151793f3fe5SMatthew G. Knepley if (dim == 0) {ierr = DMPlexGetDepthStratum(dm, dim, pStart, pEnd);CHKERRQ(ierr);} 3152793f3fe5SMatthew G. Knepley else if (dim == d) {ierr = DMPlexGetDepthStratum(dm, 1, pStart, pEnd);CHKERRQ(ierr);} 3153793f3fe5SMatthew G. Knepley else {*pStart = 0; *pEnd = 0;} 3154793f3fe5SMatthew G. Knepley } else { 3155793f3fe5SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, dim, pStart, pEnd);CHKERRQ(ierr); 3156793f3fe5SMatthew G. Knepley } 3157793f3fe5SMatthew G. Knepley PetscFunctionReturn(0); 3158793f3fe5SMatthew G. Knepley } 3159793f3fe5SMatthew G. Knepley 316028d58a37SPierre Jolivet static PetscErrorCode DMGetNeighbors_Plex(DM dm, PetscInt *nranks, const PetscMPIInt *ranks[]) 3161502a2867SDave May { 3162502a2867SDave May PetscSF sf; 31630a19bb7dSprj- PetscInt niranks, njranks, n; 31640a19bb7dSprj- const PetscMPIInt *iranks, *jranks; 31650a19bb7dSprj- DM_Plex *data = (DM_Plex*) dm->data; 31662f356facSMatthew G. Knepley PetscErrorCode ierr; 3167502a2867SDave May 31682f356facSMatthew G. Knepley PetscFunctionBegin; 3169502a2867SDave May ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 31700a19bb7dSprj- if (!data->neighbors) { 317107a779feSPierre Jolivet ierr = PetscSFSetUp(sf);CHKERRQ(ierr); 31720a19bb7dSprj- ierr = PetscSFGetRootRanks(sf, &njranks, &jranks, NULL, NULL, NULL);CHKERRQ(ierr); 31730a19bb7dSprj- ierr = PetscSFGetLeafRanks(sf, &niranks, &iranks, NULL, NULL);CHKERRQ(ierr); 31740a19bb7dSprj- ierr = PetscMalloc1(njranks + niranks + 1, &data->neighbors);CHKERRQ(ierr); 31750a19bb7dSprj- ierr = PetscArraycpy(data->neighbors + 1, jranks, njranks);CHKERRQ(ierr); 31760a19bb7dSprj- ierr = PetscArraycpy(data->neighbors + njranks + 1, iranks, niranks);CHKERRQ(ierr); 31770a19bb7dSprj- n = njranks + niranks; 31780a19bb7dSprj- ierr = PetscSortRemoveDupsMPIInt(&n, data->neighbors + 1);CHKERRQ(ierr); 31790a19bb7dSprj- /* The following cast should never fail: can't have more neighbors than PETSC_MPI_INT_MAX */ 31800a19bb7dSprj- ierr = PetscMPIIntCast(n, data->neighbors);CHKERRQ(ierr); 31810a19bb7dSprj- } 31820a19bb7dSprj- if (nranks) *nranks = data->neighbors[0]; 31830a19bb7dSprj- if (ranks) { 31840a19bb7dSprj- if (data->neighbors[0]) *ranks = data->neighbors + 1; 31850a19bb7dSprj- else *ranks = NULL; 31860a19bb7dSprj- } 3187502a2867SDave May PetscFunctionReturn(0); 3188502a2867SDave May } 3189502a2867SDave May 31901eb70e55SToby Isaac PETSC_INTERN PetscErrorCode DMInterpolateSolution_Plex(DM, DM, Mat, Vec, Vec); 31911eb70e55SToby Isaac 319246fa42a0SMatthew G. Knepley static PetscErrorCode DMInitialize_Plex(DM dm) 3193552f7358SJed Brown { 3194713918a9SToby Isaac PetscErrorCode ierr; 3195713918a9SToby Isaac 3196552f7358SJed Brown PetscFunctionBegin; 3197552f7358SJed Brown dm->ops->view = DMView_Plex; 31982c40f234SMatthew G. Knepley dm->ops->load = DMLoad_Plex; 3199552f7358SJed Brown dm->ops->setfromoptions = DMSetFromOptions_Plex; 320038221697SMatthew G. Knepley dm->ops->clone = DMClone_Plex; 3201552f7358SJed Brown dm->ops->setup = DMSetUp_Plex; 32021bb6d2a8SBarry Smith dm->ops->createlocalsection = DMCreateLocalSection_Plex; 320366ad2231SToby Isaac dm->ops->createdefaultconstraints = DMCreateDefaultConstraints_Plex; 3204552f7358SJed Brown dm->ops->createglobalvector = DMCreateGlobalVector_Plex; 3205552f7358SJed Brown dm->ops->createlocalvector = DMCreateLocalVector_Plex; 3206184d77edSJed Brown dm->ops->getlocaltoglobalmapping = NULL; 32070298fd71SBarry Smith dm->ops->createfieldis = NULL; 3208552f7358SJed Brown dm->ops->createcoordinatedm = DMCreateCoordinateDM_Plex; 3209f19dbd58SToby Isaac dm->ops->createcoordinatefield = DMCreateCoordinateField_Plex; 32100a6ba040SMatthew G. Knepley dm->ops->getcoloring = NULL; 3211552f7358SJed Brown dm->ops->creatematrix = DMCreateMatrix_Plex; 3212bceba477SMatthew G. Knepley dm->ops->createinterpolation = DMCreateInterpolation_Plex; 3213bd041c0cSMatthew G. Knepley dm->ops->createmassmatrix = DMCreateMassMatrix_Plex; 32145a84ad33SLisandro Dalcin dm->ops->createinjection = DMCreateInjection_Plex; 3215552f7358SJed Brown dm->ops->refine = DMRefine_Plex; 32160a6ba040SMatthew G. Knepley dm->ops->coarsen = DMCoarsen_Plex; 32170a6ba040SMatthew G. Knepley dm->ops->refinehierarchy = DMRefineHierarchy_Plex; 3218b653a561SMatthew G. Knepley dm->ops->coarsenhierarchy = DMCoarsenHierarchy_Plex; 32190d1cd5e0SMatthew G. Knepley dm->ops->adaptlabel = DMAdaptLabel_Plex; 32200d1cd5e0SMatthew G. Knepley dm->ops->adaptmetric = DMAdaptMetric_Plex; 32210298fd71SBarry Smith dm->ops->globaltolocalbegin = NULL; 32220298fd71SBarry Smith dm->ops->globaltolocalend = NULL; 32230298fd71SBarry Smith dm->ops->localtoglobalbegin = NULL; 32240298fd71SBarry Smith dm->ops->localtoglobalend = NULL; 3225552f7358SJed Brown dm->ops->destroy = DMDestroy_Plex; 3226552f7358SJed Brown dm->ops->createsubdm = DMCreateSubDM_Plex; 32272adcc780SMatthew G. Knepley dm->ops->createsuperdm = DMCreateSuperDM_Plex; 3228793f3fe5SMatthew G. Knepley dm->ops->getdimpoints = DMGetDimPoints_Plex; 3229552f7358SJed Brown dm->ops->locatepoints = DMLocatePoints_Plex; 32300709b2feSToby Isaac dm->ops->projectfunctionlocal = DMProjectFunctionLocal_Plex; 32310709b2feSToby Isaac dm->ops->projectfunctionlabellocal = DMProjectFunctionLabelLocal_Plex; 3232bfc4295aSToby Isaac dm->ops->projectfieldlocal = DMProjectFieldLocal_Plex; 32338c6c5593SMatthew G. Knepley dm->ops->projectfieldlabellocal = DMProjectFieldLabelLocal_Plex; 3234ece3a9fcSMatthew G. Knepley dm->ops->projectbdfieldlabellocal = DMProjectBdFieldLabelLocal_Plex; 32350709b2feSToby Isaac dm->ops->computel2diff = DMComputeL2Diff_Plex; 3236b698f381SToby Isaac dm->ops->computel2gradientdiff = DMComputeL2GradientDiff_Plex; 32372a16baeaSToby Isaac dm->ops->computel2fielddiff = DMComputeL2FieldDiff_Plex; 323828d58a37SPierre Jolivet dm->ops->getneighbors = DMGetNeighbors_Plex; 3239f1d73a7aSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexInsertBoundaryValues_C",DMPlexInsertBoundaryValues_Plex);CHKERRQ(ierr); 324056cf3b9cSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexInsertTimeDerviativeBoundaryValues_C",DMPlexInsertTimeDerivativeBoundaryValues_Plex);CHKERRQ(ierr); 32418135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMSetUpGLVisViewer_C",DMSetUpGLVisViewer_Plex);CHKERRQ(ierr); 324228d58a37SPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)dm,"DMCreateNeumannOverlap_C",DMCreateNeumannOverlap_Plex);CHKERRQ(ierr); 3243cb54e036SVaclav Hapla ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexGetOverlap_C",DMPlexGetOverlap_Plex);CHKERRQ(ierr); 32441eb70e55SToby Isaac ierr = PetscObjectComposeFunction((PetscObject)dm,"DMInterpolateSolution_C",DMInterpolateSolution_Plex);CHKERRQ(ierr); 3245552f7358SJed Brown PetscFunctionReturn(0); 3246552f7358SJed Brown } 3247552f7358SJed Brown 324846fa42a0SMatthew G. Knepley PETSC_INTERN PetscErrorCode DMClone_Plex(DM dm, DM *newdm) 324963a16f15SMatthew G. Knepley { 325063a16f15SMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) dm->data; 325163a16f15SMatthew G. Knepley PetscErrorCode ierr; 325263a16f15SMatthew G. Knepley 325363a16f15SMatthew G. Knepley PetscFunctionBegin; 325463a16f15SMatthew G. Knepley mesh->refct++; 325563a16f15SMatthew G. Knepley (*newdm)->data = mesh; 325663a16f15SMatthew G. Knepley ierr = PetscObjectChangeTypeName((PetscObject) *newdm, DMPLEX);CHKERRQ(ierr); 325763a16f15SMatthew G. Knepley ierr = DMInitialize_Plex(*newdm);CHKERRQ(ierr); 325863a16f15SMatthew G. Knepley PetscFunctionReturn(0); 325963a16f15SMatthew G. Knepley } 326063a16f15SMatthew G. Knepley 32618818961aSMatthew G Knepley /*MC 32628818961aSMatthew G Knepley DMPLEX = "plex" - A DM object that encapsulates an unstructured mesh, or CW Complex, which can be expressed using a Hasse Diagram. 32638818961aSMatthew G Knepley In the local representation, Vecs contain all unknowns in the interior and shared boundary. This is 32648818961aSMatthew G Knepley specified by a PetscSection object. Ownership in the global representation is determined by 32658818961aSMatthew G Knepley ownership of the underlying DMPlex points. This is specified by another PetscSection object. 32668818961aSMatthew G Knepley 3267e5893cccSMatthew G. Knepley Options Database Keys: 3268250712c9SMatthew G. Knepley + -dm_refine_pre - Refine mesh before distribution 3269250712c9SMatthew G. Knepley + -dm_refine_uniform_pre - Choose uniform or generator-based refinement 3270250712c9SMatthew G. Knepley + -dm_refine_volume_limit_pre - Cell volume limit after pre-refinement using generator 3271250712c9SMatthew G. Knepley . -dm_distribute - Distribute mesh across processes 3272250712c9SMatthew G. Knepley . -dm_distribute_overlap - Number of cells to overlap for distribution 3273250712c9SMatthew G. Knepley . -dm_refine - Refine mesh after distribution 3274250712c9SMatthew G. Knepley . -dm_plex_hash_location - Use grid hashing for point location 3275f12cf164SMatthew G. Knepley . -dm_plex_partition_balance - Attempt to evenly divide points on partition boundary between processes 3276f12cf164SMatthew G. Knepley . -dm_plex_remesh_bd - Allow changes to the boundary on remeshing 3277f12cf164SMatthew G. Knepley . -dm_plex_max_projection_height - Maxmimum mesh point height used to project locally 3278f12cf164SMatthew G. Knepley . -dm_plex_regular_refinement - Use special nested projection algorithm for regular refinement 3279250712c9SMatthew G. Knepley . -dm_plex_check_all - Perform all shecks below 3280f12cf164SMatthew G. Knepley . -dm_plex_check_symmetry - Check that the adjacency information in the mesh is symmetric 3281f12cf164SMatthew G. Knepley . -dm_plex_check_skeleton <celltype> - Check that each cell has the correct number of vertices 3282f12cf164SMatthew 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 3283f12cf164SMatthew G. Knepley . -dm_plex_check_geometry - Check that cells have positive volume 3284f12cf164SMatthew G. Knepley . -dm_view :mesh.tex:ascii_latex - View the mesh in LaTeX/TikZ 3285e5893cccSMatthew G. Knepley . -dm_plex_view_scale <num> - Scale the TikZ 3286e5893cccSMatthew G. Knepley - -dm_plex_print_fem <num> - View FEM assembly information, such as element vectors and matrices 3287e5893cccSMatthew G. Knepley 32888818961aSMatthew G Knepley Level: intermediate 32898818961aSMatthew G Knepley 32908818961aSMatthew G Knepley .seealso: DMType, DMPlexCreate(), DMCreate(), DMSetType() 32918818961aSMatthew G Knepley M*/ 32928818961aSMatthew G Knepley 32938cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Plex(DM dm) 3294552f7358SJed Brown { 3295552f7358SJed Brown DM_Plex *mesh; 3296412e9a14SMatthew G. Knepley PetscInt unit; 3297552f7358SJed Brown PetscErrorCode ierr; 3298552f7358SJed Brown 3299552f7358SJed Brown PetscFunctionBegin; 3300552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3301b00a9115SJed Brown ierr = PetscNewLog(dm,&mesh);CHKERRQ(ierr); 3302552f7358SJed Brown dm->data = mesh; 3303552f7358SJed Brown 3304552f7358SJed Brown mesh->refct = 1; 330582f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &mesh->coneSection);CHKERRQ(ierr); 3306552f7358SJed Brown mesh->maxConeSize = 0; 33070298fd71SBarry Smith mesh->cones = NULL; 33080298fd71SBarry Smith mesh->coneOrientations = NULL; 330982f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &mesh->supportSection);CHKERRQ(ierr); 3310552f7358SJed Brown mesh->maxSupportSize = 0; 33110298fd71SBarry Smith mesh->supports = NULL; 3312552f7358SJed Brown mesh->refinementUniform = PETSC_TRUE; 3313552f7358SJed Brown mesh->refinementLimit = -1.0; 33147d0f5628SVaclav Hapla mesh->interpolated = DMPLEX_INTERPOLATED_INVALID; 33157d0f5628SVaclav Hapla mesh->interpolatedCollective = DMPLEX_INTERPOLATED_INVALID; 3316552f7358SJed Brown 33170298fd71SBarry Smith mesh->facesTmp = NULL; 3318552f7358SJed Brown 3319d9deefdfSMatthew G. Knepley mesh->tetgenOpts = NULL; 3320d9deefdfSMatthew G. Knepley mesh->triangleOpts = NULL; 332177623264SMatthew G. Knepley ierr = PetscPartitionerCreate(PetscObjectComm((PetscObject)dm), &mesh->partitioner);CHKERRQ(ierr); 33222e62ab5aSMatthew G. Knepley mesh->remeshBd = PETSC_FALSE; 3323d9deefdfSMatthew G. Knepley 33240298fd71SBarry Smith mesh->subpointMap = NULL; 3325552f7358SJed Brown 33268865f1eaSKarl Rupp for (unit = 0; unit < NUM_PETSC_UNITS; ++unit) mesh->scale[unit] = 1.0; 3327552f7358SJed Brown 33280aef6b92SMatthew G. Knepley mesh->regularRefinement = PETSC_FALSE; 3329df0420ecSMatthew G. Knepley mesh->depthState = -1; 3330ba2698f1SMatthew G. Knepley mesh->celltypeState = -1; 33310298fd71SBarry Smith mesh->globalVertexNumbers = NULL; 33320298fd71SBarry Smith mesh->globalCellNumbers = NULL; 3333a68b90caSToby Isaac mesh->anchorSection = NULL; 3334a68b90caSToby Isaac mesh->anchorIS = NULL; 333541e6d900SToby Isaac mesh->createanchors = NULL; 3336fa73a4e1SToby Isaac mesh->computeanchormatrix = NULL; 3337d961a43aSToby Isaac mesh->parentSection = NULL; 3338d961a43aSToby Isaac mesh->parents = NULL; 3339d961a43aSToby Isaac mesh->childIDs = NULL; 3340d961a43aSToby Isaac mesh->childSection = NULL; 3341d961a43aSToby Isaac mesh->children = NULL; 3342d6a7ad0dSToby Isaac mesh->referenceTree = NULL; 3343dcbd3bf7SToby Isaac mesh->getchildsymmetry = NULL; 3344552f7358SJed Brown mesh->vtkCellHeight = 0; 3345e228b242SToby Isaac mesh->useAnchors = PETSC_FALSE; 3346552f7358SJed Brown 3347b29cfa1cSToby Isaac mesh->maxProjectionHeight = 0; 3348b29cfa1cSToby Isaac 33490a19bb7dSprj- mesh->neighbors = NULL; 33500a19bb7dSprj- 3351552f7358SJed Brown mesh->printSetValues = PETSC_FALSE; 3352552f7358SJed Brown mesh->printFEM = 0; 33536113b454SMatthew G. Knepley mesh->printTol = 1.0e-10; 3354552f7358SJed Brown 3355552f7358SJed Brown ierr = DMInitialize_Plex(dm);CHKERRQ(ierr); 3356552f7358SJed Brown PetscFunctionReturn(0); 3357552f7358SJed Brown } 3358552f7358SJed Brown 3359552f7358SJed Brown /*@ 3360552f7358SJed Brown DMPlexCreate - Creates a DMPlex object, which encapsulates an unstructured mesh, or CW complex, which can be expressed using a Hasse Diagram. 3361552f7358SJed Brown 3362d083f849SBarry Smith Collective 3363552f7358SJed Brown 3364552f7358SJed Brown Input Parameter: 3365552f7358SJed Brown . comm - The communicator for the DMPlex object 3366552f7358SJed Brown 3367552f7358SJed Brown Output Parameter: 3368552f7358SJed Brown . mesh - The DMPlex object 3369552f7358SJed Brown 3370552f7358SJed Brown Level: beginner 3371552f7358SJed Brown 3372552f7358SJed Brown @*/ 3373552f7358SJed Brown PetscErrorCode DMPlexCreate(MPI_Comm comm, DM *mesh) 3374552f7358SJed Brown { 3375552f7358SJed Brown PetscErrorCode ierr; 3376552f7358SJed Brown 3377552f7358SJed Brown PetscFunctionBegin; 3378552f7358SJed Brown PetscValidPointer(mesh,2); 3379552f7358SJed Brown ierr = DMCreate(comm, mesh);CHKERRQ(ierr); 3380552f7358SJed Brown ierr = DMSetType(*mesh, DMPLEX);CHKERRQ(ierr); 3381552f7358SJed Brown PetscFunctionReturn(0); 3382552f7358SJed Brown } 3383552f7358SJed Brown 3384b09969d6SVaclav Hapla /*@C 3385b09969d6SVaclav Hapla DMPlexBuildFromCellListParallel - Build distributed DMPLEX topology from a list of vertices for each cell (common mesh generator output) 3386b09969d6SVaclav Hapla 3387b09969d6SVaclav Hapla Input Parameters: 3388b09969d6SVaclav Hapla + dm - The DM 3389b09969d6SVaclav Hapla . numCells - The number of cells owned by this process 339025b6865aSVaclav Hapla . numVertices - The number of vertices owned by this process, or PETSC_DECIDE 339125b6865aSVaclav Hapla . NVertices - The global number of vertices, or PETSC_DECIDE 3392b09969d6SVaclav Hapla . numCorners - The number of vertices for each cell 33935e488331SVaclav Hapla - cells - An array of numCells*numCorners numbers, the global vertex numbers for each cell 3394b09969d6SVaclav Hapla 3395b09969d6SVaclav Hapla Output Parameter: 33968ddadb14SVaclav Hapla . vertexSF - (Optional) SF describing complete vertex ownership 3397b09969d6SVaclav Hapla 3398b09969d6SVaclav Hapla Notes: 3399b09969d6SVaclav Hapla Two triangles sharing a face 3400b09969d6SVaclav Hapla $ 3401b09969d6SVaclav Hapla $ 2 3402b09969d6SVaclav Hapla $ / | \ 3403b09969d6SVaclav Hapla $ / | \ 3404b09969d6SVaclav Hapla $ / | \ 3405b09969d6SVaclav Hapla $ 0 0 | 1 3 3406b09969d6SVaclav Hapla $ \ | / 3407b09969d6SVaclav Hapla $ \ | / 3408b09969d6SVaclav Hapla $ \ | / 3409b09969d6SVaclav Hapla $ 1 3410b09969d6SVaclav Hapla would have input 3411b09969d6SVaclav Hapla $ numCells = 2, numVertices = 4 3412b09969d6SVaclav Hapla $ cells = [0 1 2 1 3 2] 3413b09969d6SVaclav Hapla $ 3414b09969d6SVaclav Hapla which would result in the DMPlex 3415b09969d6SVaclav Hapla $ 3416b09969d6SVaclav Hapla $ 4 3417b09969d6SVaclav Hapla $ / | \ 3418b09969d6SVaclav Hapla $ / | \ 3419b09969d6SVaclav Hapla $ / | \ 3420b09969d6SVaclav Hapla $ 2 0 | 1 5 3421b09969d6SVaclav Hapla $ \ | / 3422b09969d6SVaclav Hapla $ \ | / 3423b09969d6SVaclav Hapla $ \ | / 3424b09969d6SVaclav Hapla $ 3 3425b09969d6SVaclav Hapla 342625b6865aSVaclav Hapla Vertices are implicitly numbered consecutively 0,...,NVertices. 342725b6865aSVaclav Hapla Each rank owns a chunk of numVertices consecutive vertices. 342825b6865aSVaclav Hapla If numVertices is PETSC_DECIDE, PETSc will distribute them as evenly as possible using PetscLayout. 342925b6865aSVaclav Hapla If both NVertices and numVertices are PETSC_DECIDE, NVertices is computed by PETSc as the maximum vertex index in cells + 1. 343025b6865aSVaclav Hapla If only NVertices is PETSC_DECIDE, it is computed as the sum of numVertices over all ranks. 343125b6865aSVaclav Hapla 3432b09969d6SVaclav Hapla The cell distribution is arbitrary non-overlapping, independent of the vertex distribution. 3433b09969d6SVaclav Hapla 3434b09969d6SVaclav Hapla Not currently supported in Fortran. 3435b09969d6SVaclav Hapla 3436b09969d6SVaclav Hapla Level: advanced 3437b09969d6SVaclav Hapla 3438b09969d6SVaclav Hapla .seealso: DMPlexBuildFromCellList(), DMPlexCreateFromCellListParallelPetsc(), DMPlexBuildCoordinatesFromCellListParallel() 3439b09969d6SVaclav Hapla @*/ 344025b6865aSVaclav Hapla PetscErrorCode DMPlexBuildFromCellListParallel(DM dm, PetscInt numCells, PetscInt numVertices, PetscInt NVertices, PetscInt numCorners, const PetscInt cells[], PetscSF *vertexSF) 3441a47d0d45SMatthew G. Knepley { 34422464107aSksagiyam PetscSF sfPoint; 34432464107aSksagiyam PetscLayout layout; 34442464107aSksagiyam PetscInt numVerticesAdj, *verticesAdj, *cones, c, p, dim; 34459852e123SBarry Smith PetscMPIInt rank, size; 3446a47d0d45SMatthew G. Knepley PetscErrorCode ierr; 3447a47d0d45SMatthew G. Knepley 3448a47d0d45SMatthew G. Knepley PetscFunctionBegin; 344925b6865aSVaclav Hapla PetscValidLogicalCollectiveInt(dm,NVertices,4); 3450b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 3451ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 3452ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRMPI(ierr); 34536cbf6523SVaclav Hapla ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 345425b6865aSVaclav Hapla /* Get/check global number of vertices */ 345525b6865aSVaclav Hapla { 345625b6865aSVaclav Hapla PetscInt NVerticesInCells, i; 345725b6865aSVaclav Hapla const PetscInt len = numCells * numCorners; 345825b6865aSVaclav Hapla 345925b6865aSVaclav Hapla /* NVerticesInCells = max(cells) + 1 */ 346025b6865aSVaclav Hapla NVerticesInCells = PETSC_MIN_INT; 346125b6865aSVaclav Hapla for (i=0; i<len; i++) if (cells[i] > NVerticesInCells) NVerticesInCells = cells[i]; 346225b6865aSVaclav Hapla ++NVerticesInCells; 3463ffc4695bSBarry Smith ierr = MPI_Allreduce(MPI_IN_PLACE, &NVerticesInCells, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 346425b6865aSVaclav Hapla 346525b6865aSVaclav Hapla if (numVertices == PETSC_DECIDE && NVertices == PETSC_DECIDE) NVertices = NVerticesInCells; 346625b6865aSVaclav 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); 346725b6865aSVaclav Hapla } 34689079aca8SVaclav Hapla /* Count locally unique vertices */ 34699079aca8SVaclav Hapla { 34709079aca8SVaclav Hapla PetscHSetI vhash; 34719079aca8SVaclav Hapla PetscInt off = 0; 34729079aca8SVaclav Hapla 3473e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&vhash);CHKERRQ(ierr); 3474a47d0d45SMatthew G. Knepley for (c = 0; c < numCells; ++c) { 3475a47d0d45SMatthew G. Knepley for (p = 0; p < numCorners; ++p) { 3476e8f14785SLisandro Dalcin ierr = PetscHSetIAdd(vhash, cells[c*numCorners+p]);CHKERRQ(ierr); 3477a47d0d45SMatthew G. Knepley } 3478a47d0d45SMatthew G. Knepley } 3479e8f14785SLisandro Dalcin ierr = PetscHSetIGetSize(vhash, &numVerticesAdj);CHKERRQ(ierr); 3480a47d0d45SMatthew G. Knepley ierr = PetscMalloc1(numVerticesAdj, &verticesAdj);CHKERRQ(ierr); 3481e8f14785SLisandro Dalcin ierr = PetscHSetIGetElems(vhash, &off, verticesAdj);CHKERRQ(ierr); 3482e8f14785SLisandro Dalcin ierr = PetscHSetIDestroy(&vhash);CHKERRQ(ierr); 3483a47d0d45SMatthew G. Knepley if (off != numVerticesAdj) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid number of local vertices %D should be %D", off, numVerticesAdj); 3484a47d0d45SMatthew G. Knepley } 34859079aca8SVaclav Hapla ierr = PetscSortInt(numVerticesAdj, verticesAdj);CHKERRQ(ierr); 3486a47d0d45SMatthew G. Knepley /* Create cones */ 3487a47d0d45SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVerticesAdj);CHKERRQ(ierr); 3488a47d0d45SMatthew G. Knepley for (c = 0; c < numCells; ++c) {ierr = DMPlexSetConeSize(dm, c, numCorners);CHKERRQ(ierr);} 3489a47d0d45SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); 3490961cfab0SVaclav Hapla ierr = DMPlexGetCones(dm,&cones);CHKERRQ(ierr); 3491a47d0d45SMatthew G. Knepley for (c = 0; c < numCells; ++c) { 3492a47d0d45SMatthew G. Knepley for (p = 0; p < numCorners; ++p) { 3493a47d0d45SMatthew G. Knepley const PetscInt gv = cells[c*numCorners+p]; 3494a47d0d45SMatthew G. Knepley PetscInt lv; 3495a47d0d45SMatthew G. Knepley 34969079aca8SVaclav Hapla /* Positions within verticesAdj form 0-based local vertex numbering; 34979079aca8SVaclav Hapla we need to shift it by numCells to get correct DAG points (cells go first) */ 3498a47d0d45SMatthew G. Knepley ierr = PetscFindInt(gv, numVerticesAdj, verticesAdj, &lv);CHKERRQ(ierr); 3499a47d0d45SMatthew G. Knepley if (lv < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not find global vertex %D in local connectivity", gv); 3500961cfab0SVaclav Hapla cones[c*numCorners+p] = lv+numCells; 3501a47d0d45SMatthew G. Knepley } 3502a47d0d45SMatthew G. Knepley } 35032464107aSksagiyam /* Build point sf */ 35042464107aSksagiyam ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)dm), &layout);CHKERRQ(ierr); 35052464107aSksagiyam ierr = PetscLayoutSetSize(layout, NVertices);CHKERRQ(ierr); 35062464107aSksagiyam ierr = PetscLayoutSetLocalSize(layout, numVertices);CHKERRQ(ierr); 35072464107aSksagiyam ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr); 35082464107aSksagiyam ierr = PetscSFCreateByMatchingIndices(layout, numVerticesAdj, verticesAdj, NULL, numCells, numVerticesAdj, verticesAdj, NULL, numCells, vertexSF, &sfPoint);CHKERRQ(ierr); 35092464107aSksagiyam ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 3510a47d0d45SMatthew G. Knepley ierr = PetscFree(verticesAdj);CHKERRQ(ierr); 3511a47d0d45SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) sfPoint, "point SF");CHKERRQ(ierr); 35122464107aSksagiyam if (dm->sf) { 35132464107aSksagiyam const char *prefix; 35142464107aSksagiyam 35152464107aSksagiyam ierr = PetscObjectGetOptionsPrefix((PetscObject)dm->sf, &prefix);CHKERRQ(ierr); 35162464107aSksagiyam ierr = PetscObjectSetOptionsPrefix((PetscObject)sfPoint, prefix);CHKERRQ(ierr); 35172464107aSksagiyam } 35182464107aSksagiyam ierr = DMSetPointSF(dm, sfPoint);CHKERRQ(ierr); 35192464107aSksagiyam ierr = PetscSFDestroy(&sfPoint);CHKERRQ(ierr); 35202464107aSksagiyam if (vertexSF) {ierr = PetscObjectSetName((PetscObject)(*vertexSF), "Vertex Ownership SF");CHKERRQ(ierr);} 3521a47d0d45SMatthew G. Knepley /* Fill in the rest of the topology structure */ 3522a47d0d45SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 3523a47d0d45SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 3524b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 3525a47d0d45SMatthew G. Knepley PetscFunctionReturn(0); 3526a47d0d45SMatthew G. Knepley } 3527a47d0d45SMatthew G. Knepley 3528b09969d6SVaclav Hapla /*@C 3529b09969d6SVaclav Hapla DMPlexBuildCoordinatesFromCellListParallel - Build DM coordinates from a list of coordinates for each owned vertex (common mesh generator output) 3530b09969d6SVaclav Hapla 3531b09969d6SVaclav Hapla Input Parameters: 3532b09969d6SVaclav Hapla + dm - The DM 3533b09969d6SVaclav Hapla . spaceDim - The spatial dimension used for coordinates 3534b09969d6SVaclav Hapla . sfVert - SF describing complete vertex ownership 3535b09969d6SVaclav Hapla - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 3536b09969d6SVaclav Hapla 3537b09969d6SVaclav Hapla Level: advanced 3538b09969d6SVaclav Hapla 3539b09969d6SVaclav Hapla Notes: 3540b09969d6SVaclav Hapla Not currently supported in Fortran. 3541b09969d6SVaclav Hapla 3542b09969d6SVaclav Hapla .seealso: DMPlexBuildCoordinatesFromCellList(), DMPlexCreateFromCellListParallelPetsc(), DMPlexBuildFromCellListParallel() 3543b09969d6SVaclav Hapla @*/ 35441edcf0b2SVaclav Hapla PetscErrorCode DMPlexBuildCoordinatesFromCellListParallel(DM dm, PetscInt spaceDim, PetscSF sfVert, const PetscReal vertexCoords[]) 3545a47d0d45SMatthew G. Knepley { 3546a47d0d45SMatthew G. Knepley PetscSection coordSection; 3547a47d0d45SMatthew G. Knepley Vec coordinates; 3548a47d0d45SMatthew G. Knepley PetscScalar *coords; 35491edcf0b2SVaclav Hapla PetscInt numVertices, numVerticesAdj, coordSize, v, vStart, vEnd; 3550a47d0d45SMatthew G. Knepley PetscErrorCode ierr; 3551a47d0d45SMatthew G. Knepley 3552a47d0d45SMatthew G. Knepley PetscFunctionBegin; 3553b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 35541edcf0b2SVaclav Hapla ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 35551edcf0b2SVaclav 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."); 35569596c6baSMatthew G. Knepley ierr = DMSetCoordinateDim(dm, spaceDim);CHKERRQ(ierr); 3557a47d0d45SMatthew G. Knepley ierr = PetscSFGetGraph(sfVert, &numVertices, &numVerticesAdj, NULL, NULL);CHKERRQ(ierr); 35581edcf0b2SVaclav 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); 3559a47d0d45SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 3560a47d0d45SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 3561a47d0d45SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, spaceDim);CHKERRQ(ierr); 35621edcf0b2SVaclav Hapla ierr = PetscSectionSetChart(coordSection, vStart, vEnd);CHKERRQ(ierr); 35631edcf0b2SVaclav Hapla for (v = vStart; v < vEnd; ++v) { 3564a47d0d45SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, spaceDim);CHKERRQ(ierr); 3565a47d0d45SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, spaceDim);CHKERRQ(ierr); 3566a47d0d45SMatthew G. Knepley } 3567a47d0d45SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 3568a47d0d45SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 3569a47d0d45SMatthew G. Knepley ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinates);CHKERRQ(ierr); 3570a47d0d45SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, spaceDim);CHKERRQ(ierr); 3571a47d0d45SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 3572a47d0d45SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 3573a47d0d45SMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 3574a47d0d45SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 3575a47d0d45SMatthew G. Knepley { 3576a47d0d45SMatthew G. Knepley MPI_Datatype coordtype; 3577a47d0d45SMatthew G. Knepley 3578a47d0d45SMatthew G. Knepley /* Need a temp buffer for coords if we have complex/single */ 3579ffc4695bSBarry Smith ierr = MPI_Type_contiguous(spaceDim, MPIU_SCALAR, &coordtype);CHKERRMPI(ierr); 3580ffc4695bSBarry Smith ierr = MPI_Type_commit(&coordtype);CHKERRMPI(ierr); 358121016a8bSBarry Smith #if defined(PETSC_USE_COMPLEX) 358221016a8bSBarry Smith { 358321016a8bSBarry Smith PetscScalar *svertexCoords; 358421016a8bSBarry Smith PetscInt i; 35853612f820SVaclav Hapla ierr = PetscMalloc1(numVertices*spaceDim,&svertexCoords);CHKERRQ(ierr); 35863612f820SVaclav Hapla for (i=0; i<numVertices*spaceDim; i++) svertexCoords[i] = vertexCoords[i]; 3587ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sfVert, coordtype, svertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 3588ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sfVert, coordtype, svertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 358921016a8bSBarry Smith ierr = PetscFree(svertexCoords);CHKERRQ(ierr); 359021016a8bSBarry Smith } 359121016a8bSBarry Smith #else 3592ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sfVert, coordtype, vertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 3593ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sfVert, coordtype, vertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 359421016a8bSBarry Smith #endif 3595ffc4695bSBarry Smith ierr = MPI_Type_free(&coordtype);CHKERRMPI(ierr); 3596a47d0d45SMatthew G. Knepley } 3597a47d0d45SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 3598a47d0d45SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 3599a47d0d45SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 3600b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 3601a47d0d45SMatthew G. Knepley PetscFunctionReturn(0); 3602a47d0d45SMatthew G. Knepley } 3603a47d0d45SMatthew G. Knepley 3604c3edce3dSSatish Balay /*@ 3605b09969d6SVaclav Hapla DMPlexCreateFromCellListParallelPetsc - Create distributed DMPLEX from a list of vertices for each cell (common mesh generator output) 3606a47d0d45SMatthew G. Knepley 3607a47d0d45SMatthew G. Knepley Input Parameters: 3608a47d0d45SMatthew G. Knepley + comm - The communicator 3609a47d0d45SMatthew G. Knepley . dim - The topological dimension of the mesh 3610a47d0d45SMatthew G. Knepley . numCells - The number of cells owned by this process 361125b6865aSVaclav Hapla . numVertices - The number of vertices owned by this process, or PETSC_DECIDE 361225b6865aSVaclav Hapla . NVertices - The global number of vertices, or PETSC_DECIDE 3613a47d0d45SMatthew G. Knepley . numCorners - The number of vertices for each cell 3614a47d0d45SMatthew G. Knepley . interpolate - Flag indicating that intermediate mesh entities (faces, edges) should be created automatically 3615a47d0d45SMatthew G. Knepley . cells - An array of numCells*numCorners numbers, the global vertex numbers for each cell 3616a47d0d45SMatthew G. Knepley . spaceDim - The spatial dimension used for coordinates 3617a47d0d45SMatthew G. Knepley - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 3618a47d0d45SMatthew G. Knepley 3619a47d0d45SMatthew G. Knepley Output Parameter: 362018d54ad4SMichael Lange + dm - The DM 3621b09969d6SVaclav Hapla - vertexSF - (Optional) SF describing complete vertex ownership 3622a47d0d45SMatthew G. Knepley 3623b09969d6SVaclav Hapla Notes: 3624b09969d6SVaclav Hapla This function is just a convenient sequence of DMCreate(), DMSetType(), DMSetDimension(), 3625b09969d6SVaclav Hapla DMPlexBuildFromCellListParallel(), DMPlexInterpolate(), DMPlexBuildCoordinatesFromCellListParallel() 3626a47d0d45SMatthew G. Knepley 362725b6865aSVaclav Hapla See DMPlexBuildFromCellListParallel() for an example and details about the topology-related parameters. 362825b6865aSVaclav Hapla See DMPlexBuildCoordinatesFromCellListParallel() for details about the geometry-related parameters. 362925b6865aSVaclav Hapla 3630b09969d6SVaclav Hapla Level: intermediate 3631a47d0d45SMatthew G. Knepley 3632b09969d6SVaclav Hapla .seealso: DMPlexCreateFromCellListPetsc(), DMPlexBuildFromCellListParallel(), DMPlexBuildCoordinatesFromCellListParallel(), DMPlexCreateFromDAG(), DMPlexCreate() 3633a47d0d45SMatthew G. Knepley @*/ 363425b6865aSVaclav 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) 3635a47d0d45SMatthew G. Knepley { 3636a47d0d45SMatthew G. Knepley PetscSF sfVert; 3637a47d0d45SMatthew G. Knepley PetscErrorCode ierr; 3638a47d0d45SMatthew G. Knepley 3639a47d0d45SMatthew G. Knepley PetscFunctionBegin; 3640a47d0d45SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 3641a47d0d45SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 3642a47d0d45SMatthew G. Knepley PetscValidLogicalCollectiveInt(*dm, dim, 2); 3643064a246eSJacob Faibussowitsch PetscValidLogicalCollectiveInt(*dm, spaceDim, 9); 3644a47d0d45SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 364525b6865aSVaclav Hapla ierr = DMPlexBuildFromCellListParallel(*dm, numCells, numVertices, NVertices, numCorners, cells, &sfVert);CHKERRQ(ierr); 3646a47d0d45SMatthew G. Knepley if (interpolate) { 36475fd9971aSMatthew G. Knepley DM idm; 3648a47d0d45SMatthew G. Knepley 3649a47d0d45SMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 3650a47d0d45SMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 3651a47d0d45SMatthew G. Knepley *dm = idm; 3652a47d0d45SMatthew G. Knepley } 36531edcf0b2SVaclav Hapla ierr = DMPlexBuildCoordinatesFromCellListParallel(*dm, spaceDim, sfVert, vertexCoords);CHKERRQ(ierr); 365418d54ad4SMichael Lange if (vertexSF) *vertexSF = sfVert; 3655fba955ccSBarry Smith else {ierr = PetscSFDestroy(&sfVert);CHKERRQ(ierr);} 3656a47d0d45SMatthew G. Knepley PetscFunctionReturn(0); 3657a47d0d45SMatthew G. Knepley } 3658a47d0d45SMatthew G. Knepley 3659a4a685f2SJacob Faibussowitsch /*@ 3660a4a685f2SJacob Faibussowitsch DMPlexCreateFromCellListParallel - Deprecated, use DMPlexCreateFromCellListParallelPetsc() 3661a4a685f2SJacob Faibussowitsch 3662a4a685f2SJacob Faibussowitsch Level: deprecated 3663a4a685f2SJacob Faibussowitsch 3664a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromCellListParallelPetsc() 3665a4a685f2SJacob Faibussowitsch @*/ 3666a4a685f2SJacob 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) 3667a4a685f2SJacob Faibussowitsch { 3668a4a685f2SJacob Faibussowitsch PetscErrorCode ierr; 3669a4a685f2SJacob Faibussowitsch PetscInt i; 3670a4a685f2SJacob Faibussowitsch PetscInt *pintCells; 3671a4a685f2SJacob Faibussowitsch 3672a4a685f2SJacob Faibussowitsch PetscFunctionBegin; 3673a4a685f2SJacob 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)); 3674a4a685f2SJacob Faibussowitsch if (sizeof(int) == sizeof(PetscInt)) { 3675a4a685f2SJacob Faibussowitsch pintCells = (PetscInt *) cells; 3676a4a685f2SJacob Faibussowitsch } else { 3677a4a685f2SJacob Faibussowitsch ierr = PetscMalloc1(numCells*numCorners, &pintCells);CHKERRQ(ierr); 3678a4a685f2SJacob Faibussowitsch for (i = 0; i < numCells*numCorners; i++) { 3679a4a685f2SJacob Faibussowitsch pintCells[i] = (PetscInt) cells[i]; 3680a4a685f2SJacob Faibussowitsch } 3681a4a685f2SJacob Faibussowitsch } 368225b6865aSVaclav Hapla ierr = DMPlexCreateFromCellListParallelPetsc(comm, dim, numCells, numVertices, PETSC_DECIDE, numCorners, interpolate, pintCells, spaceDim, vertexCoords, vertexSF, dm);CHKERRQ(ierr); 3683a4a685f2SJacob Faibussowitsch if (sizeof(int) != sizeof(PetscInt)) { 3684a4a685f2SJacob Faibussowitsch ierr = PetscFree(pintCells);CHKERRQ(ierr); 3685a4a685f2SJacob Faibussowitsch } 3686a4a685f2SJacob Faibussowitsch PetscFunctionReturn(0); 3687a4a685f2SJacob Faibussowitsch } 3688a4a685f2SJacob Faibussowitsch 3689b09969d6SVaclav Hapla /*@C 3690b09969d6SVaclav Hapla DMPlexBuildFromCellList - Build DMPLEX topology from a list of vertices for each cell (common mesh generator output) 36919298eaa6SMatthew G Knepley 36929298eaa6SMatthew G Knepley Input Parameters: 3693b09969d6SVaclav Hapla + dm - The DM 3694b09969d6SVaclav Hapla . numCells - The number of cells owned by this process 369525b6865aSVaclav Hapla . numVertices - The number of vertices owned by this process, or PETSC_DECIDE 36969298eaa6SMatthew G Knepley . numCorners - The number of vertices for each cell 36975e488331SVaclav Hapla - cells - An array of numCells*numCorners numbers, the global vertex numbers for each cell 36989298eaa6SMatthew G Knepley 3699b09969d6SVaclav Hapla Level: advanced 37009298eaa6SMatthew G Knepley 3701b09969d6SVaclav Hapla Notes: 3702b09969d6SVaclav Hapla Two triangles sharing a face 37039298eaa6SMatthew G Knepley $ 37049298eaa6SMatthew G Knepley $ 2 37059298eaa6SMatthew G Knepley $ / | \ 37069298eaa6SMatthew G Knepley $ / | \ 37079298eaa6SMatthew G Knepley $ / | \ 37089298eaa6SMatthew G Knepley $ 0 0 | 1 3 37099298eaa6SMatthew G Knepley $ \ | / 37109298eaa6SMatthew G Knepley $ \ | / 37119298eaa6SMatthew G Knepley $ \ | / 37129298eaa6SMatthew G Knepley $ 1 37139298eaa6SMatthew G Knepley would have input 37149298eaa6SMatthew G Knepley $ numCells = 2, numVertices = 4 37159298eaa6SMatthew G Knepley $ cells = [0 1 2 1 3 2] 37169298eaa6SMatthew G Knepley $ 37179298eaa6SMatthew G Knepley which would result in the DMPlex 37189298eaa6SMatthew G Knepley $ 37199298eaa6SMatthew G Knepley $ 4 37209298eaa6SMatthew G Knepley $ / | \ 37219298eaa6SMatthew G Knepley $ / | \ 37229298eaa6SMatthew G Knepley $ / | \ 37239298eaa6SMatthew G Knepley $ 2 0 | 1 5 37249298eaa6SMatthew G Knepley $ \ | / 37259298eaa6SMatthew G Knepley $ \ | / 37269298eaa6SMatthew G Knepley $ \ | / 37279298eaa6SMatthew G Knepley $ 3 37289298eaa6SMatthew G Knepley 372925b6865aSVaclav Hapla If numVertices is PETSC_DECIDE, it is computed by PETSc as the maximum vertex index in cells + 1. 373025b6865aSVaclav Hapla 3731b09969d6SVaclav Hapla Not currently supported in Fortran. 37329298eaa6SMatthew G Knepley 3733b09969d6SVaclav Hapla .seealso: DMPlexBuildFromCellListParallel(), DMPlexBuildCoordinatesFromCellList(), DMPlexCreateFromCellListPetsc() 3734b09969d6SVaclav Hapla @*/ 37355e488331SVaclav Hapla PetscErrorCode DMPlexBuildFromCellList(DM dm, PetscInt numCells, PetscInt numVertices, PetscInt numCorners, const PetscInt cells[]) 3736b09969d6SVaclav Hapla { 3737961cfab0SVaclav Hapla PetscInt *cones, c, p, dim; 3738b09969d6SVaclav Hapla PetscErrorCode ierr; 3739b09969d6SVaclav Hapla 3740b09969d6SVaclav Hapla PetscFunctionBegin; 3741b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 3742b09969d6SVaclav Hapla ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 374325b6865aSVaclav Hapla /* Get/check global number of vertices */ 374425b6865aSVaclav Hapla { 374525b6865aSVaclav Hapla PetscInt NVerticesInCells, i; 374625b6865aSVaclav Hapla const PetscInt len = numCells * numCorners; 374725b6865aSVaclav Hapla 374825b6865aSVaclav Hapla /* NVerticesInCells = max(cells) + 1 */ 374925b6865aSVaclav Hapla NVerticesInCells = PETSC_MIN_INT; 375025b6865aSVaclav Hapla for (i=0; i<len; i++) if (cells[i] > NVerticesInCells) NVerticesInCells = cells[i]; 375125b6865aSVaclav Hapla ++NVerticesInCells; 375225b6865aSVaclav Hapla 375325b6865aSVaclav Hapla if (numVertices == PETSC_DECIDE) numVertices = NVerticesInCells; 375425b6865aSVaclav 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); 375525b6865aSVaclav Hapla } 3756b09969d6SVaclav Hapla ierr = DMPlexSetChart(dm, 0, numCells+numVertices);CHKERRQ(ierr); 3757b09969d6SVaclav Hapla for (c = 0; c < numCells; ++c) { 3758b09969d6SVaclav Hapla ierr = DMPlexSetConeSize(dm, c, numCorners);CHKERRQ(ierr); 3759b09969d6SVaclav Hapla } 3760b09969d6SVaclav Hapla ierr = DMSetUp(dm);CHKERRQ(ierr); 3761961cfab0SVaclav Hapla ierr = DMPlexGetCones(dm,&cones);CHKERRQ(ierr); 3762b09969d6SVaclav Hapla for (c = 0; c < numCells; ++c) { 3763b09969d6SVaclav Hapla for (p = 0; p < numCorners; ++p) { 3764961cfab0SVaclav Hapla cones[c*numCorners+p] = cells[c*numCorners+p]+numCells; 3765b09969d6SVaclav Hapla } 3766b09969d6SVaclav Hapla } 3767b09969d6SVaclav Hapla ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 3768b09969d6SVaclav Hapla ierr = DMPlexStratify(dm);CHKERRQ(ierr); 3769b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 3770b09969d6SVaclav Hapla PetscFunctionReturn(0); 3771b09969d6SVaclav Hapla } 3772b09969d6SVaclav Hapla 3773b09969d6SVaclav Hapla /*@C 3774b09969d6SVaclav Hapla DMPlexBuildCoordinatesFromCellList - Build DM coordinates from a list of coordinates for each owned vertex (common mesh generator output) 3775b09969d6SVaclav Hapla 3776b09969d6SVaclav Hapla Input Parameters: 3777b09969d6SVaclav Hapla + dm - The DM 3778b09969d6SVaclav Hapla . spaceDim - The spatial dimension used for coordinates 3779b09969d6SVaclav Hapla - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 3780b09969d6SVaclav Hapla 3781b09969d6SVaclav Hapla Level: advanced 3782b09969d6SVaclav Hapla 3783b09969d6SVaclav Hapla Notes: 3784b09969d6SVaclav Hapla Not currently supported in Fortran. 3785b09969d6SVaclav Hapla 3786b09969d6SVaclav Hapla .seealso: DMPlexBuildCoordinatesFromCellListParallel(), DMPlexCreateFromCellListPetsc(), DMPlexBuildFromCellList() 3787b09969d6SVaclav Hapla @*/ 37881edcf0b2SVaclav Hapla PetscErrorCode DMPlexBuildCoordinatesFromCellList(DM dm, PetscInt spaceDim, const PetscReal vertexCoords[]) 3789b09969d6SVaclav Hapla { 3790b09969d6SVaclav Hapla PetscSection coordSection; 3791b09969d6SVaclav Hapla Vec coordinates; 3792b09969d6SVaclav Hapla DM cdm; 3793b09969d6SVaclav Hapla PetscScalar *coords; 37941edcf0b2SVaclav Hapla PetscInt v, vStart, vEnd, d; 3795b09969d6SVaclav Hapla PetscErrorCode ierr; 3796b09969d6SVaclav Hapla 3797b09969d6SVaclav Hapla PetscFunctionBegin; 3798b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 37991edcf0b2SVaclav Hapla ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 38001edcf0b2SVaclav 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."); 3801b09969d6SVaclav Hapla ierr = DMSetCoordinateDim(dm, spaceDim);CHKERRQ(ierr); 3802b09969d6SVaclav Hapla ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 3803b09969d6SVaclav Hapla ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 3804b09969d6SVaclav Hapla ierr = PetscSectionSetFieldComponents(coordSection, 0, spaceDim);CHKERRQ(ierr); 38051edcf0b2SVaclav Hapla ierr = PetscSectionSetChart(coordSection, vStart, vEnd);CHKERRQ(ierr); 38061edcf0b2SVaclav Hapla for (v = vStart; v < vEnd; ++v) { 3807b09969d6SVaclav Hapla ierr = PetscSectionSetDof(coordSection, v, spaceDim);CHKERRQ(ierr); 3808b09969d6SVaclav Hapla ierr = PetscSectionSetFieldDof(coordSection, v, 0, spaceDim);CHKERRQ(ierr); 3809b09969d6SVaclav Hapla } 3810b09969d6SVaclav Hapla ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 3811b09969d6SVaclav Hapla 3812b09969d6SVaclav Hapla ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 3813b09969d6SVaclav Hapla ierr = DMCreateLocalVector(cdm, &coordinates);CHKERRQ(ierr); 3814b09969d6SVaclav Hapla ierr = VecSetBlockSize(coordinates, spaceDim);CHKERRQ(ierr); 3815b09969d6SVaclav Hapla ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 381699946890SBarry Smith ierr = VecGetArrayWrite(coordinates, &coords);CHKERRQ(ierr); 38171edcf0b2SVaclav Hapla for (v = 0; v < vEnd-vStart; ++v) { 3818b09969d6SVaclav Hapla for (d = 0; d < spaceDim; ++d) { 3819b09969d6SVaclav Hapla coords[v*spaceDim+d] = vertexCoords[v*spaceDim+d]; 3820b09969d6SVaclav Hapla } 3821b09969d6SVaclav Hapla } 382299946890SBarry Smith ierr = VecRestoreArrayWrite(coordinates, &coords);CHKERRQ(ierr); 3823b09969d6SVaclav Hapla ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 3824b09969d6SVaclav Hapla ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 3825b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 3826b09969d6SVaclav Hapla PetscFunctionReturn(0); 3827b09969d6SVaclav Hapla } 3828b09969d6SVaclav Hapla 3829b09969d6SVaclav Hapla /*@ 3830b09969d6SVaclav Hapla DMPlexCreateFromCellListPetsc - Create DMPLEX from a list of vertices for each cell (common mesh generator output) 3831b09969d6SVaclav Hapla 3832b09969d6SVaclav Hapla Input Parameters: 3833b09969d6SVaclav Hapla + comm - The communicator 3834b09969d6SVaclav Hapla . dim - The topological dimension of the mesh 3835b09969d6SVaclav Hapla . numCells - The number of cells 383625b6865aSVaclav Hapla . numVertices - The number of vertices owned by this process, or PETSC_DECIDE 3837b09969d6SVaclav Hapla . numCorners - The number of vertices for each cell 3838b09969d6SVaclav Hapla . interpolate - Flag indicating that intermediate mesh entities (faces, edges) should be created automatically 3839b09969d6SVaclav Hapla . cells - An array of numCells*numCorners numbers, the vertices for each cell 3840b09969d6SVaclav Hapla . spaceDim - The spatial dimension used for coordinates 3841b09969d6SVaclav Hapla - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 3842b09969d6SVaclav Hapla 3843b09969d6SVaclav Hapla Output Parameter: 3844b09969d6SVaclav Hapla . dm - The DM 3845b09969d6SVaclav Hapla 3846b09969d6SVaclav Hapla Notes: 3847b09969d6SVaclav Hapla This function is just a convenient sequence of DMCreate(), DMSetType(), DMSetDimension(), DMPlexBuildFromCellList(), 3848b09969d6SVaclav Hapla DMPlexInterpolate(), DMPlexBuildCoordinatesFromCellList() 3849b09969d6SVaclav Hapla 385025b6865aSVaclav Hapla See DMPlexBuildFromCellList() for an example and details about the topology-related parameters. 385125b6865aSVaclav Hapla See DMPlexBuildCoordinatesFromCellList() for details about the geometry-related parameters. 385225b6865aSVaclav Hapla 3853b09969d6SVaclav Hapla Level: intermediate 3854b09969d6SVaclav Hapla 3855b09969d6SVaclav Hapla .seealso: DMPlexCreateFromCellListParallelPetsc(), DMPlexBuildFromCellList(), DMPlexBuildCoordinatesFromCellList(), DMPlexCreateFromDAG(), DMPlexCreate() 38569298eaa6SMatthew G Knepley @*/ 3857a4a685f2SJacob 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) 38589298eaa6SMatthew G Knepley { 38599298eaa6SMatthew G Knepley PetscErrorCode ierr; 38609298eaa6SMatthew G Knepley 38619298eaa6SMatthew G Knepley PetscFunctionBegin; 38625fd8819aSMatthew 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."); 38639298eaa6SMatthew G Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 38649298eaa6SMatthew G Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 3865c73cfb54SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 38665e488331SVaclav Hapla ierr = DMPlexBuildFromCellList(*dm, numCells, numVertices, numCorners, cells);CHKERRQ(ierr); 38679298eaa6SMatthew G Knepley if (interpolate) { 38685fd9971aSMatthew G. Knepley DM idm; 38699298eaa6SMatthew G Knepley 38709298eaa6SMatthew G Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 38719298eaa6SMatthew G Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 38729298eaa6SMatthew G Knepley *dm = idm; 38739298eaa6SMatthew G Knepley } 38741edcf0b2SVaclav Hapla ierr = DMPlexBuildCoordinatesFromCellList(*dm, spaceDim, vertexCoords);CHKERRQ(ierr); 38759298eaa6SMatthew G Knepley PetscFunctionReturn(0); 38769298eaa6SMatthew G Knepley } 38779298eaa6SMatthew G Knepley 3878939f6067SMatthew G. Knepley /*@ 3879a4a685f2SJacob Faibussowitsch DMPlexCreateFromCellList - Deprecated, use DMPlexCreateFromCellListPetsc() 3880a4a685f2SJacob Faibussowitsch 3881a4a685f2SJacob Faibussowitsch Level: deprecated 3882a4a685f2SJacob Faibussowitsch 3883a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromCellListPetsc() 3884a4a685f2SJacob Faibussowitsch @*/ 3885a4a685f2SJacob 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) 3886a4a685f2SJacob Faibussowitsch { 3887a4a685f2SJacob Faibussowitsch PetscErrorCode ierr; 3888a4a685f2SJacob Faibussowitsch PetscInt i; 3889a4a685f2SJacob Faibussowitsch PetscInt *pintCells; 3890a4a685f2SJacob Faibussowitsch PetscReal *prealVC; 3891a4a685f2SJacob Faibussowitsch 3892a4a685f2SJacob Faibussowitsch PetscFunctionBegin; 3893a4a685f2SJacob 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)); 3894a4a685f2SJacob Faibussowitsch if (sizeof(int) == sizeof(PetscInt)) { 3895a4a685f2SJacob Faibussowitsch pintCells = (PetscInt *) cells; 3896a4a685f2SJacob Faibussowitsch } else { 3897a4a685f2SJacob Faibussowitsch ierr = PetscMalloc1(numCells*numCorners, &pintCells);CHKERRQ(ierr); 3898a4a685f2SJacob Faibussowitsch for (i = 0; i < numCells*numCorners; i++) { 3899a4a685f2SJacob Faibussowitsch pintCells[i] = (PetscInt) cells[i]; 3900a4a685f2SJacob Faibussowitsch } 3901a4a685f2SJacob Faibussowitsch } 3902a4a685f2SJacob 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)); 3903a4a685f2SJacob Faibussowitsch if (sizeof(double) == sizeof(PetscReal)) { 3904a4a685f2SJacob Faibussowitsch prealVC = (PetscReal *) vertexCoords; 3905a4a685f2SJacob Faibussowitsch } else { 3906a4a685f2SJacob Faibussowitsch ierr = PetscMalloc1(numVertices*spaceDim, &prealVC);CHKERRQ(ierr); 3907a4a685f2SJacob Faibussowitsch for (i = 0; i < numVertices*spaceDim; i++) { 3908a4a685f2SJacob Faibussowitsch prealVC[i] = (PetscReal) vertexCoords[i]; 3909a4a685f2SJacob Faibussowitsch } 3910a4a685f2SJacob Faibussowitsch } 3911a4a685f2SJacob Faibussowitsch ierr = DMPlexCreateFromCellListPetsc(comm, dim, numCells, numVertices, numCorners, interpolate, pintCells, spaceDim, prealVC, dm);CHKERRQ(ierr); 3912a4a685f2SJacob Faibussowitsch if (sizeof(int) != sizeof(PetscInt)) { 3913a4a685f2SJacob Faibussowitsch ierr = PetscFree(pintCells);CHKERRQ(ierr); 3914a4a685f2SJacob Faibussowitsch } 3915a4a685f2SJacob Faibussowitsch if (sizeof(double) != sizeof(PetscReal)) { 3916a4a685f2SJacob Faibussowitsch ierr = PetscFree(prealVC);CHKERRQ(ierr); 3917a4a685f2SJacob Faibussowitsch } 3918a4a685f2SJacob Faibussowitsch PetscFunctionReturn(0); 3919a4a685f2SJacob Faibussowitsch } 3920a4a685f2SJacob Faibussowitsch 3921a4a685f2SJacob Faibussowitsch /*@ 3922939f6067SMatthew 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 3923939f6067SMatthew G. Knepley 3924939f6067SMatthew G. Knepley Input Parameters: 3925c73cfb54SMatthew G. Knepley + dm - The empty DM object, usually from DMCreate() and DMSetDimension() 3926939f6067SMatthew G. Knepley . depth - The depth of the DAG 3927367003a6SStefano Zampini . numPoints - Array of size depth + 1 containing the number of points at each depth 3928939f6067SMatthew G. Knepley . coneSize - The cone size of each point 3929939f6067SMatthew G. Knepley . cones - The concatenation of the cone points for each point, the cone list must be oriented correctly for each point 3930939f6067SMatthew G. Knepley . coneOrientations - The orientation of each cone point 3931367003a6SStefano Zampini - vertexCoords - An array of numPoints[0]*spacedim numbers representing the coordinates of each vertex, with spacedim the value set via DMSetCoordinateDim() 3932939f6067SMatthew G. Knepley 3933939f6067SMatthew G. Knepley Output Parameter: 3934939f6067SMatthew G. Knepley . dm - The DM 3935939f6067SMatthew G. Knepley 3936939f6067SMatthew G. Knepley Note: Two triangles sharing a face would have input 3937939f6067SMatthew G. Knepley $ depth = 1, numPoints = [4 2], coneSize = [3 3 0 0 0 0] 3938939f6067SMatthew G. Knepley $ cones = [2 3 4 3 5 4], coneOrientations = [0 0 0 0 0 0] 3939939f6067SMatthew G. Knepley $ vertexCoords = [-1.0 0.0 0.0 -1.0 0.0 1.0 1.0 0.0] 3940939f6067SMatthew G. Knepley $ 3941939f6067SMatthew G. Knepley which would result in the DMPlex 3942939f6067SMatthew G. Knepley $ 3943939f6067SMatthew G. Knepley $ 4 3944939f6067SMatthew G. Knepley $ / | \ 3945939f6067SMatthew G. Knepley $ / | \ 3946939f6067SMatthew G. Knepley $ / | \ 3947939f6067SMatthew G. Knepley $ 2 0 | 1 5 3948939f6067SMatthew G. Knepley $ \ | / 3949939f6067SMatthew G. Knepley $ \ | / 3950939f6067SMatthew G. Knepley $ \ | / 3951939f6067SMatthew G. Knepley $ 3 3952939f6067SMatthew G. Knepley $ 3953a4a685f2SJacob Faibussowitsch $ Notice that all points are numbered consecutively, unlike DMPlexCreateFromCellListPetsc() 3954939f6067SMatthew G. Knepley 3955939f6067SMatthew G. Knepley Level: advanced 3956939f6067SMatthew G. Knepley 3957a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromCellListPetsc(), DMPlexCreate() 3958939f6067SMatthew G. Knepley @*/ 39599298eaa6SMatthew G Knepley PetscErrorCode DMPlexCreateFromDAG(DM dm, PetscInt depth, const PetscInt numPoints[], const PetscInt coneSize[], const PetscInt cones[], const PetscInt coneOrientations[], const PetscScalar vertexCoords[]) 39609298eaa6SMatthew G Knepley { 39619298eaa6SMatthew G Knepley Vec coordinates; 39629298eaa6SMatthew G Knepley PetscSection coordSection; 39639298eaa6SMatthew G Knepley PetscScalar *coords; 3964811e8653SToby Isaac PetscInt coordSize, firstVertex = -1, pStart = 0, pEnd = 0, p, v, dim, dimEmbed, d, off; 39659298eaa6SMatthew G Knepley PetscErrorCode ierr; 39669298eaa6SMatthew G Knepley 39679298eaa6SMatthew G Knepley PetscFunctionBegin; 3968c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 3969811e8653SToby Isaac ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr); 397089c010cfSBarry Smith if (dimEmbed < dim) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Embedding dimension %D cannot be less than intrinsic dimension %d",dimEmbed,dim); 39719298eaa6SMatthew G Knepley for (d = 0; d <= depth; ++d) pEnd += numPoints[d]; 39729298eaa6SMatthew G Knepley ierr = DMPlexSetChart(dm, pStart, pEnd);CHKERRQ(ierr); 39739298eaa6SMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 39749298eaa6SMatthew G Knepley ierr = DMPlexSetConeSize(dm, p, coneSize[p-pStart]);CHKERRQ(ierr); 397597e052ccSToby Isaac if (firstVertex < 0 && !coneSize[p - pStart]) { 397697e052ccSToby Isaac firstVertex = p - pStart; 39779298eaa6SMatthew G Knepley } 397897e052ccSToby Isaac } 397989c010cfSBarry Smith if (firstVertex < 0 && numPoints[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Expected %D vertices but could not find any", numPoints[0]); 39809298eaa6SMatthew G Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 39819298eaa6SMatthew G Knepley for (p = pStart, off = 0; p < pEnd; off += coneSize[p-pStart], ++p) { 39829298eaa6SMatthew G Knepley ierr = DMPlexSetCone(dm, p, &cones[off]);CHKERRQ(ierr); 39839298eaa6SMatthew G Knepley ierr = DMPlexSetConeOrientation(dm, p, &coneOrientations[off]);CHKERRQ(ierr); 39849298eaa6SMatthew G Knepley } 39859298eaa6SMatthew G Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 39869298eaa6SMatthew G Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 39879298eaa6SMatthew G Knepley /* Build coordinates */ 3988c2166f76SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 39899298eaa6SMatthew G Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 3990811e8653SToby Isaac ierr = PetscSectionSetFieldComponents(coordSection, 0, dimEmbed);CHKERRQ(ierr); 39919298eaa6SMatthew G Knepley ierr = PetscSectionSetChart(coordSection, firstVertex, firstVertex+numPoints[0]);CHKERRQ(ierr); 39929298eaa6SMatthew G Knepley for (v = firstVertex; v < firstVertex+numPoints[0]; ++v) { 3993811e8653SToby Isaac ierr = PetscSectionSetDof(coordSection, v, dimEmbed);CHKERRQ(ierr); 3994811e8653SToby Isaac ierr = PetscSectionSetFieldDof(coordSection, v, 0, dimEmbed);CHKERRQ(ierr); 39959298eaa6SMatthew G Knepley } 39969298eaa6SMatthew G Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 39979298eaa6SMatthew G Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 39988b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 39996f8cbbeeSMatthew G Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 40009298eaa6SMatthew G Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 40018b9ced59SLisandro Dalcin ierr = VecSetBlockSize(coordinates, dimEmbed);CHKERRQ(ierr); 40022eb5907fSJed Brown ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 40039318fe57SMatthew G. Knepley if (vertexCoords) { 40049298eaa6SMatthew G Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 40059298eaa6SMatthew G Knepley for (v = 0; v < numPoints[0]; ++v) { 40069298eaa6SMatthew G Knepley PetscInt off; 40079298eaa6SMatthew G Knepley 40089298eaa6SMatthew G Knepley ierr = PetscSectionGetOffset(coordSection, v+firstVertex, &off);CHKERRQ(ierr); 4009811e8653SToby Isaac for (d = 0; d < dimEmbed; ++d) { 4010811e8653SToby Isaac coords[off+d] = vertexCoords[v*dimEmbed+d]; 40119298eaa6SMatthew G Knepley } 40129298eaa6SMatthew G Knepley } 40139318fe57SMatthew G. Knepley } 40149298eaa6SMatthew G Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 40159298eaa6SMatthew G Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 40169298eaa6SMatthew G Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 40179298eaa6SMatthew G Knepley PetscFunctionReturn(0); 40189298eaa6SMatthew G Knepley } 40198415267dSToby Isaac 4020ca522641SMatthew G. Knepley /*@C 40218ca92349SMatthew G. Knepley DMPlexCreateCellVertexFromFile - Create a DMPlex mesh from a simple cell-vertex file. 40228ca92349SMatthew G. Knepley 40238ca92349SMatthew G. Knepley + comm - The MPI communicator 40248ca92349SMatthew G. Knepley . filename - Name of the .dat file 40258ca92349SMatthew G. Knepley - interpolate - Create faces and edges in the mesh 40268ca92349SMatthew G. Knepley 40278ca92349SMatthew G. Knepley Output Parameter: 40288ca92349SMatthew G. Knepley . dm - The DM object representing the mesh 40298ca92349SMatthew G. Knepley 40308ca92349SMatthew G. Knepley Note: The format is the simplest possible: 40318ca92349SMatthew G. Knepley $ Ne 40328ca92349SMatthew G. Knepley $ v0 v1 ... vk 40338ca92349SMatthew G. Knepley $ Nv 40348ca92349SMatthew G. Knepley $ x y z marker 40358ca92349SMatthew G. Knepley 40368ca92349SMatthew G. Knepley Level: beginner 40378ca92349SMatthew G. Knepley 40388ca92349SMatthew G. Knepley .seealso: DMPlexCreateFromFile(), DMPlexCreateMedFromFile(), DMPlexCreateGmsh(), DMPlexCreate() 40398ca92349SMatthew G. Knepley @*/ 40408ca92349SMatthew G. Knepley PetscErrorCode DMPlexCreateCellVertexFromFile(MPI_Comm comm, const char filename[], PetscBool interpolate, DM *dm) 40418ca92349SMatthew G. Knepley { 40428ca92349SMatthew G. Knepley DMLabel marker; 40438ca92349SMatthew G. Knepley PetscViewer viewer; 40448ca92349SMatthew G. Knepley Vec coordinates; 40458ca92349SMatthew G. Knepley PetscSection coordSection; 40468ca92349SMatthew G. Knepley PetscScalar *coords; 40478ca92349SMatthew G. Knepley char line[PETSC_MAX_PATH_LEN]; 40488ca92349SMatthew G. Knepley PetscInt dim = 3, cdim = 3, coordSize, v, c, d; 40498ca92349SMatthew G. Knepley PetscMPIInt rank; 40508ca92349SMatthew G. Knepley int snum, Nv, Nc; 40518ca92349SMatthew G. Knepley PetscErrorCode ierr; 40528ca92349SMatthew G. Knepley 40538ca92349SMatthew G. Knepley PetscFunctionBegin; 4054ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 40558ca92349SMatthew G. Knepley ierr = PetscViewerCreate(comm, &viewer);CHKERRQ(ierr); 40568ca92349SMatthew G. Knepley ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr); 40578ca92349SMatthew G. Knepley ierr = PetscViewerFileSetMode(viewer, FILE_MODE_READ);CHKERRQ(ierr); 40588ca92349SMatthew G. Knepley ierr = PetscViewerFileSetName(viewer, filename);CHKERRQ(ierr); 40598ca92349SMatthew G. Knepley if (!rank) { 40608ca92349SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 2, NULL, PETSC_STRING);CHKERRQ(ierr); 40618ca92349SMatthew G. Knepley snum = sscanf(line, "%d %d", &Nc, &Nv); 40628ca92349SMatthew G. Knepley if (snum != 2) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 406325ce1634SJed Brown } else { 406425ce1634SJed Brown Nc = Nv = 0; 40658ca92349SMatthew G. Knepley } 40668ca92349SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 40678ca92349SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 40688ca92349SMatthew G. Knepley ierr = DMPlexSetChart(*dm, 0, Nc+Nv);CHKERRQ(ierr); 40698ca92349SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 40708ca92349SMatthew G. Knepley ierr = DMSetCoordinateDim(*dm, cdim);CHKERRQ(ierr); 40718ca92349SMatthew G. Knepley /* Read topology */ 40728ca92349SMatthew G. Knepley if (!rank) { 40738ca92349SMatthew G. Knepley PetscInt cone[8], corners = 8; 40748ca92349SMatthew G. Knepley int vbuf[8], v; 40758ca92349SMatthew G. Knepley 40768ca92349SMatthew G. Knepley for (c = 0; c < Nc; ++c) {ierr = DMPlexSetConeSize(*dm, c, corners);CHKERRQ(ierr);} 40778ca92349SMatthew G. Knepley ierr = DMSetUp(*dm);CHKERRQ(ierr); 40788ca92349SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 40798ca92349SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, corners, NULL, PETSC_STRING);CHKERRQ(ierr); 40808ca92349SMatthew 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]); 40818ca92349SMatthew G. Knepley if (snum != corners) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 40828ca92349SMatthew G. Knepley for (v = 0; v < corners; ++v) cone[v] = vbuf[v] + Nc; 40838ca92349SMatthew G. Knepley /* Hexahedra are inverted */ 40848ca92349SMatthew G. Knepley { 40858ca92349SMatthew G. Knepley PetscInt tmp = cone[1]; 40868ca92349SMatthew G. Knepley cone[1] = cone[3]; 40878ca92349SMatthew G. Knepley cone[3] = tmp; 40888ca92349SMatthew G. Knepley } 40898ca92349SMatthew G. Knepley ierr = DMPlexSetCone(*dm, c, cone);CHKERRQ(ierr); 40908ca92349SMatthew G. Knepley } 40918ca92349SMatthew G. Knepley } 40928ca92349SMatthew G. Knepley ierr = DMPlexSymmetrize(*dm);CHKERRQ(ierr); 40938ca92349SMatthew G. Knepley ierr = DMPlexStratify(*dm);CHKERRQ(ierr); 40948ca92349SMatthew G. Knepley /* Read coordinates */ 40958ca92349SMatthew G. Knepley ierr = DMGetCoordinateSection(*dm, &coordSection);CHKERRQ(ierr); 40968ca92349SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 40978ca92349SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, cdim);CHKERRQ(ierr); 40988ca92349SMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, Nc, Nc + Nv);CHKERRQ(ierr); 40998ca92349SMatthew G. Knepley for (v = Nc; v < Nc+Nv; ++v) { 41008ca92349SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, cdim);CHKERRQ(ierr); 41018ca92349SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, cdim);CHKERRQ(ierr); 41028ca92349SMatthew G. Knepley } 41038ca92349SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 41048ca92349SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 41058ca92349SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 41068ca92349SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 41078ca92349SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 41088ca92349SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, cdim);CHKERRQ(ierr); 41098ca92349SMatthew G. Knepley ierr = VecSetType(coordinates, VECSTANDARD);CHKERRQ(ierr); 41108ca92349SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 41118ca92349SMatthew G. Knepley if (!rank) { 41128ca92349SMatthew G. Knepley double x[3]; 41138ca92349SMatthew G. Knepley int val; 41148ca92349SMatthew G. Knepley 41158ca92349SMatthew G. Knepley ierr = DMCreateLabel(*dm, "marker");CHKERRQ(ierr); 41168ca92349SMatthew G. Knepley ierr = DMGetLabel(*dm, "marker", &marker);CHKERRQ(ierr); 41178ca92349SMatthew G. Knepley for (v = 0; v < Nv; ++v) { 41188ca92349SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 4, NULL, PETSC_STRING);CHKERRQ(ierr); 41198ca92349SMatthew G. Knepley snum = sscanf(line, "%lg %lg %lg %d", &x[0], &x[1], &x[2], &val); 41208ca92349SMatthew G. Knepley if (snum != 4) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 41218ca92349SMatthew G. Knepley for (d = 0; d < cdim; ++d) coords[v*cdim+d] = x[d]; 41228ca92349SMatthew G. Knepley if (val) {ierr = DMLabelSetValue(marker, v+Nc, val);CHKERRQ(ierr);} 41238ca92349SMatthew G. Knepley } 41248ca92349SMatthew G. Knepley } 41258ca92349SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 41268ca92349SMatthew G. Knepley ierr = DMSetCoordinatesLocal(*dm, coordinates);CHKERRQ(ierr); 41278ca92349SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 41288ca92349SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 41298ca92349SMatthew G. Knepley if (interpolate) { 41308ca92349SMatthew G. Knepley DM idm; 41318ca92349SMatthew G. Knepley DMLabel bdlabel; 41328ca92349SMatthew G. Knepley 41338ca92349SMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 41348ca92349SMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 41358ca92349SMatthew G. Knepley *dm = idm; 41368ca92349SMatthew G. Knepley 41378ca92349SMatthew G. Knepley ierr = DMGetLabel(*dm, "marker", &bdlabel);CHKERRQ(ierr); 41388ca92349SMatthew G. Knepley ierr = DMPlexMarkBoundaryFaces(*dm, PETSC_DETERMINE, bdlabel);CHKERRQ(ierr); 41398ca92349SMatthew G. Knepley ierr = DMPlexLabelComplete(*dm, bdlabel);CHKERRQ(ierr); 41408ca92349SMatthew G. Knepley } 41418ca92349SMatthew G. Knepley PetscFunctionReturn(0); 41428ca92349SMatthew G. Knepley } 41438ca92349SMatthew G. Knepley 41448ca92349SMatthew G. Knepley /*@C 4145ca522641SMatthew G. Knepley DMPlexCreateFromFile - This takes a filename and produces a DM 4146ca522641SMatthew G. Knepley 4147ca522641SMatthew G. Knepley Input Parameters: 4148ca522641SMatthew G. Knepley + comm - The communicator 4149ca522641SMatthew G. Knepley . filename - A file name 4150ca522641SMatthew G. Knepley - interpolate - Flag to create intermediate mesh pieces (edges, faces) 4151ca522641SMatthew G. Knepley 4152ca522641SMatthew G. Knepley Output Parameter: 4153ca522641SMatthew G. Knepley . dm - The DM 4154ca522641SMatthew G. Knepley 415502ef0d99SVaclav Hapla Options Database Keys: 415602ef0d99SVaclav Hapla . -dm_plex_create_from_hdf5_xdmf - use the PETSC_VIEWER_HDF5_XDMF format for reading HDF5 415702ef0d99SVaclav Hapla 4158bca97951SVaclav Hapla Use -dm_plex_create_ prefix to pass options to the internal PetscViewer, e.g. 4159bca97951SVaclav Hapla $ -dm_plex_create_viewer_hdf5_collective 4160bca97951SVaclav Hapla 4161ca522641SMatthew G. Knepley Level: beginner 4162ca522641SMatthew G. Knepley 4163a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromDAG(), DMPlexCreateFromCellListPetsc(), DMPlexCreate() 4164ca522641SMatthew G. Knepley @*/ 4165ca522641SMatthew G. Knepley PetscErrorCode DMPlexCreateFromFile(MPI_Comm comm, const char filename[], PetscBool interpolate, DM *dm) 4166ca522641SMatthew G. Knepley { 4167ca522641SMatthew G. Knepley const char *extGmsh = ".msh"; 4168de78e4feSLisandro Dalcin const char *extGmsh2 = ".msh2"; 4169de78e4feSLisandro Dalcin const char *extGmsh4 = ".msh4"; 4170ca522641SMatthew G. Knepley const char *extCGNS = ".cgns"; 4171ca522641SMatthew G. Knepley const char *extExodus = ".exo"; 417290c68965SMatthew G. Knepley const char *extGenesis = ".gen"; 41732f0bd6dcSMichael Lange const char *extFluent = ".cas"; 4174cc2f8f65SMatthew G. Knepley const char *extHDF5 = ".h5"; 4175707dd687SMichael Lange const char *extMed = ".med"; 4176f2801cd6SMatthew G. Knepley const char *extPLY = ".ply"; 4177c1cad2e7SMatthew G. Knepley const char *extEGADSLite = ".egadslite"; 4178c1cad2e7SMatthew G. Knepley const char *extEGADS = ".egads"; 4179c1cad2e7SMatthew G. Knepley const char *extIGES = ".igs"; 4180c1cad2e7SMatthew G. Knepley const char *extSTEP = ".stp"; 41818ca92349SMatthew G. Knepley const char *extCV = ".dat"; 4182ca522641SMatthew G. Knepley size_t len; 4183c1cad2e7SMatthew G. Knepley PetscBool isGmsh, isGmsh2, isGmsh4, isCGNS, isExodus, isGenesis, isFluent, isHDF5, isMed, isPLY, isEGADSLite, isEGADS, isIGES, isSTEP, isCV; 4184ca522641SMatthew G. Knepley PetscMPIInt rank; 4185ca522641SMatthew G. Knepley PetscErrorCode ierr; 4186ca522641SMatthew G. Knepley 4187ca522641SMatthew G. Knepley PetscFunctionBegin; 41885d80c0bfSVaclav Hapla PetscValidCharPointer(filename, 2); 4189ca522641SMatthew G. Knepley PetscValidPointer(dm, 4); 4190f1f45c63SVaclav Hapla ierr = DMInitializePackage();CHKERRQ(ierr); 4191f1f45c63SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_CreateFromFile,0,0,0,0);CHKERRQ(ierr); 4192ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 4193ca522641SMatthew G. Knepley ierr = PetscStrlen(filename, &len);CHKERRQ(ierr); 4194ca522641SMatthew G. Knepley if (!len) SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Filename must be a valid path"); 4195ca522641SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extGmsh, 4, &isGmsh);CHKERRQ(ierr); 4196de78e4feSLisandro Dalcin ierr = PetscStrncmp(&filename[PetscMax(0,len-5)], extGmsh2, 5, &isGmsh2);CHKERRQ(ierr); 4197de78e4feSLisandro Dalcin ierr = PetscStrncmp(&filename[PetscMax(0,len-5)], extGmsh4, 5, &isGmsh4);CHKERRQ(ierr); 4198ca522641SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-5)], extCGNS, 5, &isCGNS);CHKERRQ(ierr); 4199ca522641SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extExodus, 4, &isExodus);CHKERRQ(ierr); 420090c68965SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extGenesis, 4, &isGenesis);CHKERRQ(ierr); 42012f0bd6dcSMichael Lange ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extFluent, 4, &isFluent);CHKERRQ(ierr); 4202cc2f8f65SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-3)], extHDF5, 3, &isHDF5);CHKERRQ(ierr); 4203707dd687SMichael Lange ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extMed, 4, &isMed);CHKERRQ(ierr); 4204f2801cd6SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extPLY, 4, &isPLY);CHKERRQ(ierr); 4205c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-10)], extEGADSLite, 10, &isEGADSLite);CHKERRQ(ierr); 4206c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-6)], extEGADS, 6, &isEGADS);CHKERRQ(ierr); 4207c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extIGES, 4, &isIGES);CHKERRQ(ierr); 4208c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extSTEP, 4, &isSTEP);CHKERRQ(ierr); 42098ca92349SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extCV, 4, &isCV);CHKERRQ(ierr); 4210de78e4feSLisandro Dalcin if (isGmsh || isGmsh2 || isGmsh4) { 42117d282ae0SMichael Lange ierr = DMPlexCreateGmshFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4212ca522641SMatthew G. Knepley } else if (isCGNS) { 4213ca522641SMatthew G. Knepley ierr = DMPlexCreateCGNSFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 421490c68965SMatthew G. Knepley } else if (isExodus || isGenesis) { 4215ca522641SMatthew G. Knepley ierr = DMPlexCreateExodusFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 42162f0bd6dcSMichael Lange } else if (isFluent) { 42172f0bd6dcSMichael Lange ierr = DMPlexCreateFluentFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4218cc2f8f65SMatthew G. Knepley } else if (isHDF5) { 42199c48423bSVaclav Hapla PetscBool load_hdf5_xdmf = PETSC_FALSE; 4220cc2f8f65SMatthew G. Knepley PetscViewer viewer; 4221cc2f8f65SMatthew G. Knepley 422243b242b4SVaclav 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 */ 422343b242b4SVaclav Hapla ierr = PetscStrncmp(&filename[PetscMax(0,len-8)], ".xdmf", 5, &load_hdf5_xdmf);CHKERRQ(ierr); 42249c48423bSVaclav Hapla ierr = PetscOptionsGetBool(NULL, NULL, "-dm_plex_create_from_hdf5_xdmf", &load_hdf5_xdmf, NULL);CHKERRQ(ierr); 4225cc2f8f65SMatthew G. Knepley ierr = PetscViewerCreate(comm, &viewer);CHKERRQ(ierr); 4226cc2f8f65SMatthew G. Knepley ierr = PetscViewerSetType(viewer, PETSCVIEWERHDF5);CHKERRQ(ierr); 4227bca97951SVaclav Hapla ierr = PetscViewerSetOptionsPrefix(viewer, "dm_plex_create_");CHKERRQ(ierr); 4228bca97951SVaclav Hapla ierr = PetscViewerSetFromOptions(viewer);CHKERRQ(ierr); 4229cc2f8f65SMatthew G. Knepley ierr = PetscViewerFileSetMode(viewer, FILE_MODE_READ);CHKERRQ(ierr); 4230cc2f8f65SMatthew G. Knepley ierr = PetscViewerFileSetName(viewer, filename);CHKERRQ(ierr); 4231cc2f8f65SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 4232cc2f8f65SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 42339c48423bSVaclav Hapla if (load_hdf5_xdmf) {ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_HDF5_XDMF);CHKERRQ(ierr);} 4234cc2f8f65SMatthew G. Knepley ierr = DMLoad(*dm, viewer);CHKERRQ(ierr); 42359c48423bSVaclav Hapla if (load_hdf5_xdmf) {ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);} 4236cc2f8f65SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 42375fd9971aSMatthew G. Knepley 42385fd9971aSMatthew G. Knepley if (interpolate) { 42395fd9971aSMatthew G. Knepley DM idm; 42405fd9971aSMatthew G. Knepley 42415fd9971aSMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 42425fd9971aSMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 42435fd9971aSMatthew G. Knepley *dm = idm; 42445fd9971aSMatthew G. Knepley } 4245707dd687SMichael Lange } else if (isMed) { 4246707dd687SMichael Lange ierr = DMPlexCreateMedFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4247f2801cd6SMatthew G. Knepley } else if (isPLY) { 4248f2801cd6SMatthew G. Knepley ierr = DMPlexCreatePLYFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4249c1cad2e7SMatthew G. Knepley } else if (isEGADSLite || isEGADS || isIGES || isSTEP) { 4250c1cad2e7SMatthew G. Knepley if (isEGADSLite) {ierr = DMPlexCreateEGADSLiteFromFile(comm, filename, dm);CHKERRQ(ierr);} 4251c1cad2e7SMatthew G. Knepley else {ierr = DMPlexCreateEGADSFromFile(comm, filename, dm);CHKERRQ(ierr);} 42527bee2925SMatthew Knepley if (!interpolate) { 42537bee2925SMatthew Knepley DM udm; 42547bee2925SMatthew Knepley 42557bee2925SMatthew Knepley ierr = DMPlexUninterpolate(*dm, &udm);CHKERRQ(ierr); 42567bee2925SMatthew Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 42577bee2925SMatthew Knepley *dm = udm; 42587bee2925SMatthew Knepley } 42598ca92349SMatthew G. Knepley } else if (isCV) { 42608ca92349SMatthew G. Knepley ierr = DMPlexCreateCellVertexFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4261ca522641SMatthew G. Knepley } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot load file %s: unrecognized extension", filename); 4262f1f45c63SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_CreateFromFile,0,0,0,0);CHKERRQ(ierr); 4263ca522641SMatthew G. Knepley PetscFunctionReturn(0); 4264ca522641SMatthew G. Knepley } 4265