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> 5*b7f5c055SJed Brown #include <petsc/private/kernels/blockmatmult.h> 6*b7f5c055SJed Brown #include <petsc/private/kernels/blockinvert.h> 7552f7358SJed Brown 8b09969d6SVaclav Hapla PetscLogEvent DMPLEX_CreateFromFile, DMPLEX_BuildFromCellList, DMPLEX_BuildCoordinatesFromCellList; 958cd63d5SVaclav Hapla 109318fe57SMatthew G. Knepley /* External function declarations here */ 119318fe57SMatthew G. Knepley static PetscErrorCode DMInitialize_Plex(DM dm); 129318fe57SMatthew G. Knepley 13e600fa54SMatthew G. Knepley /* This copies internal things in the Plex structure that we generally want when making a new, related Plex */ 14e600fa54SMatthew G. Knepley PetscErrorCode DMPlexCopy_Internal(DM dmin, PetscBool copyPeriodicity, DM dmout) 15e600fa54SMatthew G. Knepley { 16e600fa54SMatthew G. Knepley const DMBoundaryType *bd; 17e600fa54SMatthew G. Knepley const PetscReal *maxCell, *L; 18e600fa54SMatthew G. Knepley PetscBool isper, dist; 19e600fa54SMatthew G. Knepley PetscErrorCode ierr; 20e600fa54SMatthew G. Knepley 21e600fa54SMatthew G. Knepley PetscFunctionBegin; 22e600fa54SMatthew G. Knepley if (copyPeriodicity) { 23e600fa54SMatthew G. Knepley ierr = DMGetPeriodicity(dmin, &isper, &maxCell, &L, &bd);CHKERRQ(ierr); 24e600fa54SMatthew G. Knepley ierr = DMSetPeriodicity(dmout, isper, maxCell, L, bd);CHKERRQ(ierr); 25e600fa54SMatthew G. Knepley } 26e600fa54SMatthew G. Knepley ierr = DMPlexDistributeGetDefault(dmin, &dist);CHKERRQ(ierr); 27e600fa54SMatthew G. Knepley ierr = DMPlexDistributeSetDefault(dmout, dist);CHKERRQ(ierr); 28e600fa54SMatthew G. Knepley ((DM_Plex *) dmout->data)->useHashLocation = ((DM_Plex *) dmin->data)->useHashLocation; 29e600fa54SMatthew G. Knepley PetscFunctionReturn(0); 30e600fa54SMatthew G. Knepley } 31e600fa54SMatthew G. Knepley 329318fe57SMatthew G. Knepley /* Replace dm with the contents of ndm, and then destroy ndm 339318fe57SMatthew G. Knepley - Share the DM_Plex structure 349318fe57SMatthew G. Knepley - Share the coordinates 359318fe57SMatthew G. Knepley - Share the SF 369318fe57SMatthew G. Knepley */ 379318fe57SMatthew G. Knepley static PetscErrorCode DMPlexReplace_Static(DM dm, DM *ndm) 389318fe57SMatthew G. Knepley { 399318fe57SMatthew G. Knepley PetscSF sf; 409318fe57SMatthew G. Knepley DM dmNew = *ndm, coordDM, coarseDM; 419318fe57SMatthew G. Knepley Vec coords; 429318fe57SMatthew G. Knepley PetscBool isper; 439318fe57SMatthew G. Knepley const PetscReal *maxCell, *L; 449318fe57SMatthew G. Knepley const DMBoundaryType *bd; 459318fe57SMatthew G. Knepley PetscInt dim, cdim; 469318fe57SMatthew G. Knepley PetscErrorCode ierr; 479318fe57SMatthew G. Knepley 489318fe57SMatthew G. Knepley PetscFunctionBegin; 499318fe57SMatthew G. Knepley if (dm == dmNew) { 509318fe57SMatthew G. Knepley ierr = DMDestroy(ndm);CHKERRQ(ierr); 519318fe57SMatthew G. Knepley PetscFunctionReturn(0); 529318fe57SMatthew G. Knepley } 539318fe57SMatthew G. Knepley dm->setupcalled = dmNew->setupcalled; 549318fe57SMatthew G. Knepley ierr = DMGetDimension(dmNew, &dim);CHKERRQ(ierr); 559318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 569318fe57SMatthew G. Knepley ierr = DMGetCoordinateDim(dmNew, &cdim);CHKERRQ(ierr); 579318fe57SMatthew G. Knepley ierr = DMSetCoordinateDim(dm, cdim);CHKERRQ(ierr); 589318fe57SMatthew G. Knepley ierr = DMGetPointSF(dmNew, &sf);CHKERRQ(ierr); 599318fe57SMatthew G. Knepley ierr = DMSetPointSF(dm, sf);CHKERRQ(ierr); 609318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dmNew, &coordDM);CHKERRQ(ierr); 619318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dmNew, &coords);CHKERRQ(ierr); 629318fe57SMatthew G. Knepley ierr = DMSetCoordinateDM(dm, coordDM);CHKERRQ(ierr); 639318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coords);CHKERRQ(ierr); 649318fe57SMatthew G. Knepley /* Do not want to create the coordinate field if it does not already exist, so do not call DMGetCoordinateField() */ 659318fe57SMatthew G. Knepley ierr = DMFieldDestroy(&dm->coordinateField);CHKERRQ(ierr); 669318fe57SMatthew G. Knepley dm->coordinateField = dmNew->coordinateField; 6761a622f3SMatthew G. Knepley ((DM_Plex *) dmNew->data)->coordFunc = ((DM_Plex *) dm->data)->coordFunc; 689318fe57SMatthew G. Knepley ierr = DMGetPeriodicity(dmNew, &isper, &maxCell, &L, &bd);CHKERRQ(ierr); 699318fe57SMatthew G. Knepley ierr = DMSetPeriodicity(dm, isper, maxCell, L, bd);CHKERRQ(ierr); 709318fe57SMatthew G. Knepley ierr = DMDestroy_Plex(dm);CHKERRQ(ierr); 719318fe57SMatthew G. Knepley ierr = DMInitialize_Plex(dm);CHKERRQ(ierr); 729318fe57SMatthew G. Knepley dm->data = dmNew->data; 739318fe57SMatthew G. Knepley ((DM_Plex *) dmNew->data)->refct++; 749318fe57SMatthew G. Knepley ierr = DMDestroyLabelLinkList_Internal(dm);CHKERRQ(ierr); 752cbb9b06SVaclav Hapla ierr = DMCopyLabels(dmNew, dm, PETSC_OWN_POINTER, PETSC_TRUE, DM_COPY_LABELS_FAIL);CHKERRQ(ierr); 769318fe57SMatthew G. Knepley ierr = DMGetCoarseDM(dmNew,&coarseDM);CHKERRQ(ierr); 779318fe57SMatthew G. Knepley ierr = DMSetCoarseDM(dm,coarseDM);CHKERRQ(ierr); 789318fe57SMatthew G. Knepley ierr = DMDestroy(ndm);CHKERRQ(ierr); 799318fe57SMatthew G. Knepley PetscFunctionReturn(0); 809318fe57SMatthew G. Knepley } 819318fe57SMatthew G. Knepley 829318fe57SMatthew G. Knepley /* Swap dm with the contents of dmNew 839318fe57SMatthew G. Knepley - Swap the DM_Plex structure 849318fe57SMatthew G. Knepley - Swap the coordinates 859318fe57SMatthew G. Knepley - Swap the point PetscSF 869318fe57SMatthew G. Knepley */ 879318fe57SMatthew G. Knepley static PetscErrorCode DMPlexSwap_Static(DM dmA, DM dmB) 889318fe57SMatthew G. Knepley { 899318fe57SMatthew G. Knepley DM coordDMA, coordDMB; 909318fe57SMatthew G. Knepley Vec coordsA, coordsB; 919318fe57SMatthew G. Knepley PetscSF sfA, sfB; 929318fe57SMatthew G. Knepley DMField fieldTmp; 939318fe57SMatthew G. Knepley void *tmp; 949318fe57SMatthew G. Knepley DMLabelLink listTmp; 959318fe57SMatthew G. Knepley DMLabel depthTmp; 969318fe57SMatthew G. Knepley PetscInt tmpI; 979318fe57SMatthew G. Knepley PetscErrorCode ierr; 989318fe57SMatthew G. Knepley 999318fe57SMatthew G. Knepley PetscFunctionBegin; 1009318fe57SMatthew G. Knepley if (dmA == dmB) PetscFunctionReturn(0); 1019318fe57SMatthew G. Knepley ierr = DMGetPointSF(dmA, &sfA);CHKERRQ(ierr); 1029318fe57SMatthew G. Knepley ierr = DMGetPointSF(dmB, &sfB);CHKERRQ(ierr); 1039318fe57SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) sfA);CHKERRQ(ierr); 1049318fe57SMatthew G. Knepley ierr = DMSetPointSF(dmA, sfB);CHKERRQ(ierr); 1059318fe57SMatthew G. Knepley ierr = DMSetPointSF(dmB, sfA);CHKERRQ(ierr); 1069318fe57SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) sfA);CHKERRQ(ierr); 1079318fe57SMatthew G. Knepley 1089318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dmA, &coordDMA);CHKERRQ(ierr); 1099318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dmB, &coordDMB);CHKERRQ(ierr); 1109318fe57SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) coordDMA);CHKERRQ(ierr); 1119318fe57SMatthew G. Knepley ierr = DMSetCoordinateDM(dmA, coordDMB);CHKERRQ(ierr); 1129318fe57SMatthew G. Knepley ierr = DMSetCoordinateDM(dmB, coordDMA);CHKERRQ(ierr); 1139318fe57SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) coordDMA);CHKERRQ(ierr); 1149318fe57SMatthew G. Knepley 1159318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dmA, &coordsA);CHKERRQ(ierr); 1169318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dmB, &coordsB);CHKERRQ(ierr); 1179318fe57SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) coordsA);CHKERRQ(ierr); 1189318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dmA, coordsB);CHKERRQ(ierr); 1199318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dmB, coordsA);CHKERRQ(ierr); 1209318fe57SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) coordsA);CHKERRQ(ierr); 1219318fe57SMatthew G. Knepley 1229318fe57SMatthew G. Knepley fieldTmp = dmA->coordinateField; 1239318fe57SMatthew G. Knepley dmA->coordinateField = dmB->coordinateField; 1249318fe57SMatthew G. Knepley dmB->coordinateField = fieldTmp; 1259318fe57SMatthew G. Knepley tmp = dmA->data; 1269318fe57SMatthew G. Knepley dmA->data = dmB->data; 1279318fe57SMatthew G. Knepley dmB->data = tmp; 1289318fe57SMatthew G. Knepley listTmp = dmA->labels; 1299318fe57SMatthew G. Knepley dmA->labels = dmB->labels; 1309318fe57SMatthew G. Knepley dmB->labels = listTmp; 1319318fe57SMatthew G. Knepley depthTmp = dmA->depthLabel; 1329318fe57SMatthew G. Knepley dmA->depthLabel = dmB->depthLabel; 1339318fe57SMatthew G. Knepley dmB->depthLabel = depthTmp; 1349318fe57SMatthew G. Knepley depthTmp = dmA->celltypeLabel; 1359318fe57SMatthew G. Knepley dmA->celltypeLabel = dmB->celltypeLabel; 1369318fe57SMatthew G. Knepley dmB->celltypeLabel = depthTmp; 1379318fe57SMatthew G. Knepley tmpI = dmA->levelup; 1389318fe57SMatthew G. Knepley dmA->levelup = dmB->levelup; 1399318fe57SMatthew G. Knepley dmB->levelup = tmpI; 1409318fe57SMatthew G. Knepley PetscFunctionReturn(0); 1419318fe57SMatthew G. Knepley } 1429318fe57SMatthew G. Knepley 1439318fe57SMatthew G. Knepley static PetscErrorCode DMPlexInterpolateInPlace_Internal(DM dm) 1449318fe57SMatthew G. Knepley { 1459318fe57SMatthew G. Knepley DM idm; 1469318fe57SMatthew G. Knepley PetscErrorCode ierr; 1479318fe57SMatthew G. Knepley 1489318fe57SMatthew G. Knepley PetscFunctionBegin; 1499318fe57SMatthew G. Knepley ierr = DMPlexInterpolate(dm, &idm);CHKERRQ(ierr); 1509318fe57SMatthew G. Knepley ierr = DMPlexCopyCoordinates(dm, idm);CHKERRQ(ierr); 1519318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &idm);CHKERRQ(ierr); 1529318fe57SMatthew G. Knepley PetscFunctionReturn(0); 1539318fe57SMatthew G. Knepley } 1549318fe57SMatthew G. Knepley 1559318fe57SMatthew G. Knepley /*@C 1569318fe57SMatthew G. Knepley DMPlexCreateCoordinateSpace - Creates a finite element space for the coordinates 1579318fe57SMatthew G. Knepley 1589318fe57SMatthew G. Knepley Collective 1599318fe57SMatthew G. Knepley 1609318fe57SMatthew G. Knepley Input Parameters: 1619318fe57SMatthew G. Knepley + DM - The DM 1629318fe57SMatthew G. Knepley . degree - The degree of the finite element 1639318fe57SMatthew G. Knepley - coordFunc - An optional function to map new points from refinement to the surface 1649318fe57SMatthew G. Knepley 1659318fe57SMatthew G. Knepley Level: advanced 1669318fe57SMatthew G. Knepley 1679318fe57SMatthew G. Knepley .seealso: PetscFECreateLagrange(), DMGetCoordinateDM() 1689318fe57SMatthew G. Knepley @*/ 1699318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateCoordinateSpace(DM dm, PetscInt degree, PetscPointFunc coordFunc) 1709318fe57SMatthew G. Knepley { 1719318fe57SMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) dm->data; 1729318fe57SMatthew G. Knepley DM cdm; 1739318fe57SMatthew G. Knepley PetscDS cds; 1749318fe57SMatthew G. Knepley PetscFE fe; 1759318fe57SMatthew G. Knepley PetscClassId id; 1769318fe57SMatthew G. Knepley PetscErrorCode ierr; 1779318fe57SMatthew G. Knepley 1789318fe57SMatthew G. Knepley PetscFunctionBegin; 1799318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 1809318fe57SMatthew G. Knepley ierr = DMGetDS(cdm, &cds);CHKERRQ(ierr); 1819318fe57SMatthew G. Knepley ierr = PetscDSGetDiscretization(cds, 0, (PetscObject *) &fe);CHKERRQ(ierr); 1829318fe57SMatthew G. Knepley ierr = PetscObjectGetClassId((PetscObject) fe, &id);CHKERRQ(ierr); 1839318fe57SMatthew G. Knepley if (id != PETSCFE_CLASSID) { 1849318fe57SMatthew G. Knepley PetscBool simplex; 1859318fe57SMatthew G. Knepley PetscInt dim, dE, qorder; 1869318fe57SMatthew G. Knepley 1879318fe57SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1889318fe57SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 1899318fe57SMatthew G. Knepley ierr = DMPlexIsSimplex(dm, &simplex);CHKERRQ(ierr); 1909318fe57SMatthew G. Knepley qorder = degree; 1919318fe57SMatthew G. Knepley ierr = PetscObjectOptionsBegin((PetscObject) cdm);CHKERRQ(ierr); 1929318fe57SMatthew 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); 1939318fe57SMatthew G. Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 1949318fe57SMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, dE, simplex, degree, qorder, &fe);CHKERRQ(ierr); 1959318fe57SMatthew G. Knepley ierr = DMSetField(cdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 1969318fe57SMatthew G. Knepley ierr = DMCreateDS(cdm);CHKERRQ(ierr); 1979318fe57SMatthew G. Knepley ierr = DMProjectCoordinates(dm, fe);CHKERRQ(ierr); 1989318fe57SMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 1999318fe57SMatthew G. Knepley } 2009318fe57SMatthew G. Knepley mesh->coordFunc = coordFunc; 2019318fe57SMatthew G. Knepley PetscFunctionReturn(0); 2029318fe57SMatthew G. Knepley } 2039318fe57SMatthew G. Knepley 2041df5d5c5SMatthew G. Knepley /*@ 2051df5d5c5SMatthew G. Knepley DMPlexCreateDoublet - Creates a mesh of two cells of the specified type, optionally with later refinement. 2061df5d5c5SMatthew G. Knepley 207d083f849SBarry Smith Collective 2081df5d5c5SMatthew G. Knepley 2091df5d5c5SMatthew G. Knepley Input Parameters: 2101df5d5c5SMatthew G. Knepley + comm - The communicator for the DM object 2111df5d5c5SMatthew G. Knepley . dim - The spatial dimension 2121df5d5c5SMatthew G. Knepley . simplex - Flag for simplicial cells, otherwise they are tensor product cells 2131df5d5c5SMatthew G. Knepley . interpolate - Flag to create intermediate mesh pieces (edges, faces) 2141df5d5c5SMatthew G. Knepley - refinementLimit - A nonzero number indicates the largest admissible volume for a refined cell 2151df5d5c5SMatthew G. Knepley 2161df5d5c5SMatthew G. Knepley Output Parameter: 2171df5d5c5SMatthew G. Knepley . dm - The DM object 2181df5d5c5SMatthew G. Knepley 2191df5d5c5SMatthew G. Knepley Level: beginner 2201df5d5c5SMatthew G. Knepley 2211df5d5c5SMatthew G. Knepley .seealso: DMSetType(), DMCreate() 2221df5d5c5SMatthew G. Knepley @*/ 2230fdc7489SMatthew Knepley PetscErrorCode DMPlexCreateDoublet(MPI_Comm comm, PetscInt dim, PetscBool simplex, PetscBool interpolate, PetscReal refinementLimit, DM *newdm) 2241df5d5c5SMatthew G. Knepley { 2251df5d5c5SMatthew G. Knepley DM dm; 2261df5d5c5SMatthew G. Knepley PetscMPIInt rank; 2271df5d5c5SMatthew G. Knepley PetscErrorCode ierr; 2281df5d5c5SMatthew G. Knepley 2291df5d5c5SMatthew G. Knepley PetscFunctionBegin; 2301df5d5c5SMatthew G. Knepley ierr = DMCreate(comm, &dm);CHKERRQ(ierr); 2311df5d5c5SMatthew G. Knepley ierr = DMSetType(dm, DMPLEX);CHKERRQ(ierr); 232c73cfb54SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 233ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 234ce78fa2fSMatthew G. Knepley switch (dim) { 235ce78fa2fSMatthew G. Knepley case 2: 236ce78fa2fSMatthew G. Knepley if (simplex) {ierr = PetscObjectSetName((PetscObject) dm, "triangular");CHKERRQ(ierr);} 237ce78fa2fSMatthew G. Knepley else {ierr = PetscObjectSetName((PetscObject) dm, "quadrilateral");CHKERRQ(ierr);} 238ce78fa2fSMatthew G. Knepley break; 239ce78fa2fSMatthew G. Knepley case 3: 240ce78fa2fSMatthew G. Knepley if (simplex) {ierr = PetscObjectSetName((PetscObject) dm, "tetrahedral");CHKERRQ(ierr);} 241ce78fa2fSMatthew G. Knepley else {ierr = PetscObjectSetName((PetscObject) dm, "hexahedral");CHKERRQ(ierr);} 242ce78fa2fSMatthew G. Knepley break; 243ce78fa2fSMatthew G. Knepley default: 24498921bdaSJacob Faibussowitsch SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make meshes for dimension %D", dim); 245ce78fa2fSMatthew G. Knepley } 2461df5d5c5SMatthew G. Knepley if (rank) { 2471df5d5c5SMatthew G. Knepley PetscInt numPoints[2] = {0, 0}; 2481df5d5c5SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm, 1, numPoints, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 2491df5d5c5SMatthew G. Knepley } else { 2501df5d5c5SMatthew G. Knepley switch (dim) { 2511df5d5c5SMatthew G. Knepley case 2: 2521df5d5c5SMatthew G. Knepley if (simplex) { 2531df5d5c5SMatthew G. Knepley PetscInt numPoints[2] = {4, 2}; 2541df5d5c5SMatthew G. Knepley PetscInt coneSize[6] = {3, 3, 0, 0, 0, 0}; 2551df5d5c5SMatthew G. Knepley PetscInt cones[6] = {2, 3, 4, 5, 4, 3}; 2561df5d5c5SMatthew G. Knepley PetscInt coneOrientations[6] = {0, 0, 0, 0, 0, 0}; 2571df5d5c5SMatthew G. Knepley PetscScalar vertexCoords[8] = {-0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 0.5, 0.5}; 2581df5d5c5SMatthew G. Knepley 2591df5d5c5SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 2601df5d5c5SMatthew G. Knepley } else { 2611df5d5c5SMatthew G. Knepley PetscInt numPoints[2] = {6, 2}; 2621df5d5c5SMatthew G. Knepley PetscInt coneSize[8] = {4, 4, 0, 0, 0, 0, 0, 0}; 2631df5d5c5SMatthew G. Knepley PetscInt cones[8] = {2, 3, 4, 5, 3, 6, 7, 4}; 2641df5d5c5SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 2651df5d5c5SMatthew 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}; 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 case 3: 2711df5d5c5SMatthew G. Knepley if (simplex) { 2721df5d5c5SMatthew G. Knepley PetscInt numPoints[2] = {5, 2}; 2731df5d5c5SMatthew G. Knepley PetscInt coneSize[7] = {4, 4, 0, 0, 0, 0, 0}; 2741df5d5c5SMatthew G. Knepley PetscInt cones[8] = {4, 3, 5, 2, 5, 3, 4, 6}; 2751df5d5c5SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 2761df5d5c5SMatthew 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}; 2771df5d5c5SMatthew G. Knepley 2781df5d5c5SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 2791df5d5c5SMatthew G. Knepley } else { 2801df5d5c5SMatthew G. Knepley PetscInt numPoints[2] = {12, 2}; 2811df5d5c5SMatthew G. Knepley PetscInt coneSize[14] = {8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 2821df5d5c5SMatthew G. Knepley PetscInt cones[16] = {2, 3, 4, 5, 6, 7, 8, 9, 5, 4, 10, 11, 7, 12, 13, 8}; 2831df5d5c5SMatthew G. Knepley PetscInt coneOrientations[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 2841df5d5c5SMatthew 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, 2851df5d5c5SMatthew 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, 2861df5d5c5SMatthew 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}; 2871df5d5c5SMatthew G. Knepley 2881df5d5c5SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 2891df5d5c5SMatthew G. Knepley } 2901df5d5c5SMatthew G. Knepley break; 2911df5d5c5SMatthew G. Knepley default: 29298921bdaSJacob Faibussowitsch SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make meshes for dimension %D", dim); 2931df5d5c5SMatthew G. Knepley } 2941df5d5c5SMatthew G. Knepley } 2951df5d5c5SMatthew G. Knepley *newdm = dm; 2961df5d5c5SMatthew G. Knepley if (refinementLimit > 0.0) { 2971df5d5c5SMatthew G. Knepley DM rdm; 2981df5d5c5SMatthew G. Knepley const char *name; 2991df5d5c5SMatthew G. Knepley 3001df5d5c5SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*newdm, PETSC_FALSE);CHKERRQ(ierr); 3011df5d5c5SMatthew G. Knepley ierr = DMPlexSetRefinementLimit(*newdm, refinementLimit);CHKERRQ(ierr); 3021df5d5c5SMatthew G. Knepley ierr = DMRefine(*newdm, comm, &rdm);CHKERRQ(ierr); 3031df5d5c5SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) *newdm, &name);CHKERRQ(ierr); 3041df5d5c5SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) rdm, name);CHKERRQ(ierr); 3051df5d5c5SMatthew G. Knepley ierr = DMDestroy(newdm);CHKERRQ(ierr); 3061df5d5c5SMatthew G. Knepley *newdm = rdm; 3071df5d5c5SMatthew G. Knepley } 3081df5d5c5SMatthew G. Knepley if (interpolate) { 3095fd9971aSMatthew G. Knepley DM idm; 3101df5d5c5SMatthew G. Knepley 3111df5d5c5SMatthew G. Knepley ierr = DMPlexInterpolate(*newdm, &idm);CHKERRQ(ierr); 3121df5d5c5SMatthew G. Knepley ierr = DMDestroy(newdm);CHKERRQ(ierr); 3131df5d5c5SMatthew G. Knepley *newdm = idm; 3141df5d5c5SMatthew G. Knepley } 3151df5d5c5SMatthew G. Knepley PetscFunctionReturn(0); 3161df5d5c5SMatthew G. Knepley } 3171df5d5c5SMatthew G. Knepley 3189318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxSurfaceMesh_Tensor_1D_Internal(DM dm, const PetscReal lower[], const PetscReal upper[], const PetscInt edges[]) 3199318fe57SMatthew G. Knepley { 3209318fe57SMatthew G. Knepley const PetscInt numVertices = 2; 3219318fe57SMatthew G. Knepley PetscInt markerRight = 1; 3229318fe57SMatthew G. Knepley PetscInt markerLeft = 1; 3239318fe57SMatthew G. Knepley PetscBool markerSeparate = PETSC_FALSE; 3249318fe57SMatthew G. Knepley Vec coordinates; 3259318fe57SMatthew G. Knepley PetscSection coordSection; 3269318fe57SMatthew G. Knepley PetscScalar *coords; 3279318fe57SMatthew G. Knepley PetscInt coordSize; 3289318fe57SMatthew G. Knepley PetscMPIInt rank; 3299318fe57SMatthew G. Knepley PetscInt cdim = 1, v; 3309318fe57SMatthew G. Knepley PetscErrorCode ierr; 331552f7358SJed Brown 3329318fe57SMatthew G. Knepley PetscFunctionBegin; 3339318fe57SMatthew G. Knepley ierr = PetscOptionsGetBool(((PetscObject) dm)->options,((PetscObject) dm)->prefix, "-dm_plex_separate_marker", &markerSeparate, NULL);CHKERRQ(ierr); 3349318fe57SMatthew G. Knepley if (markerSeparate) { 3359318fe57SMatthew G. Knepley markerRight = 2; 3369318fe57SMatthew G. Knepley markerLeft = 1; 3379318fe57SMatthew G. Knepley } 3389318fe57SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 3399318fe57SMatthew G. Knepley if (!rank) { 3409318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numVertices);CHKERRQ(ierr); 3419318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 3429318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", 0, markerLeft);CHKERRQ(ierr); 3439318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", 1, markerRight);CHKERRQ(ierr); 3449318fe57SMatthew G. Knepley } 3459318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 3469318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 3479318fe57SMatthew G. Knepley /* Build coordinates */ 3489318fe57SMatthew G. Knepley ierr = DMSetCoordinateDim(dm, cdim);CHKERRQ(ierr); 3499318fe57SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 3509318fe57SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 3519318fe57SMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, 0, numVertices);CHKERRQ(ierr); 3529318fe57SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, cdim);CHKERRQ(ierr); 3539318fe57SMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 3549318fe57SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, cdim);CHKERRQ(ierr); 3559318fe57SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, cdim);CHKERRQ(ierr); 3569318fe57SMatthew G. Knepley } 3579318fe57SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 3589318fe57SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 3599318fe57SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 3609318fe57SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 3619318fe57SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 3629318fe57SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, cdim);CHKERRQ(ierr); 3639318fe57SMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 3649318fe57SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 3659318fe57SMatthew G. Knepley coords[0] = lower[0]; 3669318fe57SMatthew G. Knepley coords[1] = upper[0]; 3679318fe57SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 3689318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 3699318fe57SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 3709318fe57SMatthew G. Knepley PetscFunctionReturn(0); 3719318fe57SMatthew G. Knepley } 37226492d91SMatthew G. Knepley 3739318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxSurfaceMesh_Tensor_2D_Internal(DM dm, const PetscReal lower[], const PetscReal upper[], const PetscInt edges[]) 374552f7358SJed Brown { 3751df21d24SMatthew G. Knepley const PetscInt numVertices = (edges[0]+1)*(edges[1]+1); 3761df21d24SMatthew G. Knepley const PetscInt numEdges = edges[0]*(edges[1]+1) + (edges[0]+1)*edges[1]; 377552f7358SJed Brown PetscInt markerTop = 1; 378552f7358SJed Brown PetscInt markerBottom = 1; 379552f7358SJed Brown PetscInt markerRight = 1; 380552f7358SJed Brown PetscInt markerLeft = 1; 381552f7358SJed Brown PetscBool markerSeparate = PETSC_FALSE; 382552f7358SJed Brown Vec coordinates; 383552f7358SJed Brown PetscSection coordSection; 384552f7358SJed Brown PetscScalar *coords; 385552f7358SJed Brown PetscInt coordSize; 386552f7358SJed Brown PetscMPIInt rank; 387552f7358SJed Brown PetscInt v, vx, vy; 388552f7358SJed Brown PetscErrorCode ierr; 389552f7358SJed Brown 390552f7358SJed Brown PetscFunctionBegin; 391c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject) dm)->options,((PetscObject) dm)->prefix, "-dm_plex_separate_marker", &markerSeparate, NULL);CHKERRQ(ierr); 392552f7358SJed Brown if (markerSeparate) { 3931df21d24SMatthew G. Knepley markerTop = 3; 3941df21d24SMatthew G. Knepley markerBottom = 1; 3951df21d24SMatthew G. Knepley markerRight = 2; 3961df21d24SMatthew G. Knepley markerLeft = 4; 397552f7358SJed Brown } 398ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 399dd400576SPatrick Sanan if (rank == 0) { 400552f7358SJed Brown PetscInt e, ex, ey; 401552f7358SJed Brown 402552f7358SJed Brown ierr = DMPlexSetChart(dm, 0, numEdges+numVertices);CHKERRQ(ierr); 403552f7358SJed Brown for (e = 0; e < numEdges; ++e) { 404552f7358SJed Brown ierr = DMPlexSetConeSize(dm, e, 2);CHKERRQ(ierr); 405552f7358SJed Brown } 406552f7358SJed Brown ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 407552f7358SJed Brown for (vx = 0; vx <= edges[0]; vx++) { 408552f7358SJed Brown for (ey = 0; ey < edges[1]; ey++) { 409552f7358SJed Brown PetscInt edge = vx*edges[1] + ey + edges[0]*(edges[1]+1); 410552f7358SJed Brown PetscInt vertex = ey*(edges[0]+1) + vx + numEdges; 411da80777bSKarl Rupp PetscInt cone[2]; 412552f7358SJed Brown 413da80777bSKarl Rupp cone[0] = vertex; cone[1] = vertex+edges[0]+1; 414552f7358SJed Brown ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); 415552f7358SJed Brown if (vx == edges[0]) { 416c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerRight);CHKERRQ(ierr); 417c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerRight);CHKERRQ(ierr); 418552f7358SJed Brown if (ey == edges[1]-1) { 419c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerRight);CHKERRQ(ierr); 420c668006fSMatthew G. Knepley ierr = DMSetLabelValue(dm, "Face Sets", cone[1], markerRight);CHKERRQ(ierr); 421552f7358SJed Brown } 422552f7358SJed Brown } else if (vx == 0) { 423c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerLeft);CHKERRQ(ierr); 424c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerLeft);CHKERRQ(ierr); 425552f7358SJed Brown if (ey == edges[1]-1) { 426c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerLeft);CHKERRQ(ierr); 427c668006fSMatthew G. Knepley ierr = DMSetLabelValue(dm, "Face Sets", cone[1], markerLeft);CHKERRQ(ierr); 428552f7358SJed Brown } 429552f7358SJed Brown } 430552f7358SJed Brown } 431552f7358SJed Brown } 432552f7358SJed Brown for (vy = 0; vy <= edges[1]; vy++) { 433552f7358SJed Brown for (ex = 0; ex < edges[0]; ex++) { 434552f7358SJed Brown PetscInt edge = vy*edges[0] + ex; 435552f7358SJed Brown PetscInt vertex = vy*(edges[0]+1) + ex + numEdges; 436da80777bSKarl Rupp PetscInt cone[2]; 437552f7358SJed Brown 438da80777bSKarl Rupp cone[0] = vertex; cone[1] = vertex+1; 439552f7358SJed Brown ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); 440552f7358SJed Brown if (vy == edges[1]) { 441c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerTop);CHKERRQ(ierr); 442c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerTop);CHKERRQ(ierr); 443552f7358SJed Brown if (ex == edges[0]-1) { 444c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerTop);CHKERRQ(ierr); 445c668006fSMatthew G. Knepley ierr = DMSetLabelValue(dm, "Face Sets", cone[1], markerTop);CHKERRQ(ierr); 446552f7358SJed Brown } 447552f7358SJed Brown } else if (vy == 0) { 448c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBottom);CHKERRQ(ierr); 449c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerBottom);CHKERRQ(ierr); 450552f7358SJed Brown if (ex == edges[0]-1) { 451c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerBottom);CHKERRQ(ierr); 452c668006fSMatthew G. Knepley ierr = DMSetLabelValue(dm, "Face Sets", cone[1], markerBottom);CHKERRQ(ierr); 453552f7358SJed Brown } 454552f7358SJed Brown } 455552f7358SJed Brown } 456552f7358SJed Brown } 457552f7358SJed Brown } 458552f7358SJed Brown ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 459552f7358SJed Brown ierr = DMPlexStratify(dm);CHKERRQ(ierr); 460552f7358SJed Brown /* Build coordinates */ 4619596c6baSMatthew G. Knepley ierr = DMSetCoordinateDim(dm, 2);CHKERRQ(ierr); 462c2166f76SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 463972bc18aSToby Isaac ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 464552f7358SJed Brown ierr = PetscSectionSetChart(coordSection, numEdges, numEdges + numVertices);CHKERRQ(ierr); 465972bc18aSToby Isaac ierr = PetscSectionSetFieldComponents(coordSection, 0, 2);CHKERRQ(ierr); 466552f7358SJed Brown for (v = numEdges; v < numEdges+numVertices; ++v) { 467552f7358SJed Brown ierr = PetscSectionSetDof(coordSection, v, 2);CHKERRQ(ierr); 468972bc18aSToby Isaac ierr = PetscSectionSetFieldDof(coordSection, v, 0, 2);CHKERRQ(ierr); 469552f7358SJed Brown } 470552f7358SJed Brown ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 471552f7358SJed Brown ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 4728b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 473da16285aSMichael Lange ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 474552f7358SJed Brown ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 4758b9ced59SLisandro Dalcin ierr = VecSetBlockSize(coordinates, 2);CHKERRQ(ierr); 4762eb5907fSJed Brown ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 477552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 478552f7358SJed Brown for (vy = 0; vy <= edges[1]; ++vy) { 479552f7358SJed Brown for (vx = 0; vx <= edges[0]; ++vx) { 480552f7358SJed Brown coords[(vy*(edges[0]+1)+vx)*2+0] = lower[0] + ((upper[0] - lower[0])/edges[0])*vx; 481552f7358SJed Brown coords[(vy*(edges[0]+1)+vx)*2+1] = lower[1] + ((upper[1] - lower[1])/edges[1])*vy; 482552f7358SJed Brown } 483552f7358SJed Brown } 484552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 485552f7358SJed Brown ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 486552f7358SJed Brown ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 487552f7358SJed Brown PetscFunctionReturn(0); 488552f7358SJed Brown } 489552f7358SJed Brown 4909318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxSurfaceMesh_Tensor_3D_Internal(DM dm, const PetscReal lower[], const PetscReal upper[], const PetscInt faces[]) 491552f7358SJed Brown { 4929e8abbc3SMichael Lange PetscInt vertices[3], numVertices; 4937b59f5a9SMichael Lange PetscInt numFaces = 2*faces[0]*faces[1] + 2*faces[1]*faces[2] + 2*faces[0]*faces[2]; 494552f7358SJed Brown Vec coordinates; 495552f7358SJed Brown PetscSection coordSection; 496552f7358SJed Brown PetscScalar *coords; 497552f7358SJed Brown PetscInt coordSize; 498552f7358SJed Brown PetscMPIInt rank; 499552f7358SJed Brown PetscInt v, vx, vy, vz; 5007b59f5a9SMichael Lange PetscInt voffset, iface=0, cone[4]; 501552f7358SJed Brown PetscErrorCode ierr; 502552f7358SJed Brown 503552f7358SJed Brown PetscFunctionBegin; 5042c71b3e2SJacob Faibussowitsch PetscCheckFalse((faces[0] < 1) || (faces[1] < 1) || (faces[2] < 1),PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Must have at least 1 face per side"); 505ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 5069e8abbc3SMichael Lange vertices[0] = faces[0]+1; vertices[1] = faces[1]+1; vertices[2] = faces[2]+1; 5079e8abbc3SMichael Lange numVertices = vertices[0]*vertices[1]*vertices[2]; 508dd400576SPatrick Sanan if (rank == 0) { 509552f7358SJed Brown PetscInt f; 510552f7358SJed Brown 511552f7358SJed Brown ierr = DMPlexSetChart(dm, 0, numFaces+numVertices);CHKERRQ(ierr); 512552f7358SJed Brown for (f = 0; f < numFaces; ++f) { 513552f7358SJed Brown ierr = DMPlexSetConeSize(dm, f, 4);CHKERRQ(ierr); 514552f7358SJed Brown } 515552f7358SJed Brown ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 5167b59f5a9SMichael Lange 5177b59f5a9SMichael Lange /* Side 0 (Top) */ 5187b59f5a9SMichael Lange for (vy = 0; vy < faces[1]; vy++) { 5197b59f5a9SMichael Lange for (vx = 0; vx < faces[0]; vx++) { 5207b59f5a9SMichael Lange voffset = numFaces + vertices[0]*vertices[1]*(vertices[2]-1) + vy*vertices[0] + vx; 5217b59f5a9SMichael Lange cone[0] = voffset; cone[1] = voffset+1; cone[2] = voffset+vertices[0]+1; cone[3] = voffset+vertices[0]; 5227b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 523c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 524c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 525c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+1, 1);CHKERRQ(ierr); 526c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+0, 1);CHKERRQ(ierr); 527c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+1, 1);CHKERRQ(ierr); 5287b59f5a9SMichael Lange iface++; 529552f7358SJed Brown } 530552f7358SJed Brown } 5317b59f5a9SMichael Lange 5327b59f5a9SMichael Lange /* Side 1 (Bottom) */ 5337b59f5a9SMichael Lange for (vy = 0; vy < faces[1]; vy++) { 5347b59f5a9SMichael Lange for (vx = 0; vx < faces[0]; vx++) { 5357b59f5a9SMichael Lange voffset = numFaces + vy*(faces[0]+1) + vx; 5367b59f5a9SMichael Lange cone[0] = voffset+1; cone[1] = voffset; cone[2] = voffset+vertices[0]; cone[3] = voffset+vertices[0]+1; 5377b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 538c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 539c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 540c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+1, 1);CHKERRQ(ierr); 541c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+0, 1);CHKERRQ(ierr); 542c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+1, 1);CHKERRQ(ierr); 5437b59f5a9SMichael Lange iface++; 544552f7358SJed Brown } 545552f7358SJed Brown } 5467b59f5a9SMichael Lange 5477b59f5a9SMichael Lange /* Side 2 (Front) */ 5487b59f5a9SMichael Lange for (vz = 0; vz < faces[2]; vz++) { 5497b59f5a9SMichael Lange for (vx = 0; vx < faces[0]; vx++) { 5507b59f5a9SMichael Lange voffset = numFaces + vz*vertices[0]*vertices[1] + vx; 5517b59f5a9SMichael Lange cone[0] = voffset; cone[1] = voffset+1; cone[2] = voffset+vertices[0]*vertices[1]+1; cone[3] = voffset+vertices[0]*vertices[1]; 5527b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 553c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 554c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 555c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+1, 1);CHKERRQ(ierr); 556c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+0, 1);CHKERRQ(ierr); 557c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+1, 1);CHKERRQ(ierr); 5587b59f5a9SMichael Lange iface++; 559552f7358SJed Brown } 5607b59f5a9SMichael Lange } 5617b59f5a9SMichael Lange 5627b59f5a9SMichael Lange /* Side 3 (Back) */ 5637b59f5a9SMichael Lange for (vz = 0; vz < faces[2]; vz++) { 5647b59f5a9SMichael Lange for (vx = 0; vx < faces[0]; vx++) { 5657b59f5a9SMichael Lange voffset = numFaces + vz*vertices[0]*vertices[1] + vertices[0]*(vertices[1]-1) + vx; 5667b59f5a9SMichael Lange cone[0] = voffset+vertices[0]*vertices[1]; cone[1] = voffset+vertices[0]*vertices[1]+1; 5677b59f5a9SMichael Lange cone[2] = voffset+1; cone[3] = voffset; 5687b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 569c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 570c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 571c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+1, 1);CHKERRQ(ierr); 572c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+0, 1);CHKERRQ(ierr); 573c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+1, 1);CHKERRQ(ierr); 5747b59f5a9SMichael Lange iface++; 5757b59f5a9SMichael Lange } 5767b59f5a9SMichael Lange } 5777b59f5a9SMichael Lange 5787b59f5a9SMichael Lange /* Side 4 (Left) */ 5797b59f5a9SMichael Lange for (vz = 0; vz < faces[2]; vz++) { 5807b59f5a9SMichael Lange for (vy = 0; vy < faces[1]; vy++) { 5817b59f5a9SMichael Lange voffset = numFaces + vz*vertices[0]*vertices[1] + vy*vertices[0]; 5827b59f5a9SMichael Lange cone[0] = voffset; cone[1] = voffset+vertices[0]*vertices[1]; 5837b59f5a9SMichael Lange cone[2] = voffset+vertices[0]*vertices[1]+vertices[0]; cone[3] = voffset+vertices[0]; 5847b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 585c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 586c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 587c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+0, 1);CHKERRQ(ierr); 588c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[1]+0, 1);CHKERRQ(ierr); 589c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+vertices[0], 1);CHKERRQ(ierr); 5907b59f5a9SMichael Lange iface++; 5917b59f5a9SMichael Lange } 5927b59f5a9SMichael Lange } 5937b59f5a9SMichael Lange 5947b59f5a9SMichael Lange /* Side 5 (Right) */ 5957b59f5a9SMichael Lange for (vz = 0; vz < faces[2]; vz++) { 5967b59f5a9SMichael Lange for (vy = 0; vy < faces[1]; vy++) { 597aab5bcd8SJed Brown voffset = numFaces + vz*vertices[0]*vertices[1] + vy*vertices[0] + faces[0]; 5987b59f5a9SMichael Lange cone[0] = voffset+vertices[0]*vertices[1]; cone[1] = voffset; 5997b59f5a9SMichael Lange cone[2] = voffset+vertices[0]; cone[3] = voffset+vertices[0]*vertices[1]+vertices[0]; 6007b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 601c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 602c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 603c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+0, 1);CHKERRQ(ierr); 604c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+0, 1);CHKERRQ(ierr); 605c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+vertices[0], 1);CHKERRQ(ierr); 6067b59f5a9SMichael Lange iface++; 6077b59f5a9SMichael Lange } 608552f7358SJed Brown } 609552f7358SJed Brown } 610552f7358SJed Brown ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 611552f7358SJed Brown ierr = DMPlexStratify(dm);CHKERRQ(ierr); 612552f7358SJed Brown /* Build coordinates */ 6139596c6baSMatthew G. Knepley ierr = DMSetCoordinateDim(dm, 3);CHKERRQ(ierr); 614c2166f76SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 6159318fe57SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 616552f7358SJed Brown ierr = PetscSectionSetChart(coordSection, numFaces, numFaces + numVertices);CHKERRQ(ierr); 6179318fe57SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, 3);CHKERRQ(ierr); 618552f7358SJed Brown for (v = numFaces; v < numFaces+numVertices; ++v) { 619552f7358SJed Brown ierr = PetscSectionSetDof(coordSection, v, 3);CHKERRQ(ierr); 6209318fe57SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, 3);CHKERRQ(ierr); 621552f7358SJed Brown } 622552f7358SJed Brown ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 623552f7358SJed Brown ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 6248b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 625552f7358SJed Brown ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 626552f7358SJed Brown ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 6278b9ced59SLisandro Dalcin ierr = VecSetBlockSize(coordinates, 3);CHKERRQ(ierr); 6282eb5907fSJed Brown ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 629552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 630552f7358SJed Brown for (vz = 0; vz <= faces[2]; ++vz) { 631552f7358SJed Brown for (vy = 0; vy <= faces[1]; ++vy) { 632552f7358SJed Brown for (vx = 0; vx <= faces[0]; ++vx) { 633552f7358SJed Brown coords[((vz*(faces[1]+1)+vy)*(faces[0]+1)+vx)*3+0] = lower[0] + ((upper[0] - lower[0])/faces[0])*vx; 634552f7358SJed Brown coords[((vz*(faces[1]+1)+vy)*(faces[0]+1)+vx)*3+1] = lower[1] + ((upper[1] - lower[1])/faces[1])*vy; 635552f7358SJed Brown coords[((vz*(faces[1]+1)+vy)*(faces[0]+1)+vx)*3+2] = lower[2] + ((upper[2] - lower[2])/faces[2])*vz; 636552f7358SJed Brown } 637552f7358SJed Brown } 638552f7358SJed Brown } 639552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 640552f7358SJed Brown ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 641552f7358SJed Brown ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 642552f7358SJed Brown PetscFunctionReturn(0); 643552f7358SJed Brown } 644552f7358SJed Brown 6459318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxSurfaceMesh_Internal(DM dm, PetscInt dim, const PetscInt faces[], const PetscReal lower[], const PetscReal upper[], PetscBool interpolate) 6469318fe57SMatthew G. Knepley { 6479318fe57SMatthew G. Knepley PetscErrorCode ierr; 6489318fe57SMatthew G. Knepley 6499318fe57SMatthew G. Knepley PetscFunctionBegin; 6509318fe57SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 6519318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim-1);CHKERRQ(ierr); 6529318fe57SMatthew G. Knepley ierr = DMSetCoordinateDim(dm, dim);CHKERRQ(ierr); 6539318fe57SMatthew G. Knepley switch (dim) { 6549318fe57SMatthew G. Knepley case 1: ierr = DMPlexCreateBoxSurfaceMesh_Tensor_1D_Internal(dm, lower, upper, faces);CHKERRQ(ierr);break; 6559318fe57SMatthew G. Knepley case 2: ierr = DMPlexCreateBoxSurfaceMesh_Tensor_2D_Internal(dm, lower, upper, faces);CHKERRQ(ierr);break; 6569318fe57SMatthew G. Knepley case 3: ierr = DMPlexCreateBoxSurfaceMesh_Tensor_3D_Internal(dm, lower, upper, faces);CHKERRQ(ierr);break; 65798921bdaSJacob Faibussowitsch default: SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Dimension not supported: %D", dim); 6589318fe57SMatthew G. Knepley } 6599318fe57SMatthew G. Knepley if (interpolate) {ierr = DMPlexInterpolateInPlace_Internal(dm);CHKERRQ(ierr);} 6609318fe57SMatthew G. Knepley PetscFunctionReturn(0); 6619318fe57SMatthew G. Knepley } 6629318fe57SMatthew G. Knepley 6639318fe57SMatthew G. Knepley /*@C 6649318fe57SMatthew G. Knepley DMPlexCreateBoxSurfaceMesh - Creates a mesh on the surface of the tensor product of unit intervals (box) using tensor cells (hexahedra). 6659318fe57SMatthew G. Knepley 6669318fe57SMatthew G. Knepley Collective 6679318fe57SMatthew G. Knepley 6689318fe57SMatthew G. Knepley Input Parameters: 6699318fe57SMatthew G. Knepley + comm - The communicator for the DM object 6709318fe57SMatthew G. Knepley . dim - The spatial dimension of the box, so the resulting mesh is has dimension dim-1 6719318fe57SMatthew 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 6729318fe57SMatthew G. Knepley . lower - The lower left corner, or NULL for (0, 0, 0) 6739318fe57SMatthew G. Knepley . upper - The upper right corner, or NULL for (1, 1, 1) 6749318fe57SMatthew G. Knepley - interpolate - Flag to create intermediate mesh pieces (edges, faces) 6759318fe57SMatthew G. Knepley 6769318fe57SMatthew G. Knepley Output Parameter: 6779318fe57SMatthew G. Knepley . dm - The DM object 6789318fe57SMatthew G. Knepley 6799318fe57SMatthew G. Knepley Level: beginner 6809318fe57SMatthew G. Knepley 6819318fe57SMatthew G. Knepley .seealso: DMSetFromOptions(), DMPlexCreateBoxMesh(), DMPlexCreateFromFile(), DMSetType(), DMCreate() 6829318fe57SMatthew G. Knepley @*/ 6839318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateBoxSurfaceMesh(MPI_Comm comm, PetscInt dim, const PetscInt faces[], const PetscReal lower[], const PetscReal upper[], PetscBool interpolate, DM *dm) 6849318fe57SMatthew G. Knepley { 6859318fe57SMatthew G. Knepley PetscInt fac[3] = {1, 1, 1}; 6869318fe57SMatthew G. Knepley PetscReal low[3] = {0, 0, 0}; 6879318fe57SMatthew G. Knepley PetscReal upp[3] = {1, 1, 1}; 6889318fe57SMatthew G. Knepley PetscErrorCode ierr; 6899318fe57SMatthew G. Knepley 6909318fe57SMatthew G. Knepley PetscFunctionBegin; 6919318fe57SMatthew G. Knepley ierr = DMCreate(comm,dm);CHKERRQ(ierr); 6929318fe57SMatthew G. Knepley ierr = DMSetType(*dm,DMPLEX);CHKERRQ(ierr); 6939318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxSurfaceMesh_Internal(*dm, dim, faces ? faces : fac, lower ? lower : low, upper ? upper : upp, interpolate);CHKERRQ(ierr); 6949318fe57SMatthew G. Knepley PetscFunctionReturn(0); 6959318fe57SMatthew G. Knepley } 6969318fe57SMatthew G. Knepley 6979318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateLineMesh_Internal(DM dm,PetscInt segments,PetscReal lower,PetscReal upper,DMBoundaryType bd) 698fdbf62faSLisandro Dalcin { 699fdbf62faSLisandro Dalcin PetscInt i,fStart,fEnd,numCells = 0,numVerts = 0; 700fdbf62faSLisandro Dalcin PetscInt numPoints[2],*coneSize,*cones,*coneOrientations; 701fdbf62faSLisandro Dalcin PetscScalar *vertexCoords; 702fdbf62faSLisandro Dalcin PetscReal L,maxCell; 703fdbf62faSLisandro Dalcin PetscBool markerSeparate = PETSC_FALSE; 704fdbf62faSLisandro Dalcin PetscInt markerLeft = 1, faceMarkerLeft = 1; 705fdbf62faSLisandro Dalcin PetscInt markerRight = 1, faceMarkerRight = 2; 706fdbf62faSLisandro Dalcin PetscBool wrap = (bd == DM_BOUNDARY_PERIODIC || bd == DM_BOUNDARY_TWIST) ? PETSC_TRUE : PETSC_FALSE; 707fdbf62faSLisandro Dalcin PetscMPIInt rank; 708fdbf62faSLisandro Dalcin PetscErrorCode ierr; 709fdbf62faSLisandro Dalcin 710fdbf62faSLisandro Dalcin PetscFunctionBegin; 7119318fe57SMatthew G. Knepley PetscValidPointer(dm,1); 712fdbf62faSLisandro Dalcin 7139318fe57SMatthew G. Knepley ierr = DMSetDimension(dm,1);CHKERRQ(ierr); 7149318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm,"marker");CHKERRQ(ierr); 7159318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm,"Face Sets");CHKERRQ(ierr); 716fdbf62faSLisandro Dalcin 7179318fe57SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm),&rank);CHKERRMPI(ierr); 718dd400576SPatrick Sanan if (rank == 0) numCells = segments; 719dd400576SPatrick Sanan if (rank == 0) numVerts = segments + (wrap ? 0 : 1); 720fdbf62faSLisandro Dalcin 721fdbf62faSLisandro Dalcin numPoints[0] = numVerts ; numPoints[1] = numCells; 722fdbf62faSLisandro Dalcin ierr = PetscMalloc4(numCells+numVerts,&coneSize,numCells*2,&cones,numCells+numVerts,&coneOrientations,numVerts,&vertexCoords);CHKERRQ(ierr); 723580bdb30SBarry Smith ierr = PetscArrayzero(coneOrientations,numCells+numVerts);CHKERRQ(ierr); 724fdbf62faSLisandro Dalcin for (i = 0; i < numCells; ++i) { coneSize[i] = 2; } 725fdbf62faSLisandro Dalcin for (i = 0; i < numVerts; ++i) { coneSize[numCells+i] = 0; } 726fdbf62faSLisandro Dalcin for (i = 0; i < numCells; ++i) { cones[2*i] = numCells + i%numVerts; cones[2*i+1] = numCells + (i+1)%numVerts; } 727fdbf62faSLisandro Dalcin for (i = 0; i < numVerts; ++i) { vertexCoords[i] = lower + (upper-lower)*((PetscReal)i/(PetscReal)numCells); } 7289318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm,1,numPoints,coneSize,cones,coneOrientations,vertexCoords);CHKERRQ(ierr); 729fdbf62faSLisandro Dalcin ierr = PetscFree4(coneSize,cones,coneOrientations,vertexCoords);CHKERRQ(ierr); 730fdbf62faSLisandro Dalcin 7319318fe57SMatthew G. Knepley ierr = PetscOptionsGetBool(((PetscObject)dm)->options,((PetscObject)dm)->prefix,"-dm_plex_separate_marker",&markerSeparate,NULL);CHKERRQ(ierr); 732fdbf62faSLisandro Dalcin if (markerSeparate) { markerLeft = faceMarkerLeft; markerRight = faceMarkerRight;} 733dd400576SPatrick Sanan if (!wrap && rank == 0) { 7349318fe57SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm,1,&fStart,&fEnd);CHKERRQ(ierr); 7359318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm,"marker",fStart,markerLeft);CHKERRQ(ierr); 7369318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm,"marker",fEnd-1,markerRight);CHKERRQ(ierr); 7379318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm,"Face Sets",fStart,faceMarkerLeft);CHKERRQ(ierr); 7389318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm,"Face Sets",fEnd-1,faceMarkerRight);CHKERRQ(ierr); 739fdbf62faSLisandro Dalcin } 740fdbf62faSLisandro Dalcin if (wrap) { 741fdbf62faSLisandro Dalcin L = upper - lower; 742fdbf62faSLisandro Dalcin maxCell = (PetscReal)1.1*(L/(PetscReal)PetscMax(1,segments)); 7439318fe57SMatthew G. Knepley ierr = DMSetPeriodicity(dm,PETSC_TRUE,&maxCell,&L,&bd);CHKERRQ(ierr); 744fdbf62faSLisandro Dalcin } 7459318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr); 746fdbf62faSLisandro Dalcin PetscFunctionReturn(0); 747fdbf62faSLisandro Dalcin } 748fdbf62faSLisandro Dalcin 7499318fe57SMatthew 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) 750d6218766SMatthew G. Knepley { 7519318fe57SMatthew G. Knepley DM boundary, vol; 752768d5fceSMatthew G. Knepley PetscInt i; 753d6218766SMatthew G. Knepley PetscErrorCode ierr; 754d6218766SMatthew G. Knepley 755d6218766SMatthew G. Knepley PetscFunctionBegin; 7569318fe57SMatthew G. Knepley PetscValidPointer(dm, 1); 7572c71b3e2SJacob Faibussowitsch for (i = 0; i < dim; ++i) PetscCheckFalse(periodicity[i] != DM_BOUNDARY_NONE,PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Periodicity is not supported for simplex meshes"); 7589318fe57SMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject) dm), &boundary);CHKERRQ(ierr); 759d6218766SMatthew G. Knepley ierr = DMSetType(boundary, DMPLEX);CHKERRQ(ierr); 7609318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxSurfaceMesh_Internal(boundary, dim, faces, lower, upper, PETSC_FALSE);CHKERRQ(ierr); 7619318fe57SMatthew G. Knepley ierr = DMPlexGenerate(boundary, NULL, interpolate, &vol);CHKERRQ(ierr); 762e600fa54SMatthew G. Knepley ierr = DMPlexCopy_Internal(dm, PETSC_TRUE, vol);CHKERRQ(ierr); 7639318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &vol);CHKERRQ(ierr); 764d6218766SMatthew G. Knepley ierr = DMDestroy(&boundary);CHKERRQ(ierr); 765d6218766SMatthew G. Knepley PetscFunctionReturn(0); 766d6218766SMatthew G. Knepley } 767d6218766SMatthew G. Knepley 7683dfda0b1SToby Isaac static PetscErrorCode DMPlexCreateCubeMesh_Internal(DM dm, const PetscReal lower[], const PetscReal upper[], const PetscInt edges[], DMBoundaryType bdX, DMBoundaryType bdY, DMBoundaryType bdZ) 7693dfda0b1SToby Isaac { 770ed0e4b50SMatthew G. Knepley DMLabel cutLabel = NULL; 771f4eb4c5dSMatthew G. Knepley PetscInt markerTop = 1, faceMarkerTop = 1; 772f4eb4c5dSMatthew G. Knepley PetscInt markerBottom = 1, faceMarkerBottom = 1; 773f4eb4c5dSMatthew G. Knepley PetscInt markerFront = 1, faceMarkerFront = 1; 774f4eb4c5dSMatthew G. Knepley PetscInt markerBack = 1, faceMarkerBack = 1; 775f4eb4c5dSMatthew G. Knepley PetscInt markerRight = 1, faceMarkerRight = 1; 776f4eb4c5dSMatthew G. Knepley PetscInt markerLeft = 1, faceMarkerLeft = 1; 7773dfda0b1SToby Isaac PetscInt dim; 778d8211ee3SMatthew G. Knepley PetscBool markerSeparate = PETSC_FALSE, cutMarker = PETSC_FALSE; 7793dfda0b1SToby Isaac PetscMPIInt rank; 7803dfda0b1SToby Isaac PetscErrorCode ierr; 7813dfda0b1SToby Isaac 7823dfda0b1SToby Isaac PetscFunctionBegin; 783f0226e14SMatthew G. Knepley ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 784ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 78550ae33c3SToby Isaac ierr = DMCreateLabel(dm,"marker");CHKERRQ(ierr); 78650ae33c3SToby Isaac ierr = DMCreateLabel(dm,"Face Sets");CHKERRQ(ierr); 7874c67ea77SStefano Zampini ierr = PetscOptionsGetBool(((PetscObject) dm)->options,((PetscObject) dm)->prefix, "-dm_plex_periodic_cut", &cutMarker, NULL);CHKERRQ(ierr); 788d8211ee3SMatthew G. Knepley if (bdX == DM_BOUNDARY_PERIODIC || bdX == DM_BOUNDARY_TWIST || 789d8211ee3SMatthew G. Knepley bdY == DM_BOUNDARY_PERIODIC || bdY == DM_BOUNDARY_TWIST || 790d8211ee3SMatthew G. Knepley bdZ == DM_BOUNDARY_PERIODIC || bdZ == DM_BOUNDARY_TWIST) { 7914c67ea77SStefano Zampini 792d1c88043SMatthew G. Knepley if (cutMarker) {ierr = DMCreateLabel(dm, "periodic_cut");CHKERRQ(ierr); ierr = DMGetLabel(dm, "periodic_cut", &cutLabel);CHKERRQ(ierr);} 793d8211ee3SMatthew G. Knepley } 7943dfda0b1SToby Isaac switch (dim) { 7953dfda0b1SToby Isaac case 2: 796f4eb4c5dSMatthew G. Knepley faceMarkerTop = 3; 797f4eb4c5dSMatthew G. Knepley faceMarkerBottom = 1; 798f4eb4c5dSMatthew G. Knepley faceMarkerRight = 2; 799f4eb4c5dSMatthew G. Knepley faceMarkerLeft = 4; 8003dfda0b1SToby Isaac break; 8013dfda0b1SToby Isaac case 3: 802f4eb4c5dSMatthew G. Knepley faceMarkerBottom = 1; 803f4eb4c5dSMatthew G. Knepley faceMarkerTop = 2; 804f4eb4c5dSMatthew G. Knepley faceMarkerFront = 3; 805f4eb4c5dSMatthew G. Knepley faceMarkerBack = 4; 806f4eb4c5dSMatthew G. Knepley faceMarkerRight = 5; 807f4eb4c5dSMatthew G. Knepley faceMarkerLeft = 6; 8083dfda0b1SToby Isaac break; 8093dfda0b1SToby Isaac default: 81098921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Dimension %D not supported",dim); 8113dfda0b1SToby Isaac } 812c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject) dm)->options,((PetscObject) dm)->prefix, "-dm_plex_separate_marker", &markerSeparate, NULL);CHKERRQ(ierr); 813f4eb4c5dSMatthew G. Knepley if (markerSeparate) { 814f4eb4c5dSMatthew G. Knepley markerBottom = faceMarkerBottom; 815f4eb4c5dSMatthew G. Knepley markerTop = faceMarkerTop; 816f4eb4c5dSMatthew G. Knepley markerFront = faceMarkerFront; 817f4eb4c5dSMatthew G. Knepley markerBack = faceMarkerBack; 818f4eb4c5dSMatthew G. Knepley markerRight = faceMarkerRight; 819f4eb4c5dSMatthew G. Knepley markerLeft = faceMarkerLeft; 8203dfda0b1SToby Isaac } 8213dfda0b1SToby Isaac { 822dd400576SPatrick Sanan const PetscInt numXEdges = rank == 0 ? edges[0] : 0; 823dd400576SPatrick Sanan const PetscInt numYEdges = rank == 0 ? edges[1] : 0; 824dd400576SPatrick Sanan const PetscInt numZEdges = rank == 0 ? edges[2] : 0; 825dd400576SPatrick Sanan const PetscInt numXVertices = rank == 0 ? (bdX == DM_BOUNDARY_PERIODIC || bdX == DM_BOUNDARY_TWIST ? edges[0] : edges[0]+1) : 0; 826dd400576SPatrick Sanan const PetscInt numYVertices = rank == 0 ? (bdY == DM_BOUNDARY_PERIODIC || bdY == DM_BOUNDARY_TWIST ? edges[1] : edges[1]+1) : 0; 827dd400576SPatrick Sanan const PetscInt numZVertices = rank == 0 ? (bdZ == DM_BOUNDARY_PERIODIC || bdZ == DM_BOUNDARY_TWIST ? edges[2] : edges[2]+1) : 0; 8283dfda0b1SToby Isaac const PetscInt numCells = numXEdges*numYEdges*numZEdges; 8293dfda0b1SToby Isaac const PetscInt numXFaces = numYEdges*numZEdges; 8303dfda0b1SToby Isaac const PetscInt numYFaces = numXEdges*numZEdges; 8313dfda0b1SToby Isaac const PetscInt numZFaces = numXEdges*numYEdges; 8323dfda0b1SToby Isaac const PetscInt numTotXFaces = numXVertices*numXFaces; 8333dfda0b1SToby Isaac const PetscInt numTotYFaces = numYVertices*numYFaces; 8343dfda0b1SToby Isaac const PetscInt numTotZFaces = numZVertices*numZFaces; 8353dfda0b1SToby Isaac const PetscInt numFaces = numTotXFaces + numTotYFaces + numTotZFaces; 8363dfda0b1SToby Isaac const PetscInt numTotXEdges = numXEdges*numYVertices*numZVertices; 8373dfda0b1SToby Isaac const PetscInt numTotYEdges = numYEdges*numXVertices*numZVertices; 8383dfda0b1SToby Isaac const PetscInt numTotZEdges = numZEdges*numXVertices*numYVertices; 8393dfda0b1SToby Isaac const PetscInt numVertices = numXVertices*numYVertices*numZVertices; 8403dfda0b1SToby Isaac const PetscInt numEdges = numTotXEdges + numTotYEdges + numTotZEdges; 8413dfda0b1SToby Isaac const PetscInt firstVertex = (dim == 2) ? numFaces : numCells; 8423dfda0b1SToby Isaac const PetscInt firstXFace = (dim == 2) ? 0 : numCells + numVertices; 8433dfda0b1SToby Isaac const PetscInt firstYFace = firstXFace + numTotXFaces; 8443dfda0b1SToby Isaac const PetscInt firstZFace = firstYFace + numTotYFaces; 8453dfda0b1SToby Isaac const PetscInt firstXEdge = numCells + numFaces + numVertices; 8463dfda0b1SToby Isaac const PetscInt firstYEdge = firstXEdge + numTotXEdges; 8473dfda0b1SToby Isaac const PetscInt firstZEdge = firstYEdge + numTotYEdges; 8483dfda0b1SToby Isaac Vec coordinates; 8493dfda0b1SToby Isaac PetscSection coordSection; 8503dfda0b1SToby Isaac PetscScalar *coords; 8513dfda0b1SToby Isaac PetscInt coordSize; 8523dfda0b1SToby Isaac PetscInt v, vx, vy, vz; 8533dfda0b1SToby Isaac PetscInt c, f, fx, fy, fz, e, ex, ey, ez; 8543dfda0b1SToby Isaac 8553dfda0b1SToby Isaac ierr = DMPlexSetChart(dm, 0, numCells+numFaces+numEdges+numVertices);CHKERRQ(ierr); 8563dfda0b1SToby Isaac for (c = 0; c < numCells; c++) { 8573dfda0b1SToby Isaac ierr = DMPlexSetConeSize(dm, c, 6);CHKERRQ(ierr); 8583dfda0b1SToby Isaac } 8593dfda0b1SToby Isaac for (f = firstXFace; f < firstXFace+numFaces; ++f) { 8603dfda0b1SToby Isaac ierr = DMPlexSetConeSize(dm, f, 4);CHKERRQ(ierr); 8613dfda0b1SToby Isaac } 8623dfda0b1SToby Isaac for (e = firstXEdge; e < firstXEdge+numEdges; ++e) { 8633dfda0b1SToby Isaac ierr = DMPlexSetConeSize(dm, e, 2);CHKERRQ(ierr); 8643dfda0b1SToby Isaac } 8653dfda0b1SToby Isaac ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 8663dfda0b1SToby Isaac /* Build cells */ 8673dfda0b1SToby Isaac for (fz = 0; fz < numZEdges; ++fz) { 8683dfda0b1SToby Isaac for (fy = 0; fy < numYEdges; ++fy) { 8693dfda0b1SToby Isaac for (fx = 0; fx < numXEdges; ++fx) { 8703dfda0b1SToby Isaac PetscInt cell = (fz*numYEdges + fy)*numXEdges + fx; 8713dfda0b1SToby Isaac PetscInt faceB = firstZFace + (fy*numXEdges+fx)*numZVertices + fz; 8723dfda0b1SToby Isaac PetscInt faceT = firstZFace + (fy*numXEdges+fx)*numZVertices + ((fz+1)%numZVertices); 8733dfda0b1SToby Isaac PetscInt faceF = firstYFace + (fz*numXEdges+fx)*numYVertices + fy; 8743dfda0b1SToby Isaac PetscInt faceK = firstYFace + (fz*numXEdges+fx)*numYVertices + ((fy+1)%numYVertices); 8753dfda0b1SToby Isaac PetscInt faceL = firstXFace + (fz*numYEdges+fy)*numXVertices + fx; 8763dfda0b1SToby Isaac PetscInt faceR = firstXFace + (fz*numYEdges+fy)*numXVertices + ((fx+1)%numXVertices); 8773dfda0b1SToby Isaac /* B, T, F, K, R, L */ 878b5a892a1SMatthew G. Knepley PetscInt ornt[6] = {-2, 0, 0, -3, 0, -2}; /* ??? */ 87942206facSLisandro Dalcin PetscInt cone[6]; 8803dfda0b1SToby Isaac 8813dfda0b1SToby Isaac /* no boundary twisting in 3D */ 8823dfda0b1SToby Isaac cone[0] = faceB; cone[1] = faceT; cone[2] = faceF; cone[3] = faceK; cone[4] = faceR; cone[5] = faceL; 8833dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, cell, cone);CHKERRQ(ierr); 8843dfda0b1SToby Isaac ierr = DMPlexSetConeOrientation(dm, cell, ornt);CHKERRQ(ierr); 8858a5b437dSMatthew G. Knepley if (bdX != DM_BOUNDARY_NONE && fx == numXEdges-1 && cutLabel) {ierr = DMLabelSetValue(cutLabel, cell, 2);CHKERRQ(ierr);} 8868a5b437dSMatthew G. Knepley if (bdY != DM_BOUNDARY_NONE && fy == numYEdges-1 && cutLabel) {ierr = DMLabelSetValue(cutLabel, cell, 2);CHKERRQ(ierr);} 8878a5b437dSMatthew G. Knepley if (bdZ != DM_BOUNDARY_NONE && fz == numZEdges-1 && cutLabel) {ierr = DMLabelSetValue(cutLabel, cell, 2);CHKERRQ(ierr);} 8883dfda0b1SToby Isaac } 8893dfda0b1SToby Isaac } 8903dfda0b1SToby Isaac } 8913dfda0b1SToby Isaac /* Build x faces */ 8923dfda0b1SToby Isaac for (fz = 0; fz < numZEdges; ++fz) { 8933dfda0b1SToby Isaac for (fy = 0; fy < numYEdges; ++fy) { 8943dfda0b1SToby Isaac for (fx = 0; fx < numXVertices; ++fx) { 8953dfda0b1SToby Isaac PetscInt face = firstXFace + (fz*numYEdges+fy) *numXVertices+fx; 8963dfda0b1SToby Isaac PetscInt edgeL = firstZEdge + (fy *numXVertices+fx)*numZEdges + fz; 8973dfda0b1SToby Isaac PetscInt edgeR = firstZEdge + (((fy+1)%numYVertices)*numXVertices+fx)*numZEdges + fz; 8983dfda0b1SToby Isaac PetscInt edgeB = firstYEdge + (fz *numXVertices+fx)*numYEdges + fy; 8993dfda0b1SToby Isaac PetscInt edgeT = firstYEdge + (((fz+1)%numZVertices)*numXVertices+fx)*numYEdges + fy; 900b5a892a1SMatthew G. Knepley PetscInt ornt[4] = {0, 0, -1, -1}; 9013dfda0b1SToby Isaac PetscInt cone[4]; 9023dfda0b1SToby Isaac 9033dfda0b1SToby Isaac if (dim == 3) { 9043dfda0b1SToby Isaac /* markers */ 9053dfda0b1SToby Isaac if (bdX != DM_BOUNDARY_PERIODIC) { 9063dfda0b1SToby Isaac if (fx == numXVertices-1) { 907c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerRight);CHKERRQ(ierr); 908c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerRight);CHKERRQ(ierr); 9093dfda0b1SToby Isaac } 9103dfda0b1SToby Isaac else if (fx == 0) { 911c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerLeft);CHKERRQ(ierr); 912c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerLeft);CHKERRQ(ierr); 9133dfda0b1SToby Isaac } 9143dfda0b1SToby Isaac } 9153dfda0b1SToby Isaac } 9163dfda0b1SToby Isaac cone[0] = edgeB; cone[1] = edgeR; cone[2] = edgeT; cone[3] = edgeL; 9173dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, face, cone);CHKERRQ(ierr); 9183dfda0b1SToby Isaac ierr = DMPlexSetConeOrientation(dm, face, ornt);CHKERRQ(ierr); 9193dfda0b1SToby Isaac } 9203dfda0b1SToby Isaac } 9213dfda0b1SToby Isaac } 9223dfda0b1SToby Isaac /* Build y faces */ 9233dfda0b1SToby Isaac for (fz = 0; fz < numZEdges; ++fz) { 92442206facSLisandro Dalcin for (fx = 0; fx < numXEdges; ++fx) { 9253dfda0b1SToby Isaac for (fy = 0; fy < numYVertices; ++fy) { 9263dfda0b1SToby Isaac PetscInt face = firstYFace + (fz*numXEdges+fx)*numYVertices + fy; 9273dfda0b1SToby Isaac PetscInt edgeL = firstZEdge + (fy*numXVertices+ fx)*numZEdges + fz; 9283dfda0b1SToby Isaac PetscInt edgeR = firstZEdge + (fy*numXVertices+((fx+1)%numXVertices))*numZEdges + fz; 9293dfda0b1SToby Isaac PetscInt edgeB = firstXEdge + (fz *numYVertices+fy)*numXEdges + fx; 9303dfda0b1SToby Isaac PetscInt edgeT = firstXEdge + (((fz+1)%numZVertices)*numYVertices+fy)*numXEdges + fx; 931b5a892a1SMatthew G. Knepley PetscInt ornt[4] = {0, 0, -1, -1}; 9323dfda0b1SToby Isaac PetscInt cone[4]; 9333dfda0b1SToby Isaac 9343dfda0b1SToby Isaac if (dim == 3) { 9353dfda0b1SToby Isaac /* markers */ 9363dfda0b1SToby Isaac if (bdY != DM_BOUNDARY_PERIODIC) { 9373dfda0b1SToby Isaac if (fy == numYVertices-1) { 938c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerBack);CHKERRQ(ierr); 939c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerBack);CHKERRQ(ierr); 9403dfda0b1SToby Isaac } 9413dfda0b1SToby Isaac else if (fy == 0) { 942c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerFront);CHKERRQ(ierr); 943c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerFront);CHKERRQ(ierr); 9443dfda0b1SToby Isaac } 9453dfda0b1SToby Isaac } 9463dfda0b1SToby Isaac } 9473dfda0b1SToby Isaac cone[0] = edgeB; cone[1] = edgeR; cone[2] = edgeT; cone[3] = edgeL; 9483dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, face, cone);CHKERRQ(ierr); 9493dfda0b1SToby Isaac ierr = DMPlexSetConeOrientation(dm, face, ornt);CHKERRQ(ierr); 9503dfda0b1SToby Isaac } 9513dfda0b1SToby Isaac } 9523dfda0b1SToby Isaac } 9533dfda0b1SToby Isaac /* Build z faces */ 9543dfda0b1SToby Isaac for (fy = 0; fy < numYEdges; ++fy) { 9553dfda0b1SToby Isaac for (fx = 0; fx < numXEdges; ++fx) { 9563dfda0b1SToby Isaac for (fz = 0; fz < numZVertices; fz++) { 9573dfda0b1SToby Isaac PetscInt face = firstZFace + (fy*numXEdges+fx)*numZVertices + fz; 9583dfda0b1SToby Isaac PetscInt edgeL = firstYEdge + (fz*numXVertices+ fx)*numYEdges + fy; 9593dfda0b1SToby Isaac PetscInt edgeR = firstYEdge + (fz*numXVertices+((fx+1)%numXVertices))*numYEdges + fy; 9603dfda0b1SToby Isaac PetscInt edgeB = firstXEdge + (fz*numYVertices+ fy)*numXEdges + fx; 9613dfda0b1SToby Isaac PetscInt edgeT = firstXEdge + (fz*numYVertices+((fy+1)%numYVertices))*numXEdges + fx; 962b5a892a1SMatthew G. Knepley PetscInt ornt[4] = {0, 0, -1, -1}; 9633dfda0b1SToby Isaac PetscInt cone[4]; 9643dfda0b1SToby Isaac 9653dfda0b1SToby Isaac if (dim == 2) { 966b5a892a1SMatthew G. Knepley if (bdX == DM_BOUNDARY_TWIST && fx == numXEdges-1) {edgeR += numYEdges-1-2*fy; ornt[1] = -1;} 9673dfda0b1SToby Isaac if (bdY == DM_BOUNDARY_TWIST && fy == numYEdges-1) {edgeT += numXEdges-1-2*fx; ornt[2] = 0;} 9688a5b437dSMatthew G. Knepley if (bdX != DM_BOUNDARY_NONE && fx == numXEdges-1 && cutLabel) {ierr = DMLabelSetValue(cutLabel, face, 2);CHKERRQ(ierr);} 9698a5b437dSMatthew G. Knepley if (bdY != DM_BOUNDARY_NONE && fy == numYEdges-1 && cutLabel) {ierr = DMLabelSetValue(cutLabel, face, 2);CHKERRQ(ierr);} 970d1c88043SMatthew G. Knepley } else { 9713dfda0b1SToby Isaac /* markers */ 9723dfda0b1SToby Isaac if (bdZ != DM_BOUNDARY_PERIODIC) { 9733dfda0b1SToby Isaac if (fz == numZVertices-1) { 974c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerTop);CHKERRQ(ierr); 975c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerTop);CHKERRQ(ierr); 9763dfda0b1SToby Isaac } 9773dfda0b1SToby Isaac else if (fz == 0) { 978c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerBottom);CHKERRQ(ierr); 979c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerBottom);CHKERRQ(ierr); 9803dfda0b1SToby Isaac } 9813dfda0b1SToby Isaac } 9823dfda0b1SToby Isaac } 9833dfda0b1SToby Isaac cone[0] = edgeB; cone[1] = edgeR; cone[2] = edgeT; cone[3] = edgeL; 9843dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, face, cone);CHKERRQ(ierr); 9853dfda0b1SToby Isaac ierr = DMPlexSetConeOrientation(dm, face, ornt);CHKERRQ(ierr); 9863dfda0b1SToby Isaac } 9873dfda0b1SToby Isaac } 9883dfda0b1SToby Isaac } 9893dfda0b1SToby Isaac /* Build Z edges*/ 9903dfda0b1SToby Isaac for (vy = 0; vy < numYVertices; vy++) { 9913dfda0b1SToby Isaac for (vx = 0; vx < numXVertices; vx++) { 9923dfda0b1SToby Isaac for (ez = 0; ez < numZEdges; ez++) { 9933dfda0b1SToby Isaac const PetscInt edge = firstZEdge + (vy*numXVertices+vx)*numZEdges + ez; 9943dfda0b1SToby Isaac const PetscInt vertexB = firstVertex + (ez *numYVertices+vy)*numXVertices + vx; 9953dfda0b1SToby Isaac const PetscInt vertexT = firstVertex + (((ez+1)%numZVertices)*numYVertices+vy)*numXVertices + vx; 9963dfda0b1SToby Isaac PetscInt cone[2]; 9973dfda0b1SToby Isaac 9983dfda0b1SToby Isaac if (dim == 3) { 9993dfda0b1SToby Isaac if (bdX != DM_BOUNDARY_PERIODIC) { 10003dfda0b1SToby Isaac if (vx == numXVertices-1) { 1001c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerRight);CHKERRQ(ierr); 10023dfda0b1SToby Isaac } 10033dfda0b1SToby Isaac else if (vx == 0) { 1004c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerLeft);CHKERRQ(ierr); 10053dfda0b1SToby Isaac } 10063dfda0b1SToby Isaac } 10073dfda0b1SToby Isaac if (bdY != DM_BOUNDARY_PERIODIC) { 10083dfda0b1SToby Isaac if (vy == numYVertices-1) { 1009c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBack);CHKERRQ(ierr); 10103dfda0b1SToby Isaac } 10113dfda0b1SToby Isaac else if (vy == 0) { 1012c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerFront);CHKERRQ(ierr); 10133dfda0b1SToby Isaac } 10143dfda0b1SToby Isaac } 10153dfda0b1SToby Isaac } 10163dfda0b1SToby Isaac cone[0] = vertexB; cone[1] = vertexT; 10173dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); 10183dfda0b1SToby Isaac } 10193dfda0b1SToby Isaac } 10203dfda0b1SToby Isaac } 10213dfda0b1SToby Isaac /* Build Y edges*/ 10223dfda0b1SToby Isaac for (vz = 0; vz < numZVertices; vz++) { 10233dfda0b1SToby Isaac for (vx = 0; vx < numXVertices; vx++) { 10243dfda0b1SToby Isaac for (ey = 0; ey < numYEdges; ey++) { 10253dfda0b1SToby Isaac const PetscInt nextv = (dim == 2 && bdY == DM_BOUNDARY_TWIST && ey == numYEdges-1) ? (numXVertices-vx-1) : (vz*numYVertices+((ey+1)%numYVertices))*numXVertices + vx; 10263dfda0b1SToby Isaac const PetscInt edge = firstYEdge + (vz*numXVertices+vx)*numYEdges + ey; 10273dfda0b1SToby Isaac const PetscInt vertexF = firstVertex + (vz*numYVertices+ey)*numXVertices + vx; 10283dfda0b1SToby Isaac const PetscInt vertexK = firstVertex + nextv; 10293dfda0b1SToby Isaac PetscInt cone[2]; 10303dfda0b1SToby Isaac 10313dfda0b1SToby Isaac cone[0] = vertexF; cone[1] = vertexK; 10323dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); 10333dfda0b1SToby Isaac if (dim == 2) { 10343dfda0b1SToby Isaac if ((bdX != DM_BOUNDARY_PERIODIC) && (bdX != DM_BOUNDARY_TWIST)) { 10353dfda0b1SToby Isaac if (vx == numXVertices-1) { 1036c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", edge, faceMarkerRight);CHKERRQ(ierr); 1037c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerRight);CHKERRQ(ierr); 1038c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerRight);CHKERRQ(ierr); 10393dfda0b1SToby Isaac if (ey == numYEdges-1) { 1040c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerRight);CHKERRQ(ierr); 10413dfda0b1SToby Isaac } 1042d8211ee3SMatthew G. Knepley } else if (vx == 0) { 1043c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", edge, faceMarkerLeft);CHKERRQ(ierr); 1044c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerLeft);CHKERRQ(ierr); 1045c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerLeft);CHKERRQ(ierr); 10463dfda0b1SToby Isaac if (ey == numYEdges-1) { 1047c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerLeft);CHKERRQ(ierr); 10483dfda0b1SToby Isaac } 10493dfda0b1SToby Isaac } 1050d8211ee3SMatthew G. Knepley } else { 10514c67ea77SStefano Zampini if (vx == 0 && cutLabel) { 1052d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, edge, 1);CHKERRQ(ierr); 1053d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, cone[0], 1);CHKERRQ(ierr); 1054d8211ee3SMatthew G. Knepley if (ey == numYEdges-1) { 1055d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, cone[1], 1);CHKERRQ(ierr); 10563dfda0b1SToby Isaac } 10573dfda0b1SToby Isaac } 1058d8211ee3SMatthew G. Knepley } 1059d8211ee3SMatthew G. Knepley } else { 10603dfda0b1SToby Isaac if (bdX != DM_BOUNDARY_PERIODIC) { 10613dfda0b1SToby Isaac if (vx == numXVertices-1) { 1062c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerRight);CHKERRQ(ierr); 1063d8211ee3SMatthew G. Knepley } else if (vx == 0) { 1064c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerLeft);CHKERRQ(ierr); 10653dfda0b1SToby Isaac } 10663dfda0b1SToby Isaac } 10673dfda0b1SToby Isaac if (bdZ != DM_BOUNDARY_PERIODIC) { 10683dfda0b1SToby Isaac if (vz == numZVertices-1) { 1069c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerTop);CHKERRQ(ierr); 1070d8211ee3SMatthew G. Knepley } else if (vz == 0) { 1071c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBottom);CHKERRQ(ierr); 10723dfda0b1SToby Isaac } 10733dfda0b1SToby Isaac } 10743dfda0b1SToby Isaac } 10753dfda0b1SToby Isaac } 10763dfda0b1SToby Isaac } 10773dfda0b1SToby Isaac } 10783dfda0b1SToby Isaac /* Build X edges*/ 10793dfda0b1SToby Isaac for (vz = 0; vz < numZVertices; vz++) { 10803dfda0b1SToby Isaac for (vy = 0; vy < numYVertices; vy++) { 10813dfda0b1SToby Isaac for (ex = 0; ex < numXEdges; ex++) { 10823dfda0b1SToby Isaac const PetscInt nextv = (dim == 2 && bdX == DM_BOUNDARY_TWIST && ex == numXEdges-1) ? (numYVertices-vy-1)*numXVertices : (vz*numYVertices+vy)*numXVertices + (ex+1)%numXVertices; 10833dfda0b1SToby Isaac const PetscInt edge = firstXEdge + (vz*numYVertices+vy)*numXEdges + ex; 10843dfda0b1SToby Isaac const PetscInt vertexL = firstVertex + (vz*numYVertices+vy)*numXVertices + ex; 10853dfda0b1SToby Isaac const PetscInt vertexR = firstVertex + nextv; 10863dfda0b1SToby Isaac PetscInt cone[2]; 10873dfda0b1SToby Isaac 10883dfda0b1SToby Isaac cone[0] = vertexL; cone[1] = vertexR; 10893dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); 10903dfda0b1SToby Isaac if (dim == 2) { 10913dfda0b1SToby Isaac if ((bdY != DM_BOUNDARY_PERIODIC) && (bdY != DM_BOUNDARY_TWIST)) { 10923dfda0b1SToby Isaac if (vy == numYVertices-1) { 1093c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", edge, faceMarkerTop);CHKERRQ(ierr); 1094c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerTop);CHKERRQ(ierr); 1095c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerTop);CHKERRQ(ierr); 10963dfda0b1SToby Isaac if (ex == numXEdges-1) { 1097c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerTop);CHKERRQ(ierr); 10983dfda0b1SToby Isaac } 1099d8211ee3SMatthew G. Knepley } else if (vy == 0) { 1100c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", edge, faceMarkerBottom);CHKERRQ(ierr); 1101c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBottom);CHKERRQ(ierr); 1102c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerBottom);CHKERRQ(ierr); 11033dfda0b1SToby Isaac if (ex == numXEdges-1) { 1104c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerBottom);CHKERRQ(ierr); 11053dfda0b1SToby Isaac } 11063dfda0b1SToby Isaac } 1107d8211ee3SMatthew G. Knepley } else { 11084c67ea77SStefano Zampini if (vy == 0 && cutLabel) { 1109d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, edge, 1);CHKERRQ(ierr); 1110d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, cone[0], 1);CHKERRQ(ierr); 1111d8211ee3SMatthew G. Knepley if (ex == numXEdges-1) { 1112d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, cone[1], 1);CHKERRQ(ierr); 11133dfda0b1SToby Isaac } 11143dfda0b1SToby Isaac } 1115d8211ee3SMatthew G. Knepley } 1116d8211ee3SMatthew G. Knepley } else { 11173dfda0b1SToby Isaac if (bdY != DM_BOUNDARY_PERIODIC) { 11183dfda0b1SToby Isaac if (vy == numYVertices-1) { 1119c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBack);CHKERRQ(ierr); 11203dfda0b1SToby Isaac } 11213dfda0b1SToby Isaac else if (vy == 0) { 1122c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerFront);CHKERRQ(ierr); 11233dfda0b1SToby Isaac } 11243dfda0b1SToby Isaac } 11253dfda0b1SToby Isaac if (bdZ != DM_BOUNDARY_PERIODIC) { 11263dfda0b1SToby Isaac if (vz == numZVertices-1) { 1127c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerTop);CHKERRQ(ierr); 11283dfda0b1SToby Isaac } 11293dfda0b1SToby Isaac else if (vz == 0) { 1130c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBottom);CHKERRQ(ierr); 11313dfda0b1SToby Isaac } 11323dfda0b1SToby Isaac } 11333dfda0b1SToby Isaac } 11343dfda0b1SToby Isaac } 11353dfda0b1SToby Isaac } 11363dfda0b1SToby Isaac } 11373dfda0b1SToby Isaac ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 11383dfda0b1SToby Isaac ierr = DMPlexStratify(dm);CHKERRQ(ierr); 11393dfda0b1SToby Isaac /* Build coordinates */ 11403dfda0b1SToby Isaac ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 11413dfda0b1SToby Isaac ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 11423dfda0b1SToby Isaac ierr = PetscSectionSetFieldComponents(coordSection, 0, dim);CHKERRQ(ierr); 11433dfda0b1SToby Isaac ierr = PetscSectionSetChart(coordSection, firstVertex, firstVertex+numVertices);CHKERRQ(ierr); 11443dfda0b1SToby Isaac for (v = firstVertex; v < firstVertex+numVertices; ++v) { 11453dfda0b1SToby Isaac ierr = PetscSectionSetDof(coordSection, v, dim);CHKERRQ(ierr); 11463dfda0b1SToby Isaac ierr = PetscSectionSetFieldDof(coordSection, v, 0, dim);CHKERRQ(ierr); 11473dfda0b1SToby Isaac } 11483dfda0b1SToby Isaac ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 11493dfda0b1SToby Isaac ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 11508b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 1151da16285aSMichael Lange ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 11523dfda0b1SToby Isaac ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 11538b9ced59SLisandro Dalcin ierr = VecSetBlockSize(coordinates, dim);CHKERRQ(ierr); 11543dfda0b1SToby Isaac ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 11553dfda0b1SToby Isaac ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 11563dfda0b1SToby Isaac for (vz = 0; vz < numZVertices; ++vz) { 11573dfda0b1SToby Isaac for (vy = 0; vy < numYVertices; ++vy) { 11583dfda0b1SToby Isaac for (vx = 0; vx < numXVertices; ++vx) { 11593dfda0b1SToby Isaac coords[((vz*numYVertices+vy)*numXVertices+vx)*dim+0] = lower[0] + ((upper[0] - lower[0])/numXEdges)*vx; 11603dfda0b1SToby Isaac coords[((vz*numYVertices+vy)*numXVertices+vx)*dim+1] = lower[1] + ((upper[1] - lower[1])/numYEdges)*vy; 11613dfda0b1SToby Isaac if (dim == 3) { 11623dfda0b1SToby Isaac coords[((vz*numYVertices+vy)*numXVertices+vx)*dim+2] = lower[2] + ((upper[2] - lower[2])/numZEdges)*vz; 11633dfda0b1SToby Isaac } 11643dfda0b1SToby Isaac } 11653dfda0b1SToby Isaac } 11663dfda0b1SToby Isaac } 11673dfda0b1SToby Isaac ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 11683dfda0b1SToby Isaac ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 11693dfda0b1SToby Isaac ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 11703dfda0b1SToby Isaac } 11713dfda0b1SToby Isaac PetscFunctionReturn(0); 11723dfda0b1SToby Isaac } 11733dfda0b1SToby Isaac 11749318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxMesh_Tensor_Internal(DM dm, PetscInt dim, const PetscInt faces[], const PetscReal lower[], const PetscReal upper[], const DMBoundaryType periodicity[]) 1175a6dfd86eSKarl Rupp { 11769318fe57SMatthew G. Knepley DMBoundaryType bdt[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE}; 11779318fe57SMatthew G. Knepley PetscInt fac[3] = {0, 0, 0}, d; 1178552f7358SJed Brown PetscErrorCode ierr; 1179552f7358SJed Brown 1180552f7358SJed Brown PetscFunctionBegin; 11819318fe57SMatthew G. Knepley PetscValidPointer(dm, 1); 11829318fe57SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 11839318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 11849318fe57SMatthew G. Knepley for (d = 0; d < dim; ++d) {fac[d] = faces[d]; bdt[d] = periodicity[d];} 11859318fe57SMatthew G. Knepley ierr = DMPlexCreateCubeMesh_Internal(dm, lower, upper, fac, bdt[0], bdt[1], bdt[2]);CHKERRQ(ierr); 1186768d5fceSMatthew G. Knepley if (periodicity[0] == DM_BOUNDARY_PERIODIC || periodicity[0] == DM_BOUNDARY_TWIST || 1187768d5fceSMatthew G. Knepley periodicity[1] == DM_BOUNDARY_PERIODIC || periodicity[1] == DM_BOUNDARY_TWIST || 1188768d5fceSMatthew G. Knepley (dim > 2 && (periodicity[2] == DM_BOUNDARY_PERIODIC || periodicity[2] == DM_BOUNDARY_TWIST))) { 1189768d5fceSMatthew G. Knepley PetscReal L[3]; 1190768d5fceSMatthew G. Knepley PetscReal maxCell[3]; 1191552f7358SJed Brown 11929318fe57SMatthew G. Knepley for (d = 0; d < dim; ++d) { 11939318fe57SMatthew G. Knepley L[d] = upper[d] - lower[d]; 11949318fe57SMatthew G. Knepley maxCell[d] = 1.1 * (L[d] / PetscMax(1, faces[d])); 1195768d5fceSMatthew G. Knepley } 11969318fe57SMatthew G. Knepley ierr = DMSetPeriodicity(dm, PETSC_TRUE, maxCell, L, periodicity);CHKERRQ(ierr); 1197768d5fceSMatthew G. Knepley } 11989318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr); 11999318fe57SMatthew G. Knepley PetscFunctionReturn(0); 12009318fe57SMatthew G. Knepley } 12019318fe57SMatthew G. Knepley 12029318fe57SMatthew 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) 12039318fe57SMatthew G. Knepley { 12049318fe57SMatthew G. Knepley PetscErrorCode ierr; 12059318fe57SMatthew G. Knepley 12069318fe57SMatthew G. Knepley PetscFunctionBegin; 12079318fe57SMatthew G. Knepley if (dim == 1) {ierr = DMPlexCreateLineMesh_Internal(dm, faces[0], lower[0], upper[0], periodicity[0]);CHKERRQ(ierr);} 12089318fe57SMatthew G. Knepley else if (simplex) {ierr = DMPlexCreateBoxMesh_Simplex_Internal(dm, dim, faces, lower, upper, periodicity, interpolate);CHKERRQ(ierr);} 12099318fe57SMatthew G. Knepley else {ierr = DMPlexCreateBoxMesh_Tensor_Internal(dm, dim, faces, lower, upper, periodicity);CHKERRQ(ierr);} 12109318fe57SMatthew G. Knepley if (!interpolate && dim > 1 && !simplex) { 1211768d5fceSMatthew G. Knepley DM udm; 1212768d5fceSMatthew G. Knepley 12139318fe57SMatthew G. Knepley ierr = DMPlexUninterpolate(dm, &udm);CHKERRQ(ierr); 12149318fe57SMatthew G. Knepley ierr = DMPlexCopyCoordinates(dm, udm);CHKERRQ(ierr); 12159318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &udm);CHKERRQ(ierr); 1216768d5fceSMatthew G. Knepley } 1217768d5fceSMatthew G. Knepley PetscFunctionReturn(0); 1218c8c68bd8SToby Isaac } 1219c8c68bd8SToby Isaac 1220768d5fceSMatthew G. Knepley /*@C 1221768d5fceSMatthew G. Knepley DMPlexCreateBoxMesh - Creates a mesh on the tensor product of unit intervals (box) using simplices or tensor cells (hexahedra). 1222768d5fceSMatthew G. Knepley 1223d083f849SBarry Smith Collective 1224768d5fceSMatthew G. Knepley 1225768d5fceSMatthew G. Knepley Input Parameters: 1226768d5fceSMatthew G. Knepley + comm - The communicator for the DM object 1227768d5fceSMatthew G. Knepley . dim - The spatial dimension 1228768d5fceSMatthew G. Knepley . simplex - PETSC_TRUE for simplices, PETSC_FALSE for tensor cells 1229fdbf62faSLisandro Dalcin . faces - Number of faces per dimension, or NULL for (1,) in 1D and (2, 2) in 2D and (1, 1, 1) in 3D 1230768d5fceSMatthew G. Knepley . lower - The lower left corner, or NULL for (0, 0, 0) 1231768d5fceSMatthew G. Knepley . upper - The upper right corner, or NULL for (1, 1, 1) 1232fdbf62faSLisandro Dalcin . periodicity - The boundary type for the X,Y,Z direction, or NULL for DM_BOUNDARY_NONE 1233768d5fceSMatthew G. Knepley - interpolate - Flag to create intermediate mesh pieces (edges, faces) 1234768d5fceSMatthew G. Knepley 1235768d5fceSMatthew G. Knepley Output Parameter: 1236768d5fceSMatthew G. Knepley . dm - The DM object 1237768d5fceSMatthew G. Knepley 12389318fe57SMatthew G. Knepley Note: If you want to customize this mesh using options, you just need to 12399318fe57SMatthew G. Knepley $ DMCreate(comm, &dm); 12409318fe57SMatthew G. Knepley $ DMSetType(dm, DMPLEX); 12419318fe57SMatthew G. Knepley $ DMSetFromOptions(dm); 12429318fe57SMatthew G. Knepley and use the options on the DMSetFromOptions() page. 12431367e252SJed Brown 12441367e252SJed Brown Here is the numbering returned for 2 faces in each direction for tensor cells: 1245768d5fceSMatthew G. Knepley $ 10---17---11---18----12 1246768d5fceSMatthew G. Knepley $ | | | 1247768d5fceSMatthew G. Knepley $ | | | 1248768d5fceSMatthew G. Knepley $ 20 2 22 3 24 1249768d5fceSMatthew G. Knepley $ | | | 1250768d5fceSMatthew G. Knepley $ | | | 1251768d5fceSMatthew G. Knepley $ 7---15----8---16----9 1252768d5fceSMatthew G. Knepley $ | | | 1253768d5fceSMatthew G. Knepley $ | | | 1254768d5fceSMatthew G. Knepley $ 19 0 21 1 23 1255768d5fceSMatthew G. Knepley $ | | | 1256768d5fceSMatthew G. Knepley $ | | | 1257768d5fceSMatthew G. Knepley $ 4---13----5---14----6 1258768d5fceSMatthew G. Knepley 1259768d5fceSMatthew G. Knepley and for simplicial cells 1260768d5fceSMatthew G. Knepley 1261768d5fceSMatthew G. Knepley $ 14----8---15----9----16 1262768d5fceSMatthew G. Knepley $ |\ 5 |\ 7 | 1263768d5fceSMatthew G. Knepley $ | \ | \ | 1264768d5fceSMatthew G. Knepley $ 13 2 14 3 15 1265768d5fceSMatthew G. Knepley $ | 4 \ | 6 \ | 1266768d5fceSMatthew G. Knepley $ | \ | \ | 1267768d5fceSMatthew G. Knepley $ 11----6---12----7----13 1268768d5fceSMatthew G. Knepley $ |\ |\ | 1269768d5fceSMatthew G. Knepley $ | \ 1 | \ 3 | 1270768d5fceSMatthew G. Knepley $ 10 0 11 1 12 1271768d5fceSMatthew G. Knepley $ | 0 \ | 2 \ | 1272768d5fceSMatthew G. Knepley $ | \ | \ | 1273768d5fceSMatthew G. Knepley $ 8----4----9----5----10 1274768d5fceSMatthew G. Knepley 1275768d5fceSMatthew G. Knepley Level: beginner 1276768d5fceSMatthew G. Knepley 12779318fe57SMatthew G. Knepley .seealso: DMSetFromOptions(), DMPlexCreateFromFile(), DMPlexCreateHexCylinderMesh(), DMSetType(), DMCreate() 1278768d5fceSMatthew G. Knepley @*/ 1279768d5fceSMatthew 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) 1280552f7358SJed Brown { 12819318fe57SMatthew G. Knepley PetscInt fac[3] = {1, 1, 1}; 1282fdbf62faSLisandro Dalcin PetscReal low[3] = {0, 0, 0}; 1283fdbf62faSLisandro Dalcin PetscReal upp[3] = {1, 1, 1}; 1284fdbf62faSLisandro Dalcin DMBoundaryType bdt[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE}; 1285768d5fceSMatthew G. Knepley PetscErrorCode ierr; 1286552f7358SJed Brown 1287768d5fceSMatthew G. Knepley PetscFunctionBegin; 12889318fe57SMatthew G. Knepley ierr = DMCreate(comm,dm);CHKERRQ(ierr); 12899318fe57SMatthew G. Knepley ierr = DMSetType(*dm,DMPLEX);CHKERRQ(ierr); 12909318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxMesh_Internal(*dm, dim, simplex, faces ? faces : fac, lower ? lower : low, upper ? upper : upp, periodicity ? periodicity : bdt, interpolate);CHKERRQ(ierr); 12919318fe57SMatthew G. Knepley PetscFunctionReturn(0); 12929318fe57SMatthew G. Knepley } 1293fdbf62faSLisandro Dalcin 1294d410b0cfSMatthew G. Knepley static PetscErrorCode DMPlexCreateWedgeBoxMesh_Internal(DM dm, const PetscInt faces[], const PetscReal lower[], const PetscReal upper[], const DMBoundaryType periodicity[]) 12959318fe57SMatthew G. Knepley { 12969318fe57SMatthew G. Knepley DM bdm, vol; 12979318fe57SMatthew G. Knepley PetscInt i; 12989318fe57SMatthew G. Knepley PetscErrorCode ierr; 12999318fe57SMatthew G. Knepley 13009318fe57SMatthew G. Knepley PetscFunctionBegin; 13012c71b3e2SJacob Faibussowitsch for (i = 0; i < 3; ++i) PetscCheckFalse(periodicity[i] != DM_BOUNDARY_NONE,PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Periodicity not yet supported"); 13029318fe57SMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject) dm), &bdm);CHKERRQ(ierr); 13039318fe57SMatthew G. Knepley ierr = DMSetType(bdm, DMPLEX);CHKERRQ(ierr); 13049318fe57SMatthew G. Knepley ierr = DMSetDimension(bdm, 2);CHKERRQ(ierr); 1305d410b0cfSMatthew G. Knepley ierr = DMPlexCreateBoxMesh_Simplex_Internal(bdm, 2, faces, lower, upper, periodicity, PETSC_TRUE);CHKERRQ(ierr); 1306d410b0cfSMatthew G. Knepley ierr = DMPlexExtrude(bdm, faces[2], upper[2] - lower[2], PETSC_TRUE, PETSC_FALSE, NULL, NULL, &vol);CHKERRQ(ierr); 13079318fe57SMatthew G. Knepley ierr = DMDestroy(&bdm);CHKERRQ(ierr); 13089318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &vol);CHKERRQ(ierr); 13099318fe57SMatthew G. Knepley if (lower[2] != 0.0) { 13109318fe57SMatthew G. Knepley Vec v; 13119318fe57SMatthew G. Knepley PetscScalar *x; 13129318fe57SMatthew G. Knepley PetscInt cDim, n; 13139318fe57SMatthew G. Knepley 13149318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &v);CHKERRQ(ierr); 13159318fe57SMatthew G. Knepley ierr = VecGetBlockSize(v, &cDim);CHKERRQ(ierr); 13169318fe57SMatthew G. Knepley ierr = VecGetLocalSize(v, &n);CHKERRQ(ierr); 13179318fe57SMatthew G. Knepley ierr = VecGetArray(v, &x);CHKERRQ(ierr); 13189318fe57SMatthew G. Knepley x += cDim; 13199318fe57SMatthew G. Knepley for (i = 0; i < n; i += cDim) x[i] += lower[2]; 13209318fe57SMatthew G. Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 13219318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, v);CHKERRQ(ierr); 13229318fe57SMatthew G. Knepley } 1323552f7358SJed Brown PetscFunctionReturn(0); 1324552f7358SJed Brown } 1325552f7358SJed Brown 132600dabe28SStefano Zampini /*@ 132700dabe28SStefano Zampini DMPlexCreateWedgeBoxMesh - Creates a 3-D mesh tesselating the (x,y) plane and extruding in the third direction using wedge cells. 132800dabe28SStefano Zampini 1329d083f849SBarry Smith Collective 133000dabe28SStefano Zampini 133100dabe28SStefano Zampini Input Parameters: 133200dabe28SStefano Zampini + comm - The communicator for the DM object 133300dabe28SStefano Zampini . faces - Number of faces per dimension, or NULL for (1, 1, 1) 133400dabe28SStefano Zampini . lower - The lower left corner, or NULL for (0, 0, 0) 133500dabe28SStefano Zampini . upper - The upper right corner, or NULL for (1, 1, 1) 133600dabe28SStefano Zampini . periodicity - The boundary type for the X,Y,Z direction, or NULL for DM_BOUNDARY_NONE 1337d0fcb9c2SMatthew G. Knepley . orderHeight - If PETSC_TRUE, orders the extruded cells in the height first. Otherwise, orders the cell on the layers first 133800dabe28SStefano Zampini - interpolate - Flag to create intermediate mesh pieces (edges, faces) 133900dabe28SStefano Zampini 134000dabe28SStefano Zampini Output Parameter: 134100dabe28SStefano Zampini . dm - The DM object 134200dabe28SStefano Zampini 134300dabe28SStefano Zampini Level: beginner 134400dabe28SStefano Zampini 1345d410b0cfSMatthew G. Knepley .seealso: DMPlexCreateHexCylinderMesh(), DMPlexCreateWedgeCylinderMesh(), DMExtrude(), DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 134600dabe28SStefano Zampini @*/ 1347d0fcb9c2SMatthew 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) 134800dabe28SStefano Zampini { 13499318fe57SMatthew G. Knepley PetscInt fac[3] = {1, 1, 1}; 135000dabe28SStefano Zampini PetscReal low[3] = {0, 0, 0}; 135100dabe28SStefano Zampini PetscReal upp[3] = {1, 1, 1}; 135200dabe28SStefano Zampini DMBoundaryType bdt[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE}; 135300dabe28SStefano Zampini PetscErrorCode ierr; 135400dabe28SStefano Zampini 135500dabe28SStefano Zampini PetscFunctionBegin; 13569318fe57SMatthew G. Knepley ierr = DMCreate(comm,dm);CHKERRQ(ierr); 13579318fe57SMatthew G. Knepley ierr = DMSetType(*dm,DMPLEX);CHKERRQ(ierr); 1358d410b0cfSMatthew G. Knepley ierr = DMPlexCreateWedgeBoxMesh_Internal(*dm, faces ? faces : fac, lower ? lower : low, upper ? upper : upp, periodicity ? periodicity : bdt);CHKERRQ(ierr); 1359d410b0cfSMatthew G. Knepley if (!interpolate) { 1360d410b0cfSMatthew G. Knepley DM udm; 136100dabe28SStefano Zampini 1362d410b0cfSMatthew G. Knepley ierr = DMPlexUninterpolate(*dm, &udm);CHKERRQ(ierr); 1363d410b0cfSMatthew G. Knepley ierr = DMPlexReplace_Static(*dm, &udm);CHKERRQ(ierr); 136400dabe28SStefano Zampini } 136500dabe28SStefano Zampini PetscFunctionReturn(0); 136600dabe28SStefano Zampini } 136700dabe28SStefano Zampini 1368a9074c1eSMatthew G. Knepley /*@C 1369a9074c1eSMatthew G. Knepley DMPlexSetOptionsPrefix - Sets the prefix used for searching for all DM options in the database. 1370a9074c1eSMatthew G. Knepley 1371d083f849SBarry Smith Logically Collective on dm 1372a9074c1eSMatthew G. Knepley 1373a9074c1eSMatthew G. Knepley Input Parameters: 1374a9074c1eSMatthew G. Knepley + dm - the DM context 1375a9074c1eSMatthew G. Knepley - prefix - the prefix to prepend to all option names 1376a9074c1eSMatthew G. Knepley 1377a9074c1eSMatthew G. Knepley Notes: 1378a9074c1eSMatthew G. Knepley A hyphen (-) must NOT be given at the beginning of the prefix name. 1379a9074c1eSMatthew G. Knepley The first character of all runtime options is AUTOMATICALLY the hyphen. 1380a9074c1eSMatthew G. Knepley 1381a9074c1eSMatthew G. Knepley Level: advanced 1382a9074c1eSMatthew G. Knepley 1383a9074c1eSMatthew G. Knepley .seealso: SNESSetFromOptions() 1384a9074c1eSMatthew G. Knepley @*/ 1385a9074c1eSMatthew G. Knepley PetscErrorCode DMPlexSetOptionsPrefix(DM dm, const char prefix[]) 1386a9074c1eSMatthew G. Knepley { 1387a9074c1eSMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) dm->data; 1388a9074c1eSMatthew G. Knepley PetscErrorCode ierr; 1389a9074c1eSMatthew G. Knepley 1390a9074c1eSMatthew G. Knepley PetscFunctionBegin; 1391a9074c1eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1392a9074c1eSMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) dm, prefix);CHKERRQ(ierr); 1393a9074c1eSMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) mesh->partitioner, prefix);CHKERRQ(ierr); 1394a9074c1eSMatthew G. Knepley PetscFunctionReturn(0); 1395a9074c1eSMatthew G. Knepley } 1396a9074c1eSMatthew G. Knepley 13979318fe57SMatthew G. Knepley /* Remap geometry to cylinder 139861a622f3SMatthew G. Knepley TODO: This only works for a single refinement, then it is broken 139961a622f3SMatthew G. Knepley 14009318fe57SMatthew G. Knepley Interior square: Linear interpolation is correct 14019318fe57SMatthew G. Knepley The other cells all have vertices on rays from the origin. We want to uniformly expand the spacing 14029318fe57SMatthew G. Knepley such that the last vertex is on the unit circle. So the closest and farthest vertices are at distance 14030510c589SMatthew G. Knepley 14049318fe57SMatthew G. Knepley phi = arctan(y/x) 14059318fe57SMatthew G. Knepley d_close = sqrt(1/8 + 1/4 sin^2(phi)) 14069318fe57SMatthew G. Knepley d_far = sqrt(1/2 + sin^2(phi)) 14070510c589SMatthew G. Knepley 14089318fe57SMatthew G. Knepley so we remap them using 14090510c589SMatthew G. Knepley 14109318fe57SMatthew G. Knepley x_new = x_close + (x - x_close) (1 - d_close) / (d_far - d_close) 14119318fe57SMatthew G. Knepley y_new = y_close + (y - y_close) (1 - d_close) / (d_far - d_close) 14120510c589SMatthew G. Knepley 14139318fe57SMatthew G. Knepley If pi/4 < phi < 3pi/4 or -3pi/4 < phi < -pi/4, then we switch x and y. 14149318fe57SMatthew G. Knepley */ 14159318fe57SMatthew G. Knepley static void snapToCylinder(PetscInt dim, PetscInt Nf, PetscInt NfAux, 14169318fe57SMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 14179318fe57SMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 14189318fe57SMatthew G. Knepley PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 14199318fe57SMatthew G. Knepley { 14209318fe57SMatthew G. Knepley const PetscReal dis = 1.0/PetscSqrtReal(2.0); 14219318fe57SMatthew G. Knepley const PetscReal ds2 = 0.5*dis; 142222cc497dSMatthew G. Knepley 14239318fe57SMatthew G. Knepley if ((PetscAbsScalar(u[0]) <= ds2) && (PetscAbsScalar(u[1]) <= ds2)) { 14249318fe57SMatthew G. Knepley f0[0] = u[0]; 14259318fe57SMatthew G. Knepley f0[1] = u[1]; 14269318fe57SMatthew G. Knepley } else { 14279318fe57SMatthew G. Knepley PetscReal phi, sinp, cosp, dc, df, x, y, xc, yc; 14280510c589SMatthew G. Knepley 14299318fe57SMatthew G. Knepley x = PetscRealPart(u[0]); 14309318fe57SMatthew G. Knepley y = PetscRealPart(u[1]); 14319318fe57SMatthew G. Knepley phi = PetscAtan2Real(y, x); 14329318fe57SMatthew G. Knepley sinp = PetscSinReal(phi); 14339318fe57SMatthew G. Knepley cosp = PetscCosReal(phi); 14349318fe57SMatthew G. Knepley if ((PetscAbsReal(phi) > PETSC_PI/4.0) && (PetscAbsReal(phi) < 3.0*PETSC_PI/4.0)) { 14359318fe57SMatthew G. Knepley dc = PetscAbsReal(ds2/sinp); 14369318fe57SMatthew G. Knepley df = PetscAbsReal(dis/sinp); 14379318fe57SMatthew G. Knepley xc = ds2*x/PetscAbsReal(y); 14389318fe57SMatthew G. Knepley yc = ds2*PetscSignReal(y); 14399318fe57SMatthew G. Knepley } else { 14409318fe57SMatthew G. Knepley dc = PetscAbsReal(ds2/cosp); 14419318fe57SMatthew G. Knepley df = PetscAbsReal(dis/cosp); 14429318fe57SMatthew G. Knepley xc = ds2*PetscSignReal(x); 14439318fe57SMatthew G. Knepley yc = ds2*y/PetscAbsReal(x); 14449318fe57SMatthew G. Knepley } 14459318fe57SMatthew G. Knepley f0[0] = xc + (u[0] - xc)*(1.0 - dc)/(df - dc); 14469318fe57SMatthew G. Knepley f0[1] = yc + (u[1] - yc)*(1.0 - dc)/(df - dc); 14479318fe57SMatthew G. Knepley } 14489318fe57SMatthew G. Knepley f0[2] = u[2]; 14499318fe57SMatthew G. Knepley } 14500510c589SMatthew G. Knepley 14519318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateHexCylinderMesh_Internal(DM dm, DMBoundaryType periodicZ) 14520510c589SMatthew G. Knepley { 14530510c589SMatthew G. Knepley const PetscInt dim = 3; 14549318fe57SMatthew G. Knepley PetscInt numCells, numVertices; 1455d8c47e87SMatthew G. Knepley PetscMPIInt rank; 14560510c589SMatthew G. Knepley PetscErrorCode ierr; 14570510c589SMatthew G. Knepley 14580510c589SMatthew G. Knepley PetscFunctionBegin; 14599318fe57SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 14609318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 14610510c589SMatthew G. Knepley /* Create topology */ 14620510c589SMatthew G. Knepley { 14630510c589SMatthew G. Knepley PetscInt cone[8], c; 14640510c589SMatthew G. Knepley 1465dd400576SPatrick Sanan numCells = rank == 0 ? 5 : 0; 1466dd400576SPatrick Sanan numVertices = rank == 0 ? 16 : 0; 1467006a8963SMatthew G. Knepley if (periodicZ == DM_BOUNDARY_PERIODIC) { 1468ae8bcbbbSMatthew G. Knepley numCells *= 3; 1469dd400576SPatrick Sanan numVertices = rank == 0 ? 24 : 0; 1470006a8963SMatthew G. Knepley } 14719318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVertices);CHKERRQ(ierr); 14729318fe57SMatthew G. Knepley for (c = 0; c < numCells; c++) {ierr = DMPlexSetConeSize(dm, c, 8);CHKERRQ(ierr);} 14739318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); 1474dd400576SPatrick Sanan if (rank == 0) { 1475006a8963SMatthew G. Knepley if (periodicZ == DM_BOUNDARY_PERIODIC) { 1476ae8bcbbbSMatthew G. Knepley cone[0] = 15; cone[1] = 18; cone[2] = 17; cone[3] = 16; 1477ae8bcbbbSMatthew G. Knepley cone[4] = 31; cone[5] = 32; cone[6] = 33; cone[7] = 34; 14789318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 0, cone);CHKERRQ(ierr); 1479ae8bcbbbSMatthew G. Knepley cone[0] = 16; cone[1] = 17; cone[2] = 24; cone[3] = 23; 1480ae8bcbbbSMatthew G. Knepley cone[4] = 32; cone[5] = 36; cone[6] = 37; cone[7] = 33; /* 22 25 26 21 */ 14819318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 1, cone);CHKERRQ(ierr); 1482ae8bcbbbSMatthew G. Knepley cone[0] = 18; cone[1] = 27; cone[2] = 24; cone[3] = 17; 1483ae8bcbbbSMatthew G. Knepley cone[4] = 34; cone[5] = 33; cone[6] = 37; cone[7] = 38; 14849318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 2, cone);CHKERRQ(ierr); 1485ae8bcbbbSMatthew G. Knepley cone[0] = 29; cone[1] = 27; cone[2] = 18; cone[3] = 15; 1486ae8bcbbbSMatthew G. Knepley cone[4] = 35; cone[5] = 31; cone[6] = 34; cone[7] = 38; 14879318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 3, cone);CHKERRQ(ierr); 1488ae8bcbbbSMatthew G. Knepley cone[0] = 29; cone[1] = 15; cone[2] = 16; cone[3] = 23; 1489ae8bcbbbSMatthew G. Knepley cone[4] = 35; cone[5] = 36; cone[6] = 32; cone[7] = 31; 14909318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 4, cone);CHKERRQ(ierr); 1491006a8963SMatthew G. Knepley 1492ae8bcbbbSMatthew G. Knepley cone[0] = 31; cone[1] = 34; cone[2] = 33; cone[3] = 32; 1493ae8bcbbbSMatthew G. Knepley cone[4] = 19; cone[5] = 22; cone[6] = 21; cone[7] = 20; 14949318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 5, cone);CHKERRQ(ierr); 1495ae8bcbbbSMatthew G. Knepley cone[0] = 32; cone[1] = 33; cone[2] = 37; cone[3] = 36; 1496ae8bcbbbSMatthew G. Knepley cone[4] = 22; cone[5] = 25; cone[6] = 26; cone[7] = 21; 14979318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 6, cone);CHKERRQ(ierr); 1498ae8bcbbbSMatthew G. Knepley cone[0] = 34; cone[1] = 38; cone[2] = 37; cone[3] = 33; 1499ae8bcbbbSMatthew G. Knepley cone[4] = 20; cone[5] = 21; cone[6] = 26; cone[7] = 28; 15009318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 7, cone);CHKERRQ(ierr); 1501ae8bcbbbSMatthew G. Knepley cone[0] = 35; cone[1] = 38; cone[2] = 34; cone[3] = 31; 1502ae8bcbbbSMatthew G. Knepley cone[4] = 30; cone[5] = 19; cone[6] = 20; cone[7] = 28; 15039318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 8, cone);CHKERRQ(ierr); 1504ae8bcbbbSMatthew G. Knepley cone[0] = 35; cone[1] = 31; cone[2] = 32; cone[3] = 36; 1505ae8bcbbbSMatthew G. Knepley cone[4] = 30; cone[5] = 25; cone[6] = 22; cone[7] = 19; 15069318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 9, cone);CHKERRQ(ierr); 1507ae8bcbbbSMatthew G. Knepley 1508ae8bcbbbSMatthew G. Knepley cone[0] = 19; cone[1] = 20; cone[2] = 21; cone[3] = 22; 1509ae8bcbbbSMatthew G. Knepley cone[4] = 15; cone[5] = 16; cone[6] = 17; cone[7] = 18; 15109318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 10, cone);CHKERRQ(ierr); 1511ae8bcbbbSMatthew G. Knepley cone[0] = 22; cone[1] = 21; cone[2] = 26; cone[3] = 25; 1512ae8bcbbbSMatthew G. Knepley cone[4] = 16; cone[5] = 23; cone[6] = 24; cone[7] = 17; 15139318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 11, cone);CHKERRQ(ierr); 1514ae8bcbbbSMatthew G. Knepley cone[0] = 20; cone[1] = 28; cone[2] = 26; cone[3] = 21; 1515ae8bcbbbSMatthew G. Knepley cone[4] = 18; cone[5] = 17; cone[6] = 24; cone[7] = 27; 15169318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 12, cone);CHKERRQ(ierr); 1517ae8bcbbbSMatthew G. Knepley cone[0] = 30; cone[1] = 28; cone[2] = 20; cone[3] = 19; 1518ae8bcbbbSMatthew G. Knepley cone[4] = 29; cone[5] = 15; cone[6] = 18; cone[7] = 27; 15199318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 13, cone);CHKERRQ(ierr); 1520ae8bcbbbSMatthew G. Knepley cone[0] = 30; cone[1] = 19; cone[2] = 22; cone[3] = 25; 1521ae8bcbbbSMatthew G. Knepley cone[4] = 29; cone[5] = 23; cone[6] = 16; cone[7] = 15; 15229318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 14, cone);CHKERRQ(ierr); 1523006a8963SMatthew G. Knepley } else { 152410c6f908SMatthew G. Knepley cone[0] = 5; cone[1] = 8; cone[2] = 7; cone[3] = 6; 152510c6f908SMatthew G. Knepley cone[4] = 9; cone[5] = 12; cone[6] = 11; cone[7] = 10; 15269318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 0, cone);CHKERRQ(ierr); 152710c6f908SMatthew G. Knepley cone[0] = 6; cone[1] = 7; cone[2] = 14; cone[3] = 13; 152810c6f908SMatthew G. Knepley cone[4] = 12; cone[5] = 15; cone[6] = 16; cone[7] = 11; 15299318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 1, cone);CHKERRQ(ierr); 153010c6f908SMatthew G. Knepley cone[0] = 8; cone[1] = 17; cone[2] = 14; cone[3] = 7; 153110c6f908SMatthew G. Knepley cone[4] = 10; cone[5] = 11; cone[6] = 16; cone[7] = 18; 15329318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 2, cone);CHKERRQ(ierr); 153310c6f908SMatthew G. Knepley cone[0] = 19; cone[1] = 17; cone[2] = 8; cone[3] = 5; 153410c6f908SMatthew G. Knepley cone[4] = 20; cone[5] = 9; cone[6] = 10; cone[7] = 18; 15359318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 3, cone);CHKERRQ(ierr); 153610c6f908SMatthew G. Knepley cone[0] = 19; cone[1] = 5; cone[2] = 6; cone[3] = 13; 153710c6f908SMatthew G. Knepley cone[4] = 20; cone[5] = 15; cone[6] = 12; cone[7] = 9; 15389318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 4, cone);CHKERRQ(ierr); 1539006a8963SMatthew G. Knepley } 1540d8c47e87SMatthew G. Knepley } 15419318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 15429318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 15430510c589SMatthew G. Knepley } 1544dbc1dc17SMatthew G. Knepley /* Create cube geometry */ 15450510c589SMatthew G. Knepley { 15460510c589SMatthew G. Knepley Vec coordinates; 15470510c589SMatthew G. Knepley PetscSection coordSection; 15480510c589SMatthew G. Knepley PetscScalar *coords; 15490510c589SMatthew G. Knepley PetscInt coordSize, v; 15500510c589SMatthew G. Knepley const PetscReal dis = 1.0/PetscSqrtReal(2.0); 15510510c589SMatthew G. Knepley const PetscReal ds2 = dis/2.0; 15520510c589SMatthew G. Knepley 15530510c589SMatthew G. Knepley /* Build coordinates */ 15549318fe57SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 15550510c589SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 15560510c589SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, dim);CHKERRQ(ierr); 15570510c589SMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, numCells, numCells+numVertices);CHKERRQ(ierr); 15580510c589SMatthew G. Knepley for (v = numCells; v < numCells+numVertices; ++v) { 15590510c589SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, dim);CHKERRQ(ierr); 15600510c589SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, dim);CHKERRQ(ierr); 15610510c589SMatthew G. Knepley } 15620510c589SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 15630510c589SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 15640510c589SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 15650510c589SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 15660510c589SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 15670510c589SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, dim);CHKERRQ(ierr); 15680510c589SMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 15690510c589SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 1570dd400576SPatrick Sanan if (rank == 0) { 15710510c589SMatthew G. Knepley coords[0*dim+0] = -ds2; coords[0*dim+1] = -ds2; coords[0*dim+2] = 0.0; 15720510c589SMatthew G. Knepley coords[1*dim+0] = ds2; coords[1*dim+1] = -ds2; coords[1*dim+2] = 0.0; 15730510c589SMatthew G. Knepley coords[2*dim+0] = ds2; coords[2*dim+1] = ds2; coords[2*dim+2] = 0.0; 15740510c589SMatthew G. Knepley coords[3*dim+0] = -ds2; coords[3*dim+1] = ds2; coords[3*dim+2] = 0.0; 15750510c589SMatthew G. Knepley coords[4*dim+0] = -ds2; coords[4*dim+1] = -ds2; coords[4*dim+2] = 1.0; 15760510c589SMatthew G. Knepley coords[5*dim+0] = -ds2; coords[5*dim+1] = ds2; coords[5*dim+2] = 1.0; 15770510c589SMatthew G. Knepley coords[6*dim+0] = ds2; coords[6*dim+1] = ds2; coords[6*dim+2] = 1.0; 15780510c589SMatthew G. Knepley coords[7*dim+0] = ds2; coords[7*dim+1] = -ds2; coords[7*dim+2] = 1.0; 15790510c589SMatthew G. Knepley coords[ 8*dim+0] = dis; coords[ 8*dim+1] = -dis; coords[ 8*dim+2] = 0.0; 15800510c589SMatthew G. Knepley coords[ 9*dim+0] = dis; coords[ 9*dim+1] = dis; coords[ 9*dim+2] = 0.0; 15810510c589SMatthew G. Knepley coords[10*dim+0] = dis; coords[10*dim+1] = -dis; coords[10*dim+2] = 1.0; 15820510c589SMatthew G. Knepley coords[11*dim+0] = dis; coords[11*dim+1] = dis; coords[11*dim+2] = 1.0; 15830510c589SMatthew G. Knepley coords[12*dim+0] = -dis; coords[12*dim+1] = dis; coords[12*dim+2] = 0.0; 15840510c589SMatthew G. Knepley coords[13*dim+0] = -dis; coords[13*dim+1] = dis; coords[13*dim+2] = 1.0; 15850510c589SMatthew G. Knepley coords[14*dim+0] = -dis; coords[14*dim+1] = -dis; coords[14*dim+2] = 0.0; 15860510c589SMatthew G. Knepley coords[15*dim+0] = -dis; coords[15*dim+1] = -dis; coords[15*dim+2] = 1.0; 1587ae8bcbbbSMatthew G. Knepley if (periodicZ == DM_BOUNDARY_PERIODIC) { 1588ae8bcbbbSMatthew G. Knepley /* 15 31 19 */ coords[16*dim+0] = -ds2; coords[16*dim+1] = -ds2; coords[16*dim+2] = 0.5; 1589ae8bcbbbSMatthew G. Knepley /* 16 32 22 */ coords[17*dim+0] = ds2; coords[17*dim+1] = -ds2; coords[17*dim+2] = 0.5; 1590ae8bcbbbSMatthew G. Knepley /* 17 33 21 */ coords[18*dim+0] = ds2; coords[18*dim+1] = ds2; coords[18*dim+2] = 0.5; 1591ae8bcbbbSMatthew G. Knepley /* 18 34 20 */ coords[19*dim+0] = -ds2; coords[19*dim+1] = ds2; coords[19*dim+2] = 0.5; 1592ae8bcbbbSMatthew G. Knepley /* 29 35 30 */ coords[20*dim+0] = -dis; coords[20*dim+1] = -dis; coords[20*dim+2] = 0.5; 1593ae8bcbbbSMatthew G. Knepley /* 23 36 25 */ coords[21*dim+0] = dis; coords[21*dim+1] = -dis; coords[21*dim+2] = 0.5; 1594ae8bcbbbSMatthew G. Knepley /* 24 37 26 */ coords[22*dim+0] = dis; coords[22*dim+1] = dis; coords[22*dim+2] = 0.5; 1595ae8bcbbbSMatthew G. Knepley /* 27 38 28 */ coords[23*dim+0] = -dis; coords[23*dim+1] = dis; coords[23*dim+2] = 0.5; 1596ae8bcbbbSMatthew G. Knepley } 1597d8c47e87SMatthew G. Knepley } 15980510c589SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 15999318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 16000510c589SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 16010510c589SMatthew G. Knepley } 1602006a8963SMatthew G. Knepley /* Create periodicity */ 1603006a8963SMatthew G. Knepley if (periodicZ == DM_BOUNDARY_PERIODIC || periodicZ == DM_BOUNDARY_TWIST) { 1604006a8963SMatthew G. Knepley PetscReal L[3]; 1605006a8963SMatthew G. Knepley PetscReal maxCell[3]; 1606006a8963SMatthew G. Knepley DMBoundaryType bdType[3]; 1607006a8963SMatthew G. Knepley PetscReal lower[3] = {0.0, 0.0, 0.0}; 1608ae8bcbbbSMatthew G. Knepley PetscReal upper[3] = {1.0, 1.0, 1.5}; 1609ae8bcbbbSMatthew G. Knepley PetscInt i, numZCells = 3; 1610006a8963SMatthew G. Knepley 1611006a8963SMatthew G. Knepley bdType[0] = DM_BOUNDARY_NONE; 1612006a8963SMatthew G. Knepley bdType[1] = DM_BOUNDARY_NONE; 1613006a8963SMatthew G. Knepley bdType[2] = periodicZ; 1614006a8963SMatthew G. Knepley for (i = 0; i < dim; i++) { 1615006a8963SMatthew G. Knepley L[i] = upper[i] - lower[i]; 1616006a8963SMatthew G. Knepley maxCell[i] = 1.1 * (L[i] / numZCells); 1617006a8963SMatthew G. Knepley } 16189318fe57SMatthew G. Knepley ierr = DMSetPeriodicity(dm, PETSC_TRUE, maxCell, L, bdType);CHKERRQ(ierr); 1619006a8963SMatthew G. Knepley } 1620dbc1dc17SMatthew G. Knepley { 16219318fe57SMatthew G. Knepley DM cdm; 16229318fe57SMatthew G. Knepley PetscDS cds; 16239318fe57SMatthew G. Knepley PetscScalar c[2] = {1.0, 1.0}; 1624dbc1dc17SMatthew G. Knepley 16259318fe57SMatthew G. Knepley ierr = DMPlexCreateCoordinateSpace(dm, 1, snapToCylinder);CHKERRQ(ierr); 16269318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 16279318fe57SMatthew G. Knepley ierr = DMGetDS(cdm, &cds);CHKERRQ(ierr); 16289318fe57SMatthew G. Knepley ierr = PetscDSSetConstants(cds, 2, c);CHKERRQ(ierr); 1629dbc1dc17SMatthew G. Knepley } 16309318fe57SMatthew G. Knepley /* Wait for coordinate creation before doing in-place modification */ 16319318fe57SMatthew G. Knepley ierr = DMPlexInterpolateInPlace_Internal(dm);CHKERRQ(ierr); 16320510c589SMatthew G. Knepley PetscFunctionReturn(0); 16330510c589SMatthew G. Knepley } 16340510c589SMatthew G. Knepley 163524119c2aSMatthew G. Knepley /*@ 16369318fe57SMatthew G. Knepley DMPlexCreateHexCylinderMesh - Creates a mesh on the tensor product of the unit interval with the circle (cylinder) using hexahedra. 163724119c2aSMatthew G. Knepley 1638d083f849SBarry Smith Collective 163924119c2aSMatthew G. Knepley 164024119c2aSMatthew G. Knepley Input Parameters: 164124119c2aSMatthew G. Knepley + comm - The communicator for the DM object 16429318fe57SMatthew G. Knepley - periodicZ - The boundary type for the Z direction 164324119c2aSMatthew G. Knepley 164424119c2aSMatthew G. Knepley Output Parameter: 164524119c2aSMatthew G. Knepley . dm - The DM object 164624119c2aSMatthew G. Knepley 16479318fe57SMatthew G. Knepley Note: 16489318fe57SMatthew G. Knepley Here is the output numbering looking from the bottom of the cylinder: 16499318fe57SMatthew G. Knepley $ 17-----14 16509318fe57SMatthew G. Knepley $ | | 16519318fe57SMatthew G. Knepley $ | 2 | 16529318fe57SMatthew G. Knepley $ | | 16539318fe57SMatthew G. Knepley $ 17-----8-----7-----14 16549318fe57SMatthew G. Knepley $ | | | | 16559318fe57SMatthew G. Knepley $ | 3 | 0 | 1 | 16569318fe57SMatthew G. Knepley $ | | | | 16579318fe57SMatthew G. Knepley $ 19-----5-----6-----13 16589318fe57SMatthew G. Knepley $ | | 16599318fe57SMatthew G. Knepley $ | 4 | 16609318fe57SMatthew G. Knepley $ | | 16619318fe57SMatthew G. Knepley $ 19-----13 16629318fe57SMatthew G. Knepley $ 16639318fe57SMatthew G. Knepley $ and up through the top 16649318fe57SMatthew G. Knepley $ 16659318fe57SMatthew G. Knepley $ 18-----16 16669318fe57SMatthew G. Knepley $ | | 16679318fe57SMatthew G. Knepley $ | 2 | 16689318fe57SMatthew G. Knepley $ | | 16699318fe57SMatthew G. Knepley $ 18----10----11-----16 16709318fe57SMatthew G. Knepley $ | | | | 16719318fe57SMatthew G. Knepley $ | 3 | 0 | 1 | 16729318fe57SMatthew G. Knepley $ | | | | 16739318fe57SMatthew G. Knepley $ 20-----9----12-----15 16749318fe57SMatthew G. Knepley $ | | 16759318fe57SMatthew G. Knepley $ | 4 | 16769318fe57SMatthew G. Knepley $ | | 16779318fe57SMatthew G. Knepley $ 20-----15 16789318fe57SMatthew G. Knepley 167924119c2aSMatthew G. Knepley Level: beginner 168024119c2aSMatthew G. Knepley 16819318fe57SMatthew G. Knepley .seealso: DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 168224119c2aSMatthew G. Knepley @*/ 16839318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateHexCylinderMesh(MPI_Comm comm, DMBoundaryType periodicZ, DM *dm) 16849318fe57SMatthew G. Knepley { 16859318fe57SMatthew G. Knepley PetscErrorCode ierr; 16869318fe57SMatthew G. Knepley 16879318fe57SMatthew G. Knepley PetscFunctionBegin; 16889318fe57SMatthew G. Knepley PetscValidPointer(dm, 3); 16899318fe57SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 16909318fe57SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 16919318fe57SMatthew G. Knepley ierr = DMPlexCreateHexCylinderMesh_Internal(*dm, periodicZ);CHKERRQ(ierr); 16929318fe57SMatthew G. Knepley PetscFunctionReturn(0); 16939318fe57SMatthew G. Knepley } 16949318fe57SMatthew G. Knepley 16959318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateWedgeCylinderMesh_Internal(DM dm, PetscInt n, PetscBool interpolate) 169624119c2aSMatthew G. Knepley { 169724119c2aSMatthew G. Knepley const PetscInt dim = 3; 1698412e9a14SMatthew G. Knepley PetscInt numCells, numVertices, v; 16999fe9f049SMatthew G. Knepley PetscMPIInt rank; 170024119c2aSMatthew G. Knepley PetscErrorCode ierr; 170124119c2aSMatthew G. Knepley 170224119c2aSMatthew G. Knepley PetscFunctionBegin; 17032c71b3e2SJacob Faibussowitsch PetscCheckFalse(n < 0,PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Number of wedges %D cannot be negative", n); 17049318fe57SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 17059318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 1706412e9a14SMatthew G. Knepley /* Must create the celltype label here so that we do not automatically try to compute the types */ 17079318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm, "celltype");CHKERRQ(ierr); 170824119c2aSMatthew G. Knepley /* Create topology */ 170924119c2aSMatthew G. Knepley { 171024119c2aSMatthew G. Knepley PetscInt cone[6], c; 171124119c2aSMatthew G. Knepley 1712dd400576SPatrick Sanan numCells = rank == 0 ? n : 0; 1713dd400576SPatrick Sanan numVertices = rank == 0 ? 2*(n+1) : 0; 17149318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVertices);CHKERRQ(ierr); 17159318fe57SMatthew G. Knepley for (c = 0; c < numCells; c++) {ierr = DMPlexSetConeSize(dm, c, 6);CHKERRQ(ierr);} 17169318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); 171724119c2aSMatthew G. Knepley for (c = 0; c < numCells; c++) { 171824119c2aSMatthew G. Knepley cone[0] = c+n*1; cone[1] = (c+1)%n+n*1; cone[2] = 0+3*n; 171924119c2aSMatthew G. Knepley cone[3] = c+n*2; cone[4] = (c+1)%n+n*2; cone[5] = 1+3*n; 17209318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, c, cone);CHKERRQ(ierr); 17219318fe57SMatthew G. Knepley ierr = DMPlexSetCellType(dm, c, DM_POLYTOPE_TRI_PRISM_TENSOR);CHKERRQ(ierr); 172224119c2aSMatthew G. Knepley } 17239318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 17249318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 172524119c2aSMatthew G. Knepley } 1726412e9a14SMatthew G. Knepley for (v = numCells; v < numCells+numVertices; ++v) { 17279318fe57SMatthew G. Knepley ierr = DMPlexSetCellType(dm, v, DM_POLYTOPE_POINT);CHKERRQ(ierr); 172824119c2aSMatthew G. Knepley } 172924119c2aSMatthew G. Knepley /* Create cylinder geometry */ 173024119c2aSMatthew G. Knepley { 173124119c2aSMatthew G. Knepley Vec coordinates; 173224119c2aSMatthew G. Knepley PetscSection coordSection; 173324119c2aSMatthew G. Knepley PetscScalar *coords; 1734412e9a14SMatthew G. Knepley PetscInt coordSize, c; 173524119c2aSMatthew G. Knepley 173624119c2aSMatthew G. Knepley /* Build coordinates */ 17379318fe57SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 173824119c2aSMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 173924119c2aSMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, dim);CHKERRQ(ierr); 174024119c2aSMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, numCells, numCells+numVertices);CHKERRQ(ierr); 174124119c2aSMatthew G. Knepley for (v = numCells; v < numCells+numVertices; ++v) { 174224119c2aSMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, dim);CHKERRQ(ierr); 174324119c2aSMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, dim);CHKERRQ(ierr); 174424119c2aSMatthew G. Knepley } 174524119c2aSMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 174624119c2aSMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 174724119c2aSMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 174824119c2aSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 174924119c2aSMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 175024119c2aSMatthew G. Knepley ierr = VecSetBlockSize(coordinates, dim);CHKERRQ(ierr); 175124119c2aSMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 175224119c2aSMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 175324119c2aSMatthew G. Knepley for (c = 0; c < numCells; c++) { 175424119c2aSMatthew 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; 175524119c2aSMatthew 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; 175624119c2aSMatthew G. Knepley } 1757dd400576SPatrick Sanan if (rank == 0) { 175824119c2aSMatthew 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; 175924119c2aSMatthew 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; 17609fe9f049SMatthew G. Knepley } 176124119c2aSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 17629318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 176324119c2aSMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 176424119c2aSMatthew G. Knepley } 17659318fe57SMatthew G. Knepley /* Interpolate */ 17669318fe57SMatthew G. Knepley if (interpolate) {ierr = DMPlexInterpolateInPlace_Internal(dm);CHKERRQ(ierr);} 17679318fe57SMatthew G. Knepley PetscFunctionReturn(0); 17689318fe57SMatthew G. Knepley } 17699318fe57SMatthew G. Knepley 17709318fe57SMatthew G. Knepley /*@ 17719318fe57SMatthew G. Knepley DMPlexCreateWedgeCylinderMesh - Creates a mesh on the tensor product of the unit interval with the circle (cylinder) using wedges. 17729318fe57SMatthew G. Knepley 17739318fe57SMatthew G. Knepley Collective 17749318fe57SMatthew G. Knepley 17759318fe57SMatthew G. Knepley Input Parameters: 17769318fe57SMatthew G. Knepley + comm - The communicator for the DM object 17779318fe57SMatthew G. Knepley . n - The number of wedges around the origin 17789318fe57SMatthew G. Knepley - interpolate - Create edges and faces 17799318fe57SMatthew G. Knepley 17809318fe57SMatthew G. Knepley Output Parameter: 17819318fe57SMatthew G. Knepley . dm - The DM object 17829318fe57SMatthew G. Knepley 17839318fe57SMatthew G. Knepley Level: beginner 17849318fe57SMatthew G. Knepley 17859318fe57SMatthew G. Knepley .seealso: DMPlexCreateHexCylinderMesh(), DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 17869318fe57SMatthew G. Knepley @*/ 17879318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateWedgeCylinderMesh(MPI_Comm comm, PetscInt n, PetscBool interpolate, DM *dm) 17889318fe57SMatthew G. Knepley { 17899318fe57SMatthew G. Knepley PetscErrorCode ierr; 17909318fe57SMatthew G. Knepley 17919318fe57SMatthew G. Knepley PetscFunctionBegin; 17929318fe57SMatthew G. Knepley PetscValidPointer(dm, 4); 17939318fe57SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 17949318fe57SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 17959318fe57SMatthew G. Knepley ierr = DMPlexCreateWedgeCylinderMesh_Internal(*dm, n, interpolate);CHKERRQ(ierr); 179624119c2aSMatthew G. Knepley PetscFunctionReturn(0); 179724119c2aSMatthew G. Knepley } 179824119c2aSMatthew G. Knepley 17999fbee547SJacob Faibussowitsch static inline PetscReal DiffNormReal(PetscInt dim, const PetscReal x[], const PetscReal y[]) 180065a81367SMatthew G. Knepley { 180165a81367SMatthew G. Knepley PetscReal prod = 0.0; 180265a81367SMatthew G. Knepley PetscInt i; 180365a81367SMatthew G. Knepley for (i = 0; i < dim; ++i) prod += PetscSqr(x[i] - y[i]); 180465a81367SMatthew G. Knepley return PetscSqrtReal(prod); 180565a81367SMatthew G. Knepley } 18069fbee547SJacob Faibussowitsch static inline PetscReal DotReal(PetscInt dim, const PetscReal x[], const PetscReal y[]) 180765a81367SMatthew G. Knepley { 180865a81367SMatthew G. Knepley PetscReal prod = 0.0; 180965a81367SMatthew G. Knepley PetscInt i; 181065a81367SMatthew G. Knepley for (i = 0; i < dim; ++i) prod += x[i]*y[i]; 181165a81367SMatthew G. Knepley return prod; 181265a81367SMatthew G. Knepley } 181365a81367SMatthew G. Knepley 181451a74b61SMatthew G. Knepley /* The first constant is the sphere radius */ 181551a74b61SMatthew G. Knepley static void snapToSphere(PetscInt dim, PetscInt Nf, PetscInt NfAux, 181651a74b61SMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 181751a74b61SMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 181851a74b61SMatthew G. Knepley PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 181951a74b61SMatthew G. Knepley { 182051a74b61SMatthew G. Knepley PetscReal r = PetscRealPart(constants[0]); 182151a74b61SMatthew G. Knepley PetscReal norm2 = 0.0, fac; 182251a74b61SMatthew G. Knepley PetscInt n = uOff[1] - uOff[0], d; 182351a74b61SMatthew G. Knepley 182451a74b61SMatthew G. Knepley for (d = 0; d < n; ++d) norm2 += PetscSqr(PetscRealPart(u[d])); 182551a74b61SMatthew G. Knepley fac = r/PetscSqrtReal(norm2); 182651a74b61SMatthew G. Knepley for (d = 0; d < n; ++d) f0[d] = u[d]*fac; 182751a74b61SMatthew G. Knepley } 182851a74b61SMatthew G. Knepley 18299318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateSphereMesh_Internal(DM dm, PetscInt dim, PetscBool simplex, PetscReal R) 18302829fed8SMatthew G. Knepley { 183165a81367SMatthew G. Knepley const PetscInt embedDim = dim+1; 183265a81367SMatthew G. Knepley PetscSection coordSection; 183365a81367SMatthew G. Knepley Vec coordinates; 183465a81367SMatthew G. Knepley PetscScalar *coords; 183565a81367SMatthew G. Knepley PetscReal *coordsIn; 183665a81367SMatthew G. Knepley PetscInt numCells, numEdges, numVerts, firstVertex, v, firstEdge, coordSize, d, c, e; 183765a81367SMatthew G. Knepley PetscMPIInt rank; 183865a81367SMatthew G. Knepley PetscErrorCode ierr; 183965a81367SMatthew G. Knepley 184065a81367SMatthew G. Knepley PetscFunctionBegin; 18419318fe57SMatthew G. Knepley PetscValidLogicalCollectiveBool(dm, simplex, 3); 18429318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 18439318fe57SMatthew G. Knepley ierr = DMSetCoordinateDim(dm, dim+1);CHKERRQ(ierr); 18449318fe57SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 184565a81367SMatthew G. Knepley switch (dim) { 184665a81367SMatthew G. Knepley case 2: 184765a81367SMatthew G. Knepley if (simplex) { 184851a74b61SMatthew G. Knepley const PetscReal radius = PetscSqrtReal(1 + PETSC_PHI*PETSC_PHI)/(1.0 + PETSC_PHI); 184951a74b61SMatthew G. Knepley const PetscReal edgeLen = 2.0/(1.0 + PETSC_PHI) * (R/radius); 185065a81367SMatthew G. Knepley const PetscInt degree = 5; 185151a74b61SMatthew G. Knepley PetscReal vertex[3] = {0.0, 1.0/(1.0 + PETSC_PHI), PETSC_PHI/(1.0 + PETSC_PHI)}; 185265a81367SMatthew G. Knepley PetscInt s[3] = {1, 1, 1}; 185365a81367SMatthew G. Knepley PetscInt cone[3]; 185465a81367SMatthew G. Knepley PetscInt *graph, p, i, j, k; 185565a81367SMatthew G. Knepley 185651a74b61SMatthew G. Knepley vertex[0] *= R/radius; vertex[1] *= R/radius; vertex[2] *= R/radius; 1857dd400576SPatrick Sanan numCells = rank == 0 ? 20 : 0; 1858dd400576SPatrick Sanan numVerts = rank == 0 ? 12 : 0; 185965a81367SMatthew G. Knepley firstVertex = numCells; 186051a74b61SMatthew G. Knepley /* Use icosahedron, which for a R-sphere has coordinates which are all cyclic permutations of 186165a81367SMatthew G. Knepley 186265a81367SMatthew G. Knepley (0, \pm 1/\phi+1, \pm \phi/\phi+1) 186365a81367SMatthew G. Knepley 186465a81367SMatthew G. Knepley where \phi^2 - \phi - 1 = 0, meaning \phi is the golden ratio \frac{1 + \sqrt{5}}{2}. The edge 186551a74b61SMatthew G. Knepley length is then given by 2/(1+\phi) = 2 * 0.38197 = 0.76393. 186665a81367SMatthew G. Knepley */ 186765a81367SMatthew G. Knepley /* Construct vertices */ 186865a81367SMatthew G. Knepley ierr = PetscCalloc1(numVerts * embedDim, &coordsIn);CHKERRQ(ierr); 1869dd400576SPatrick Sanan if (rank == 0) { 187065a81367SMatthew G. Knepley for (p = 0, i = 0; p < embedDim; ++p) { 187165a81367SMatthew G. Knepley for (s[1] = -1; s[1] < 2; s[1] += 2) { 187265a81367SMatthew G. Knepley for (s[2] = -1; s[2] < 2; s[2] += 2) { 187365a81367SMatthew G. Knepley for (d = 0; d < embedDim; ++d) coordsIn[i*embedDim+d] = s[(d+p)%embedDim]*vertex[(d+p)%embedDim]; 187465a81367SMatthew G. Knepley ++i; 187565a81367SMatthew G. Knepley } 187665a81367SMatthew G. Knepley } 187765a81367SMatthew G. Knepley } 187845da822fSValeria Barra } 187965a81367SMatthew G. Knepley /* Construct graph */ 188065a81367SMatthew G. Knepley ierr = PetscCalloc1(numVerts * numVerts, &graph);CHKERRQ(ierr); 188165a81367SMatthew G. Knepley for (i = 0; i < numVerts; ++i) { 188265a81367SMatthew G. Knepley for (j = 0, k = 0; j < numVerts; ++j) { 188365a81367SMatthew G. Knepley if (PetscAbsReal(DiffNormReal(embedDim, &coordsIn[i*embedDim], &coordsIn[j*embedDim]) - edgeLen) < PETSC_SMALL) {graph[i*numVerts+j] = 1; ++k;} 188465a81367SMatthew G. Knepley } 18852c71b3e2SJacob Faibussowitsch PetscCheckFalse(k != degree,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid icosahedron, vertex %D degree %D != %D", i, k, degree); 188665a81367SMatthew G. Knepley } 188765a81367SMatthew G. Knepley /* Build Topology */ 18889318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVerts);CHKERRQ(ierr); 188965a81367SMatthew G. Knepley for (c = 0; c < numCells; c++) { 18909318fe57SMatthew G. Knepley ierr = DMPlexSetConeSize(dm, c, embedDim);CHKERRQ(ierr); 189165a81367SMatthew G. Knepley } 18929318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 189365a81367SMatthew G. Knepley /* Cells */ 189465a81367SMatthew G. Knepley for (i = 0, c = 0; i < numVerts; ++i) { 189565a81367SMatthew G. Knepley for (j = 0; j < i; ++j) { 189665a81367SMatthew G. Knepley for (k = 0; k < j; ++k) { 189765a81367SMatthew G. Knepley if (graph[i*numVerts+j] && graph[j*numVerts+k] && graph[k*numVerts+i]) { 189865a81367SMatthew G. Knepley cone[0] = firstVertex+i; cone[1] = firstVertex+j; cone[2] = firstVertex+k; 189965a81367SMatthew G. Knepley /* Check orientation */ 190065a81367SMatthew G. Knepley { 190165a81367SMatthew 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}}}; 190265a81367SMatthew G. Knepley PetscReal normal[3]; 190365a81367SMatthew G. Knepley PetscInt e, f; 190465a81367SMatthew G. Knepley 190565a81367SMatthew G. Knepley for (d = 0; d < embedDim; ++d) { 190665a81367SMatthew G. Knepley normal[d] = 0.0; 190765a81367SMatthew G. Knepley for (e = 0; e < embedDim; ++e) { 190865a81367SMatthew G. Knepley for (f = 0; f < embedDim; ++f) { 190965a81367SMatthew G. Knepley normal[d] += epsilon[d][e][f]*(coordsIn[j*embedDim+e] - coordsIn[i*embedDim+e])*(coordsIn[k*embedDim+f] - coordsIn[i*embedDim+f]); 191065a81367SMatthew G. Knepley } 191165a81367SMatthew G. Knepley } 191265a81367SMatthew G. Knepley } 191365a81367SMatthew G. Knepley if (DotReal(embedDim, normal, &coordsIn[i*embedDim]) < 0) {PetscInt tmp = cone[1]; cone[1] = cone[2]; cone[2] = tmp;} 191465a81367SMatthew G. Knepley } 19159318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, c++, cone);CHKERRQ(ierr); 191665a81367SMatthew G. Knepley } 191765a81367SMatthew G. Knepley } 191865a81367SMatthew G. Knepley } 191965a81367SMatthew G. Knepley } 19209318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 19219318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 192265a81367SMatthew G. Knepley ierr = PetscFree(graph);CHKERRQ(ierr); 192365a81367SMatthew G. Knepley } else { 19242829fed8SMatthew G. Knepley /* 19252829fed8SMatthew G. Knepley 12-21--13 19262829fed8SMatthew G. Knepley | | 19272829fed8SMatthew G. Knepley 25 4 24 19282829fed8SMatthew G. Knepley | | 19292829fed8SMatthew G. Knepley 12-25--9-16--8-24--13 19302829fed8SMatthew G. Knepley | | | | 19312829fed8SMatthew G. Knepley 23 5 17 0 15 3 22 19322829fed8SMatthew G. Knepley | | | | 19332829fed8SMatthew G. Knepley 10-20--6-14--7-19--11 19342829fed8SMatthew G. Knepley | | 19352829fed8SMatthew G. Knepley 20 1 19 19362829fed8SMatthew G. Knepley | | 19372829fed8SMatthew G. Knepley 10-18--11 19382829fed8SMatthew G. Knepley | | 19392829fed8SMatthew G. Knepley 23 2 22 19402829fed8SMatthew G. Knepley | | 19412829fed8SMatthew G. Knepley 12-21--13 19422829fed8SMatthew G. Knepley */ 19432829fed8SMatthew G. Knepley PetscInt cone[4], ornt[4]; 19442829fed8SMatthew G. Knepley 1945dd400576SPatrick Sanan numCells = rank == 0 ? 6 : 0; 1946dd400576SPatrick Sanan numEdges = rank == 0 ? 12 : 0; 1947dd400576SPatrick Sanan numVerts = rank == 0 ? 8 : 0; 194865a81367SMatthew G. Knepley firstVertex = numCells; 194965a81367SMatthew G. Knepley firstEdge = numCells + numVerts; 19502829fed8SMatthew G. Knepley /* Build Topology */ 19519318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numEdges+numVerts);CHKERRQ(ierr); 19522829fed8SMatthew G. Knepley for (c = 0; c < numCells; c++) { 19539318fe57SMatthew G. Knepley ierr = DMPlexSetConeSize(dm, c, 4);CHKERRQ(ierr); 19542829fed8SMatthew G. Knepley } 19552829fed8SMatthew G. Knepley for (e = firstEdge; e < firstEdge+numEdges; ++e) { 19569318fe57SMatthew G. Knepley ierr = DMPlexSetConeSize(dm, e, 2);CHKERRQ(ierr); 19572829fed8SMatthew G. Knepley } 19589318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 1959dd400576SPatrick Sanan if (rank == 0) { 19602829fed8SMatthew G. Knepley /* Cell 0 */ 19612829fed8SMatthew G. Knepley cone[0] = 14; cone[1] = 15; cone[2] = 16; cone[3] = 17; 19629318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 0, cone);CHKERRQ(ierr); 19632829fed8SMatthew G. Knepley ornt[0] = 0; ornt[1] = 0; ornt[2] = 0; ornt[3] = 0; 19649318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 0, ornt);CHKERRQ(ierr); 19652829fed8SMatthew G. Knepley /* Cell 1 */ 19662829fed8SMatthew G. Knepley cone[0] = 18; cone[1] = 19; cone[2] = 14; cone[3] = 20; 19679318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 1, cone);CHKERRQ(ierr); 1968b5a892a1SMatthew G. Knepley ornt[0] = 0; ornt[1] = 0; ornt[2] = -1; ornt[3] = 0; 19699318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 1, ornt);CHKERRQ(ierr); 19702829fed8SMatthew G. Knepley /* Cell 2 */ 19712829fed8SMatthew G. Knepley cone[0] = 21; cone[1] = 22; cone[2] = 18; cone[3] = 23; 19729318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 2, cone);CHKERRQ(ierr); 1973b5a892a1SMatthew G. Knepley ornt[0] = 0; ornt[1] = 0; ornt[2] = -1; ornt[3] = 0; 19749318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 2, ornt);CHKERRQ(ierr); 19752829fed8SMatthew G. Knepley /* Cell 3 */ 19762829fed8SMatthew G. Knepley cone[0] = 19; cone[1] = 22; cone[2] = 24; cone[3] = 15; 19779318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 3, cone);CHKERRQ(ierr); 1978b5a892a1SMatthew G. Knepley ornt[0] = -1; ornt[1] = -1; ornt[2] = 0; ornt[3] = -1; 19799318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 3, ornt);CHKERRQ(ierr); 19802829fed8SMatthew G. Knepley /* Cell 4 */ 19812829fed8SMatthew G. Knepley cone[0] = 16; cone[1] = 24; cone[2] = 21; cone[3] = 25; 19829318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 4, cone);CHKERRQ(ierr); 1983b5a892a1SMatthew G. Knepley ornt[0] = -1; ornt[1] = -1; ornt[2] = -1; ornt[3] = 0; 19849318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 4, ornt);CHKERRQ(ierr); 19852829fed8SMatthew G. Knepley /* Cell 5 */ 19862829fed8SMatthew G. Knepley cone[0] = 20; cone[1] = 17; cone[2] = 25; cone[3] = 23; 19879318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 5, cone);CHKERRQ(ierr); 1988b5a892a1SMatthew G. Knepley ornt[0] = -1; ornt[1] = -1; ornt[2] = -1; ornt[3] = -1; 19899318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 5, ornt);CHKERRQ(ierr); 19902829fed8SMatthew G. Knepley /* Edges */ 19912829fed8SMatthew G. Knepley cone[0] = 6; cone[1] = 7; 19929318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 14, cone);CHKERRQ(ierr); 19932829fed8SMatthew G. Knepley cone[0] = 7; cone[1] = 8; 19949318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 15, cone);CHKERRQ(ierr); 19952829fed8SMatthew G. Knepley cone[0] = 8; cone[1] = 9; 19969318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 16, cone);CHKERRQ(ierr); 19972829fed8SMatthew G. Knepley cone[0] = 9; cone[1] = 6; 19989318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 17, cone);CHKERRQ(ierr); 19992829fed8SMatthew G. Knepley cone[0] = 10; cone[1] = 11; 20009318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 18, cone);CHKERRQ(ierr); 20012829fed8SMatthew G. Knepley cone[0] = 11; cone[1] = 7; 20029318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 19, cone);CHKERRQ(ierr); 20032829fed8SMatthew G. Knepley cone[0] = 6; cone[1] = 10; 20049318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 20, cone);CHKERRQ(ierr); 20052829fed8SMatthew G. Knepley cone[0] = 12; cone[1] = 13; 20069318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 21, cone);CHKERRQ(ierr); 20072829fed8SMatthew G. Knepley cone[0] = 13; cone[1] = 11; 20089318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 22, cone);CHKERRQ(ierr); 20092829fed8SMatthew G. Knepley cone[0] = 10; cone[1] = 12; 20109318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 23, cone);CHKERRQ(ierr); 20112829fed8SMatthew G. Knepley cone[0] = 13; cone[1] = 8; 20129318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 24, cone);CHKERRQ(ierr); 20132829fed8SMatthew G. Knepley cone[0] = 12; cone[1] = 9; 20149318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 25, cone);CHKERRQ(ierr); 201545da822fSValeria Barra } 20169318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 20179318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 20182829fed8SMatthew G. Knepley /* Build coordinates */ 201965a81367SMatthew G. Knepley ierr = PetscCalloc1(numVerts * embedDim, &coordsIn);CHKERRQ(ierr); 2020dd400576SPatrick Sanan if (rank == 0) { 202151a74b61SMatthew G. Knepley coordsIn[0*embedDim+0] = -R; coordsIn[0*embedDim+1] = R; coordsIn[0*embedDim+2] = -R; 202251a74b61SMatthew G. Knepley coordsIn[1*embedDim+0] = R; coordsIn[1*embedDim+1] = R; coordsIn[1*embedDim+2] = -R; 202351a74b61SMatthew G. Knepley coordsIn[2*embedDim+0] = R; coordsIn[2*embedDim+1] = -R; coordsIn[2*embedDim+2] = -R; 202451a74b61SMatthew G. Knepley coordsIn[3*embedDim+0] = -R; coordsIn[3*embedDim+1] = -R; coordsIn[3*embedDim+2] = -R; 202551a74b61SMatthew G. Knepley coordsIn[4*embedDim+0] = -R; coordsIn[4*embedDim+1] = R; coordsIn[4*embedDim+2] = R; 202651a74b61SMatthew G. Knepley coordsIn[5*embedDim+0] = R; coordsIn[5*embedDim+1] = R; coordsIn[5*embedDim+2] = R; 202751a74b61SMatthew G. Knepley coordsIn[6*embedDim+0] = -R; coordsIn[6*embedDim+1] = -R; coordsIn[6*embedDim+2] = R; 202851a74b61SMatthew G. Knepley coordsIn[7*embedDim+0] = R; coordsIn[7*embedDim+1] = -R; coordsIn[7*embedDim+2] = R; 202965a81367SMatthew G. Knepley } 203045da822fSValeria Barra } 203165a81367SMatthew G. Knepley break; 203265a81367SMatthew G. Knepley case 3: 2033116ded15SMatthew G. Knepley if (simplex) { 2034116ded15SMatthew G. Knepley const PetscReal edgeLen = 1.0/PETSC_PHI; 203551a74b61SMatthew G. Knepley PetscReal vertexA[4] = {0.5, 0.5, 0.5, 0.5}; 203651a74b61SMatthew G. Knepley PetscReal vertexB[4] = {1.0, 0.0, 0.0, 0.0}; 203751a74b61SMatthew G. Knepley PetscReal vertexC[4] = {0.5, 0.5*PETSC_PHI, 0.5/PETSC_PHI, 0.0}; 2038116ded15SMatthew G. Knepley const PetscInt degree = 12; 2039116ded15SMatthew G. Knepley PetscInt s[4] = {1, 1, 1}; 2040116ded15SMatthew 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}, 2041116ded15SMatthew 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}}; 2042116ded15SMatthew G. Knepley PetscInt cone[4]; 2043116ded15SMatthew G. Knepley PetscInt *graph, p, i, j, k, l; 2044116ded15SMatthew G. Knepley 204551a74b61SMatthew G. Knepley vertexA[0] *= R; vertexA[1] *= R; vertexA[2] *= R; vertexA[3] *= R; 204651a74b61SMatthew G. Knepley vertexB[0] *= R; vertexB[1] *= R; vertexB[2] *= R; vertexB[3] *= R; 204751a74b61SMatthew G. Knepley vertexC[0] *= R; vertexC[1] *= R; vertexC[2] *= R; vertexC[3] *= R; 2048dd400576SPatrick Sanan numCells = rank == 0 ? 600 : 0; 2049dd400576SPatrick Sanan numVerts = rank == 0 ? 120 : 0; 2050116ded15SMatthew G. Knepley firstVertex = numCells; 2051116ded15SMatthew G. Knepley /* Use the 600-cell, which for a unit sphere has coordinates which are 2052116ded15SMatthew G. Knepley 2053116ded15SMatthew G. Knepley 1/2 (\pm 1, \pm 1, \pm 1, \pm 1) 16 2054116ded15SMatthew G. Knepley (\pm 1, 0, 0, 0) all cyclic permutations 8 2055116ded15SMatthew G. Knepley 1/2 (\pm 1, \pm phi, \pm 1/phi, 0) all even permutations 96 2056116ded15SMatthew G. Knepley 2057116ded15SMatthew G. Knepley where \phi^2 - \phi - 1 = 0, meaning \phi is the golden ratio \frac{1 + \sqrt{5}}{2}. The edge 20586333ae4fSvaleriabarra length is then given by 1/\phi = 0.61803. 2059116ded15SMatthew G. Knepley 2060116ded15SMatthew G. Knepley http://buzzard.pugetsound.edu/sage-practice/ch03s03.html 2061116ded15SMatthew G. Knepley http://mathworld.wolfram.com/600-Cell.html 2062116ded15SMatthew G. Knepley */ 2063116ded15SMatthew G. Knepley /* Construct vertices */ 2064116ded15SMatthew G. Knepley ierr = PetscCalloc1(numVerts * embedDim, &coordsIn);CHKERRQ(ierr); 2065116ded15SMatthew G. Knepley i = 0; 2066dd400576SPatrick Sanan if (rank == 0) { 2067116ded15SMatthew G. Knepley for (s[0] = -1; s[0] < 2; s[0] += 2) { 2068116ded15SMatthew G. Knepley for (s[1] = -1; s[1] < 2; s[1] += 2) { 2069116ded15SMatthew G. Knepley for (s[2] = -1; s[2] < 2; s[2] += 2) { 2070116ded15SMatthew G. Knepley for (s[3] = -1; s[3] < 2; s[3] += 2) { 2071116ded15SMatthew G. Knepley for (d = 0; d < embedDim; ++d) coordsIn[i*embedDim+d] = s[d]*vertexA[d]; 2072116ded15SMatthew G. Knepley ++i; 2073116ded15SMatthew G. Knepley } 2074116ded15SMatthew G. Knepley } 2075116ded15SMatthew G. Knepley } 2076116ded15SMatthew G. Knepley } 2077116ded15SMatthew G. Knepley for (p = 0; p < embedDim; ++p) { 2078116ded15SMatthew G. Knepley s[1] = s[2] = s[3] = 1; 2079116ded15SMatthew G. Knepley for (s[0] = -1; s[0] < 2; s[0] += 2) { 2080116ded15SMatthew G. Knepley for (d = 0; d < embedDim; ++d) coordsIn[i*embedDim+d] = s[(d+p)%embedDim]*vertexB[(d+p)%embedDim]; 2081116ded15SMatthew G. Knepley ++i; 2082116ded15SMatthew G. Knepley } 2083116ded15SMatthew G. Knepley } 2084116ded15SMatthew G. Knepley for (p = 0; p < 12; ++p) { 2085116ded15SMatthew G. Knepley s[3] = 1; 2086116ded15SMatthew G. Knepley for (s[0] = -1; s[0] < 2; s[0] += 2) { 2087116ded15SMatthew G. Knepley for (s[1] = -1; s[1] < 2; s[1] += 2) { 2088116ded15SMatthew G. Knepley for (s[2] = -1; s[2] < 2; s[2] += 2) { 2089116ded15SMatthew G. Knepley for (d = 0; d < embedDim; ++d) coordsIn[i*embedDim+d] = s[evenPerm[p][d]]*vertexC[evenPerm[p][d]]; 2090116ded15SMatthew G. Knepley ++i; 2091116ded15SMatthew G. Knepley } 2092116ded15SMatthew G. Knepley } 2093116ded15SMatthew G. Knepley } 2094116ded15SMatthew G. Knepley } 209545da822fSValeria Barra } 20962c71b3e2SJacob Faibussowitsch PetscCheckFalse(i != numVerts,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid 600-cell, vertices %D != %D", i, numVerts); 2097116ded15SMatthew G. Knepley /* Construct graph */ 2098116ded15SMatthew G. Knepley ierr = PetscCalloc1(numVerts * numVerts, &graph);CHKERRQ(ierr); 2099116ded15SMatthew G. Knepley for (i = 0; i < numVerts; ++i) { 2100116ded15SMatthew G. Knepley for (j = 0, k = 0; j < numVerts; ++j) { 2101116ded15SMatthew G. Knepley if (PetscAbsReal(DiffNormReal(embedDim, &coordsIn[i*embedDim], &coordsIn[j*embedDim]) - edgeLen) < PETSC_SMALL) {graph[i*numVerts+j] = 1; ++k;} 2102116ded15SMatthew G. Knepley } 21032c71b3e2SJacob Faibussowitsch PetscCheckFalse(k != degree,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid 600-cell, vertex %D degree %D != %D", i, k, degree); 2104116ded15SMatthew G. Knepley } 2105116ded15SMatthew G. Knepley /* Build Topology */ 21069318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVerts);CHKERRQ(ierr); 2107116ded15SMatthew G. Knepley for (c = 0; c < numCells; c++) { 21089318fe57SMatthew G. Knepley ierr = DMPlexSetConeSize(dm, c, embedDim);CHKERRQ(ierr); 2109116ded15SMatthew G. Knepley } 21109318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 2111116ded15SMatthew G. Knepley /* Cells */ 2112dd400576SPatrick Sanan if (rank == 0) { 2113116ded15SMatthew G. Knepley for (i = 0, c = 0; i < numVerts; ++i) { 2114116ded15SMatthew G. Knepley for (j = 0; j < i; ++j) { 2115116ded15SMatthew G. Knepley for (k = 0; k < j; ++k) { 2116116ded15SMatthew G. Knepley for (l = 0; l < k; ++l) { 2117116ded15SMatthew G. Knepley if (graph[i*numVerts+j] && graph[j*numVerts+k] && graph[k*numVerts+i] && 2118116ded15SMatthew G. Knepley graph[l*numVerts+i] && graph[l*numVerts+j] && graph[l*numVerts+k]) { 2119116ded15SMatthew G. Knepley cone[0] = firstVertex+i; cone[1] = firstVertex+j; cone[2] = firstVertex+k; cone[3] = firstVertex+l; 2120116ded15SMatthew G. Knepley /* Check orientation: https://ef.gy/linear-algebra:normal-vectors-in-higher-dimensional-spaces */ 2121116ded15SMatthew G. Knepley { 2122116ded15SMatthew 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}}, 2123116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 1}, { 0, 0, -1, 0}}, 2124116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 0, -1}, { 0, 0, 0, 0}, { 0, 1, 0, 0}}, 2125116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 1, 0}, { 0, -1, 0, 0}, { 0, 0, 0, 0}}}, 2126116ded15SMatthew G. Knepley 2127116ded15SMatthew G. Knepley {{{0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, -1}, { 0, 0, 1, 0}}, 2128116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}}, 2129116ded15SMatthew G. Knepley {{0, 0, 0, 1}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, {-1, 0, 0, 0}}, 2130116ded15SMatthew G. Knepley {{0, 0, -1, 0}, { 0, 0, 0, 0}, { 1, 0, 0, 0}, { 0, 0, 0, 0}}}, 2131116ded15SMatthew G. Knepley 2132116ded15SMatthew G. Knepley {{{0, 0, 0, 0}, { 0, 0, 0, 1}, { 0, 0, 0, 0}, { 0, -1, 0, 0}}, 2133116ded15SMatthew G. Knepley {{0, 0, 0, -1}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 1, 0, 0, 0}}, 2134116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}}, 2135116ded15SMatthew G. Knepley {{0, 1, 0, 0}, {-1, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}}}, 2136116ded15SMatthew G. Knepley 2137116ded15SMatthew G. Knepley {{{0, 0, 0, 0}, { 0, 0, -1, 0}, { 0, 1, 0, 0}, { 0, 0, 0, 0}}, 2138116ded15SMatthew G. Knepley {{0, 0, 1, 0}, { 0, 0, 0, 0}, {-1, 0, 0, 0}, { 0, 0, 0, 0}}, 2139116ded15SMatthew G. Knepley {{0, -1, 0, 0}, { 1, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}}, 2140116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}}}}; 2141116ded15SMatthew G. Knepley PetscReal normal[4]; 2142116ded15SMatthew G. Knepley PetscInt e, f, g; 2143116ded15SMatthew G. Knepley 2144116ded15SMatthew G. Knepley for (d = 0; d < embedDim; ++d) { 2145116ded15SMatthew G. Knepley normal[d] = 0.0; 2146116ded15SMatthew G. Knepley for (e = 0; e < embedDim; ++e) { 2147116ded15SMatthew G. Knepley for (f = 0; f < embedDim; ++f) { 2148116ded15SMatthew G. Knepley for (g = 0; g < embedDim; ++g) { 2149116ded15SMatthew 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]); 2150116ded15SMatthew G. Knepley } 2151116ded15SMatthew G. Knepley } 2152116ded15SMatthew G. Knepley } 2153116ded15SMatthew G. Knepley } 2154116ded15SMatthew G. Knepley if (DotReal(embedDim, normal, &coordsIn[i*embedDim]) < 0) {PetscInt tmp = cone[1]; cone[1] = cone[2]; cone[2] = tmp;} 2155116ded15SMatthew G. Knepley } 21569318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, c++, cone);CHKERRQ(ierr); 2157116ded15SMatthew G. Knepley } 2158116ded15SMatthew G. Knepley } 2159116ded15SMatthew G. Knepley } 2160116ded15SMatthew G. Knepley } 2161116ded15SMatthew G. Knepley } 216245da822fSValeria Barra } 21639318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 21649318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 2165116ded15SMatthew G. Knepley ierr = PetscFree(graph);CHKERRQ(ierr); 2166116ded15SMatthew G. Knepley break; 2167116ded15SMatthew G. Knepley } 216898921bdaSJacob Faibussowitsch default: SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Unsupported dimension for sphere: %D", dim); 216965a81367SMatthew G. Knepley } 217065a81367SMatthew G. Knepley /* Create coordinates */ 21719318fe57SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 21722829fed8SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 21732829fed8SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, embedDim);CHKERRQ(ierr); 21742829fed8SMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, firstVertex, firstVertex+numVerts);CHKERRQ(ierr); 21752829fed8SMatthew G. Knepley for (v = firstVertex; v < firstVertex+numVerts; ++v) { 21762829fed8SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, embedDim);CHKERRQ(ierr); 21772829fed8SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, embedDim);CHKERRQ(ierr); 21782829fed8SMatthew G. Knepley } 21792829fed8SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 21802829fed8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 21812829fed8SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 21822829fed8SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, embedDim);CHKERRQ(ierr); 21832829fed8SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 21842829fed8SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 21852829fed8SMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 21862829fed8SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 218765a81367SMatthew G. Knepley for (v = 0; v < numVerts; ++v) for (d = 0; d < embedDim; ++d) {coords[v*embedDim+d] = coordsIn[v*embedDim+d];} 21882829fed8SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 21899318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 21902829fed8SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 219165a81367SMatthew G. Knepley ierr = PetscFree(coordsIn);CHKERRQ(ierr); 219251a74b61SMatthew G. Knepley { 219351a74b61SMatthew G. Knepley DM cdm; 219451a74b61SMatthew G. Knepley PetscDS cds; 21959318fe57SMatthew G. Knepley PetscScalar c = R; 219651a74b61SMatthew G. Knepley 21979318fe57SMatthew G. Knepley ierr = DMPlexCreateCoordinateSpace(dm, 1, snapToSphere);CHKERRQ(ierr); 21989318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 219951a74b61SMatthew G. Knepley ierr = DMGetDS(cdm, &cds);CHKERRQ(ierr); 22009318fe57SMatthew G. Knepley ierr = PetscDSSetConstants(cds, 1, &c);CHKERRQ(ierr); 220151a74b61SMatthew G. Knepley } 22029318fe57SMatthew G. Knepley /* Wait for coordinate creation before doing in-place modification */ 22039318fe57SMatthew G. Knepley if (simplex) {ierr = DMPlexInterpolateInPlace_Internal(dm);CHKERRQ(ierr);} 22049318fe57SMatthew G. Knepley PetscFunctionReturn(0); 22059318fe57SMatthew G. Knepley } 22069318fe57SMatthew G. Knepley 2207*b7f5c055SJed Brown typedef void (*TPSEvaluateFunc)(const PetscReal[], PetscReal*, PetscReal[], PetscReal(*)[3]); 2208*b7f5c055SJed Brown 2209*b7f5c055SJed Brown /* 2210*b7f5c055SJed Brown The Schwarz P implicit surface is 2211*b7f5c055SJed Brown 2212*b7f5c055SJed Brown f(x) = cos(x0) + cos(x1) + cos(x2) = 0 2213*b7f5c055SJed Brown */ 2214*b7f5c055SJed Brown static void TPSEvaluate_SchwarzP(const PetscReal y[3], PetscReal *f, PetscReal grad[], PetscReal (*hess)[3]) 2215*b7f5c055SJed Brown { 2216*b7f5c055SJed Brown PetscReal c[3] = {PetscCosReal(y[0] * PETSC_PI), PetscCosReal(y[1] * PETSC_PI), PetscCosReal(y[2] * PETSC_PI)}; 2217*b7f5c055SJed Brown PetscReal g[3] = {-PetscSinReal(y[0] * PETSC_PI), -PetscSinReal(y[1] * PETSC_PI), -PetscSinReal(y[2] * PETSC_PI)}; 2218*b7f5c055SJed Brown f[0] = c[0] + c[1] + c[2]; 2219*b7f5c055SJed Brown for (PetscInt i=0; i<3; i++) { 2220*b7f5c055SJed Brown grad[i] = PETSC_PI * g[i]; 2221*b7f5c055SJed Brown for (PetscInt j=0; j<3; j++) { 2222*b7f5c055SJed Brown hess[i][j] = (i == j) ? -PetscSqr(PETSC_PI) * c[i] : 0.; 2223*b7f5c055SJed Brown } 2224*b7f5c055SJed Brown } 2225*b7f5c055SJed Brown } 2226*b7f5c055SJed Brown 2227*b7f5c055SJed Brown /* 2228*b7f5c055SJed Brown The Gyroid implicit surface is 2229*b7f5c055SJed Brown 2230*b7f5c055SJed Brown f(x,y,z) = sin(pi * x) * cos (pi * (y + 1/2)) + sin(pi * (y + 1/2)) * cos(pi * (z + 1/4)) + sin(pi * (z + 1/4)) * cos(pi * x) 2231*b7f5c055SJed Brown 2232*b7f5c055SJed Brown */ 2233*b7f5c055SJed Brown static void TPSEvaluate_Gyroid(const PetscReal y[3], PetscReal *f, PetscReal grad[], PetscReal (*hess)[3]) 2234*b7f5c055SJed Brown { 2235*b7f5c055SJed Brown PetscReal s[3] = {PetscSinReal(PETSC_PI * y[0]), PetscSinReal(PETSC_PI * (y[1] + .5)), PetscSinReal(PETSC_PI * (y[2] + .25))}; 2236*b7f5c055SJed Brown PetscReal c[3] = {PetscCosReal(PETSC_PI * y[0]), PetscCosReal(PETSC_PI * (y[1] + .5)), PetscCosReal(PETSC_PI * (y[2] + .25))}; 2237*b7f5c055SJed Brown f[0] = s[0] * c[1] + s[1] * c[2] + s[2] * c[0]; 2238*b7f5c055SJed Brown grad[0] = PETSC_PI * (c[0] * c[1] - s[2] * s[0]); 2239*b7f5c055SJed Brown grad[1] = PETSC_PI * (c[1] * c[2] - s[0] * s[1]); 2240*b7f5c055SJed Brown grad[2] = PETSC_PI * (c[2] * c[0] - s[1] * s[2]); 2241*b7f5c055SJed Brown hess[0][0] = -PetscSqr(PETSC_PI) * (s[0] * c[1] + s[2] * c[0]); 2242*b7f5c055SJed Brown hess[0][1] = -PetscSqr(PETSC_PI) * (c[0] * s[1]); 2243*b7f5c055SJed Brown hess[0][2] = -PetscSqr(PETSC_PI) * (c[2] * s[0]); 2244*b7f5c055SJed Brown hess[1][0] = -PetscSqr(PETSC_PI) * (s[1] * c[2] + s[0] * c[1]); 2245*b7f5c055SJed Brown hess[1][1] = -PetscSqr(PETSC_PI) * (c[1] * s[2]); 2246*b7f5c055SJed Brown hess[2][2] = -PetscSqr(PETSC_PI) * (c[0] * s[1]); 2247*b7f5c055SJed Brown hess[2][0] = -PetscSqr(PETSC_PI) * (s[2] * c[0] + s[1] * c[2]); 2248*b7f5c055SJed Brown hess[2][1] = -PetscSqr(PETSC_PI) * (c[2] * s[0]); 2249*b7f5c055SJed Brown hess[2][2] = -PetscSqr(PETSC_PI) * (c[1] * s[2]); 2250*b7f5c055SJed Brown } 2251*b7f5c055SJed Brown 2252*b7f5c055SJed Brown /* 2253*b7f5c055SJed Brown We wish to solve 2254*b7f5c055SJed Brown 2255*b7f5c055SJed Brown min_y || y - x ||^2 subject to f(y) = 0 2256*b7f5c055SJed Brown 2257*b7f5c055SJed Brown Let g(y) = grad(f). The minimization problem is equivalent to asking to satisfy 2258*b7f5c055SJed Brown f(y) = 0 and (y-x) is parallel to g(y). We do this by using Householder QR to obtain a basis for the 2259*b7f5c055SJed Brown tangent space and ask for both components in the tangent space to be zero. 2260*b7f5c055SJed Brown 2261*b7f5c055SJed Brown Take g to be a column vector and compute the "full QR" factorization Q R = g, 2262*b7f5c055SJed Brown where Q = I - 2 n n^T is a symmetric orthogonal matrix. 2263*b7f5c055SJed Brown The first column of Q is parallel to g so the remaining two columns span the null space. 2264*b7f5c055SJed Brown Let Qn = Q[:,1:] be those remaining columns. Then Qn Qn^T is an orthogonal projector into the tangent space. 2265*b7f5c055SJed Brown Since Q is symmetric, this is equivalent to multipyling by Q and taking the last two entries. 2266*b7f5c055SJed Brown In total, we have a system of 3 equations in 3 unknowns: 2267*b7f5c055SJed Brown 2268*b7f5c055SJed Brown f(y) = 0 1 equation 2269*b7f5c055SJed Brown Qn^T (y - x) = 0 2 equations 2270*b7f5c055SJed Brown 2271*b7f5c055SJed Brown Here, we compute the residual and Jacobian of this system. 2272*b7f5c055SJed Brown */ 2273*b7f5c055SJed Brown static void TPSNearestPointResJac(TPSEvaluateFunc feval, const PetscScalar x[], const PetscScalar y[], PetscScalar res[], PetscScalar J[]) 2274*b7f5c055SJed Brown { 2275*b7f5c055SJed Brown PetscReal yreal[3] = {PetscRealPart(y[0]), PetscRealPart(y[1]), PetscRealPart(y[2])}; 2276*b7f5c055SJed Brown PetscReal d[3] = {PetscRealPart(y[0] - x[0]), PetscRealPart(y[1] - x[1]), PetscRealPart(y[2] - x[2])}; 2277*b7f5c055SJed Brown PetscReal f, grad[3], n[3], n_y[3][3], norm, norm_y[3], nd, nd_y[3], sign; 2278*b7f5c055SJed Brown 2279*b7f5c055SJed Brown feval(yreal, &f, grad, n_y); 2280*b7f5c055SJed Brown 2281*b7f5c055SJed Brown for (PetscInt i=0; i<3; i++) n[i] = grad[i]; 2282*b7f5c055SJed Brown norm = PetscSqrtReal(PetscSqr(n[0]) + PetscSqr(n[1]) + PetscSqr(n[2])); 2283*b7f5c055SJed Brown for (PetscInt i=0; i<3; i++) { 2284*b7f5c055SJed Brown norm_y[i] = 1. / norm * n[i] * n_y[i][i]; 2285*b7f5c055SJed Brown } 2286*b7f5c055SJed Brown 2287*b7f5c055SJed Brown // Define the Householder reflector 2288*b7f5c055SJed Brown sign = n[0] >= 0 ? 1. : -1.; 2289*b7f5c055SJed Brown n[0] += norm * sign; 2290*b7f5c055SJed Brown for (PetscInt i=0; i<3; i++) n_y[0][i] += norm_y[i] * sign; 2291*b7f5c055SJed Brown 2292*b7f5c055SJed Brown norm = PetscSqrtReal(PetscSqr(n[0]) + PetscSqr(n[1]) + PetscSqr(n[2])); 2293*b7f5c055SJed Brown norm_y[0] = 1. / norm * (n[0] * n_y[0][0]); 2294*b7f5c055SJed Brown norm_y[1] = 1. / norm * (n[0] * n_y[0][1] + n[1] * n_y[1][1]); 2295*b7f5c055SJed Brown norm_y[2] = 1. / norm * (n[0] * n_y[0][2] + n[2] * n_y[2][2]); 2296*b7f5c055SJed Brown 2297*b7f5c055SJed Brown for (PetscInt i=0; i<3; i++) { 2298*b7f5c055SJed Brown n[i] /= norm; 2299*b7f5c055SJed Brown for (PetscInt j=0; j<3; j++) { 2300*b7f5c055SJed Brown // note that n[i] is n_old[i]/norm when executing the code below 2301*b7f5c055SJed Brown n_y[i][j] = n_y[i][j] / norm - n[i] / norm * norm_y[j]; 2302*b7f5c055SJed Brown } 2303*b7f5c055SJed Brown } 2304*b7f5c055SJed Brown 2305*b7f5c055SJed Brown nd = n[0] * d[0] + n[1] * d[1] + n[2] * d[2]; 2306*b7f5c055SJed Brown for (PetscInt i=0; i<3; i++) nd_y[i] = n[i] + n_y[0][i] * d[0] + n_y[1][i] * d[1] + n_y[2][i] * d[2]; 2307*b7f5c055SJed Brown 2308*b7f5c055SJed Brown res[0] = f; 2309*b7f5c055SJed Brown res[1] = d[1] - 2 * n[1] * nd; 2310*b7f5c055SJed Brown res[2] = d[2] - 2 * n[2] * nd; 2311*b7f5c055SJed Brown // J[j][i] is J_{ij} (column major) 2312*b7f5c055SJed Brown for (PetscInt j=0; j<3; j++) { 2313*b7f5c055SJed Brown J[0 + j*3] = grad[j]; 2314*b7f5c055SJed Brown J[1 + j*3] = (j == 1)*1. - 2 * (n_y[1][j] * nd + n[1] * nd_y[j]); 2315*b7f5c055SJed Brown J[2 + j*3] = (j == 2)*1. - 2 * (n_y[2][j] * nd + n[2] * nd_y[j]); 2316*b7f5c055SJed Brown } 2317*b7f5c055SJed Brown } 2318*b7f5c055SJed Brown 2319*b7f5c055SJed Brown /* 2320*b7f5c055SJed Brown Project x to the nearest point on the implicit surface using Newton's method. 2321*b7f5c055SJed Brown */ 2322*b7f5c055SJed Brown static PetscErrorCode TPSNearestPoint(TPSEvaluateFunc feval, PetscScalar x[]) 2323*b7f5c055SJed Brown { 2324*b7f5c055SJed Brown PetscScalar y[3] = {x[0], x[1], x[2]}; // Initial guess 2325*b7f5c055SJed Brown PetscErrorCode ierr; 2326*b7f5c055SJed Brown 2327*b7f5c055SJed Brown PetscFunctionBegin; 2328*b7f5c055SJed Brown for (PetscInt iter=0; iter<10; iter++) { 2329*b7f5c055SJed Brown PetscScalar res[3], J[9]; 2330*b7f5c055SJed Brown PetscReal resnorm; 2331*b7f5c055SJed Brown TPSNearestPointResJac(feval, x, y, res, J); 2332*b7f5c055SJed Brown resnorm = PetscSqrtReal(PetscSqr(PetscRealPart(res[0])) + PetscSqr(PetscRealPart(res[1])) + PetscSqr(PetscRealPart(res[2]))); 2333*b7f5c055SJed Brown if (0) { // Turn on this monitor if you need to confirm quadratic convergence 2334*b7f5c055SJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, "[%D] res [%g %g %g]\n", iter, PetscRealPart(res[0]), PetscRealPart(res[1]), PetscRealPart(res[2]));CHKERRQ(ierr); 2335*b7f5c055SJed Brown } 2336*b7f5c055SJed Brown if (resnorm < PETSC_SMALL) break; 2337*b7f5c055SJed Brown 2338*b7f5c055SJed Brown // Take the Newton step 2339*b7f5c055SJed Brown ierr = PetscKernel_A_gets_inverse_A_3(J, 0., PETSC_FALSE, NULL);CHKERRQ(ierr); 2340*b7f5c055SJed Brown PetscKernel_v_gets_v_minus_A_times_w_3(y, J, res); 2341*b7f5c055SJed Brown } 2342*b7f5c055SJed Brown for (PetscInt i=0; i<3; i++) x[i] = y[i]; 2343*b7f5c055SJed Brown PetscFunctionReturn(0); 2344*b7f5c055SJed Brown } 2345*b7f5c055SJed Brown 2346*b7f5c055SJed Brown const char *const DMPlexTPSTypes[] = {"SCHWARZ_P", "GYROID", "DMPlexTPSType", "DMPLEX_TPS_", NULL}; 2347*b7f5c055SJed Brown 2348*b7f5c055SJed Brown static PetscErrorCode DMPlexCreateTPSMesh_Internal(DM dm, DMPlexTPSType tpstype, const PetscInt extent[], const DMBoundaryType periodic[], PetscInt refinements, PetscInt layers, PetscReal thickness) 2349*b7f5c055SJed Brown { 2350*b7f5c055SJed Brown PetscErrorCode ierr; 2351*b7f5c055SJed Brown PetscMPIInt rank; 2352*b7f5c055SJed Brown PetscInt topoDim = 2, spaceDim = 3, numFaces = 0, numVertices = 0, numEdges = 0; 2353*b7f5c055SJed Brown PetscInt (*edges)[2] = NULL, *edgeSets = NULL; 2354*b7f5c055SJed Brown PetscInt *cells_flat = NULL; 2355*b7f5c055SJed Brown PetscReal *vtxCoords = NULL; 2356*b7f5c055SJed Brown TPSEvaluateFunc evalFunc = NULL; 2357*b7f5c055SJed Brown DMLabel label; 2358*b7f5c055SJed Brown 2359*b7f5c055SJed Brown PetscFunctionBegin; 2360*b7f5c055SJed Brown ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 2361*b7f5c055SJed Brown PetscCheck((layers != 0) ^ (thickness == 0.), PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_INCOMP, "Layers %D must be nonzero iff thickness %g is nonzero", layers, (double)thickness); 2362*b7f5c055SJed Brown switch (tpstype) { 2363*b7f5c055SJed Brown case DMPLEX_TPS_SCHWARZ_P: 2364*b7f5c055SJed Brown PetscCheck(!periodic || (periodic[0] == DM_BOUNDARY_NONE && periodic[1] == DM_BOUNDARY_NONE && periodic[2] == DM_BOUNDARY_NONE), PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Schwarz P does not support periodic meshes"); 2365*b7f5c055SJed Brown if (!rank) { 2366*b7f5c055SJed Brown PetscInt (*cells)[6][4][4] = NULL; // [junction, junction-face, cell, conn] 2367*b7f5c055SJed Brown PetscInt Njunctions = 0, Ncuts = 0, Npipes[3], vcount; 2368*b7f5c055SJed Brown PetscReal L = 1; 2369*b7f5c055SJed Brown 2370*b7f5c055SJed Brown Npipes[0] = (extent[0] + 1) * extent[1] * extent[2]; 2371*b7f5c055SJed Brown Npipes[1] = extent[0] * (extent[1] + 1) * extent[2]; 2372*b7f5c055SJed Brown Npipes[2] = extent[0] * extent[1] * (extent[2] + 1); 2373*b7f5c055SJed Brown Njunctions = extent[0] * extent[1] * extent[2]; 2374*b7f5c055SJed Brown Ncuts = 2 * (extent[0] * extent[1] + extent[1] * extent[2] + extent[2] * extent[0]); 2375*b7f5c055SJed Brown numVertices = 4 * (Npipes[0] + Npipes[1] + Npipes[2]) + 8 * Njunctions; 2376*b7f5c055SJed Brown ierr = PetscMalloc1(3*numVertices, &vtxCoords);CHKERRQ(ierr); 2377*b7f5c055SJed Brown ierr = PetscMalloc1(Njunctions, &cells);CHKERRQ(ierr); 2378*b7f5c055SJed Brown ierr = PetscMalloc1(Ncuts*4, &edges);CHKERRQ(ierr); 2379*b7f5c055SJed Brown ierr = PetscMalloc1(Ncuts*4, &edgeSets);CHKERRQ(ierr); 2380*b7f5c055SJed Brown // x-normal pipes 2381*b7f5c055SJed Brown vcount = 0; 2382*b7f5c055SJed Brown for (PetscInt i=0; i<extent[0]+1; i++) { 2383*b7f5c055SJed Brown for (PetscInt j=0; j<extent[1]; j++) { 2384*b7f5c055SJed Brown for (PetscInt k=0; k<extent[2]; k++) { 2385*b7f5c055SJed Brown for (PetscInt l=0; l<4; l++) { 2386*b7f5c055SJed Brown vtxCoords[vcount++] = (2*i - 1) * L; 2387*b7f5c055SJed Brown vtxCoords[vcount++] = 2 * j * L + PetscCosReal((2*l + 1) * PETSC_PI / 4) * L / 2; 2388*b7f5c055SJed Brown vtxCoords[vcount++] = 2 * k * L + PetscSinReal((2*l + 1) * PETSC_PI / 4) * L / 2; 2389*b7f5c055SJed Brown } 2390*b7f5c055SJed Brown } 2391*b7f5c055SJed Brown } 2392*b7f5c055SJed Brown } 2393*b7f5c055SJed Brown // y-normal pipes 2394*b7f5c055SJed Brown for (PetscInt i=0; i<extent[0]; i++) { 2395*b7f5c055SJed Brown for (PetscInt j=0; j<extent[1]+1; j++) { 2396*b7f5c055SJed Brown for (PetscInt k=0; k<extent[2]; k++) { 2397*b7f5c055SJed Brown for (PetscInt l=0; l<4; l++) { 2398*b7f5c055SJed Brown vtxCoords[vcount++] = 2 * i * L + PetscSinReal((2*l + 1) * PETSC_PI / 4) * L / 2; 2399*b7f5c055SJed Brown vtxCoords[vcount++] = (2*j - 1) * L; 2400*b7f5c055SJed Brown vtxCoords[vcount++] = 2 * k * L + PetscCosReal((2*l + 1) * PETSC_PI / 4) * L / 2; 2401*b7f5c055SJed Brown } 2402*b7f5c055SJed Brown } 2403*b7f5c055SJed Brown } 2404*b7f5c055SJed Brown } 2405*b7f5c055SJed Brown // z-normal pipes 2406*b7f5c055SJed Brown for (PetscInt i=0; i<extent[0]; i++) { 2407*b7f5c055SJed Brown for (PetscInt j=0; j<extent[1]; j++) { 2408*b7f5c055SJed Brown for (PetscInt k=0; k<extent[2]+1; k++) { 2409*b7f5c055SJed Brown for (PetscInt l=0; l<4; l++) { 2410*b7f5c055SJed Brown vtxCoords[vcount++] = 2 * i * L + PetscCosReal((2*l + 1) * PETSC_PI / 4) * L / 2; 2411*b7f5c055SJed Brown vtxCoords[vcount++] = 2 * j * L + PetscSinReal((2*l + 1) * PETSC_PI / 4) * L / 2; 2412*b7f5c055SJed Brown vtxCoords[vcount++] = (2*k - 1) * L; 2413*b7f5c055SJed Brown } 2414*b7f5c055SJed Brown } 2415*b7f5c055SJed Brown } 2416*b7f5c055SJed Brown } 2417*b7f5c055SJed Brown // junctions 2418*b7f5c055SJed Brown for (PetscInt i=0; i<extent[0]; i++) { 2419*b7f5c055SJed Brown for (PetscInt j=0; j<extent[1]; j++) { 2420*b7f5c055SJed Brown for (PetscInt k=0; k<extent[2]; k++) { 2421*b7f5c055SJed Brown const PetscInt J = (i*extent[1] + j)*extent[2] + k, Jvoff = (Npipes[0] + Npipes[1] + Npipes[2])*4 + J*8; 2422*b7f5c055SJed Brown PetscCheck(vcount / 3 == Jvoff, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected vertex count"); 2423*b7f5c055SJed Brown for (PetscInt ii=0; ii<2; ii++) { 2424*b7f5c055SJed Brown for (PetscInt jj=0; jj<2; jj++) { 2425*b7f5c055SJed Brown for (PetscInt kk=0; kk<2; kk++) { 2426*b7f5c055SJed Brown double Ls = (1 - sqrt(2) / 4) * L; 2427*b7f5c055SJed Brown vtxCoords[vcount++] = 2*i*L + (2*ii-1) * Ls; 2428*b7f5c055SJed Brown vtxCoords[vcount++] = 2*j*L + (2*jj-1) * Ls; 2429*b7f5c055SJed Brown vtxCoords[vcount++] = 2*k*L + (2*kk-1) * Ls; 2430*b7f5c055SJed Brown } 2431*b7f5c055SJed Brown } 2432*b7f5c055SJed Brown } 2433*b7f5c055SJed Brown const PetscInt jfaces[3][2][4] = { 2434*b7f5c055SJed Brown {{3,1,0,2}, {7,5,4,6}}, // x-aligned 2435*b7f5c055SJed Brown {{5,4,0,1}, {7,6,2,3}}, // y-aligned 2436*b7f5c055SJed Brown {{6,2,0,4}, {7,3,1,5}} // z-aligned 2437*b7f5c055SJed Brown }; 2438*b7f5c055SJed Brown const PetscInt pipe_lo[3] = { // vertex numbers of pipes 2439*b7f5c055SJed Brown ((i * extent[1] + j) * extent[2] + k)*4, 2440*b7f5c055SJed Brown ((i * (extent[1] + 1) + j) * extent[2] + k + Npipes[0])*4, 2441*b7f5c055SJed Brown ((i * extent[1] + j) * (extent[2]+1) + k + Npipes[0] + Npipes[1])*4 2442*b7f5c055SJed Brown }; 2443*b7f5c055SJed Brown const PetscInt pipe_hi[3] = { // vertex numbers of pipes 2444*b7f5c055SJed Brown (((i + 1) * extent[1] + j) * extent[2] + k)*4, 2445*b7f5c055SJed Brown ((i * (extent[1] + 1) + j + 1) * extent[2] + k + Npipes[0])*4, 2446*b7f5c055SJed Brown ((i * extent[1] + j) * (extent[2]+1) + k + 1 + Npipes[0] + Npipes[1])*4 2447*b7f5c055SJed Brown }; 2448*b7f5c055SJed Brown for (PetscInt dir=0; dir<3; dir++) { // x,y,z 2449*b7f5c055SJed Brown const PetscInt ijk[3] = {i, j, k}; 2450*b7f5c055SJed Brown for (PetscInt l=0; l<4; l++) { // rotations 2451*b7f5c055SJed Brown cells[J][dir*2+0][l][0] = pipe_lo[dir] + l; 2452*b7f5c055SJed Brown cells[J][dir*2+0][l][1] = Jvoff + jfaces[dir][0][l]; 2453*b7f5c055SJed Brown cells[J][dir*2+0][l][2] = Jvoff + jfaces[dir][0][(l-1+4)%4]; 2454*b7f5c055SJed Brown cells[J][dir*2+0][l][3] = pipe_lo[dir] + (l-1+4)%4; 2455*b7f5c055SJed Brown cells[J][dir*2+1][l][0] = Jvoff + jfaces[dir][1][l]; 2456*b7f5c055SJed Brown cells[J][dir*2+1][l][1] = pipe_hi[dir] + l; 2457*b7f5c055SJed Brown cells[J][dir*2+1][l][2] = pipe_hi[dir] + (l-1+4)%4; 2458*b7f5c055SJed Brown cells[J][dir*2+1][l][3] = Jvoff + jfaces[dir][1][(l-1+4)%4]; 2459*b7f5c055SJed Brown if (ijk[dir] == 0) { 2460*b7f5c055SJed Brown edges[numEdges][0] = pipe_lo[dir] + l; 2461*b7f5c055SJed Brown edges[numEdges][1] = pipe_lo[dir] + (l+1) % 4; 2462*b7f5c055SJed Brown edgeSets[numEdges] = dir*2 + 1; 2463*b7f5c055SJed Brown numEdges++; 2464*b7f5c055SJed Brown } 2465*b7f5c055SJed Brown if (ijk[dir] + 1 == extent[dir]) { 2466*b7f5c055SJed Brown edges[numEdges][0] = pipe_hi[dir] + l; 2467*b7f5c055SJed Brown edges[numEdges][1] = pipe_hi[dir] + (l+1) % 4; 2468*b7f5c055SJed Brown edgeSets[numEdges] = dir*2 + 2; 2469*b7f5c055SJed Brown numEdges++; 2470*b7f5c055SJed Brown } 2471*b7f5c055SJed Brown } 2472*b7f5c055SJed Brown } 2473*b7f5c055SJed Brown } 2474*b7f5c055SJed Brown } 2475*b7f5c055SJed Brown } 2476*b7f5c055SJed Brown PetscCheck(numEdges == Ncuts * 4, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge count %D incompatible with number of cuts %D", numEdges, Ncuts); 2477*b7f5c055SJed Brown numFaces = 24 * Njunctions; 2478*b7f5c055SJed Brown cells_flat = cells[0][0][0]; 2479*b7f5c055SJed Brown } 2480*b7f5c055SJed Brown evalFunc = TPSEvaluate_SchwarzP; 2481*b7f5c055SJed Brown break; 2482*b7f5c055SJed Brown case DMPLEX_TPS_GYROID: 2483*b7f5c055SJed Brown if (!rank) { 2484*b7f5c055SJed Brown // This is a coarse mesh approximation of the gyroid shifted to being the zero of the level set 2485*b7f5c055SJed Brown // 2486*b7f5c055SJed Brown // sin(pi*x)*cos(pi*(y+1/2)) + sin(pi*(y+1/2))*cos(pi*(z+1/4)) + sin(pi*(z+1/4))*cos(x) 2487*b7f5c055SJed Brown // 2488*b7f5c055SJed Brown // on the cell [0,2]^3. 2489*b7f5c055SJed Brown // 2490*b7f5c055SJed Brown // Think about dividing that cell into four columns, and focus on the column [0,1]x[0,1]x[0,2]. 2491*b7f5c055SJed Brown // If you looked at the gyroid in that column at different slices of z you would see that it kind of spins 2492*b7f5c055SJed Brown // like a boomerang: 2493*b7f5c055SJed Brown // 2494*b7f5c055SJed Brown // z = 0 z = 1/4 z = 1/2 z = 3/4 // 2495*b7f5c055SJed Brown // ----- ------- ------- ------- // 2496*b7f5c055SJed Brown // // 2497*b7f5c055SJed Brown // + + + + + + + \ + // 2498*b7f5c055SJed Brown // \ / \ // 2499*b7f5c055SJed Brown // \ `-_ _-' / } // 2500*b7f5c055SJed Brown // *-_ `-' _-' / // 2501*b7f5c055SJed Brown // + `-+ + + +-' + + / + // 2502*b7f5c055SJed Brown // // 2503*b7f5c055SJed Brown // // 2504*b7f5c055SJed Brown // z = 1 z = 5/4 z = 3/2 z = 7/4 // 2505*b7f5c055SJed Brown // ----- ------- ------- ------- // 2506*b7f5c055SJed Brown // // 2507*b7f5c055SJed Brown // +-_ + + + + _-+ + / + // 2508*b7f5c055SJed Brown // `-_ _-_ _-` / // 2509*b7f5c055SJed Brown // \ _-' `-_ / { // 2510*b7f5c055SJed Brown // \ / \ // 2511*b7f5c055SJed Brown // + + + + + + + \ + // 2512*b7f5c055SJed Brown // 2513*b7f5c055SJed Brown // 2514*b7f5c055SJed Brown // This course mesh approximates each of these slices by two line segments, 2515*b7f5c055SJed Brown // and then connects the segments in consecutive layers with quadrilateral faces. 2516*b7f5c055SJed Brown // All of the end points of the segments are multiples of 1/4 except for the 2517*b7f5c055SJed Brown // point * in the picture for z = 0 above and the similar points in other layers. 2518*b7f5c055SJed Brown // That point is at (gamma, gamma, 0), where gamma is calculated below. 2519*b7f5c055SJed Brown // 2520*b7f5c055SJed Brown // The column [1,2]x[1,2]x[0,2] looks the same as this column; 2521*b7f5c055SJed Brown // The columns [1,2]x[0,1]x[0,2] and [0,1]x[1,2]x[0,2] are mirror images. 2522*b7f5c055SJed Brown // 2523*b7f5c055SJed Brown // As for how this method turned into the names given to the vertices: 2524*b7f5c055SJed Brown // that was not systematic, it was just the way it worked out in my handwritten notes. 2525*b7f5c055SJed Brown 2526*b7f5c055SJed Brown PetscInt facesPerBlock = 64; 2527*b7f5c055SJed Brown PetscInt vertsPerBlock = 56; 2528*b7f5c055SJed Brown PetscInt extentPlus[3]; 2529*b7f5c055SJed Brown PetscInt numBlocks, numBlocksPlus; 2530*b7f5c055SJed Brown const PetscInt A = 0, B = 1, C = 2, D = 3, E = 4, F = 5, G = 6, H = 7, 2531*b7f5c055SJed Brown II = 8, J = 9, K = 10, L = 11, M = 12, N = 13, O = 14, P = 15, 2532*b7f5c055SJed Brown Q = 16, R = 17, S = 18, T = 19, U = 20, V = 21, W = 22, X = 23, 2533*b7f5c055SJed Brown Y = 24, Z = 25, Ap = 26, Bp = 27, Cp = 28, Dp = 29, Ep = 30, Fp = 31, 2534*b7f5c055SJed Brown Gp = 32, Hp = 33, Ip = 34, Jp = 35, Kp = 36, Lp = 37, Mp = 38, Np = 39, 2535*b7f5c055SJed Brown Op = 40, Pp = 41, Qp = 42, Rp = 43, Sp = 44, Tp = 45, Up = 46, Vp = 47, 2536*b7f5c055SJed Brown Wp = 48, Xp = 49, Yp = 50, Zp = 51, Aq = 52, Bq = 53, Cq = 54, Dq = 55; 2537*b7f5c055SJed Brown const PetscInt pattern[64][4] = 2538*b7f5c055SJed Brown { /* face to vertex within the coarse discretization of a single gyroid block */ 2539*b7f5c055SJed Brown /* layer 0 */ 2540*b7f5c055SJed Brown {A,C,K,G},{C,B,II,K},{D,A,H,L},{B+56*1,D,L,J},{E,B+56*1,J,N},{A+56*2,E,N,H+56*2},{F,A+56*2,G+56*2,M},{B,F,M,II}, 2541*b7f5c055SJed Brown /* layer 1 */ 2542*b7f5c055SJed Brown {G,K,Q,O},{K,II,P,Q},{L,H,O+56*1,R},{J,L,R,P},{N,J,P,S},{H+56*2,N,S,O+56*3},{M,G+56*2,O+56*2,T},{II,M,T,P}, 2543*b7f5c055SJed Brown /* layer 2 */ 2544*b7f5c055SJed Brown {O,Q,Y,U},{Q,P,W,Y},{R,O+56*1,U+56*1,Ap},{P,R,Ap,W},{S,P,X,Bp},{O+56*3,S,Bp,V+56*1},{T,O+56*2,V,Z},{P,T,Z,X}, 2545*b7f5c055SJed Brown /* layer 3 */ 2546*b7f5c055SJed Brown {U,Y,Ep,Dp},{Y,W,Cp,Ep},{Ap,U+56*1,Dp+56*1,Gp},{W,Ap,Gp,Cp},{Bp,X,Cp+56*2,Fp},{V+56*1,Bp,Fp,Dp+56*1},{Z,V,Dp,Hp},{X,Z,Hp,Cp+56*2}, 2547*b7f5c055SJed Brown /* layer 4 */ 2548*b7f5c055SJed Brown {Dp,Ep,Mp,Kp},{Ep,Cp,Ip,Mp},{Gp,Dp+56*1,Lp,Np},{Cp,Gp,Np,Jp},{Fp,Cp+56*2,Jp+56*2,Pp},{Dp+56*1,Fp,Pp,Lp},{Hp,Dp,Kp,Op},{Cp+56*2,Hp,Op,Ip+56*2}, 2549*b7f5c055SJed Brown /* layer 5 */ 2550*b7f5c055SJed Brown {Kp,Mp,Sp,Rp},{Mp,Ip,Qp,Sp},{Np,Lp,Rp,Tp},{Jp,Np,Tp,Qp+56*1},{Pp,Jp+56*2,Qp+56*3,Up},{Lp,Pp,Up,Rp},{Op,Kp,Rp,Vp},{Ip+56*2,Op,Vp,Qp+56*2}, 2551*b7f5c055SJed Brown /* layer 6 */ 2552*b7f5c055SJed Brown {Rp,Sp,Aq,Yp},{Sp,Qp,Wp,Aq},{Tp,Rp,Yp,Cq},{Qp+56*1,Tp,Cq,Wp+56*1},{Up,Qp+56*3,Xp+56*1,Dq},{Rp,Up,Dq,Zp},{Vp,Rp,Zp,Bq},{Qp+56*2,Vp,Bq,Xp}, 2553*b7f5c055SJed Brown /* layer 7 (the top is the periodic image of the bottom of layer 0) */ 2554*b7f5c055SJed Brown {Yp,Aq,C+56*4,A+56*4},{Aq,Wp,B+56*4,C+56*4},{Cq,Yp,A+56*4,D+56*4},{Wp+56*1,Cq,D+56*4,B+56*5},{Dq,Xp+56*1,B+56*5,E+56*4},{Zp,Dq,E+56*4,A+56*6},{Bq,Zp,A+56*6,F+56*4},{Xp,Bq,F+56*4,B+56*4} 2555*b7f5c055SJed Brown }; 2556*b7f5c055SJed Brown const PetscReal gamma = PetscAcosReal((PetscSqrtReal(3.)-1.) / PetscSqrtReal(2.)) / PETSC_PI; 2557*b7f5c055SJed Brown const PetscReal patternCoords[56][3] = 2558*b7f5c055SJed Brown { 2559*b7f5c055SJed Brown /* A */ {1.,0.,0.}, 2560*b7f5c055SJed Brown /* B */ {0.,1.,0.}, 2561*b7f5c055SJed Brown /* C */ {gamma,gamma,0.}, 2562*b7f5c055SJed Brown /* D */ {1+gamma,1-gamma,0.}, 2563*b7f5c055SJed Brown /* E */ {2-gamma,2-gamma,0.}, 2564*b7f5c055SJed Brown /* F */ {1-gamma,1+gamma,0.}, 2565*b7f5c055SJed Brown 2566*b7f5c055SJed Brown /* G */ {.5,0,.25}, 2567*b7f5c055SJed Brown /* H */ {1.5,0.,.25}, 2568*b7f5c055SJed Brown /* II */ {.5,1.,.25}, 2569*b7f5c055SJed Brown /* J */ {1.5,1.,.25}, 2570*b7f5c055SJed Brown /* K */ {.25,.5,.25}, 2571*b7f5c055SJed Brown /* L */ {1.25,.5,.25}, 2572*b7f5c055SJed Brown /* M */ {.75,1.5,.25}, 2573*b7f5c055SJed Brown /* N */ {1.75,1.5,.25}, 2574*b7f5c055SJed Brown 2575*b7f5c055SJed Brown /* O */ {0.,0.,.5}, 2576*b7f5c055SJed Brown /* P */ {1.,1.,.5}, 2577*b7f5c055SJed Brown /* Q */ {gamma,1-gamma,.5}, 2578*b7f5c055SJed Brown /* R */ {1+gamma,gamma,.5}, 2579*b7f5c055SJed Brown /* S */ {2-gamma,1+gamma,.5}, 2580*b7f5c055SJed Brown /* T */ {1-gamma,2-gamma,.5}, 2581*b7f5c055SJed Brown 2582*b7f5c055SJed Brown /* U */ {0.,.5,.75}, 2583*b7f5c055SJed Brown /* V */ {0.,1.5,.75}, 2584*b7f5c055SJed Brown /* W */ {1.,.5,.75}, 2585*b7f5c055SJed Brown /* X */ {1.,1.5,.75}, 2586*b7f5c055SJed Brown /* Y */ {.5,.75,.75}, 2587*b7f5c055SJed Brown /* Z */ {.5,1.75,.75}, 2588*b7f5c055SJed Brown /* Ap */ {1.5,.25,.75}, 2589*b7f5c055SJed Brown /* Bp */ {1.5,1.25,.75}, 2590*b7f5c055SJed Brown 2591*b7f5c055SJed Brown /* Cp */ {1.,0.,1.}, 2592*b7f5c055SJed Brown /* Dp */ {0.,1.,1.}, 2593*b7f5c055SJed Brown /* Ep */ {1-gamma,1-gamma,1.}, 2594*b7f5c055SJed Brown /* Fp */ {1+gamma,1+gamma,1.}, 2595*b7f5c055SJed Brown /* Gp */ {2-gamma,gamma,1.}, 2596*b7f5c055SJed Brown /* Hp */ {gamma,2-gamma,1.}, 2597*b7f5c055SJed Brown 2598*b7f5c055SJed Brown /* Ip */ {.5,0.,1.25}, 2599*b7f5c055SJed Brown /* Jp */ {1.5,0.,1.25}, 2600*b7f5c055SJed Brown /* Kp */ {.5,1.,1.25}, 2601*b7f5c055SJed Brown /* Lp */ {1.5,1.,1.25}, 2602*b7f5c055SJed Brown /* Mp */ {.75,.5,1.25}, 2603*b7f5c055SJed Brown /* Np */ {1.75,.5,1.25}, 2604*b7f5c055SJed Brown /* Op */ {.25,1.5,1.25}, 2605*b7f5c055SJed Brown /* Pp */ {1.25,1.5,1.25}, 2606*b7f5c055SJed Brown 2607*b7f5c055SJed Brown /* Qp */ {0.,0.,1.5}, 2608*b7f5c055SJed Brown /* Rp */ {1.,1.,1.5}, 2609*b7f5c055SJed Brown /* Sp */ {1-gamma,gamma,1.5}, 2610*b7f5c055SJed Brown /* Tp */ {2-gamma,1-gamma,1.5}, 2611*b7f5c055SJed Brown /* Up */ {1+gamma,2-gamma,1.5}, 2612*b7f5c055SJed Brown /* Vp */ {gamma,1+gamma,1.5}, 2613*b7f5c055SJed Brown 2614*b7f5c055SJed Brown /* Wp */ {0.,.5,1.75}, 2615*b7f5c055SJed Brown /* Xp */ {0.,1.5,1.75}, 2616*b7f5c055SJed Brown /* Yp */ {1.,.5,1.75}, 2617*b7f5c055SJed Brown /* Zp */ {1.,1.5,1.75}, 2618*b7f5c055SJed Brown /* Aq */ {.5,.25,1.75}, 2619*b7f5c055SJed Brown /* Bq */ {.5,1.25,1.75}, 2620*b7f5c055SJed Brown /* Cq */ {1.5,.75,1.75}, 2621*b7f5c055SJed Brown /* Dq */ {1.5,1.75,1.75}, 2622*b7f5c055SJed Brown }; 2623*b7f5c055SJed Brown PetscInt (*cells)[64][4] = NULL; 2624*b7f5c055SJed Brown PetscBool *seen; 2625*b7f5c055SJed Brown PetscInt *vertToTrueVert; 2626*b7f5c055SJed Brown PetscInt count; 2627*b7f5c055SJed Brown 2628*b7f5c055SJed Brown for (PetscInt i = 0; i < 3; i++) extentPlus[i] = extent[i] + 1; 2629*b7f5c055SJed Brown numBlocks = 1; 2630*b7f5c055SJed Brown for (PetscInt i = 0; i < 3; i++) numBlocks *= extent[i]; 2631*b7f5c055SJed Brown numBlocksPlus = 1; 2632*b7f5c055SJed Brown for (PetscInt i = 0; i < 3; i++) numBlocksPlus *= extentPlus[i]; 2633*b7f5c055SJed Brown numFaces = numBlocks * facesPerBlock; 2634*b7f5c055SJed Brown ierr = PetscMalloc1(numBlocks, &cells);CHKERRQ(ierr); 2635*b7f5c055SJed Brown ierr = PetscCalloc1(numBlocksPlus * vertsPerBlock,&seen);CHKERRQ(ierr); 2636*b7f5c055SJed Brown for (PetscInt k = 0; k < extent[2]; k++) { 2637*b7f5c055SJed Brown for (PetscInt j = 0; j < extent[1]; j++) { 2638*b7f5c055SJed Brown for (PetscInt i = 0; i < extent[0]; i++) { 2639*b7f5c055SJed Brown for (PetscInt f = 0; f < facesPerBlock; f++) { 2640*b7f5c055SJed Brown for (PetscInt v = 0; v < 4; v++) { 2641*b7f5c055SJed Brown PetscInt vertRaw = pattern[f][v]; 2642*b7f5c055SJed Brown PetscInt blockidx = vertRaw / 56; 2643*b7f5c055SJed Brown PetscInt patternvert = vertRaw % 56; 2644*b7f5c055SJed Brown PetscInt xplus = (blockidx & 1); 2645*b7f5c055SJed Brown PetscInt yplus = (blockidx & 2) >> 1; 2646*b7f5c055SJed Brown PetscInt zplus = (blockidx & 4) >> 2; 2647*b7f5c055SJed Brown PetscInt zcoord = (periodic && periodic[2] == DM_BOUNDARY_PERIODIC) ? ((k + zplus) % extent[2]) : (k + zplus); 2648*b7f5c055SJed Brown PetscInt ycoord = (periodic && periodic[1] == DM_BOUNDARY_PERIODIC) ? ((j + yplus) % extent[1]) : (j + yplus); 2649*b7f5c055SJed Brown PetscInt xcoord = (periodic && periodic[0] == DM_BOUNDARY_PERIODIC) ? ((i + xplus) % extent[0]) : (i + xplus); 2650*b7f5c055SJed Brown PetscInt vert = ((zcoord * extentPlus[1] + ycoord) * extentPlus[0] + xcoord) * 56 + patternvert; 2651*b7f5c055SJed Brown 2652*b7f5c055SJed Brown cells[(k * extent[1] + j) * extent[0] + i][f][v] = vert; 2653*b7f5c055SJed Brown seen[vert] = PETSC_TRUE; 2654*b7f5c055SJed Brown } 2655*b7f5c055SJed Brown } 2656*b7f5c055SJed Brown } 2657*b7f5c055SJed Brown } 2658*b7f5c055SJed Brown } 2659*b7f5c055SJed Brown for (PetscInt i = 0; i < numBlocksPlus * vertsPerBlock; i++) if (seen[i]) numVertices++; 2660*b7f5c055SJed Brown count = 0; 2661*b7f5c055SJed Brown ierr = PetscMalloc1(numBlocksPlus * vertsPerBlock, &vertToTrueVert);CHKERRQ(ierr); 2662*b7f5c055SJed Brown ierr = PetscMalloc1(numVertices * 3, &vtxCoords);CHKERRQ(ierr); 2663*b7f5c055SJed Brown for (PetscInt i = 0; i < numBlocksPlus * vertsPerBlock; i++) vertToTrueVert[i] = -1; 2664*b7f5c055SJed Brown for (PetscInt k = 0; k < extentPlus[2]; k++) { 2665*b7f5c055SJed Brown for (PetscInt j = 0; j < extentPlus[1]; j++) { 2666*b7f5c055SJed Brown for (PetscInt i = 0; i < extentPlus[0]; i++) { 2667*b7f5c055SJed Brown for (PetscInt v = 0; v < vertsPerBlock; v++) { 2668*b7f5c055SJed Brown PetscInt vIdx = ((k * extentPlus[1] + j) * extentPlus[0] + i) * vertsPerBlock + v; 2669*b7f5c055SJed Brown 2670*b7f5c055SJed Brown if (seen[vIdx]) { 2671*b7f5c055SJed Brown PetscInt thisVert; 2672*b7f5c055SJed Brown 2673*b7f5c055SJed Brown vertToTrueVert[vIdx] = thisVert = count++; 2674*b7f5c055SJed Brown 2675*b7f5c055SJed Brown for (PetscInt d = 0; d < 3; d++) vtxCoords[3 * thisVert + d] = patternCoords[v][d]; 2676*b7f5c055SJed Brown vtxCoords[3 * thisVert + 0] += i * 2; 2677*b7f5c055SJed Brown vtxCoords[3 * thisVert + 1] += j * 2; 2678*b7f5c055SJed Brown vtxCoords[3 * thisVert + 2] += k * 2; 2679*b7f5c055SJed Brown } 2680*b7f5c055SJed Brown } 2681*b7f5c055SJed Brown } 2682*b7f5c055SJed Brown } 2683*b7f5c055SJed Brown } 2684*b7f5c055SJed Brown for (PetscInt i = 0; i < numBlocks; i++) { 2685*b7f5c055SJed Brown for (PetscInt f = 0; f < facesPerBlock; f++) { 2686*b7f5c055SJed Brown for (PetscInt v = 0; v < 4; v++) { 2687*b7f5c055SJed Brown cells[i][f][v] = vertToTrueVert[cells[i][f][v]]; 2688*b7f5c055SJed Brown } 2689*b7f5c055SJed Brown } 2690*b7f5c055SJed Brown } 2691*b7f5c055SJed Brown ierr = PetscFree(vertToTrueVert);CHKERRQ(ierr); 2692*b7f5c055SJed Brown ierr = PetscFree(seen);CHKERRQ(ierr); 2693*b7f5c055SJed Brown cells_flat = cells[0][0]; 2694*b7f5c055SJed Brown numEdges = 0; 2695*b7f5c055SJed Brown for (PetscInt i = 0; i < numFaces; i++) { 2696*b7f5c055SJed Brown for (PetscInt e = 0; e < 4; e++) { 2697*b7f5c055SJed Brown PetscInt ev[] = {cells_flat[i*4 + e], cells_flat[i*4 + ((e+1)%4)]}; 2698*b7f5c055SJed Brown const PetscReal *evCoords[] = {&vtxCoords[3*ev[0]], &vtxCoords[3*ev[1]]}; 2699*b7f5c055SJed Brown 2700*b7f5c055SJed Brown for (PetscInt d = 0; d < 3; d++) { 2701*b7f5c055SJed Brown if (!periodic || periodic[0] != DM_BOUNDARY_PERIODIC) { 2702*b7f5c055SJed Brown if (evCoords[0][d] == 0. && evCoords[1][d] == 0.) numEdges++; 2703*b7f5c055SJed Brown if (evCoords[0][d] == 2.*extent[d] && evCoords[1][d] == 2.*extent[d]) numEdges++; 2704*b7f5c055SJed Brown } 2705*b7f5c055SJed Brown } 2706*b7f5c055SJed Brown } 2707*b7f5c055SJed Brown } 2708*b7f5c055SJed Brown ierr = PetscMalloc1(numEdges, &edges);CHKERRQ(ierr); 2709*b7f5c055SJed Brown ierr = PetscMalloc1(numEdges, &edgeSets);CHKERRQ(ierr); 2710*b7f5c055SJed Brown for (PetscInt edge = 0, i = 0; i < numFaces; i++) { 2711*b7f5c055SJed Brown for (PetscInt e = 0; e < 4; e++) { 2712*b7f5c055SJed Brown PetscInt ev[] = {cells_flat[i*4 + e], cells_flat[i*4 + ((e+1)%4)]}; 2713*b7f5c055SJed Brown const PetscReal *evCoords[] = {&vtxCoords[3*ev[0]], &vtxCoords[3*ev[1]]}; 2714*b7f5c055SJed Brown 2715*b7f5c055SJed Brown for (PetscInt d = 0; d < 3; d++) { 2716*b7f5c055SJed Brown if (!periodic || periodic[d] != DM_BOUNDARY_PERIODIC) { 2717*b7f5c055SJed Brown if (evCoords[0][d] == 0. && evCoords[1][d] == 0.) { 2718*b7f5c055SJed Brown edges[edge][0] = ev[0]; 2719*b7f5c055SJed Brown edges[edge][1] = ev[1]; 2720*b7f5c055SJed Brown edgeSets[edge++] = 2 * d; 2721*b7f5c055SJed Brown } 2722*b7f5c055SJed Brown if (evCoords[0][d] == 2.*extent[d] && evCoords[1][d] == 2.*extent[d]) { 2723*b7f5c055SJed Brown edges[edge][0] = ev[0]; 2724*b7f5c055SJed Brown edges[edge][1] = ev[1]; 2725*b7f5c055SJed Brown edgeSets[edge++] = 2 * d + 1; 2726*b7f5c055SJed Brown } 2727*b7f5c055SJed Brown } 2728*b7f5c055SJed Brown } 2729*b7f5c055SJed Brown } 2730*b7f5c055SJed Brown } 2731*b7f5c055SJed Brown } 2732*b7f5c055SJed Brown evalFunc = TPSEvaluate_Gyroid; 2733*b7f5c055SJed Brown break; 2734*b7f5c055SJed Brown } 2735*b7f5c055SJed Brown 2736*b7f5c055SJed Brown ierr = DMSetDimension(dm, topoDim);CHKERRQ(ierr); 2737*b7f5c055SJed Brown if (!rank) {ierr = DMPlexBuildFromCellList(dm, numFaces, numVertices, 4, cells_flat);CHKERRQ(ierr);} 2738*b7f5c055SJed Brown else {ierr = DMPlexBuildFromCellList(dm, 0, 0, 0, NULL);CHKERRQ(ierr);} 2739*b7f5c055SJed Brown ierr = PetscFree(cells_flat);CHKERRQ(ierr); 2740*b7f5c055SJed Brown { 2741*b7f5c055SJed Brown DM idm; 2742*b7f5c055SJed Brown ierr = DMPlexInterpolate(dm, &idm);CHKERRQ(ierr); 2743*b7f5c055SJed Brown ierr = DMPlexReplace_Static(dm, &idm);CHKERRQ(ierr); 2744*b7f5c055SJed Brown } 2745*b7f5c055SJed Brown if (!rank) {ierr = DMPlexBuildCoordinatesFromCellList(dm, spaceDim, vtxCoords);CHKERRQ(ierr);} 2746*b7f5c055SJed Brown else {ierr = DMPlexBuildCoordinatesFromCellList(dm, spaceDim, NULL);CHKERRQ(ierr);} 2747*b7f5c055SJed Brown ierr = PetscFree(vtxCoords);CHKERRQ(ierr); 2748*b7f5c055SJed Brown 2749*b7f5c055SJed Brown ierr = DMCreateLabel(dm, "Face Sets");CHKERRQ(ierr); 2750*b7f5c055SJed Brown ierr = DMGetLabel(dm, "Face Sets", &label);CHKERRQ(ierr); 2751*b7f5c055SJed Brown for (PetscInt e=0; e<numEdges; e++) { 2752*b7f5c055SJed Brown PetscInt njoin; 2753*b7f5c055SJed Brown const PetscInt *join, verts[] = {numFaces + edges[e][0], numFaces + edges[e][1]}; 2754*b7f5c055SJed Brown ierr = DMPlexGetJoin(dm, 2, verts, &njoin, &join);CHKERRQ(ierr); 2755*b7f5c055SJed Brown PetscCheck(njoin == 1, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Expected unique join of vertices %D and %D", edges[e][0], edges[e][1]); 2756*b7f5c055SJed Brown ierr = DMLabelSetValue(label, join[0], edgeSets[e]);CHKERRQ(ierr); 2757*b7f5c055SJed Brown ierr = DMPlexRestoreJoin(dm, 2, verts, &njoin, &join);CHKERRQ(ierr); 2758*b7f5c055SJed Brown } 2759*b7f5c055SJed Brown ierr = PetscFree(edges);CHKERRQ(ierr); 2760*b7f5c055SJed Brown ierr = PetscFree(edgeSets);CHKERRQ(ierr); 2761*b7f5c055SJed Brown 2762*b7f5c055SJed Brown ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr); 2763*b7f5c055SJed Brown for (PetscInt refine=0; refine<refinements; refine++) { 2764*b7f5c055SJed Brown PetscInt m; 2765*b7f5c055SJed Brown DM dmf; 2766*b7f5c055SJed Brown Vec X; 2767*b7f5c055SJed Brown PetscScalar *x; 2768*b7f5c055SJed Brown ierr = DMRefine(dm, MPI_COMM_NULL, &dmf);CHKERRQ(ierr); 2769*b7f5c055SJed Brown ierr = DMPlexReplace_Static(dm, &dmf);CHKERRQ(ierr); 2770*b7f5c055SJed Brown 2771*b7f5c055SJed Brown ierr = DMGetCoordinatesLocal(dm, &X);CHKERRQ(ierr); 2772*b7f5c055SJed Brown ierr = VecGetLocalSize(X, &m);CHKERRQ(ierr); 2773*b7f5c055SJed Brown ierr = VecGetArray(X, &x);CHKERRQ(ierr); 2774*b7f5c055SJed Brown for (PetscInt i=0; i<m; i+=3) { 2775*b7f5c055SJed Brown ierr = TPSNearestPoint(evalFunc, &x[i]);CHKERRQ(ierr); 2776*b7f5c055SJed Brown } 2777*b7f5c055SJed Brown ierr = VecRestoreArray(X, &x);CHKERRQ(ierr); 2778*b7f5c055SJed Brown } 2779*b7f5c055SJed Brown 2780*b7f5c055SJed Brown // Face Sets has already been propagated to new vertices during refinement; this propagates to the initial vertices. 2781*b7f5c055SJed Brown ierr = DMGetLabel(dm, "Face Sets", &label);CHKERRQ(ierr); 2782*b7f5c055SJed Brown ierr = DMPlexLabelComplete(dm, label);CHKERRQ(ierr); 2783*b7f5c055SJed Brown 2784*b7f5c055SJed Brown if (thickness > 0) { 2785*b7f5c055SJed Brown DM dm3; 2786*b7f5c055SJed Brown ierr = DMPlexExtrude(dm, layers, thickness, PETSC_FALSE, PETSC_TRUE, NULL, NULL, &dm3);CHKERRQ(ierr); 2787*b7f5c055SJed Brown ierr = DMPlexReplace_Static(dm, &dm3);CHKERRQ(ierr); 2788*b7f5c055SJed Brown } 2789*b7f5c055SJed Brown PetscFunctionReturn(0); 2790*b7f5c055SJed Brown } 2791*b7f5c055SJed Brown 2792*b7f5c055SJed Brown /*@ 2793*b7f5c055SJed Brown DMPlexCreateTPSMesh - Create a distributed, interpolated mesh of a triply-periodic surface 2794*b7f5c055SJed Brown 2795*b7f5c055SJed Brown Collective 2796*b7f5c055SJed Brown 2797*b7f5c055SJed Brown Input Parameters: 2798*b7f5c055SJed Brown + comm - The communicator for the DM object 2799*b7f5c055SJed Brown . tpstype - Type of triply-periodic surface 2800*b7f5c055SJed Brown . extent - Array of length 3 containing number of periods in each direction 2801*b7f5c055SJed Brown . periodic - array of length 3 with periodicity, or NULL for non-periodic 2802*b7f5c055SJed Brown . thickness - Thickness in normal direction 2803*b7f5c055SJed Brown - refinements - Number of factor-of-2 refinements 2804*b7f5c055SJed Brown 2805*b7f5c055SJed Brown Output Parameter: 2806*b7f5c055SJed Brown . dm - The DM object 2807*b7f5c055SJed Brown 2808*b7f5c055SJed Brown Notes: 2809*b7f5c055SJed Brown This meshes the surface of the Schwarz P or Gyroid surfaces. Schwarz P is is the simplest member of the triply-periodic minimal surfaces. 2810*b7f5c055SJed Brown https://en.wikipedia.org/wiki/Schwarz_minimal_surface#Schwarz_P_(%22Primitive%22) and can be cut with "clean" boundaries. 2811*b7f5c055SJed Brown The Gyroid (https://en.wikipedia.org/wiki/Gyroid) is another triply-periodic minimal surface with applications in additive manufacturing; it is much more difficult to "cut" since there are no planes of symmetry. 2812*b7f5c055SJed Brown Our implementation creates a very coarse mesh of the surface and refines (by 4-way splitting) as many times as requested. 2813*b7f5c055SJed Brown On each refinement, all vertices are projected to their nearest point on the surface. 2814*b7f5c055SJed Brown This projection could readily be extended to related surfaces. 2815*b7f5c055SJed Brown 2816*b7f5c055SJed Brown The face (edge) sets for the Schwarz P surface are numbered 1(-x), 2(+x), 3(-y), 4(+y), 5(-z), 6(+z). 2817*b7f5c055SJed Brown When the mesh is refined, "Face Sets" contain the new vertices (created during refinement). Use DMPlexLabelComplete() to propagate to coarse-level vertices. 2818*b7f5c055SJed Brown 2819*b7f5c055SJed Brown References: 2820*b7f5c055SJed Brown Maskery et al, Insights into the mechanical properties of several triply periodic minimal surface lattice structures made by polymer additive manufacturing, 2017. https://doi.org/10.1016/j.polymer.2017.11.049 2821*b7f5c055SJed Brown 2822*b7f5c055SJed Brown Developer Notes: 2823*b7f5c055SJed Brown The Gyroid mesh does not currently mark boundary sets. 2824*b7f5c055SJed Brown 2825*b7f5c055SJed Brown Level: beginner 2826*b7f5c055SJed Brown 2827*b7f5c055SJed Brown .seealso: DMPlexCreateSphereMesh(), DMSetType(), DMCreate() 2828*b7f5c055SJed Brown @*/ 2829*b7f5c055SJed Brown PetscErrorCode DMPlexCreateTPSMesh(MPI_Comm comm, DMPlexTPSType tpstype, const PetscInt extent[], const DMBoundaryType periodic[], PetscInt refinements, PetscInt layers, PetscReal thickness, DM *dm) 2830*b7f5c055SJed Brown { 2831*b7f5c055SJed Brown PetscErrorCode ierr; 2832*b7f5c055SJed Brown 2833*b7f5c055SJed Brown PetscFunctionBegin; 2834*b7f5c055SJed Brown ierr = DMCreate(comm, dm);CHKERRQ(ierr); 2835*b7f5c055SJed Brown ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 2836*b7f5c055SJed Brown ierr = DMPlexCreateTPSMesh_Internal(*dm, tpstype, extent, periodic, refinements, layers, thickness);CHKERRQ(ierr); 2837*b7f5c055SJed Brown PetscFunctionReturn(0); 2838*b7f5c055SJed Brown } 2839*b7f5c055SJed Brown 28409318fe57SMatthew G. Knepley /*@ 28419318fe57SMatthew G. Knepley DMPlexCreateSphereMesh - Creates a mesh on the d-dimensional sphere, S^d. 28429318fe57SMatthew G. Knepley 28439318fe57SMatthew G. Knepley Collective 28449318fe57SMatthew G. Knepley 28459318fe57SMatthew G. Knepley Input Parameters: 28469318fe57SMatthew G. Knepley + comm - The communicator for the DM object 28479318fe57SMatthew G. Knepley . dim - The dimension 28489318fe57SMatthew G. Knepley . simplex - Use simplices, or tensor product cells 28499318fe57SMatthew G. Knepley - R - The radius 28509318fe57SMatthew G. Knepley 28519318fe57SMatthew G. Knepley Output Parameter: 28529318fe57SMatthew G. Knepley . dm - The DM object 28539318fe57SMatthew G. Knepley 28549318fe57SMatthew G. Knepley Level: beginner 28559318fe57SMatthew G. Knepley 28569318fe57SMatthew G. Knepley .seealso: DMPlexCreateBallMesh(), DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 28579318fe57SMatthew G. Knepley @*/ 28589318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateSphereMesh(MPI_Comm comm, PetscInt dim, PetscBool simplex, PetscReal R, DM *dm) 28599318fe57SMatthew G. Knepley { 28609318fe57SMatthew G. Knepley PetscErrorCode ierr; 28619318fe57SMatthew G. Knepley 28629318fe57SMatthew G. Knepley PetscFunctionBegin; 28639318fe57SMatthew G. Knepley PetscValidPointer(dm, 5); 28649318fe57SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 28659318fe57SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 28669318fe57SMatthew G. Knepley ierr = DMPlexCreateSphereMesh_Internal(*dm, dim, simplex, R);CHKERRQ(ierr); 28679318fe57SMatthew G. Knepley PetscFunctionReturn(0); 28689318fe57SMatthew G. Knepley } 28699318fe57SMatthew G. Knepley 28709318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBallMesh_Internal(DM dm, PetscInt dim, PetscReal R) 28719318fe57SMatthew G. Knepley { 28729318fe57SMatthew G. Knepley DM sdm, vol; 28739318fe57SMatthew G. Knepley DMLabel bdlabel; 28749318fe57SMatthew G. Knepley PetscErrorCode ierr; 28759318fe57SMatthew G. Knepley 28769318fe57SMatthew G. Knepley PetscFunctionBegin; 28779318fe57SMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject) dm), &sdm);CHKERRQ(ierr); 28789318fe57SMatthew G. Knepley ierr = DMSetType(sdm, DMPLEX);CHKERRQ(ierr); 28799318fe57SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) sdm, "bd_");CHKERRQ(ierr); 28809318fe57SMatthew G. Knepley ierr = DMPlexCreateSphereMesh_Internal(sdm, dim-1, PETSC_TRUE, R);CHKERRQ(ierr); 28819318fe57SMatthew G. Knepley ierr = DMSetFromOptions(sdm);CHKERRQ(ierr); 28829318fe57SMatthew G. Knepley ierr = DMViewFromOptions(sdm, NULL, "-dm_view");CHKERRQ(ierr); 28839318fe57SMatthew G. Knepley ierr = DMPlexGenerate(sdm, NULL, PETSC_TRUE, &vol);CHKERRQ(ierr); 28849318fe57SMatthew G. Knepley ierr = DMDestroy(&sdm);CHKERRQ(ierr); 28859318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &vol);CHKERRQ(ierr); 28869318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm, "marker");CHKERRQ(ierr); 28879318fe57SMatthew G. Knepley ierr = DMGetLabel(dm, "marker", &bdlabel);CHKERRQ(ierr); 28889318fe57SMatthew G. Knepley ierr = DMPlexMarkBoundaryFaces(dm, PETSC_DETERMINE, bdlabel);CHKERRQ(ierr); 28899318fe57SMatthew G. Knepley ierr = DMPlexLabelComplete(dm, bdlabel);CHKERRQ(ierr); 289051a74b61SMatthew G. Knepley PetscFunctionReturn(0); 289151a74b61SMatthew G. Knepley } 289251a74b61SMatthew G. Knepley 289351a74b61SMatthew G. Knepley /*@ 289451a74b61SMatthew G. Knepley DMPlexCreateBallMesh - Creates a simplex mesh on the d-dimensional ball, B^d. 289551a74b61SMatthew G. Knepley 289651a74b61SMatthew G. Knepley Collective 289751a74b61SMatthew G. Knepley 289851a74b61SMatthew G. Knepley Input Parameters: 289951a74b61SMatthew G. Knepley + comm - The communicator for the DM object 290051a74b61SMatthew G. Knepley . dim - The dimension 290151a74b61SMatthew G. Knepley - R - The radius 290251a74b61SMatthew G. Knepley 290351a74b61SMatthew G. Knepley Output Parameter: 290451a74b61SMatthew G. Knepley . dm - The DM object 290551a74b61SMatthew G. Knepley 290651a74b61SMatthew G. Knepley Options Database Keys: 290751a74b61SMatthew G. Knepley - bd_dm_refine - This will refine the surface mesh preserving the sphere geometry 290851a74b61SMatthew G. Knepley 290951a74b61SMatthew G. Knepley Level: beginner 291051a74b61SMatthew G. Knepley 291151a74b61SMatthew G. Knepley .seealso: DMPlexCreateSphereMesh(), DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 291251a74b61SMatthew G. Knepley @*/ 291351a74b61SMatthew G. Knepley PetscErrorCode DMPlexCreateBallMesh(MPI_Comm comm, PetscInt dim, PetscReal R, DM *dm) 291451a74b61SMatthew G. Knepley { 291551a74b61SMatthew G. Knepley PetscErrorCode ierr; 291651a74b61SMatthew G. Knepley 291751a74b61SMatthew G. Knepley PetscFunctionBegin; 29189318fe57SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 29199318fe57SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 29209318fe57SMatthew G. Knepley ierr = DMPlexCreateBallMesh_Internal(*dm, dim, R);CHKERRQ(ierr); 29212829fed8SMatthew G. Knepley PetscFunctionReturn(0); 29222829fed8SMatthew G. Knepley } 29232829fed8SMatthew G. Knepley 29249318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateReferenceCell_Internal(DM rdm, DMPolytopeType ct) 29250a6ba040SMatthew G. Knepley { 29260a6ba040SMatthew G. Knepley PetscErrorCode ierr; 29270a6ba040SMatthew G. Knepley 29280a6ba040SMatthew G. Knepley PetscFunctionBegin; 29299318fe57SMatthew G. Knepley switch (ct) { 29309318fe57SMatthew G. Knepley case DM_POLYTOPE_POINT: 29319318fe57SMatthew G. Knepley { 29329318fe57SMatthew G. Knepley PetscInt numPoints[1] = {1}; 29339318fe57SMatthew G. Knepley PetscInt coneSize[1] = {0}; 29349318fe57SMatthew G. Knepley PetscInt cones[1] = {0}; 29359318fe57SMatthew G. Knepley PetscInt coneOrientations[1] = {0}; 29369318fe57SMatthew G. Knepley PetscScalar vertexCoords[1] = {0.0}; 29379318fe57SMatthew G. Knepley 29389318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 0);CHKERRQ(ierr); 29399318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 0, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 29409318fe57SMatthew G. Knepley } 29419318fe57SMatthew G. Knepley break; 29429318fe57SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 29439318fe57SMatthew G. Knepley { 29449318fe57SMatthew G. Knepley PetscInt numPoints[2] = {2, 1}; 29459318fe57SMatthew G. Knepley PetscInt coneSize[3] = {2, 0, 0}; 29469318fe57SMatthew G. Knepley PetscInt cones[2] = {1, 2}; 29479318fe57SMatthew G. Knepley PetscInt coneOrientations[2] = {0, 0}; 29489318fe57SMatthew G. Knepley PetscScalar vertexCoords[2] = {-1.0, 1.0}; 29499318fe57SMatthew G. Knepley 29509318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 1);CHKERRQ(ierr); 29519318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 29529318fe57SMatthew G. Knepley } 29539318fe57SMatthew G. Knepley break; 2954b5a892a1SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 2955b5a892a1SMatthew G. Knepley { 2956b5a892a1SMatthew G. Knepley PetscInt numPoints[2] = {2, 1}; 2957b5a892a1SMatthew G. Knepley PetscInt coneSize[3] = {2, 0, 0}; 2958b5a892a1SMatthew G. Knepley PetscInt cones[2] = {1, 2}; 2959b5a892a1SMatthew G. Knepley PetscInt coneOrientations[2] = {0, 0}; 2960b5a892a1SMatthew G. Knepley PetscScalar vertexCoords[2] = {-1.0, 1.0}; 2961b5a892a1SMatthew G. Knepley 2962b5a892a1SMatthew G. Knepley ierr = DMSetDimension(rdm, 1);CHKERRQ(ierr); 2963b5a892a1SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 2964b5a892a1SMatthew G. Knepley } 2965b5a892a1SMatthew G. Knepley break; 29669318fe57SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 29679318fe57SMatthew G. Knepley { 29689318fe57SMatthew G. Knepley PetscInt numPoints[2] = {3, 1}; 29699318fe57SMatthew G. Knepley PetscInt coneSize[4] = {3, 0, 0, 0}; 29709318fe57SMatthew G. Knepley PetscInt cones[3] = {1, 2, 3}; 29719318fe57SMatthew G. Knepley PetscInt coneOrientations[3] = {0, 0, 0}; 29729318fe57SMatthew G. Knepley PetscScalar vertexCoords[6] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0}; 29739318fe57SMatthew G. Knepley 29749318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 2);CHKERRQ(ierr); 29759318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 29769318fe57SMatthew G. Knepley } 29779318fe57SMatthew G. Knepley break; 29789318fe57SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 29799318fe57SMatthew G. Knepley { 29809318fe57SMatthew G. Knepley PetscInt numPoints[2] = {4, 1}; 29819318fe57SMatthew G. Knepley PetscInt coneSize[5] = {4, 0, 0, 0, 0}; 29829318fe57SMatthew G. Knepley PetscInt cones[4] = {1, 2, 3, 4}; 29839318fe57SMatthew G. Knepley PetscInt coneOrientations[4] = {0, 0, 0, 0}; 29849318fe57SMatthew G. Knepley PetscScalar vertexCoords[8] = {-1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0}; 29859318fe57SMatthew G. Knepley 29869318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 2);CHKERRQ(ierr); 29879318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 29889318fe57SMatthew G. Knepley } 29899318fe57SMatthew G. Knepley break; 29909318fe57SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 29919318fe57SMatthew G. Knepley { 29929318fe57SMatthew G. Knepley PetscInt numPoints[2] = {4, 1}; 29939318fe57SMatthew G. Knepley PetscInt coneSize[5] = {4, 0, 0, 0, 0}; 29949318fe57SMatthew G. Knepley PetscInt cones[4] = {1, 2, 3, 4}; 29959318fe57SMatthew G. Knepley PetscInt coneOrientations[4] = {0, 0, 0, 0}; 29969318fe57SMatthew G. Knepley PetscScalar vertexCoords[8] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0}; 29979318fe57SMatthew G. Knepley 29989318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 2);CHKERRQ(ierr); 29999318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 30009318fe57SMatthew G. Knepley } 30019318fe57SMatthew G. Knepley break; 30029318fe57SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 30039318fe57SMatthew G. Knepley { 30049318fe57SMatthew G. Knepley PetscInt numPoints[2] = {4, 1}; 30059318fe57SMatthew G. Knepley PetscInt coneSize[5] = {4, 0, 0, 0, 0}; 3006f0edb160SMatthew G. Knepley PetscInt cones[4] = {1, 2, 3, 4}; 30079318fe57SMatthew G. Knepley PetscInt coneOrientations[4] = {0, 0, 0, 0}; 3008f0edb160SMatthew 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}; 30099318fe57SMatthew G. Knepley 30109318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 30119318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 30129318fe57SMatthew G. Knepley } 30139318fe57SMatthew G. Knepley break; 30149318fe57SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 30159318fe57SMatthew G. Knepley { 30169318fe57SMatthew G. Knepley PetscInt numPoints[2] = {8, 1}; 30179318fe57SMatthew G. Knepley PetscInt coneSize[9] = {8, 0, 0, 0, 0, 0, 0, 0, 0}; 3018f0edb160SMatthew G. Knepley PetscInt cones[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 30199318fe57SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 3020f0edb160SMatthew 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, 30219318fe57SMatthew 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}; 30229318fe57SMatthew G. Knepley 30239318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 30249318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 30259318fe57SMatthew G. Knepley } 30269318fe57SMatthew G. Knepley break; 30279318fe57SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 30289318fe57SMatthew G. Knepley { 30299318fe57SMatthew G. Knepley PetscInt numPoints[2] = {6, 1}; 30309318fe57SMatthew G. Knepley PetscInt coneSize[7] = {6, 0, 0, 0, 0, 0, 0}; 3031f0edb160SMatthew G. Knepley PetscInt cones[6] = {1, 2, 3, 4, 5, 6}; 30329318fe57SMatthew G. Knepley PetscInt coneOrientations[6] = {0, 0, 0, 0, 0, 0}; 3033f0edb160SMatthew G. Knepley PetscScalar vertexCoords[18] = {-1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 30349318fe57SMatthew G. Knepley -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0}; 30359318fe57SMatthew G. Knepley 30369318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 30379318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 30389318fe57SMatthew G. Knepley } 30399318fe57SMatthew G. Knepley break; 30409318fe57SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 30419318fe57SMatthew G. Knepley { 30429318fe57SMatthew G. Knepley PetscInt numPoints[2] = {6, 1}; 30439318fe57SMatthew G. Knepley PetscInt coneSize[7] = {6, 0, 0, 0, 0, 0, 0}; 30449318fe57SMatthew G. Knepley PetscInt cones[6] = {1, 2, 3, 4, 5, 6}; 30459318fe57SMatthew G. Knepley PetscInt coneOrientations[6] = {0, 0, 0, 0, 0, 0}; 30469318fe57SMatthew G. Knepley PetscScalar vertexCoords[18] = {-1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 30479318fe57SMatthew G. Knepley -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0}; 30489318fe57SMatthew G. Knepley 30499318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 30509318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 30519318fe57SMatthew G. Knepley } 30529318fe57SMatthew G. Knepley break; 30539318fe57SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 30549318fe57SMatthew G. Knepley { 30559318fe57SMatthew G. Knepley PetscInt numPoints[2] = {8, 1}; 30569318fe57SMatthew G. Knepley PetscInt coneSize[9] = {8, 0, 0, 0, 0, 0, 0, 0, 0}; 30579318fe57SMatthew G. Knepley PetscInt cones[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 30589318fe57SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 30599318fe57SMatthew 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, 30609318fe57SMatthew 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}; 30619318fe57SMatthew G. Knepley 30629318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 30639318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 30649318fe57SMatthew G. Knepley } 30659318fe57SMatthew G. Knepley break; 30669318fe57SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 30679318fe57SMatthew G. Knepley { 30689318fe57SMatthew G. Knepley PetscInt numPoints[2] = {5, 1}; 30699318fe57SMatthew G. Knepley PetscInt coneSize[6] = {5, 0, 0, 0, 0, 0}; 3070f0edb160SMatthew G. Knepley PetscInt cones[5] = {1, 2, 3, 4, 5}; 30719318fe57SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 3072f0edb160SMatthew 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, 30739318fe57SMatthew G. Knepley 0.0, 0.0, 1.0}; 30749318fe57SMatthew G. Knepley 30759318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 30769318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 30779318fe57SMatthew G. Knepley } 30789318fe57SMatthew G. Knepley break; 307998921bdaSJacob Faibussowitsch default: SETERRQ(PetscObjectComm((PetscObject) rdm), PETSC_ERR_ARG_WRONG, "Cannot create reference cell for cell type %s", DMPolytopeTypes[ct]); 30809318fe57SMatthew G. Knepley } 30819318fe57SMatthew G. Knepley { 30829318fe57SMatthew G. Knepley PetscInt Nv, v; 30839318fe57SMatthew G. Knepley 30849318fe57SMatthew G. Knepley /* Must create the celltype label here so that we do not automatically try to compute the types */ 30859318fe57SMatthew G. Knepley ierr = DMCreateLabel(rdm, "celltype");CHKERRQ(ierr); 30869318fe57SMatthew G. Knepley ierr = DMPlexSetCellType(rdm, 0, ct);CHKERRQ(ierr); 30879318fe57SMatthew G. Knepley ierr = DMPlexGetChart(rdm, NULL, &Nv);CHKERRQ(ierr); 30889318fe57SMatthew G. Knepley for (v = 1; v < Nv; ++v) {ierr = DMPlexSetCellType(rdm, v, DM_POLYTOPE_POINT);CHKERRQ(ierr);} 30899318fe57SMatthew G. Knepley } 30909318fe57SMatthew G. Knepley ierr = DMPlexInterpolateInPlace_Internal(rdm);CHKERRQ(ierr); 3091b7f6ffafSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) rdm, DMPolytopeTypes[ct]);CHKERRQ(ierr); 30920a6ba040SMatthew G. Knepley PetscFunctionReturn(0); 30930a6ba040SMatthew G. Knepley } 30940a6ba040SMatthew G. Knepley 30959318fe57SMatthew G. Knepley /*@ 30969318fe57SMatthew G. Knepley DMPlexCreateReferenceCell - Create a DMPLEX with the appropriate FEM reference cell 30979318fe57SMatthew G. Knepley 30989318fe57SMatthew G. Knepley Collective 30999318fe57SMatthew G. Knepley 31009318fe57SMatthew G. Knepley Input Parameters: 31019318fe57SMatthew G. Knepley + comm - The communicator 31029318fe57SMatthew G. Knepley - ct - The cell type of the reference cell 31039318fe57SMatthew G. Knepley 31049318fe57SMatthew G. Knepley Output Parameter: 31059318fe57SMatthew G. Knepley . refdm - The reference cell 31069318fe57SMatthew G. Knepley 31079318fe57SMatthew G. Knepley Level: intermediate 31089318fe57SMatthew G. Knepley 31099318fe57SMatthew G. Knepley .seealso: DMPlexCreateReferenceCell(), DMPlexCreateBoxMesh() 31109318fe57SMatthew G. Knepley @*/ 31119318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateReferenceCell(MPI_Comm comm, DMPolytopeType ct, DM *refdm) 31120a6ba040SMatthew G. Knepley { 31130a6ba040SMatthew G. Knepley PetscErrorCode ierr; 31140a6ba040SMatthew G. Knepley 31150a6ba040SMatthew G. Knepley PetscFunctionBegin; 31169318fe57SMatthew G. Knepley ierr = DMCreate(comm, refdm);CHKERRQ(ierr); 31179318fe57SMatthew G. Knepley ierr = DMSetType(*refdm, DMPLEX);CHKERRQ(ierr); 31189318fe57SMatthew G. Knepley ierr = DMPlexCreateReferenceCell_Internal(*refdm, ct);CHKERRQ(ierr); 31199318fe57SMatthew G. Knepley PetscFunctionReturn(0); 31209318fe57SMatthew G. Knepley } 312179a015ccSMatthew G. Knepley 31229318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoundaryLabel_Private(DM dm, const char name[]) 31239318fe57SMatthew G. Knepley { 31249318fe57SMatthew G. Knepley DM plex; 31259318fe57SMatthew G. Knepley DMLabel label; 31269318fe57SMatthew G. Knepley PetscBool hasLabel; 31279318fe57SMatthew G. Knepley PetscErrorCode ierr; 31280a6ba040SMatthew G. Knepley 31299318fe57SMatthew G. Knepley PetscFunctionBeginUser; 31309318fe57SMatthew G. Knepley ierr = DMHasLabel(dm, name, &hasLabel);CHKERRQ(ierr); 31319318fe57SMatthew G. Knepley if (hasLabel) PetscFunctionReturn(0); 31329318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm, name);CHKERRQ(ierr); 31339318fe57SMatthew G. Knepley ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 31349318fe57SMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 31359318fe57SMatthew G. Knepley ierr = DMPlexMarkBoundaryFaces(plex, 1, label);CHKERRQ(ierr); 31369318fe57SMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 31379318fe57SMatthew G. Knepley PetscFunctionReturn(0); 31389318fe57SMatthew G. Knepley } 3139acdc6f61SToby Isaac 3140*b7f5c055SJed Brown const char * const DMPlexShapes[] = {"box", "box_surface", "ball", "sphere", "cylinder", "schwarz_p", "gyroid", "unknown", "DMPlexShape", "DM_SHAPE_", NULL}; 31419318fe57SMatthew G. Knepley 314261a622f3SMatthew G. Knepley static PetscErrorCode DMPlexCreateFromOptions_Internal(PetscOptionItems *PetscOptionsObject, PetscBool *useCoordSpace, DM dm) 31439318fe57SMatthew G. Knepley { 31449318fe57SMatthew G. Knepley DMPlexShape shape = DM_SHAPE_BOX; 31459318fe57SMatthew G. Knepley DMPolytopeType cell = DM_POLYTOPE_TRIANGLE; 31469318fe57SMatthew G. Knepley PetscInt dim = 2; 31479318fe57SMatthew G. Knepley PetscBool simplex = PETSC_TRUE, interpolate = PETSC_TRUE, adjCone = PETSC_FALSE, adjClosure = PETSC_TRUE, refDomain = PETSC_FALSE; 3148cd7e8a5eSksagiyam PetscBool flg, flg2, fflg, bdfflg, nameflg; 31499318fe57SMatthew G. Knepley MPI_Comm comm; 3150ed5e4e85SVaclav Hapla char filename[PETSC_MAX_PATH_LEN] = "<unspecified>"; 3151ed5e4e85SVaclav Hapla char bdFilename[PETSC_MAX_PATH_LEN] = "<unspecified>"; 3152ed5e4e85SVaclav Hapla char plexname[PETSC_MAX_PATH_LEN] = ""; 31539318fe57SMatthew G. Knepley PetscErrorCode ierr; 31549318fe57SMatthew G. Knepley 31559318fe57SMatthew G. Knepley PetscFunctionBegin; 31569318fe57SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 31579318fe57SMatthew G. Knepley /* TODO Turn this into a registration interface */ 31589318fe57SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_filename", "File containing a mesh", "DMPlexCreateFromFile", filename, filename, sizeof(filename), &fflg);CHKERRQ(ierr); 31599318fe57SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_boundary_filename", "File containing a mesh boundary", "DMPlexCreateFromFile", bdFilename, bdFilename, sizeof(bdFilename), &bdfflg);CHKERRQ(ierr); 3160cd7e8a5eSksagiyam ierr = PetscOptionsString("-dm_plex_name", "Name of the mesh in the file", "DMPlexCreateFromFile", plexname, plexname, sizeof(plexname), &nameflg);CHKERRQ(ierr); 31619318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_cell", "Cell shape", "", DMPolytopeTypes, (PetscEnum) cell, (PetscEnum *) &cell, NULL);CHKERRQ(ierr); 31629318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_reference_cell_domain", "Use a reference cell domain", "", refDomain, &refDomain, NULL);CHKERRQ(ierr); 31639318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_shape", "Shape for built-in mesh", "", DMPlexShapes, (PetscEnum) shape, (PetscEnum *) &shape, &flg);CHKERRQ(ierr); 31649318fe57SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_plex_dim", "Topological dimension of the mesh", "DMGetDimension", dim, &dim, &flg, 0);CHKERRQ(ierr); 31652c71b3e2SJacob Faibussowitsch PetscCheckFalse((dim < 0) || (dim > 3),comm, PETSC_ERR_ARG_OUTOFRANGE, "Dimension %D should be in [1, 3]", dim); 31669318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_simplex", "Mesh cell shape", "", simplex, &simplex, &flg);CHKERRQ(ierr); 31679318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_interpolate", "Flag to create edges and faces automatically", "", interpolate, &interpolate, &flg);CHKERRQ(ierr); 31689318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_adj_cone", "Set adjacency direction", "DMSetBasicAdjacency", adjCone, &adjCone, &flg);CHKERRQ(ierr); 31699318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_adj_closure", "Set adjacency size", "DMSetBasicAdjacency", adjClosure, &adjClosure, &flg2);CHKERRQ(ierr); 31709318fe57SMatthew G. Knepley if (flg || flg2) {ierr = DMSetBasicAdjacency(dm, adjCone, adjClosure);CHKERRQ(ierr);} 31719318fe57SMatthew G. Knepley 317261a622f3SMatthew G. Knepley switch (cell) { 317361a622f3SMatthew G. Knepley case DM_POLYTOPE_POINT: 317461a622f3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 317561a622f3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 317661a622f3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 317761a622f3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 317861a622f3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 317961a622f3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 318061a622f3SMatthew G. Knepley *useCoordSpace = PETSC_TRUE;break; 318161a622f3SMatthew G. Knepley default: *useCoordSpace = PETSC_FALSE;break; 318261a622f3SMatthew G. Knepley } 318361a622f3SMatthew G. Knepley 31849318fe57SMatthew G. Knepley if (fflg) { 31859318fe57SMatthew G. Knepley DM dmnew; 31869318fe57SMatthew G. Knepley 3187cd7e8a5eSksagiyam ierr = DMPlexCreateFromFile(PetscObjectComm((PetscObject) dm), filename, plexname, interpolate, &dmnew);CHKERRQ(ierr); 3188e600fa54SMatthew G. Knepley ierr = DMPlexCopy_Internal(dm, PETSC_FALSE, dmnew);CHKERRQ(ierr); 31899318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &dmnew);CHKERRQ(ierr); 31909318fe57SMatthew G. Knepley } else if (refDomain) { 31919318fe57SMatthew G. Knepley ierr = DMPlexCreateReferenceCell_Internal(dm, cell);CHKERRQ(ierr); 31929318fe57SMatthew G. Knepley } else if (bdfflg) { 31939318fe57SMatthew G. Knepley DM bdm, dmnew; 31949318fe57SMatthew G. Knepley 3195cd7e8a5eSksagiyam ierr = DMPlexCreateFromFile(PetscObjectComm((PetscObject) dm), bdFilename, plexname, interpolate, &bdm);CHKERRQ(ierr); 31969318fe57SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) bdm, "bd_");CHKERRQ(ierr); 31979318fe57SMatthew G. Knepley ierr = DMSetFromOptions(bdm);CHKERRQ(ierr); 31989318fe57SMatthew G. Knepley ierr = DMPlexGenerate(bdm, NULL, interpolate, &dmnew);CHKERRQ(ierr); 31999318fe57SMatthew G. Knepley ierr = DMDestroy(&bdm);CHKERRQ(ierr); 3200e600fa54SMatthew G. Knepley ierr = DMPlexCopy_Internal(dm, PETSC_FALSE, dmnew);CHKERRQ(ierr); 32019318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &dmnew);CHKERRQ(ierr); 32029318fe57SMatthew G. Knepley } else { 32039318fe57SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) dm, DMPlexShapes[shape]);CHKERRQ(ierr); 32049318fe57SMatthew G. Knepley switch (shape) { 32059318fe57SMatthew G. Knepley case DM_SHAPE_BOX: 32069318fe57SMatthew G. Knepley { 32079318fe57SMatthew G. Knepley PetscInt faces[3] = {0, 0, 0}; 32089318fe57SMatthew G. Knepley PetscReal lower[3] = {0, 0, 0}; 32099318fe57SMatthew G. Knepley PetscReal upper[3] = {1, 1, 1}; 32109318fe57SMatthew G. Knepley DMBoundaryType bdt[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE}; 32119318fe57SMatthew G. Knepley PetscInt i, n; 32129318fe57SMatthew G. Knepley 32139318fe57SMatthew G. Knepley n = dim; 32149318fe57SMatthew G. Knepley for (i = 0; i < dim; ++i) faces[i] = (dim == 1 ? 1 : 4-dim); 32159318fe57SMatthew G. Knepley ierr = PetscOptionsIntArray("-dm_plex_box_faces", "Number of faces along each dimension", "", faces, &n, &flg);CHKERRQ(ierr); 32169318fe57SMatthew G. Knepley n = 3; 32179318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_lower", "Lower left corner of box", "", lower, &n, &flg);CHKERRQ(ierr); 32182c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && (n != dim),comm, PETSC_ERR_ARG_SIZ, "Lower box point had %D values, should have been %D", n, dim); 32199318fe57SMatthew G. Knepley n = 3; 32209318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_upper", "Upper right corner of box", "", upper, &n, &flg);CHKERRQ(ierr); 32212c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && (n != dim),comm, PETSC_ERR_ARG_SIZ, "Upper box point had %D values, should have been %D", n, dim); 32229318fe57SMatthew G. Knepley n = 3; 32239318fe57SMatthew G. Knepley ierr = PetscOptionsEnumArray("-dm_plex_box_bd", "Boundary type for each dimension", "", DMBoundaryTypes, (PetscEnum *) bdt, &n, &flg);CHKERRQ(ierr); 32242c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && (n != dim),comm, PETSC_ERR_ARG_SIZ, "Box boundary types had %D values, should have been %D", n, dim); 32259318fe57SMatthew G. Knepley switch (cell) { 322661a622f3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 3227d410b0cfSMatthew G. Knepley ierr = DMPlexCreateWedgeBoxMesh_Internal(dm, faces, lower, upper, bdt);CHKERRQ(ierr); 3228d410b0cfSMatthew G. Knepley if (!interpolate) { 3229d410b0cfSMatthew G. Knepley DM udm; 3230d410b0cfSMatthew G. Knepley 3231d410b0cfSMatthew G. Knepley ierr = DMPlexUninterpolate(dm, &udm);CHKERRQ(ierr); 3232d410b0cfSMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &udm);CHKERRQ(ierr); 3233d410b0cfSMatthew G. Knepley } 32349318fe57SMatthew G. Knepley break; 32359318fe57SMatthew G. Knepley default: 32369318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxMesh_Internal(dm, dim, simplex, faces, lower, upper, bdt, interpolate);CHKERRQ(ierr); 32379318fe57SMatthew G. Knepley break; 32389318fe57SMatthew G. Knepley } 32399318fe57SMatthew G. Knepley } 32409318fe57SMatthew G. Knepley break; 32419318fe57SMatthew G. Knepley case DM_SHAPE_BOX_SURFACE: 32429318fe57SMatthew G. Knepley { 32439318fe57SMatthew G. Knepley PetscInt faces[3] = {0, 0, 0}; 32449318fe57SMatthew G. Knepley PetscReal lower[3] = {0, 0, 0}; 32459318fe57SMatthew G. Knepley PetscReal upper[3] = {1, 1, 1}; 32469318fe57SMatthew G. Knepley PetscInt i, n; 32479318fe57SMatthew G. Knepley 32489318fe57SMatthew G. Knepley n = dim+1; 32499318fe57SMatthew G. Knepley for (i = 0; i < dim+1; ++i) faces[i] = (dim+1 == 1 ? 1 : 4-(dim+1)); 32509318fe57SMatthew G. Knepley ierr = PetscOptionsIntArray("-dm_plex_box_faces", "Number of faces along each dimension", "", faces, &n, &flg);CHKERRQ(ierr); 32519318fe57SMatthew G. Knepley n = 3; 32529318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_lower", "Lower left corner of box", "", lower, &n, &flg);CHKERRQ(ierr); 32532c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && (n != dim+1),comm, PETSC_ERR_ARG_SIZ, "Lower box point had %D values, should have been %D", n, dim+1); 32549318fe57SMatthew G. Knepley n = 3; 32559318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_upper", "Upper right corner of box", "", upper, &n, &flg);CHKERRQ(ierr); 32562c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && (n != dim+1),comm, PETSC_ERR_ARG_SIZ, "Upper box point had %D values, should have been %D", n, dim+1); 32579318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxSurfaceMesh_Internal(dm, dim+1, faces, lower, upper, interpolate);CHKERRQ(ierr); 32589318fe57SMatthew G. Knepley } 32599318fe57SMatthew G. Knepley break; 32609318fe57SMatthew G. Knepley case DM_SHAPE_SPHERE: 32619318fe57SMatthew G. Knepley { 32629318fe57SMatthew G. Knepley PetscReal R = 1.0; 32639318fe57SMatthew G. Knepley 32649318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_sphere_radius", "Radius of the sphere", "", R, &R, &flg);CHKERRQ(ierr); 32659318fe57SMatthew G. Knepley ierr = DMPlexCreateSphereMesh_Internal(dm, dim, simplex, R);CHKERRQ(ierr); 32669318fe57SMatthew G. Knepley } 32679318fe57SMatthew G. Knepley break; 32689318fe57SMatthew G. Knepley case DM_SHAPE_BALL: 32699318fe57SMatthew G. Knepley { 32709318fe57SMatthew G. Knepley PetscReal R = 1.0; 32719318fe57SMatthew G. Knepley 32729318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_ball_radius", "Radius of the ball", "", R, &R, &flg);CHKERRQ(ierr); 32739318fe57SMatthew G. Knepley ierr = DMPlexCreateBallMesh_Internal(dm, dim, R);CHKERRQ(ierr); 32749318fe57SMatthew G. Knepley } 32759318fe57SMatthew G. Knepley break; 32769318fe57SMatthew G. Knepley case DM_SHAPE_CYLINDER: 32779318fe57SMatthew G. Knepley { 32789318fe57SMatthew G. Knepley DMBoundaryType bdt = DM_BOUNDARY_NONE; 32799318fe57SMatthew G. Knepley PetscInt Nw = 6; 32809318fe57SMatthew G. Knepley 32819318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_cylinder_bd", "Boundary type in the z direction", "", DMBoundaryTypes, (PetscEnum) bdt, (PetscEnum *) &bdt, NULL);CHKERRQ(ierr); 328261a622f3SMatthew G. Knepley ierr = PetscOptionsInt("-dm_plex_cylinder_num_wedges", "Number of wedges around the cylinder", "", Nw, &Nw, NULL);CHKERRQ(ierr); 32839318fe57SMatthew G. Knepley switch (cell) { 328461a622f3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 32859318fe57SMatthew G. Knepley ierr = DMPlexCreateWedgeCylinderMesh_Internal(dm, Nw, interpolate);CHKERRQ(ierr); 32869318fe57SMatthew G. Knepley break; 32879318fe57SMatthew G. Knepley default: 32889318fe57SMatthew G. Knepley ierr = DMPlexCreateHexCylinderMesh_Internal(dm, bdt);CHKERRQ(ierr); 32899318fe57SMatthew G. Knepley break; 32909318fe57SMatthew G. Knepley } 32919318fe57SMatthew G. Knepley } 32929318fe57SMatthew G. Knepley break; 3293*b7f5c055SJed Brown case DM_SHAPE_SCHWARZ_P: // fallthrough 3294*b7f5c055SJed Brown case DM_SHAPE_GYROID: 3295*b7f5c055SJed Brown { 3296*b7f5c055SJed Brown PetscInt extent[3] = {1,1,1}, refine = 0, layers = 0, three; 3297*b7f5c055SJed Brown PetscReal thickness = 0.; 3298*b7f5c055SJed Brown DMBoundaryType periodic[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE}; 3299*b7f5c055SJed Brown DMPlexTPSType tps_type = shape == DM_SHAPE_SCHWARZ_P ? DMPLEX_TPS_SCHWARZ_P : DMPLEX_TPS_GYROID; 3300*b7f5c055SJed Brown ierr = PetscOptionsIntArray("-dm_plex_tps_extent", "Number of replicas for each of three dimensions", NULL, extent, (three=3, &three), NULL);CHKERRQ(ierr); 3301*b7f5c055SJed Brown ierr = PetscOptionsInt("-dm_plex_tps_refine", "Number of refinements", NULL, refine, &refine, NULL);CHKERRQ(ierr); 3302*b7f5c055SJed Brown ierr = PetscOptionsEnumArray("-dm_plex_tps_periodic", "Periodicity in each of three dimensions", NULL, DMBoundaryTypes, (PetscEnum*)periodic, (three=3, &three), NULL);CHKERRQ(ierr); 3303*b7f5c055SJed Brown ierr = PetscOptionsInt("-dm_plex_tps_layers", "Number of layers in volumetric extrusion (or zero to not extrude)", NULL, layers, &layers, NULL);CHKERRQ(ierr); 3304*b7f5c055SJed Brown ierr = PetscOptionsReal("-dm_plex_tps_thickness", "Thickness of volumetric extrusion", NULL, thickness, &thickness, NULL);CHKERRQ(ierr); 3305*b7f5c055SJed Brown 3306*b7f5c055SJed Brown ierr = DMPlexCreateTPSMesh_Internal(dm, tps_type, extent, periodic, refine, layers, thickness);CHKERRQ(ierr); 3307*b7f5c055SJed Brown } 3308*b7f5c055SJed Brown break; 330998921bdaSJacob Faibussowitsch default: SETERRQ(comm, PETSC_ERR_SUP, "Domain shape %s is unsupported", DMPlexShapes[shape]); 33109318fe57SMatthew G. Knepley } 33119318fe57SMatthew G. Knepley } 33129318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr); 3313ed5e4e85SVaclav Hapla if (!((PetscObject)dm)->name && nameflg) { 3314ed5e4e85SVaclav Hapla ierr = PetscObjectSetName((PetscObject)dm, plexname);CHKERRQ(ierr); 3315ed5e4e85SVaclav Hapla } 33160a6ba040SMatthew G. Knepley PetscFunctionReturn(0); 33170a6ba040SMatthew G. Knepley } 33180a6ba040SMatthew G. Knepley 331947920aaeSMatthew G. Knepley PetscErrorCode DMSetFromOptions_NonRefinement_Plex(PetscOptionItems *PetscOptionsObject, DM dm) 33200a6ba040SMatthew G. Knepley { 33210a6ba040SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 3322c0f0dcc3SMatthew G. Knepley PetscBool flg; 33239318fe57SMatthew G. Knepley char bdLabel[PETSC_MAX_PATH_LEN]; 33240a6ba040SMatthew G. Knepley PetscErrorCode ierr; 33250a6ba040SMatthew G. Knepley 33260a6ba040SMatthew G. Knepley PetscFunctionBegin; 33270a6ba040SMatthew G. Knepley /* Handle viewing */ 33280c77aedcSMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_print_set_values", "Output all set values info", "DMPlexMatSetClosure", PETSC_FALSE, &mesh->printSetValues, NULL);CHKERRQ(ierr); 33295a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_plex_print_fem", "Debug output level all fem computations", "DMPlexSNESComputeResidualFEM", 0, &mesh->printFEM, NULL,0);CHKERRQ(ierr); 33300c77aedcSMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_print_tol", "Tolerance for FEM output", "DMPlexSNESComputeResidualFEM", mesh->printTol, &mesh->printTol, NULL);CHKERRQ(ierr); 33315a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_plex_print_l2", "Debug output level all L2 diff computations", "DMComputeL2Diff", 0, &mesh->printL2, NULL,0);CHKERRQ(ierr); 3332c0f0dcc3SMatthew G. Knepley ierr = DMMonitorSetFromOptions(dm, "-dm_plex_monitor_throughput", "Monitor the simulation throughput", "DMPlexMonitorThroughput", DMPlexMonitorThroughput, NULL, &flg);CHKERRQ(ierr); 3333c0f0dcc3SMatthew G. Knepley if (flg) {ierr = PetscLogDefaultBegin();CHKERRQ(ierr);} 33349318fe57SMatthew G. Knepley /* Labeling */ 33359318fe57SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_boundary_label", "Label to mark the mesh boundary", "", bdLabel, bdLabel, sizeof(bdLabel), &flg);CHKERRQ(ierr); 33369318fe57SMatthew G. Knepley if (flg) {ierr = DMPlexCreateBoundaryLabel_Private(dm, bdLabel);CHKERRQ(ierr);} 3337953fc75cSMatthew G. Knepley /* Point Location */ 33380c77aedcSMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_hash_location", "Use grid hashing for point location", "DMInterpolate", PETSC_FALSE, &mesh->useHashLocation, NULL);CHKERRQ(ierr); 33390848f4b5SMatthew G. Knepley /* Partitioning and distribution */ 334098ba2d7fSLawrence 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); 33412e62ab5aSMatthew G. Knepley /* Generation and remeshing */ 33420c77aedcSMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_remesh_bd", "Allow changes to the boundary on remeshing", "DMAdapt", PETSC_FALSE, &mesh->remeshBd, NULL);CHKERRQ(ierr); 3343b29cfa1cSToby Isaac /* Projection behavior */ 33445a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_plex_max_projection_height", "Maxmimum mesh point height used to project locally", "DMPlexSetMaxProjectionHeight", 0, &mesh->maxProjectionHeight, NULL,0);CHKERRQ(ierr); 334564141f95SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_regular_refinement", "Use special nested projection algorithm for regular refinement", "DMPlexSetRegularRefinement", mesh->regularRefinement, &mesh->regularRefinement, NULL);CHKERRQ(ierr); 3346f12cf164SMatthew G. Knepley /* Checking structure */ 3347f12cf164SMatthew G. Knepley { 3348e902f1eaSVaclav Hapla PetscBool flg = PETSC_FALSE, flg2 = PETSC_FALSE, all = PETSC_FALSE; 3349f12cf164SMatthew G. Knepley 3350e902f1eaSVaclav Hapla ierr = PetscOptionsBool("-dm_plex_check_all", "Perform all checks", NULL, PETSC_FALSE, &all, &flg2);CHKERRQ(ierr); 3351f12cf164SMatthew 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); 3352e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckSymmetry(dm);CHKERRQ(ierr);} 335325c50c26SVaclav 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); 3354e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckSkeleton(dm, 0);CHKERRQ(ierr);} 335525c50c26SVaclav 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); 3356e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckFaces(dm, 0);CHKERRQ(ierr);} 3357f12cf164SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_check_geometry", "Check that cells have positive volume", "DMPlexCheckGeometry", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 3358e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckGeometry(dm);CHKERRQ(ierr);} 335975ebff7aSVaclav Hapla ierr = PetscOptionsBool("-dm_plex_check_pointsf", "Check some necessary conditions for PointSF", "DMPlexCheckPointSF", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 3360e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckPointSF(dm);CHKERRQ(ierr);} 336175ebff7aSVaclav 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); 3362e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckInterfaceCones(dm);CHKERRQ(ierr);} 3363412e9a14SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_check_cell_shape", "Check cell shape", "DMPlexCheckCellShape", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 3364412e9a14SMatthew G. Knepley if (flg && flg2) {ierr = DMPlexCheckCellShape(dm, PETSC_TRUE, PETSC_DETERMINE);CHKERRQ(ierr);} 3365f12cf164SMatthew G. Knepley } 33669318fe57SMatthew G. Knepley { 33679318fe57SMatthew G. Knepley PetscReal scale = 1.0; 33684f3833eaSMatthew G. Knepley 33699318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_scale", "Scale factor for mesh coordinates", "DMPlexScale", scale, &scale, &flg);CHKERRQ(ierr); 33709318fe57SMatthew G. Knepley if (flg) { 33719318fe57SMatthew G. Knepley Vec coordinates, coordinatesLocal; 33729318fe57SMatthew G. Knepley 33739318fe57SMatthew G. Knepley ierr = DMGetCoordinates(dm, &coordinates);CHKERRQ(ierr); 33749318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinatesLocal);CHKERRQ(ierr); 33759318fe57SMatthew G. Knepley ierr = VecScale(coordinates, scale);CHKERRQ(ierr); 33769318fe57SMatthew G. Knepley ierr = VecScale(coordinatesLocal, scale);CHKERRQ(ierr); 33779318fe57SMatthew G. Knepley } 33789318fe57SMatthew G. Knepley } 33794f3833eaSMatthew G. Knepley ierr = PetscPartitionerSetFromOptions(mesh->partitioner);CHKERRQ(ierr); 338068d4fef7SMatthew G. Knepley PetscFunctionReturn(0); 338168d4fef7SMatthew G. Knepley } 338268d4fef7SMatthew G. Knepley 338346fa42a0SMatthew G. Knepley static PetscErrorCode DMSetFromOptions_Plex(PetscOptionItems *PetscOptionsObject,DM dm) 338468d4fef7SMatthew G. Knepley { 3385bdf63967SMatthew G. Knepley PetscFunctionList ordlist; 3386bdf63967SMatthew G. Knepley char oname[256]; 3387d410b0cfSMatthew G. Knepley PetscReal volume = -1.0; 33889318fe57SMatthew G. Knepley PetscInt prerefine = 0, refine = 0, r, coarsen = 0, overlap = 0, extLayers = 0, dim; 3389e600fa54SMatthew G. Knepley PetscBool uniformOrig, created = PETSC_FALSE, uniform = PETSC_TRUE, distribute, interpolate = PETSC_TRUE, coordSpace = PETSC_TRUE, remap = PETSC_TRUE, ghostCells = PETSC_FALSE, isHierarchy, ignoreModel = PETSC_FALSE, flg; 339068d4fef7SMatthew G. Knepley PetscErrorCode ierr; 339168d4fef7SMatthew G. Knepley 339268d4fef7SMatthew G. Knepley PetscFunctionBegin; 3393064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 33941a1499c8SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"DMPlex Options");CHKERRQ(ierr); 33959318fe57SMatthew G. Knepley /* Handle automatic creation */ 33969318fe57SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 339761a622f3SMatthew G. Knepley if (dim < 0) {ierr = DMPlexCreateFromOptions_Internal(PetscOptionsObject, &coordSpace, dm);CHKERRQ(ierr);created = PETSC_TRUE;} 3398d89e6e46SMatthew G. Knepley /* Handle interpolation before distribution */ 3399d89e6e46SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_interpolate_pre", "Flag to interpolate mesh before distribution", "", interpolate, &interpolate, &flg);CHKERRQ(ierr); 3400d89e6e46SMatthew G. Knepley if (flg) { 3401d89e6e46SMatthew G. Knepley DMPlexInterpolatedFlag interpolated; 3402d89e6e46SMatthew G. Knepley 3403d89e6e46SMatthew G. Knepley ierr = DMPlexIsInterpolated(dm, &interpolated);CHKERRQ(ierr); 3404d89e6e46SMatthew G. Knepley if (interpolated == DMPLEX_INTERPOLATED_FULL && !interpolate) { 3405d89e6e46SMatthew G. Knepley DM udm; 3406d89e6e46SMatthew G. Knepley 3407d89e6e46SMatthew G. Knepley ierr = DMPlexUninterpolate(dm, &udm);CHKERRQ(ierr); 3408d89e6e46SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &udm);CHKERRQ(ierr); 3409d89e6e46SMatthew G. Knepley } else if (interpolated != DMPLEX_INTERPOLATED_FULL && interpolate) { 3410d89e6e46SMatthew G. Knepley DM idm; 3411d89e6e46SMatthew G. Knepley 3412d89e6e46SMatthew G. Knepley ierr = DMPlexInterpolate(dm, &idm);CHKERRQ(ierr); 3413d89e6e46SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &idm);CHKERRQ(ierr); 3414d89e6e46SMatthew G. Knepley } 3415d89e6e46SMatthew G. Knepley } 34169b44eab4SMatthew G. Knepley /* Handle DMPlex refinement before distribution */ 3417c1cad2e7SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_ignore_model", "Flag to ignore the geometry model when refining", "DMCreate", ignoreModel, &ignoreModel, &flg);CHKERRQ(ierr); 3418c1cad2e7SMatthew G. Knepley if (flg) {((DM_Plex *) dm->data)->ignoreModel = ignoreModel;} 3419250712c9SMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &uniformOrig);CHKERRQ(ierr); 34209318fe57SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_refine_pre", "The number of refinements before distribution", "DMCreate", prerefine, &prerefine, NULL,0);CHKERRQ(ierr); 342161a622f3SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_remap_pre", "Flag to control coordinate remapping", "DMCreate", remap, &remap, NULL);CHKERRQ(ierr); 3422250712c9SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_uniform_pre", "Flag for uniform refinement before distribution", "DMCreate", uniform, &uniform, &flg);CHKERRQ(ierr); 3423250712c9SMatthew G. Knepley if (flg) {ierr = DMPlexSetRefinementUniform(dm, uniform);CHKERRQ(ierr);} 3424250712c9SMatthew G. Knepley ierr = PetscOptionsReal("-dm_refine_volume_limit_pre", "The maximum cell volume after refinement before distribution", "DMCreate", volume, &volume, &flg);CHKERRQ(ierr); 34259318fe57SMatthew G. Knepley if (flg) { 34269318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, PETSC_FALSE);CHKERRQ(ierr); 34279318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementLimit(dm, volume);CHKERRQ(ierr); 34289318fe57SMatthew G. Knepley prerefine = PetscMax(prerefine, 1); 34299318fe57SMatthew G. Knepley } 34309b44eab4SMatthew G. Knepley for (r = 0; r < prerefine; ++r) { 34319b44eab4SMatthew G. Knepley DM rdm; 34329b44eab4SMatthew G. Knepley PetscPointFunc coordFunc = ((DM_Plex*) dm->data)->coordFunc; 34339b44eab4SMatthew G. Knepley 34349b44eab4SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 34359b44eab4SMatthew G. Knepley ierr = DMRefine(dm, PetscObjectComm((PetscObject) dm), &rdm);CHKERRQ(ierr); 34369318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &rdm);CHKERRQ(ierr); 34379b44eab4SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 343861a622f3SMatthew G. Knepley if (coordFunc && remap) { 34399b44eab4SMatthew G. Knepley ierr = DMPlexRemapGeometry(dm, 0.0, coordFunc);CHKERRQ(ierr); 34409b44eab4SMatthew G. Knepley ((DM_Plex*) dm->data)->coordFunc = coordFunc; 34419b44eab4SMatthew G. Knepley } 34429b44eab4SMatthew G. Knepley } 3443250712c9SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, uniformOrig);CHKERRQ(ierr); 34449318fe57SMatthew G. Knepley /* Handle DMPlex extrusion before distribution */ 3445d410b0cfSMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_extrude", "The number of layers to extrude", "", extLayers, &extLayers, NULL, 0);CHKERRQ(ierr); 34469318fe57SMatthew G. Knepley if (extLayers) { 34479318fe57SMatthew G. Knepley DM edm; 34489318fe57SMatthew G. Knepley 3449d410b0cfSMatthew G. Knepley ierr = DMExtrude(dm, extLayers, &edm);CHKERRQ(ierr); 34509318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &edm);CHKERRQ(ierr); 345148d16a33SMatthew G. Knepley ((DM_Plex *) dm->data)->coordFunc = NULL; 3452d410b0cfSMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 3453d410b0cfSMatthew G. Knepley extLayers = 0; 34549318fe57SMatthew G. Knepley } 3455bdf63967SMatthew G. Knepley /* Handle DMPlex reordering before distribution */ 3456bdf63967SMatthew G. Knepley ierr = MatGetOrderingList(&ordlist);CHKERRQ(ierr); 3457bdf63967SMatthew G. Knepley ierr = PetscOptionsFList("-dm_plex_reorder", "Set mesh reordering type", "DMPlexGetOrdering", ordlist, MATORDERINGNATURAL, oname, sizeof(oname), &flg);CHKERRQ(ierr); 3458bdf63967SMatthew G. Knepley if (flg) { 3459bdf63967SMatthew G. Knepley DM pdm; 3460bdf63967SMatthew G. Knepley IS perm; 3461bdf63967SMatthew G. Knepley 3462bdf63967SMatthew G. Knepley ierr = DMPlexGetOrdering(dm, oname, NULL, &perm);CHKERRQ(ierr); 3463bdf63967SMatthew G. Knepley ierr = DMPlexPermute(dm, perm, &pdm);CHKERRQ(ierr); 3464bdf63967SMatthew G. Knepley ierr = ISDestroy(&perm);CHKERRQ(ierr); 3465bdf63967SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &pdm);CHKERRQ(ierr); 3466bdf63967SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 3467bdf63967SMatthew G. Knepley } 34689b44eab4SMatthew G. Knepley /* Handle DMPlex distribution */ 3469e600fa54SMatthew G. Knepley ierr = DMPlexDistributeGetDefault(dm, &distribute);CHKERRQ(ierr); 34709b44eab4SMatthew G. Knepley ierr = PetscOptionsBool("-dm_distribute", "Flag to redistribute a mesh among processes", "DMCreate", distribute, &distribute, NULL);CHKERRQ(ierr); 34719b44eab4SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_distribute_overlap", "The size of the overlap halo", "DMCreate", overlap, &overlap, NULL, 0);CHKERRQ(ierr); 34729b44eab4SMatthew G. Knepley if (distribute) { 34739b44eab4SMatthew G. Knepley DM pdm = NULL; 34749b44eab4SMatthew G. Knepley PetscPartitioner part; 34759b44eab4SMatthew G. Knepley 34769b44eab4SMatthew G. Knepley ierr = DMPlexGetPartitioner(dm, &part);CHKERRQ(ierr); 34779b44eab4SMatthew G. Knepley ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); 34789b44eab4SMatthew G. Knepley ierr = DMPlexDistribute(dm, overlap, NULL, &pdm);CHKERRQ(ierr); 34799b44eab4SMatthew G. Knepley if (pdm) { 34809318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &pdm);CHKERRQ(ierr); 34819b44eab4SMatthew G. Knepley } 34829b44eab4SMatthew G. Knepley } 34839318fe57SMatthew G. Knepley /* Create coordinate space */ 34849318fe57SMatthew G. Knepley if (created) { 348561a622f3SMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) dm->data; 34869318fe57SMatthew G. Knepley PetscInt degree = 1; 348761a622f3SMatthew G. Knepley PetscBool periodic, flg; 34889318fe57SMatthew G. Knepley 348961a622f3SMatthew G. Knepley ierr = PetscOptionsBool("-dm_coord_space", "Use an FEM space for coordinates", "", coordSpace, &coordSpace, &flg);CHKERRQ(ierr); 34909318fe57SMatthew G. Knepley ierr = PetscOptionsInt("-dm_coord_petscspace_degree", "FEM degree for coordinate space", "", degree, °ree, NULL);CHKERRQ(ierr); 349161a622f3SMatthew G. Knepley if (coordSpace) {ierr = DMPlexCreateCoordinateSpace(dm, degree, mesh->coordFunc);CHKERRQ(ierr);} 349261a622f3SMatthew G. Knepley if (flg && !coordSpace) { 349361a622f3SMatthew G. Knepley DM cdm; 349461a622f3SMatthew G. Knepley PetscDS cds; 349561a622f3SMatthew G. Knepley PetscObject obj; 349661a622f3SMatthew G. Knepley PetscClassId id; 349761a622f3SMatthew G. Knepley 349861a622f3SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 349961a622f3SMatthew G. Knepley ierr = DMGetDS(cdm, &cds);CHKERRQ(ierr); 350061a622f3SMatthew G. Knepley ierr = PetscDSGetDiscretization(cds, 0, &obj);CHKERRQ(ierr); 350161a622f3SMatthew G. Knepley ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 350261a622f3SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 350361a622f3SMatthew G. Knepley PetscContainer dummy; 350461a622f3SMatthew G. Knepley 350561a622f3SMatthew G. Knepley ierr = PetscContainerCreate(PETSC_COMM_SELF, &dummy);CHKERRQ(ierr); 350661a622f3SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) dummy, "coordinates");CHKERRQ(ierr); 350761a622f3SMatthew G. Knepley ierr = DMSetField(cdm, 0, NULL, (PetscObject) dummy);CHKERRQ(ierr); 350861a622f3SMatthew G. Knepley ierr = PetscContainerDestroy(&dummy);CHKERRQ(ierr); 350961a622f3SMatthew G. Knepley ierr = DMClearDS(cdm);CHKERRQ(ierr); 351061a622f3SMatthew G. Knepley } 351161a622f3SMatthew G. Knepley mesh->coordFunc = NULL; 351261a622f3SMatthew G. Knepley } 35139318fe57SMatthew G. Knepley ierr = DMLocalizeCoordinates(dm);CHKERRQ(ierr); 351461a622f3SMatthew G. Knepley ierr = DMGetPeriodicity(dm, &periodic, NULL, NULL, NULL);CHKERRQ(ierr); 351561a622f3SMatthew G. Knepley if (periodic) {ierr = DMSetPeriodicity(dm, PETSC_TRUE, NULL, NULL, NULL);CHKERRQ(ierr);} 35169318fe57SMatthew G. Knepley } 351768d4fef7SMatthew G. Knepley /* Handle DMPlex refinement */ 351861a622f3SMatthew G. Knepley remap = PETSC_TRUE; 35195a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_refine", "The number of uniform refinements", "DMCreate", refine, &refine, NULL,0);CHKERRQ(ierr); 352061a622f3SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_remap", "Flag to control coordinate remapping", "DMCreate", remap, &remap, NULL);CHKERRQ(ierr); 35215a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_refine_hierarchy", "The number of uniform refinements", "DMCreate", refine, &refine, &isHierarchy,0);CHKERRQ(ierr); 3522b6a0289aSMatthew G. Knepley if (refine) {ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr);} 352368d4fef7SMatthew G. Knepley if (refine && isHierarchy) { 3524acdc6f61SToby Isaac DM *dms, coarseDM; 352568d4fef7SMatthew G. Knepley 3526acdc6f61SToby Isaac ierr = DMGetCoarseDM(dm, &coarseDM);CHKERRQ(ierr); 3527acdc6f61SToby Isaac ierr = PetscObjectReference((PetscObject)coarseDM);CHKERRQ(ierr); 352868d4fef7SMatthew G. Knepley ierr = PetscMalloc1(refine,&dms);CHKERRQ(ierr); 352968d4fef7SMatthew G. Knepley ierr = DMRefineHierarchy(dm, refine, dms);CHKERRQ(ierr); 353068d4fef7SMatthew G. Knepley /* Total hack since we do not pass in a pointer */ 353168d4fef7SMatthew G. Knepley ierr = DMPlexSwap_Static(dm, dms[refine-1]);CHKERRQ(ierr); 353268d4fef7SMatthew G. Knepley if (refine == 1) { 3533a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dm, dms[0]);CHKERRQ(ierr); 35340aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dm, PETSC_TRUE);CHKERRQ(ierr); 353568d4fef7SMatthew G. Knepley } else { 3536a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dm, dms[refine-2]);CHKERRQ(ierr); 35370aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dm, PETSC_TRUE);CHKERRQ(ierr); 3538a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dms[0], dms[refine-1]);CHKERRQ(ierr); 35390aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dms[0], PETSC_TRUE);CHKERRQ(ierr); 354068d4fef7SMatthew G. Knepley } 3541acdc6f61SToby Isaac ierr = DMSetCoarseDM(dms[refine-1], coarseDM);CHKERRQ(ierr); 3542acdc6f61SToby Isaac ierr = PetscObjectDereference((PetscObject)coarseDM);CHKERRQ(ierr); 354368d4fef7SMatthew G. Knepley /* Free DMs */ 354468d4fef7SMatthew G. Knepley for (r = 0; r < refine; ++r) { 3545547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dms[r]);CHKERRQ(ierr); 354668d4fef7SMatthew G. Knepley ierr = DMDestroy(&dms[r]);CHKERRQ(ierr); 354768d4fef7SMatthew G. Knepley } 354868d4fef7SMatthew G. Knepley ierr = PetscFree(dms);CHKERRQ(ierr); 354968d4fef7SMatthew G. Knepley } else { 355068d4fef7SMatthew G. Knepley for (r = 0; r < refine; ++r) { 35519318fe57SMatthew G. Knepley DM rdm; 355251a74b61SMatthew G. Knepley PetscPointFunc coordFunc = ((DM_Plex*) dm->data)->coordFunc; 355368d4fef7SMatthew G. Knepley 35541a1499c8SBarry Smith ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 35559318fe57SMatthew G. Knepley ierr = DMRefine(dm, PetscObjectComm((PetscObject) dm), &rdm);CHKERRQ(ierr); 355668d4fef7SMatthew G. Knepley /* Total hack since we do not pass in a pointer */ 35579318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &rdm);CHKERRQ(ierr); 3558547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 355961a622f3SMatthew G. Knepley if (coordFunc && remap) { 356051a74b61SMatthew G. Knepley ierr = DMPlexRemapGeometry(dm, 0.0, coordFunc);CHKERRQ(ierr); 356151a74b61SMatthew G. Knepley ((DM_Plex*) dm->data)->coordFunc = coordFunc; 356251a74b61SMatthew G. Knepley } 356368d4fef7SMatthew G. Knepley } 356468d4fef7SMatthew G. Knepley } 35653cf6fe12SMatthew G. Knepley /* Handle DMPlex coarsening */ 35665a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_coarsen", "Coarsen the mesh", "DMCreate", coarsen, &coarsen, NULL,0);CHKERRQ(ierr); 35675a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_coarsen_hierarchy", "The number of coarsenings", "DMCreate", coarsen, &coarsen, &isHierarchy,0);CHKERRQ(ierr); 3568b653a561SMatthew G. Knepley if (coarsen && isHierarchy) { 3569b653a561SMatthew G. Knepley DM *dms; 3570b653a561SMatthew G. Knepley 3571b653a561SMatthew G. Knepley ierr = PetscMalloc1(coarsen, &dms);CHKERRQ(ierr); 3572b653a561SMatthew G. Knepley ierr = DMCoarsenHierarchy(dm, coarsen, dms);CHKERRQ(ierr); 3573b653a561SMatthew G. Knepley /* Free DMs */ 3574b653a561SMatthew G. Knepley for (r = 0; r < coarsen; ++r) { 3575547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dms[r]);CHKERRQ(ierr); 3576b653a561SMatthew G. Knepley ierr = DMDestroy(&dms[r]);CHKERRQ(ierr); 3577b653a561SMatthew G. Knepley } 3578b653a561SMatthew G. Knepley ierr = PetscFree(dms);CHKERRQ(ierr); 3579b653a561SMatthew G. Knepley } else { 3580b653a561SMatthew G. Knepley for (r = 0; r < coarsen; ++r) { 35819318fe57SMatthew G. Knepley DM cdm; 35829318fe57SMatthew G. Knepley PetscPointFunc coordFunc = ((DM_Plex*) dm->data)->coordFunc; 35833cf6fe12SMatthew G. Knepley 35843cf6fe12SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 35859318fe57SMatthew G. Knepley ierr = DMCoarsen(dm, PetscObjectComm((PetscObject) dm), &cdm);CHKERRQ(ierr); 35863cf6fe12SMatthew G. Knepley /* Total hack since we do not pass in a pointer */ 35879318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &cdm);CHKERRQ(ierr); 3588547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 35899318fe57SMatthew G. Knepley if (coordFunc) { 35909318fe57SMatthew G. Knepley ierr = DMPlexRemapGeometry(dm, 0.0, coordFunc);CHKERRQ(ierr); 35919318fe57SMatthew G. Knepley ((DM_Plex*) dm->data)->coordFunc = coordFunc; 35929318fe57SMatthew G. Knepley } 35933cf6fe12SMatthew G. Knepley } 3594b653a561SMatthew G. Knepley } 3595909dfd52SMatthew G. Knepley /* Handle ghost cells */ 3596909dfd52SMatthew 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); 3597909dfd52SMatthew G. Knepley if (ghostCells) { 3598909dfd52SMatthew G. Knepley DM gdm; 3599909dfd52SMatthew G. Knepley char lname[PETSC_MAX_PATH_LEN]; 3600909dfd52SMatthew G. Knepley 3601909dfd52SMatthew G. Knepley lname[0] = '\0'; 3602909dfd52SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_fv_ghost_cells_label", "Label name for ghost cells boundary", "DMCreate", lname, lname, sizeof(lname), &flg);CHKERRQ(ierr); 3603909dfd52SMatthew G. Knepley ierr = DMPlexConstructGhostCells(dm, flg ? lname : NULL, NULL, &gdm);CHKERRQ(ierr); 3604909dfd52SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &gdm);CHKERRQ(ierr); 3605909dfd52SMatthew G. Knepley } 36063cf6fe12SMatthew G. Knepley /* Handle */ 36071a1499c8SBarry Smith ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 36080a6ba040SMatthew G. Knepley ierr = PetscOptionsTail();CHKERRQ(ierr); 36090a6ba040SMatthew G. Knepley PetscFunctionReturn(0); 36100a6ba040SMatthew G. Knepley } 36110a6ba040SMatthew G. Knepley 3612552f7358SJed Brown static PetscErrorCode DMCreateGlobalVector_Plex(DM dm,Vec *vec) 3613552f7358SJed Brown { 3614552f7358SJed Brown PetscErrorCode ierr; 3615552f7358SJed Brown 3616552f7358SJed Brown PetscFunctionBegin; 3617552f7358SJed Brown ierr = DMCreateGlobalVector_Section_Private(dm,vec);CHKERRQ(ierr); 3618552f7358SJed Brown /* ierr = VecSetOperation(*vec, VECOP_DUPLICATE, (void(*)(void)) VecDuplicate_MPI_DM);CHKERRQ(ierr); */ 3619552f7358SJed Brown ierr = VecSetOperation(*vec, VECOP_VIEW, (void (*)(void)) VecView_Plex);CHKERRQ(ierr); 3620d930f514SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_VIEWNATIVE, (void (*)(void)) VecView_Plex_Native);CHKERRQ(ierr); 36212c40f234SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_LOAD, (void (*)(void)) VecLoad_Plex);CHKERRQ(ierr); 3622d930f514SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_LOADNATIVE, (void (*)(void)) VecLoad_Plex_Native);CHKERRQ(ierr); 3623552f7358SJed Brown PetscFunctionReturn(0); 3624552f7358SJed Brown } 3625552f7358SJed Brown 3626552f7358SJed Brown static PetscErrorCode DMCreateLocalVector_Plex(DM dm,Vec *vec) 3627552f7358SJed Brown { 3628552f7358SJed Brown PetscErrorCode ierr; 3629552f7358SJed Brown 3630552f7358SJed Brown PetscFunctionBegin; 3631552f7358SJed Brown ierr = DMCreateLocalVector_Section_Private(dm,vec);CHKERRQ(ierr); 3632552f7358SJed Brown ierr = VecSetOperation(*vec, VECOP_VIEW, (void (*)(void)) VecView_Plex_Local);CHKERRQ(ierr); 36332c40f234SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_LOAD, (void (*)(void)) VecLoad_Plex_Local);CHKERRQ(ierr); 3634552f7358SJed Brown PetscFunctionReturn(0); 3635552f7358SJed Brown } 3636552f7358SJed Brown 3637793f3fe5SMatthew G. Knepley static PetscErrorCode DMGetDimPoints_Plex(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 3638793f3fe5SMatthew G. Knepley { 3639793f3fe5SMatthew G. Knepley PetscInt depth, d; 3640793f3fe5SMatthew G. Knepley PetscErrorCode ierr; 3641793f3fe5SMatthew G. Knepley 3642793f3fe5SMatthew G. Knepley PetscFunctionBegin; 3643793f3fe5SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3644793f3fe5SMatthew G. Knepley if (depth == 1) { 3645793f3fe5SMatthew G. Knepley ierr = DMGetDimension(dm, &d);CHKERRQ(ierr); 3646793f3fe5SMatthew G. Knepley if (dim == 0) {ierr = DMPlexGetDepthStratum(dm, dim, pStart, pEnd);CHKERRQ(ierr);} 3647793f3fe5SMatthew G. Knepley else if (dim == d) {ierr = DMPlexGetDepthStratum(dm, 1, pStart, pEnd);CHKERRQ(ierr);} 3648793f3fe5SMatthew G. Knepley else {*pStart = 0; *pEnd = 0;} 3649793f3fe5SMatthew G. Knepley } else { 3650793f3fe5SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, dim, pStart, pEnd);CHKERRQ(ierr); 3651793f3fe5SMatthew G. Knepley } 3652793f3fe5SMatthew G. Knepley PetscFunctionReturn(0); 3653793f3fe5SMatthew G. Knepley } 3654793f3fe5SMatthew G. Knepley 365528d58a37SPierre Jolivet static PetscErrorCode DMGetNeighbors_Plex(DM dm, PetscInt *nranks, const PetscMPIInt *ranks[]) 3656502a2867SDave May { 3657502a2867SDave May PetscSF sf; 36580a19bb7dSprj- PetscInt niranks, njranks, n; 36590a19bb7dSprj- const PetscMPIInt *iranks, *jranks; 36600a19bb7dSprj- DM_Plex *data = (DM_Plex*) dm->data; 36612f356facSMatthew G. Knepley PetscErrorCode ierr; 3662502a2867SDave May 36632f356facSMatthew G. Knepley PetscFunctionBegin; 3664502a2867SDave May ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 36650a19bb7dSprj- if (!data->neighbors) { 366607a779feSPierre Jolivet ierr = PetscSFSetUp(sf);CHKERRQ(ierr); 36670a19bb7dSprj- ierr = PetscSFGetRootRanks(sf, &njranks, &jranks, NULL, NULL, NULL);CHKERRQ(ierr); 36680a19bb7dSprj- ierr = PetscSFGetLeafRanks(sf, &niranks, &iranks, NULL, NULL);CHKERRQ(ierr); 36690a19bb7dSprj- ierr = PetscMalloc1(njranks + niranks + 1, &data->neighbors);CHKERRQ(ierr); 36700a19bb7dSprj- ierr = PetscArraycpy(data->neighbors + 1, jranks, njranks);CHKERRQ(ierr); 36710a19bb7dSprj- ierr = PetscArraycpy(data->neighbors + njranks + 1, iranks, niranks);CHKERRQ(ierr); 36720a19bb7dSprj- n = njranks + niranks; 36730a19bb7dSprj- ierr = PetscSortRemoveDupsMPIInt(&n, data->neighbors + 1);CHKERRQ(ierr); 36740a19bb7dSprj- /* The following cast should never fail: can't have more neighbors than PETSC_MPI_INT_MAX */ 36750a19bb7dSprj- ierr = PetscMPIIntCast(n, data->neighbors);CHKERRQ(ierr); 36760a19bb7dSprj- } 36770a19bb7dSprj- if (nranks) *nranks = data->neighbors[0]; 36780a19bb7dSprj- if (ranks) { 36790a19bb7dSprj- if (data->neighbors[0]) *ranks = data->neighbors + 1; 36800a19bb7dSprj- else *ranks = NULL; 36810a19bb7dSprj- } 3682502a2867SDave May PetscFunctionReturn(0); 3683502a2867SDave May } 3684502a2867SDave May 36851eb70e55SToby Isaac PETSC_INTERN PetscErrorCode DMInterpolateSolution_Plex(DM, DM, Mat, Vec, Vec); 36861eb70e55SToby Isaac 368746fa42a0SMatthew G. Knepley static PetscErrorCode DMInitialize_Plex(DM dm) 3688552f7358SJed Brown { 3689713918a9SToby Isaac PetscErrorCode ierr; 3690713918a9SToby Isaac 3691552f7358SJed Brown PetscFunctionBegin; 3692552f7358SJed Brown dm->ops->view = DMView_Plex; 36932c40f234SMatthew G. Knepley dm->ops->load = DMLoad_Plex; 3694552f7358SJed Brown dm->ops->setfromoptions = DMSetFromOptions_Plex; 369538221697SMatthew G. Knepley dm->ops->clone = DMClone_Plex; 3696552f7358SJed Brown dm->ops->setup = DMSetUp_Plex; 36971bb6d2a8SBarry Smith dm->ops->createlocalsection = DMCreateLocalSection_Plex; 369866ad2231SToby Isaac dm->ops->createdefaultconstraints = DMCreateDefaultConstraints_Plex; 3699552f7358SJed Brown dm->ops->createglobalvector = DMCreateGlobalVector_Plex; 3700552f7358SJed Brown dm->ops->createlocalvector = DMCreateLocalVector_Plex; 3701184d77edSJed Brown dm->ops->getlocaltoglobalmapping = NULL; 37020298fd71SBarry Smith dm->ops->createfieldis = NULL; 3703552f7358SJed Brown dm->ops->createcoordinatedm = DMCreateCoordinateDM_Plex; 3704f19dbd58SToby Isaac dm->ops->createcoordinatefield = DMCreateCoordinateField_Plex; 37050a6ba040SMatthew G. Knepley dm->ops->getcoloring = NULL; 3706552f7358SJed Brown dm->ops->creatematrix = DMCreateMatrix_Plex; 3707bceba477SMatthew G. Knepley dm->ops->createinterpolation = DMCreateInterpolation_Plex; 3708bd041c0cSMatthew G. Knepley dm->ops->createmassmatrix = DMCreateMassMatrix_Plex; 3709b4937a87SMatthew G. Knepley dm->ops->createmassmatrixlumped = DMCreateMassMatrixLumped_Plex; 37105a84ad33SLisandro Dalcin dm->ops->createinjection = DMCreateInjection_Plex; 3711552f7358SJed Brown dm->ops->refine = DMRefine_Plex; 37120a6ba040SMatthew G. Knepley dm->ops->coarsen = DMCoarsen_Plex; 37130a6ba040SMatthew G. Knepley dm->ops->refinehierarchy = DMRefineHierarchy_Plex; 3714b653a561SMatthew G. Knepley dm->ops->coarsenhierarchy = DMCoarsenHierarchy_Plex; 3715d410b0cfSMatthew G. Knepley dm->ops->extrude = DMExtrude_Plex; 37160298fd71SBarry Smith dm->ops->globaltolocalbegin = NULL; 37170298fd71SBarry Smith dm->ops->globaltolocalend = NULL; 37180298fd71SBarry Smith dm->ops->localtoglobalbegin = NULL; 37190298fd71SBarry Smith dm->ops->localtoglobalend = NULL; 3720552f7358SJed Brown dm->ops->destroy = DMDestroy_Plex; 3721552f7358SJed Brown dm->ops->createsubdm = DMCreateSubDM_Plex; 37222adcc780SMatthew G. Knepley dm->ops->createsuperdm = DMCreateSuperDM_Plex; 3723793f3fe5SMatthew G. Knepley dm->ops->getdimpoints = DMGetDimPoints_Plex; 3724552f7358SJed Brown dm->ops->locatepoints = DMLocatePoints_Plex; 37250709b2feSToby Isaac dm->ops->projectfunctionlocal = DMProjectFunctionLocal_Plex; 37260709b2feSToby Isaac dm->ops->projectfunctionlabellocal = DMProjectFunctionLabelLocal_Plex; 3727bfc4295aSToby Isaac dm->ops->projectfieldlocal = DMProjectFieldLocal_Plex; 37288c6c5593SMatthew G. Knepley dm->ops->projectfieldlabellocal = DMProjectFieldLabelLocal_Plex; 3729ece3a9fcSMatthew G. Knepley dm->ops->projectbdfieldlabellocal = DMProjectBdFieldLabelLocal_Plex; 37300709b2feSToby Isaac dm->ops->computel2diff = DMComputeL2Diff_Plex; 3731b698f381SToby Isaac dm->ops->computel2gradientdiff = DMComputeL2GradientDiff_Plex; 37322a16baeaSToby Isaac dm->ops->computel2fielddiff = DMComputeL2FieldDiff_Plex; 373328d58a37SPierre Jolivet dm->ops->getneighbors = DMGetNeighbors_Plex; 3734f1d73a7aSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexInsertBoundaryValues_C",DMPlexInsertBoundaryValues_Plex);CHKERRQ(ierr); 373556cf3b9cSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexInsertTimeDerviativeBoundaryValues_C",DMPlexInsertTimeDerivativeBoundaryValues_Plex);CHKERRQ(ierr); 37368135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMSetUpGLVisViewer_C",DMSetUpGLVisViewer_Plex);CHKERRQ(ierr); 373728d58a37SPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)dm,"DMCreateNeumannOverlap_C",DMCreateNeumannOverlap_Plex);CHKERRQ(ierr); 3738cb54e036SVaclav Hapla ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexGetOverlap_C",DMPlexGetOverlap_Plex);CHKERRQ(ierr); 3739e600fa54SMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexDistributeGetDefault_C",DMPlexDistributeGetDefault_Plex);CHKERRQ(ierr); 3740e600fa54SMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexDistributeSetDefault_C",DMPlexDistributeSetDefault_Plex);CHKERRQ(ierr); 37411eb70e55SToby Isaac ierr = PetscObjectComposeFunction((PetscObject)dm,"DMInterpolateSolution_C",DMInterpolateSolution_Plex);CHKERRQ(ierr); 3742552f7358SJed Brown PetscFunctionReturn(0); 3743552f7358SJed Brown } 3744552f7358SJed Brown 374546fa42a0SMatthew G. Knepley PETSC_INTERN PetscErrorCode DMClone_Plex(DM dm, DM *newdm) 374663a16f15SMatthew G. Knepley { 374763a16f15SMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) dm->data; 374863a16f15SMatthew G. Knepley PetscErrorCode ierr; 374963a16f15SMatthew G. Knepley 375063a16f15SMatthew G. Knepley PetscFunctionBegin; 375163a16f15SMatthew G. Knepley mesh->refct++; 375263a16f15SMatthew G. Knepley (*newdm)->data = mesh; 375363a16f15SMatthew G. Knepley ierr = PetscObjectChangeTypeName((PetscObject) *newdm, DMPLEX);CHKERRQ(ierr); 375463a16f15SMatthew G. Knepley ierr = DMInitialize_Plex(*newdm);CHKERRQ(ierr); 375563a16f15SMatthew G. Knepley PetscFunctionReturn(0); 375663a16f15SMatthew G. Knepley } 375763a16f15SMatthew G. Knepley 37588818961aSMatthew G Knepley /*MC 37598818961aSMatthew G Knepley DMPLEX = "plex" - A DM object that encapsulates an unstructured mesh, or CW Complex, which can be expressed using a Hasse Diagram. 37608818961aSMatthew G Knepley In the local representation, Vecs contain all unknowns in the interior and shared boundary. This is 37618818961aSMatthew G Knepley specified by a PetscSection object. Ownership in the global representation is determined by 37628818961aSMatthew G Knepley ownership of the underlying DMPlex points. This is specified by another PetscSection object. 37638818961aSMatthew G Knepley 3764e5893cccSMatthew G. Knepley Options Database Keys: 3765250712c9SMatthew G. Knepley + -dm_refine_pre - Refine mesh before distribution 3766250712c9SMatthew G. Knepley + -dm_refine_uniform_pre - Choose uniform or generator-based refinement 3767250712c9SMatthew G. Knepley + -dm_refine_volume_limit_pre - Cell volume limit after pre-refinement using generator 3768250712c9SMatthew G. Knepley . -dm_distribute - Distribute mesh across processes 3769250712c9SMatthew G. Knepley . -dm_distribute_overlap - Number of cells to overlap for distribution 3770250712c9SMatthew G. Knepley . -dm_refine - Refine mesh after distribution 3771250712c9SMatthew G. Knepley . -dm_plex_hash_location - Use grid hashing for point location 3772ddce0771SMatthew G. Knepley . -dm_plex_hash_box_faces <n,m,p> - The number of divisions in each direction of the grid hash 3773f12cf164SMatthew G. Knepley . -dm_plex_partition_balance - Attempt to evenly divide points on partition boundary between processes 3774f12cf164SMatthew G. Knepley . -dm_plex_remesh_bd - Allow changes to the boundary on remeshing 3775f12cf164SMatthew G. Knepley . -dm_plex_max_projection_height - Maxmimum mesh point height used to project locally 3776f12cf164SMatthew G. Knepley . -dm_plex_regular_refinement - Use special nested projection algorithm for regular refinement 3777250712c9SMatthew G. Knepley . -dm_plex_check_all - Perform all shecks below 3778f12cf164SMatthew G. Knepley . -dm_plex_check_symmetry - Check that the adjacency information in the mesh is symmetric 3779f12cf164SMatthew G. Knepley . -dm_plex_check_skeleton <celltype> - Check that each cell has the correct number of vertices 3780f12cf164SMatthew 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 3781f12cf164SMatthew G. Knepley . -dm_plex_check_geometry - Check that cells have positive volume 3782f12cf164SMatthew G. Knepley . -dm_view :mesh.tex:ascii_latex - View the mesh in LaTeX/TikZ 3783e5893cccSMatthew G. Knepley . -dm_plex_view_scale <num> - Scale the TikZ 3784e5893cccSMatthew G. Knepley - -dm_plex_print_fem <num> - View FEM assembly information, such as element vectors and matrices 3785e5893cccSMatthew G. Knepley 37868818961aSMatthew G Knepley Level: intermediate 37878818961aSMatthew G Knepley 37888818961aSMatthew G Knepley .seealso: DMType, DMPlexCreate(), DMCreate(), DMSetType() 37898818961aSMatthew G Knepley M*/ 37908818961aSMatthew G Knepley 37918cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Plex(DM dm) 3792552f7358SJed Brown { 3793552f7358SJed Brown DM_Plex *mesh; 3794412e9a14SMatthew G. Knepley PetscInt unit; 3795552f7358SJed Brown PetscErrorCode ierr; 3796552f7358SJed Brown 3797552f7358SJed Brown PetscFunctionBegin; 3798552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3799b00a9115SJed Brown ierr = PetscNewLog(dm,&mesh);CHKERRQ(ierr); 3800552f7358SJed Brown dm->data = mesh; 3801552f7358SJed Brown 3802552f7358SJed Brown mesh->refct = 1; 380382f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &mesh->coneSection);CHKERRQ(ierr); 3804552f7358SJed Brown mesh->maxConeSize = 0; 38050298fd71SBarry Smith mesh->cones = NULL; 38060298fd71SBarry Smith mesh->coneOrientations = NULL; 380782f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &mesh->supportSection);CHKERRQ(ierr); 3808552f7358SJed Brown mesh->maxSupportSize = 0; 38090298fd71SBarry Smith mesh->supports = NULL; 3810552f7358SJed Brown mesh->refinementUniform = PETSC_TRUE; 3811552f7358SJed Brown mesh->refinementLimit = -1.0; 3812e600fa54SMatthew G. Knepley mesh->distDefault = PETSC_TRUE; 38137d0f5628SVaclav Hapla mesh->interpolated = DMPLEX_INTERPOLATED_INVALID; 38147d0f5628SVaclav Hapla mesh->interpolatedCollective = DMPLEX_INTERPOLATED_INVALID; 3815552f7358SJed Brown 38160298fd71SBarry Smith mesh->facesTmp = NULL; 3817552f7358SJed Brown 3818d9deefdfSMatthew G. Knepley mesh->tetgenOpts = NULL; 3819d9deefdfSMatthew G. Knepley mesh->triangleOpts = NULL; 382077623264SMatthew G. Knepley ierr = PetscPartitionerCreate(PetscObjectComm((PetscObject)dm), &mesh->partitioner);CHKERRQ(ierr); 38212e62ab5aSMatthew G. Knepley mesh->remeshBd = PETSC_FALSE; 3822d9deefdfSMatthew G. Knepley 38230298fd71SBarry Smith mesh->subpointMap = NULL; 3824552f7358SJed Brown 38258865f1eaSKarl Rupp for (unit = 0; unit < NUM_PETSC_UNITS; ++unit) mesh->scale[unit] = 1.0; 3826552f7358SJed Brown 38270aef6b92SMatthew G. Knepley mesh->regularRefinement = PETSC_FALSE; 3828df0420ecSMatthew G. Knepley mesh->depthState = -1; 3829ba2698f1SMatthew G. Knepley mesh->celltypeState = -1; 38300298fd71SBarry Smith mesh->globalVertexNumbers = NULL; 38310298fd71SBarry Smith mesh->globalCellNumbers = NULL; 3832a68b90caSToby Isaac mesh->anchorSection = NULL; 3833a68b90caSToby Isaac mesh->anchorIS = NULL; 383441e6d900SToby Isaac mesh->createanchors = NULL; 3835fa73a4e1SToby Isaac mesh->computeanchormatrix = NULL; 3836d961a43aSToby Isaac mesh->parentSection = NULL; 3837d961a43aSToby Isaac mesh->parents = NULL; 3838d961a43aSToby Isaac mesh->childIDs = NULL; 3839d961a43aSToby Isaac mesh->childSection = NULL; 3840d961a43aSToby Isaac mesh->children = NULL; 3841d6a7ad0dSToby Isaac mesh->referenceTree = NULL; 3842dcbd3bf7SToby Isaac mesh->getchildsymmetry = NULL; 3843552f7358SJed Brown mesh->vtkCellHeight = 0; 3844e228b242SToby Isaac mesh->useAnchors = PETSC_FALSE; 3845552f7358SJed Brown 3846b29cfa1cSToby Isaac mesh->maxProjectionHeight = 0; 3847b29cfa1cSToby Isaac 38480a19bb7dSprj- mesh->neighbors = NULL; 38490a19bb7dSprj- 3850552f7358SJed Brown mesh->printSetValues = PETSC_FALSE; 3851552f7358SJed Brown mesh->printFEM = 0; 38526113b454SMatthew G. Knepley mesh->printTol = 1.0e-10; 3853552f7358SJed Brown 3854552f7358SJed Brown ierr = DMInitialize_Plex(dm);CHKERRQ(ierr); 3855552f7358SJed Brown PetscFunctionReturn(0); 3856552f7358SJed Brown } 3857552f7358SJed Brown 3858552f7358SJed Brown /*@ 3859552f7358SJed Brown DMPlexCreate - Creates a DMPlex object, which encapsulates an unstructured mesh, or CW complex, which can be expressed using a Hasse Diagram. 3860552f7358SJed Brown 3861d083f849SBarry Smith Collective 3862552f7358SJed Brown 3863552f7358SJed Brown Input Parameter: 3864552f7358SJed Brown . comm - The communicator for the DMPlex object 3865552f7358SJed Brown 3866552f7358SJed Brown Output Parameter: 3867552f7358SJed Brown . mesh - The DMPlex object 3868552f7358SJed Brown 3869552f7358SJed Brown Level: beginner 3870552f7358SJed Brown 3871552f7358SJed Brown @*/ 3872552f7358SJed Brown PetscErrorCode DMPlexCreate(MPI_Comm comm, DM *mesh) 3873552f7358SJed Brown { 3874552f7358SJed Brown PetscErrorCode ierr; 3875552f7358SJed Brown 3876552f7358SJed Brown PetscFunctionBegin; 3877552f7358SJed Brown PetscValidPointer(mesh,2); 3878552f7358SJed Brown ierr = DMCreate(comm, mesh);CHKERRQ(ierr); 3879552f7358SJed Brown ierr = DMSetType(*mesh, DMPLEX);CHKERRQ(ierr); 3880552f7358SJed Brown PetscFunctionReturn(0); 3881552f7358SJed Brown } 3882552f7358SJed Brown 3883b09969d6SVaclav Hapla /*@C 3884b09969d6SVaclav Hapla DMPlexBuildFromCellListParallel - Build distributed DMPLEX topology from a list of vertices for each cell (common mesh generator output) 3885b09969d6SVaclav Hapla 3886b09969d6SVaclav Hapla Input Parameters: 3887b09969d6SVaclav Hapla + dm - The DM 3888b09969d6SVaclav Hapla . numCells - The number of cells owned by this process 3889325d53feSBarry Smith . numVertices - The number of vertices to be owned by this process, or PETSC_DECIDE 3890325d53feSBarry Smith . NVertices - The global number of vertices, or PETSC_DETERMINE 3891b09969d6SVaclav Hapla . numCorners - The number of vertices for each cell 38925e488331SVaclav Hapla - cells - An array of numCells*numCorners numbers, the global vertex numbers for each cell 3893b09969d6SVaclav Hapla 3894be8c289dSNicolas Barral Output Parameters: 3895be8c289dSNicolas Barral + vertexSF - (Optional) SF describing complete vertex ownership 3896be8c289dSNicolas Barral - verticesAdjSaved - (Optional) vertex adjacency array 3897b09969d6SVaclav Hapla 3898b09969d6SVaclav Hapla Notes: 3899b09969d6SVaclav Hapla Two triangles sharing a face 3900b09969d6SVaclav Hapla $ 3901b09969d6SVaclav Hapla $ 2 3902b09969d6SVaclav Hapla $ / | \ 3903b09969d6SVaclav Hapla $ / | \ 3904b09969d6SVaclav Hapla $ / | \ 3905b09969d6SVaclav Hapla $ 0 0 | 1 3 3906b09969d6SVaclav Hapla $ \ | / 3907b09969d6SVaclav Hapla $ \ | / 3908b09969d6SVaclav Hapla $ \ | / 3909b09969d6SVaclav Hapla $ 1 3910b09969d6SVaclav Hapla would have input 3911b09969d6SVaclav Hapla $ numCells = 2, numVertices = 4 3912b09969d6SVaclav Hapla $ cells = [0 1 2 1 3 2] 3913b09969d6SVaclav Hapla $ 3914b09969d6SVaclav Hapla which would result in the DMPlex 3915b09969d6SVaclav Hapla $ 3916b09969d6SVaclav Hapla $ 4 3917b09969d6SVaclav Hapla $ / | \ 3918b09969d6SVaclav Hapla $ / | \ 3919b09969d6SVaclav Hapla $ / | \ 3920b09969d6SVaclav Hapla $ 2 0 | 1 5 3921b09969d6SVaclav Hapla $ \ | / 3922b09969d6SVaclav Hapla $ \ | / 3923b09969d6SVaclav Hapla $ \ | / 3924b09969d6SVaclav Hapla $ 3 3925b09969d6SVaclav Hapla 392625b6865aSVaclav Hapla Vertices are implicitly numbered consecutively 0,...,NVertices. 392725b6865aSVaclav Hapla Each rank owns a chunk of numVertices consecutive vertices. 392825b6865aSVaclav Hapla If numVertices is PETSC_DECIDE, PETSc will distribute them as evenly as possible using PetscLayout. 3929325d53feSBarry Smith If NVertices is PETSC_DETERMINE and numVertices is PETSC_DECIDE, NVertices is computed by PETSc as the maximum vertex index in cells + 1. 3930325d53feSBarry Smith If only NVertices is PETSC_DETERMINE, it is computed as the sum of numVertices over all ranks. 393125b6865aSVaclav Hapla 3932b09969d6SVaclav Hapla The cell distribution is arbitrary non-overlapping, independent of the vertex distribution. 3933b09969d6SVaclav Hapla 3934b09969d6SVaclav Hapla Not currently supported in Fortran. 3935b09969d6SVaclav Hapla 3936b09969d6SVaclav Hapla Level: advanced 3937b09969d6SVaclav Hapla 3938b09969d6SVaclav Hapla .seealso: DMPlexBuildFromCellList(), DMPlexCreateFromCellListParallelPetsc(), DMPlexBuildCoordinatesFromCellListParallel() 3939b09969d6SVaclav Hapla @*/ 3940be8c289dSNicolas Barral PetscErrorCode DMPlexBuildFromCellListParallel(DM dm, PetscInt numCells, PetscInt numVertices, PetscInt NVertices, PetscInt numCorners, const PetscInt cells[], PetscSF *vertexSF, PetscInt **verticesAdjSaved) 3941a47d0d45SMatthew G. Knepley { 39422464107aSksagiyam PetscSF sfPoint; 39432464107aSksagiyam PetscLayout layout; 39442464107aSksagiyam PetscInt numVerticesAdj, *verticesAdj, *cones, c, p, dim; 39459852e123SBarry Smith PetscMPIInt rank, size; 3946a47d0d45SMatthew G. Knepley PetscErrorCode ierr; 3947a47d0d45SMatthew G. Knepley 3948a47d0d45SMatthew G. Knepley PetscFunctionBegin; 394925b6865aSVaclav Hapla PetscValidLogicalCollectiveInt(dm,NVertices,4); 3950b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 3951ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 3952ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRMPI(ierr); 39536cbf6523SVaclav Hapla ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 395425b6865aSVaclav Hapla /* Get/check global number of vertices */ 395525b6865aSVaclav Hapla { 395625b6865aSVaclav Hapla PetscInt NVerticesInCells, i; 395725b6865aSVaclav Hapla const PetscInt len = numCells * numCorners; 395825b6865aSVaclav Hapla 395925b6865aSVaclav Hapla /* NVerticesInCells = max(cells) + 1 */ 396025b6865aSVaclav Hapla NVerticesInCells = PETSC_MIN_INT; 396125b6865aSVaclav Hapla for (i=0; i<len; i++) if (cells[i] > NVerticesInCells) NVerticesInCells = cells[i]; 396225b6865aSVaclav Hapla ++NVerticesInCells; 3963ffc4695bSBarry Smith ierr = MPI_Allreduce(MPI_IN_PLACE, &NVerticesInCells, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 396425b6865aSVaclav Hapla 396525b6865aSVaclav Hapla if (numVertices == PETSC_DECIDE && NVertices == PETSC_DECIDE) NVertices = NVerticesInCells; 39662c71b3e2SJacob Faibussowitsch else PetscCheckFalse(NVertices != PETSC_DECIDE && NVertices < NVerticesInCells,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); 396725b6865aSVaclav Hapla } 39689079aca8SVaclav Hapla /* Count locally unique vertices */ 39699079aca8SVaclav Hapla { 39709079aca8SVaclav Hapla PetscHSetI vhash; 39719079aca8SVaclav Hapla PetscInt off = 0; 39729079aca8SVaclav Hapla 3973e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&vhash);CHKERRQ(ierr); 3974a47d0d45SMatthew G. Knepley for (c = 0; c < numCells; ++c) { 3975a47d0d45SMatthew G. Knepley for (p = 0; p < numCorners; ++p) { 3976e8f14785SLisandro Dalcin ierr = PetscHSetIAdd(vhash, cells[c*numCorners+p]);CHKERRQ(ierr); 3977a47d0d45SMatthew G. Knepley } 3978a47d0d45SMatthew G. Knepley } 3979e8f14785SLisandro Dalcin ierr = PetscHSetIGetSize(vhash, &numVerticesAdj);CHKERRQ(ierr); 3980be8c289dSNicolas Barral if (!verticesAdjSaved) { ierr = PetscMalloc1(numVerticesAdj, &verticesAdj);CHKERRQ(ierr); } 3981be8c289dSNicolas Barral else { verticesAdj = *verticesAdjSaved; } 3982e8f14785SLisandro Dalcin ierr = PetscHSetIGetElems(vhash, &off, verticesAdj);CHKERRQ(ierr); 3983e8f14785SLisandro Dalcin ierr = PetscHSetIDestroy(&vhash);CHKERRQ(ierr); 39842c71b3e2SJacob Faibussowitsch PetscCheckFalse(off != numVerticesAdj,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid number of local vertices %D should be %D", off, numVerticesAdj); 3985a47d0d45SMatthew G. Knepley } 39869079aca8SVaclav Hapla ierr = PetscSortInt(numVerticesAdj, verticesAdj);CHKERRQ(ierr); 3987a47d0d45SMatthew G. Knepley /* Create cones */ 3988a47d0d45SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVerticesAdj);CHKERRQ(ierr); 3989a47d0d45SMatthew G. Knepley for (c = 0; c < numCells; ++c) {ierr = DMPlexSetConeSize(dm, c, numCorners);CHKERRQ(ierr);} 3990a47d0d45SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); 3991961cfab0SVaclav Hapla ierr = DMPlexGetCones(dm,&cones);CHKERRQ(ierr); 3992a47d0d45SMatthew G. Knepley for (c = 0; c < numCells; ++c) { 3993a47d0d45SMatthew G. Knepley for (p = 0; p < numCorners; ++p) { 3994a47d0d45SMatthew G. Knepley const PetscInt gv = cells[c*numCorners+p]; 3995a47d0d45SMatthew G. Knepley PetscInt lv; 3996a47d0d45SMatthew G. Knepley 39979079aca8SVaclav Hapla /* Positions within verticesAdj form 0-based local vertex numbering; 39989079aca8SVaclav Hapla we need to shift it by numCells to get correct DAG points (cells go first) */ 3999a47d0d45SMatthew G. Knepley ierr = PetscFindInt(gv, numVerticesAdj, verticesAdj, &lv);CHKERRQ(ierr); 40002c71b3e2SJacob Faibussowitsch PetscCheckFalse(lv < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not find global vertex %D in local connectivity", gv); 4001961cfab0SVaclav Hapla cones[c*numCorners+p] = lv+numCells; 4002a47d0d45SMatthew G. Knepley } 4003a47d0d45SMatthew G. Knepley } 40042464107aSksagiyam /* Build point sf */ 40052464107aSksagiyam ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)dm), &layout);CHKERRQ(ierr); 40062464107aSksagiyam ierr = PetscLayoutSetSize(layout, NVertices);CHKERRQ(ierr); 40072464107aSksagiyam ierr = PetscLayoutSetLocalSize(layout, numVertices);CHKERRQ(ierr); 40082464107aSksagiyam ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr); 40092464107aSksagiyam ierr = PetscSFCreateByMatchingIndices(layout, numVerticesAdj, verticesAdj, NULL, numCells, numVerticesAdj, verticesAdj, NULL, numCells, vertexSF, &sfPoint);CHKERRQ(ierr); 40102464107aSksagiyam ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 4011be8c289dSNicolas Barral if (!verticesAdjSaved) { ierr = PetscFree(verticesAdj);CHKERRQ(ierr); } 4012a47d0d45SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) sfPoint, "point SF");CHKERRQ(ierr); 40132464107aSksagiyam if (dm->sf) { 40142464107aSksagiyam const char *prefix; 40152464107aSksagiyam 40162464107aSksagiyam ierr = PetscObjectGetOptionsPrefix((PetscObject)dm->sf, &prefix);CHKERRQ(ierr); 40172464107aSksagiyam ierr = PetscObjectSetOptionsPrefix((PetscObject)sfPoint, prefix);CHKERRQ(ierr); 40182464107aSksagiyam } 40192464107aSksagiyam ierr = DMSetPointSF(dm, sfPoint);CHKERRQ(ierr); 40202464107aSksagiyam ierr = PetscSFDestroy(&sfPoint);CHKERRQ(ierr); 40212464107aSksagiyam if (vertexSF) {ierr = PetscObjectSetName((PetscObject)(*vertexSF), "Vertex Ownership SF");CHKERRQ(ierr);} 4022a47d0d45SMatthew G. Knepley /* Fill in the rest of the topology structure */ 4023a47d0d45SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 4024a47d0d45SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 4025b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 4026a47d0d45SMatthew G. Knepley PetscFunctionReturn(0); 4027a47d0d45SMatthew G. Knepley } 4028a47d0d45SMatthew G. Knepley 4029b09969d6SVaclav Hapla /*@C 4030b09969d6SVaclav Hapla DMPlexBuildCoordinatesFromCellListParallel - Build DM coordinates from a list of coordinates for each owned vertex (common mesh generator output) 4031b09969d6SVaclav Hapla 4032b09969d6SVaclav Hapla Input Parameters: 4033b09969d6SVaclav Hapla + dm - The DM 4034b09969d6SVaclav Hapla . spaceDim - The spatial dimension used for coordinates 4035b09969d6SVaclav Hapla . sfVert - SF describing complete vertex ownership 4036b09969d6SVaclav Hapla - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 4037b09969d6SVaclav Hapla 4038b09969d6SVaclav Hapla Level: advanced 4039b09969d6SVaclav Hapla 4040b09969d6SVaclav Hapla Notes: 4041b09969d6SVaclav Hapla Not currently supported in Fortran. 4042b09969d6SVaclav Hapla 4043b09969d6SVaclav Hapla .seealso: DMPlexBuildCoordinatesFromCellList(), DMPlexCreateFromCellListParallelPetsc(), DMPlexBuildFromCellListParallel() 4044b09969d6SVaclav Hapla @*/ 40451edcf0b2SVaclav Hapla PetscErrorCode DMPlexBuildCoordinatesFromCellListParallel(DM dm, PetscInt spaceDim, PetscSF sfVert, const PetscReal vertexCoords[]) 4046a47d0d45SMatthew G. Knepley { 4047a47d0d45SMatthew G. Knepley PetscSection coordSection; 4048a47d0d45SMatthew G. Knepley Vec coordinates; 4049a47d0d45SMatthew G. Knepley PetscScalar *coords; 40501edcf0b2SVaclav Hapla PetscInt numVertices, numVerticesAdj, coordSize, v, vStart, vEnd; 4051a47d0d45SMatthew G. Knepley PetscErrorCode ierr; 4052a47d0d45SMatthew G. Knepley 4053a47d0d45SMatthew G. Knepley PetscFunctionBegin; 4054b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 40551edcf0b2SVaclav Hapla ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 40562c71b3e2SJacob Faibussowitsch PetscCheckFalse(vStart < 0 || vEnd < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "DM is not set up properly. DMPlexBuildFromCellList() should be called first."); 40579596c6baSMatthew G. Knepley ierr = DMSetCoordinateDim(dm, spaceDim);CHKERRQ(ierr); 4058a47d0d45SMatthew G. Knepley ierr = PetscSFGetGraph(sfVert, &numVertices, &numVerticesAdj, NULL, NULL);CHKERRQ(ierr); 40592c71b3e2SJacob Faibussowitsch PetscCheckFalse(vEnd - vStart != numVerticesAdj,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Supplied sfVert has wrong number of leaves = %D != %D = vEnd - vStart",numVerticesAdj,vEnd - vStart); 4060a47d0d45SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 4061a47d0d45SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 4062a47d0d45SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, spaceDim);CHKERRQ(ierr); 40631edcf0b2SVaclav Hapla ierr = PetscSectionSetChart(coordSection, vStart, vEnd);CHKERRQ(ierr); 40641edcf0b2SVaclav Hapla for (v = vStart; v < vEnd; ++v) { 4065a47d0d45SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, spaceDim);CHKERRQ(ierr); 4066a47d0d45SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, spaceDim);CHKERRQ(ierr); 4067a47d0d45SMatthew G. Knepley } 4068a47d0d45SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 4069a47d0d45SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 4070a47d0d45SMatthew G. Knepley ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinates);CHKERRQ(ierr); 4071a47d0d45SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, spaceDim);CHKERRQ(ierr); 4072a47d0d45SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 4073a47d0d45SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 4074a47d0d45SMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 4075a47d0d45SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 4076a47d0d45SMatthew G. Knepley { 4077a47d0d45SMatthew G. Knepley MPI_Datatype coordtype; 4078a47d0d45SMatthew G. Knepley 4079a47d0d45SMatthew G. Knepley /* Need a temp buffer for coords if we have complex/single */ 4080ffc4695bSBarry Smith ierr = MPI_Type_contiguous(spaceDim, MPIU_SCALAR, &coordtype);CHKERRMPI(ierr); 4081ffc4695bSBarry Smith ierr = MPI_Type_commit(&coordtype);CHKERRMPI(ierr); 408221016a8bSBarry Smith #if defined(PETSC_USE_COMPLEX) 408321016a8bSBarry Smith { 408421016a8bSBarry Smith PetscScalar *svertexCoords; 408521016a8bSBarry Smith PetscInt i; 40863612f820SVaclav Hapla ierr = PetscMalloc1(numVertices*spaceDim,&svertexCoords);CHKERRQ(ierr); 40873612f820SVaclav Hapla for (i=0; i<numVertices*spaceDim; i++) svertexCoords[i] = vertexCoords[i]; 4088ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sfVert, coordtype, svertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 4089ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sfVert, coordtype, svertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 409021016a8bSBarry Smith ierr = PetscFree(svertexCoords);CHKERRQ(ierr); 409121016a8bSBarry Smith } 409221016a8bSBarry Smith #else 4093ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sfVert, coordtype, vertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 4094ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sfVert, coordtype, vertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 409521016a8bSBarry Smith #endif 4096ffc4695bSBarry Smith ierr = MPI_Type_free(&coordtype);CHKERRMPI(ierr); 4097a47d0d45SMatthew G. Knepley } 4098a47d0d45SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 4099a47d0d45SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 4100a47d0d45SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 4101b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 4102a47d0d45SMatthew G. Knepley PetscFunctionReturn(0); 4103a47d0d45SMatthew G. Knepley } 4104a47d0d45SMatthew G. Knepley 4105c3edce3dSSatish Balay /*@ 4106b09969d6SVaclav Hapla DMPlexCreateFromCellListParallelPetsc - Create distributed DMPLEX from a list of vertices for each cell (common mesh generator output) 4107a47d0d45SMatthew G. Knepley 4108a47d0d45SMatthew G. Knepley Input Parameters: 4109a47d0d45SMatthew G. Knepley + comm - The communicator 4110a47d0d45SMatthew G. Knepley . dim - The topological dimension of the mesh 4111a47d0d45SMatthew G. Knepley . numCells - The number of cells owned by this process 411225b6865aSVaclav Hapla . numVertices - The number of vertices owned by this process, or PETSC_DECIDE 411325b6865aSVaclav Hapla . NVertices - The global number of vertices, or PETSC_DECIDE 4114a47d0d45SMatthew G. Knepley . numCorners - The number of vertices for each cell 4115a47d0d45SMatthew G. Knepley . interpolate - Flag indicating that intermediate mesh entities (faces, edges) should be created automatically 4116a47d0d45SMatthew G. Knepley . cells - An array of numCells*numCorners numbers, the global vertex numbers for each cell 4117a47d0d45SMatthew G. Knepley . spaceDim - The spatial dimension used for coordinates 4118a47d0d45SMatthew G. Knepley - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 4119a47d0d45SMatthew G. Knepley 4120d8d19677SJose E. Roman Output Parameters: 412118d54ad4SMichael Lange + dm - The DM 4122be8c289dSNicolas Barral . vertexSF - (Optional) SF describing complete vertex ownership 4123be8c289dSNicolas Barral - verticesAdjSaved - (Optional) vertex adjacency array 4124a47d0d45SMatthew G. Knepley 4125b09969d6SVaclav Hapla Notes: 4126b09969d6SVaclav Hapla This function is just a convenient sequence of DMCreate(), DMSetType(), DMSetDimension(), 4127b09969d6SVaclav Hapla DMPlexBuildFromCellListParallel(), DMPlexInterpolate(), DMPlexBuildCoordinatesFromCellListParallel() 4128a47d0d45SMatthew G. Knepley 412925b6865aSVaclav Hapla See DMPlexBuildFromCellListParallel() for an example and details about the topology-related parameters. 413025b6865aSVaclav Hapla See DMPlexBuildCoordinatesFromCellListParallel() for details about the geometry-related parameters. 413125b6865aSVaclav Hapla 4132b09969d6SVaclav Hapla Level: intermediate 4133a47d0d45SMatthew G. Knepley 4134b09969d6SVaclav Hapla .seealso: DMPlexCreateFromCellListPetsc(), DMPlexBuildFromCellListParallel(), DMPlexBuildCoordinatesFromCellListParallel(), DMPlexCreateFromDAG(), DMPlexCreate() 4135a47d0d45SMatthew G. Knepley @*/ 4136be8c289dSNicolas Barral 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, PetscInt **verticesAdj, DM *dm) 4137a47d0d45SMatthew G. Knepley { 4138a47d0d45SMatthew G. Knepley PetscSF sfVert; 4139a47d0d45SMatthew G. Knepley PetscErrorCode ierr; 4140a47d0d45SMatthew G. Knepley 4141a47d0d45SMatthew G. Knepley PetscFunctionBegin; 4142a47d0d45SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 4143a47d0d45SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 4144a47d0d45SMatthew G. Knepley PetscValidLogicalCollectiveInt(*dm, dim, 2); 4145064a246eSJacob Faibussowitsch PetscValidLogicalCollectiveInt(*dm, spaceDim, 9); 4146a47d0d45SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 4147be8c289dSNicolas Barral ierr = DMPlexBuildFromCellListParallel(*dm, numCells, numVertices, NVertices, numCorners, cells, &sfVert, verticesAdj);CHKERRQ(ierr); 4148a47d0d45SMatthew G. Knepley if (interpolate) { 41495fd9971aSMatthew G. Knepley DM idm; 4150a47d0d45SMatthew G. Knepley 4151a47d0d45SMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 4152a47d0d45SMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 4153a47d0d45SMatthew G. Knepley *dm = idm; 4154a47d0d45SMatthew G. Knepley } 41551edcf0b2SVaclav Hapla ierr = DMPlexBuildCoordinatesFromCellListParallel(*dm, spaceDim, sfVert, vertexCoords);CHKERRQ(ierr); 415618d54ad4SMichael Lange if (vertexSF) *vertexSF = sfVert; 4157fba955ccSBarry Smith else {ierr = PetscSFDestroy(&sfVert);CHKERRQ(ierr);} 4158a47d0d45SMatthew G. Knepley PetscFunctionReturn(0); 4159a47d0d45SMatthew G. Knepley } 4160a47d0d45SMatthew G. Knepley 4161a4a685f2SJacob Faibussowitsch /*@ 4162a4a685f2SJacob Faibussowitsch DMPlexCreateFromCellListParallel - Deprecated, use DMPlexCreateFromCellListParallelPetsc() 4163a4a685f2SJacob Faibussowitsch 4164a4a685f2SJacob Faibussowitsch Level: deprecated 4165a4a685f2SJacob Faibussowitsch 4166a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromCellListParallelPetsc() 4167a4a685f2SJacob Faibussowitsch @*/ 4168a4a685f2SJacob 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) 4169a4a685f2SJacob Faibussowitsch { 4170a4a685f2SJacob Faibussowitsch PetscErrorCode ierr; 4171a4a685f2SJacob Faibussowitsch PetscInt i; 4172a4a685f2SJacob Faibussowitsch PetscInt *pintCells; 4173a4a685f2SJacob Faibussowitsch 4174a4a685f2SJacob Faibussowitsch PetscFunctionBegin; 41752c71b3e2SJacob Faibussowitsch PetscCheckFalse(sizeof(int) > sizeof(PetscInt),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)); 4176a4a685f2SJacob Faibussowitsch if (sizeof(int) == sizeof(PetscInt)) { 4177a4a685f2SJacob Faibussowitsch pintCells = (PetscInt *) cells; 4178a4a685f2SJacob Faibussowitsch } else { 4179a4a685f2SJacob Faibussowitsch ierr = PetscMalloc1(numCells*numCorners, &pintCells);CHKERRQ(ierr); 4180a4a685f2SJacob Faibussowitsch for (i = 0; i < numCells*numCorners; i++) { 4181a4a685f2SJacob Faibussowitsch pintCells[i] = (PetscInt) cells[i]; 4182a4a685f2SJacob Faibussowitsch } 4183a4a685f2SJacob Faibussowitsch } 4184be8c289dSNicolas Barral ierr = DMPlexCreateFromCellListParallelPetsc(comm, dim, numCells, numVertices, PETSC_DECIDE, numCorners, interpolate, pintCells, spaceDim, vertexCoords, vertexSF, NULL, dm);CHKERRQ(ierr); 4185a4a685f2SJacob Faibussowitsch if (sizeof(int) != sizeof(PetscInt)) { 4186a4a685f2SJacob Faibussowitsch ierr = PetscFree(pintCells);CHKERRQ(ierr); 4187a4a685f2SJacob Faibussowitsch } 4188a4a685f2SJacob Faibussowitsch PetscFunctionReturn(0); 4189a4a685f2SJacob Faibussowitsch } 4190a4a685f2SJacob Faibussowitsch 4191b09969d6SVaclav Hapla /*@C 4192b09969d6SVaclav Hapla DMPlexBuildFromCellList - Build DMPLEX topology from a list of vertices for each cell (common mesh generator output) 41939298eaa6SMatthew G Knepley 41949298eaa6SMatthew G Knepley Input Parameters: 4195b09969d6SVaclav Hapla + dm - The DM 4196b09969d6SVaclav Hapla . numCells - The number of cells owned by this process 4197325d53feSBarry Smith . numVertices - The number of vertices owned by this process, or PETSC_DETERMINE 41989298eaa6SMatthew G Knepley . numCorners - The number of vertices for each cell 41995e488331SVaclav Hapla - cells - An array of numCells*numCorners numbers, the global vertex numbers for each cell 42009298eaa6SMatthew G Knepley 4201b09969d6SVaclav Hapla Level: advanced 42029298eaa6SMatthew G Knepley 4203b09969d6SVaclav Hapla Notes: 4204b09969d6SVaclav Hapla Two triangles sharing a face 42059298eaa6SMatthew G Knepley $ 42069298eaa6SMatthew G Knepley $ 2 42079298eaa6SMatthew G Knepley $ / | \ 42089298eaa6SMatthew G Knepley $ / | \ 42099298eaa6SMatthew G Knepley $ / | \ 42109298eaa6SMatthew G Knepley $ 0 0 | 1 3 42119298eaa6SMatthew G Knepley $ \ | / 42129298eaa6SMatthew G Knepley $ \ | / 42139298eaa6SMatthew G Knepley $ \ | / 42149298eaa6SMatthew G Knepley $ 1 42159298eaa6SMatthew G Knepley would have input 42169298eaa6SMatthew G Knepley $ numCells = 2, numVertices = 4 42179298eaa6SMatthew G Knepley $ cells = [0 1 2 1 3 2] 42189298eaa6SMatthew G Knepley $ 42199298eaa6SMatthew G Knepley which would result in the DMPlex 42209298eaa6SMatthew G Knepley $ 42219298eaa6SMatthew G Knepley $ 4 42229298eaa6SMatthew G Knepley $ / | \ 42239298eaa6SMatthew G Knepley $ / | \ 42249298eaa6SMatthew G Knepley $ / | \ 42259298eaa6SMatthew G Knepley $ 2 0 | 1 5 42269298eaa6SMatthew G Knepley $ \ | / 42279298eaa6SMatthew G Knepley $ \ | / 42289298eaa6SMatthew G Knepley $ \ | / 42299298eaa6SMatthew G Knepley $ 3 42309298eaa6SMatthew G Knepley 4231325d53feSBarry Smith If numVertices is PETSC_DETERMINE, it is computed by PETSc as the maximum vertex index in cells + 1. 423225b6865aSVaclav Hapla 4233b09969d6SVaclav Hapla Not currently supported in Fortran. 42349298eaa6SMatthew G Knepley 4235b09969d6SVaclav Hapla .seealso: DMPlexBuildFromCellListParallel(), DMPlexBuildCoordinatesFromCellList(), DMPlexCreateFromCellListPetsc() 4236b09969d6SVaclav Hapla @*/ 42375e488331SVaclav Hapla PetscErrorCode DMPlexBuildFromCellList(DM dm, PetscInt numCells, PetscInt numVertices, PetscInt numCorners, const PetscInt cells[]) 4238b09969d6SVaclav Hapla { 4239961cfab0SVaclav Hapla PetscInt *cones, c, p, dim; 4240b09969d6SVaclav Hapla PetscErrorCode ierr; 4241b09969d6SVaclav Hapla 4242b09969d6SVaclav Hapla PetscFunctionBegin; 4243b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 4244b09969d6SVaclav Hapla ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 424525b6865aSVaclav Hapla /* Get/check global number of vertices */ 424625b6865aSVaclav Hapla { 424725b6865aSVaclav Hapla PetscInt NVerticesInCells, i; 424825b6865aSVaclav Hapla const PetscInt len = numCells * numCorners; 424925b6865aSVaclav Hapla 425025b6865aSVaclav Hapla /* NVerticesInCells = max(cells) + 1 */ 425125b6865aSVaclav Hapla NVerticesInCells = PETSC_MIN_INT; 425225b6865aSVaclav Hapla for (i=0; i<len; i++) if (cells[i] > NVerticesInCells) NVerticesInCells = cells[i]; 425325b6865aSVaclav Hapla ++NVerticesInCells; 425425b6865aSVaclav Hapla 425525b6865aSVaclav Hapla if (numVertices == PETSC_DECIDE) numVertices = NVerticesInCells; 42562c71b3e2SJacob Faibussowitsch else PetscCheckFalse(numVertices < NVerticesInCells,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); 425725b6865aSVaclav Hapla } 4258b09969d6SVaclav Hapla ierr = DMPlexSetChart(dm, 0, numCells+numVertices);CHKERRQ(ierr); 4259b09969d6SVaclav Hapla for (c = 0; c < numCells; ++c) { 4260b09969d6SVaclav Hapla ierr = DMPlexSetConeSize(dm, c, numCorners);CHKERRQ(ierr); 4261b09969d6SVaclav Hapla } 4262b09969d6SVaclav Hapla ierr = DMSetUp(dm);CHKERRQ(ierr); 4263961cfab0SVaclav Hapla ierr = DMPlexGetCones(dm,&cones);CHKERRQ(ierr); 4264b09969d6SVaclav Hapla for (c = 0; c < numCells; ++c) { 4265b09969d6SVaclav Hapla for (p = 0; p < numCorners; ++p) { 4266961cfab0SVaclav Hapla cones[c*numCorners+p] = cells[c*numCorners+p]+numCells; 4267b09969d6SVaclav Hapla } 4268b09969d6SVaclav Hapla } 4269b09969d6SVaclav Hapla ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 4270b09969d6SVaclav Hapla ierr = DMPlexStratify(dm);CHKERRQ(ierr); 4271b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 4272b09969d6SVaclav Hapla PetscFunctionReturn(0); 4273b09969d6SVaclav Hapla } 4274b09969d6SVaclav Hapla 4275b09969d6SVaclav Hapla /*@C 4276b09969d6SVaclav Hapla DMPlexBuildCoordinatesFromCellList - Build DM coordinates from a list of coordinates for each owned vertex (common mesh generator output) 4277b09969d6SVaclav Hapla 4278b09969d6SVaclav Hapla Input Parameters: 4279b09969d6SVaclav Hapla + dm - The DM 4280b09969d6SVaclav Hapla . spaceDim - The spatial dimension used for coordinates 4281b09969d6SVaclav Hapla - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 4282b09969d6SVaclav Hapla 4283b09969d6SVaclav Hapla Level: advanced 4284b09969d6SVaclav Hapla 4285b09969d6SVaclav Hapla Notes: 4286b09969d6SVaclav Hapla Not currently supported in Fortran. 4287b09969d6SVaclav Hapla 4288b09969d6SVaclav Hapla .seealso: DMPlexBuildCoordinatesFromCellListParallel(), DMPlexCreateFromCellListPetsc(), DMPlexBuildFromCellList() 4289b09969d6SVaclav Hapla @*/ 42901edcf0b2SVaclav Hapla PetscErrorCode DMPlexBuildCoordinatesFromCellList(DM dm, PetscInt spaceDim, const PetscReal vertexCoords[]) 4291b09969d6SVaclav Hapla { 4292b09969d6SVaclav Hapla PetscSection coordSection; 4293b09969d6SVaclav Hapla Vec coordinates; 4294b09969d6SVaclav Hapla DM cdm; 4295b09969d6SVaclav Hapla PetscScalar *coords; 42961edcf0b2SVaclav Hapla PetscInt v, vStart, vEnd, d; 4297b09969d6SVaclav Hapla PetscErrorCode ierr; 4298b09969d6SVaclav Hapla 4299b09969d6SVaclav Hapla PetscFunctionBegin; 4300b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 43011edcf0b2SVaclav Hapla ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 43022c71b3e2SJacob Faibussowitsch PetscCheckFalse(vStart < 0 || vEnd < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "DM is not set up properly. DMPlexBuildFromCellList() should be called first."); 4303b09969d6SVaclav Hapla ierr = DMSetCoordinateDim(dm, spaceDim);CHKERRQ(ierr); 4304b09969d6SVaclav Hapla ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 4305b09969d6SVaclav Hapla ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 4306b09969d6SVaclav Hapla ierr = PetscSectionSetFieldComponents(coordSection, 0, spaceDim);CHKERRQ(ierr); 43071edcf0b2SVaclav Hapla ierr = PetscSectionSetChart(coordSection, vStart, vEnd);CHKERRQ(ierr); 43081edcf0b2SVaclav Hapla for (v = vStart; v < vEnd; ++v) { 4309b09969d6SVaclav Hapla ierr = PetscSectionSetDof(coordSection, v, spaceDim);CHKERRQ(ierr); 4310b09969d6SVaclav Hapla ierr = PetscSectionSetFieldDof(coordSection, v, 0, spaceDim);CHKERRQ(ierr); 4311b09969d6SVaclav Hapla } 4312b09969d6SVaclav Hapla ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 4313b09969d6SVaclav Hapla 4314b09969d6SVaclav Hapla ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 4315b09969d6SVaclav Hapla ierr = DMCreateLocalVector(cdm, &coordinates);CHKERRQ(ierr); 4316b09969d6SVaclav Hapla ierr = VecSetBlockSize(coordinates, spaceDim);CHKERRQ(ierr); 4317b09969d6SVaclav Hapla ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 431899946890SBarry Smith ierr = VecGetArrayWrite(coordinates, &coords);CHKERRQ(ierr); 43191edcf0b2SVaclav Hapla for (v = 0; v < vEnd-vStart; ++v) { 4320b09969d6SVaclav Hapla for (d = 0; d < spaceDim; ++d) { 4321b09969d6SVaclav Hapla coords[v*spaceDim+d] = vertexCoords[v*spaceDim+d]; 4322b09969d6SVaclav Hapla } 4323b09969d6SVaclav Hapla } 432499946890SBarry Smith ierr = VecRestoreArrayWrite(coordinates, &coords);CHKERRQ(ierr); 4325b09969d6SVaclav Hapla ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 4326b09969d6SVaclav Hapla ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 4327b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 4328b09969d6SVaclav Hapla PetscFunctionReturn(0); 4329b09969d6SVaclav Hapla } 4330b09969d6SVaclav Hapla 4331b09969d6SVaclav Hapla /*@ 43323df08285SMatthew G. Knepley DMPlexCreateFromCellListPetsc - Create DMPLEX from a list of vertices for each cell (common mesh generator output), but only process 0 takes in the input 43333df08285SMatthew G. Knepley 43343df08285SMatthew G. Knepley Collective on comm 4335b09969d6SVaclav Hapla 4336b09969d6SVaclav Hapla Input Parameters: 4337b09969d6SVaclav Hapla + comm - The communicator 4338b09969d6SVaclav Hapla . dim - The topological dimension of the mesh 43393df08285SMatthew G. Knepley . numCells - The number of cells, only on process 0 43403df08285SMatthew G. Knepley . numVertices - The number of vertices owned by this process, or PETSC_DECIDE, only on process 0 43413df08285SMatthew G. Knepley . numCorners - The number of vertices for each cell, only on process 0 4342b09969d6SVaclav Hapla . interpolate - Flag indicating that intermediate mesh entities (faces, edges) should be created automatically 43433df08285SMatthew G. Knepley . cells - An array of numCells*numCorners numbers, the vertices for each cell, only on process 0 4344b09969d6SVaclav Hapla . spaceDim - The spatial dimension used for coordinates 43453df08285SMatthew G. Knepley - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex, only on process 0 4346b09969d6SVaclav Hapla 4347b09969d6SVaclav Hapla Output Parameter: 43483df08285SMatthew G. Knepley . dm - The DM, which only has points on process 0 4349b09969d6SVaclav Hapla 4350b09969d6SVaclav Hapla Notes: 4351b09969d6SVaclav Hapla This function is just a convenient sequence of DMCreate(), DMSetType(), DMSetDimension(), DMPlexBuildFromCellList(), 4352b09969d6SVaclav Hapla DMPlexInterpolate(), DMPlexBuildCoordinatesFromCellList() 4353b09969d6SVaclav Hapla 435425b6865aSVaclav Hapla See DMPlexBuildFromCellList() for an example and details about the topology-related parameters. 435525b6865aSVaclav Hapla See DMPlexBuildCoordinatesFromCellList() for details about the geometry-related parameters. 43563df08285SMatthew G. Knepley See DMPlexCreateFromCellListParallelPetsc() for parallel input 435725b6865aSVaclav Hapla 4358b09969d6SVaclav Hapla Level: intermediate 4359b09969d6SVaclav Hapla 4360b09969d6SVaclav Hapla .seealso: DMPlexCreateFromCellListParallelPetsc(), DMPlexBuildFromCellList(), DMPlexBuildCoordinatesFromCellList(), DMPlexCreateFromDAG(), DMPlexCreate() 43619298eaa6SMatthew G Knepley @*/ 4362a4a685f2SJacob 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) 43639298eaa6SMatthew G Knepley { 43643df08285SMatthew G. Knepley PetscMPIInt rank; 43659298eaa6SMatthew G Knepley PetscErrorCode ierr; 43669298eaa6SMatthew G Knepley 43679298eaa6SMatthew G Knepley PetscFunctionBegin; 43682c71b3e2SJacob Faibussowitsch PetscCheckFalse(!dim,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."); 43693df08285SMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 43709298eaa6SMatthew G Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 43719298eaa6SMatthew G Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 4372c73cfb54SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 43733df08285SMatthew G. Knepley if (!rank) {ierr = DMPlexBuildFromCellList(*dm, numCells, numVertices, numCorners, cells);CHKERRQ(ierr);} 43743df08285SMatthew G. Knepley else {ierr = DMPlexBuildFromCellList(*dm, 0, 0, 0, NULL);CHKERRQ(ierr);} 43759298eaa6SMatthew G Knepley if (interpolate) { 43765fd9971aSMatthew G. Knepley DM idm; 43779298eaa6SMatthew G Knepley 43789298eaa6SMatthew G Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 43799298eaa6SMatthew G Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 43809298eaa6SMatthew G Knepley *dm = idm; 43819298eaa6SMatthew G Knepley } 43823df08285SMatthew G. Knepley if (!rank) {ierr = DMPlexBuildCoordinatesFromCellList(*dm, spaceDim, vertexCoords);CHKERRQ(ierr);} 43833df08285SMatthew G. Knepley else {ierr = DMPlexBuildCoordinatesFromCellList(*dm, spaceDim, NULL);CHKERRQ(ierr);} 43849298eaa6SMatthew G Knepley PetscFunctionReturn(0); 43859298eaa6SMatthew G Knepley } 43869298eaa6SMatthew G Knepley 4387939f6067SMatthew G. Knepley /*@ 4388a4a685f2SJacob Faibussowitsch DMPlexCreateFromCellList - Deprecated, use DMPlexCreateFromCellListPetsc() 4389a4a685f2SJacob Faibussowitsch 4390a4a685f2SJacob Faibussowitsch Level: deprecated 4391a4a685f2SJacob Faibussowitsch 4392a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromCellListPetsc() 4393a4a685f2SJacob Faibussowitsch @*/ 4394a4a685f2SJacob 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) 4395a4a685f2SJacob Faibussowitsch { 4396a4a685f2SJacob Faibussowitsch PetscErrorCode ierr; 4397a4a685f2SJacob Faibussowitsch PetscInt i; 4398a4a685f2SJacob Faibussowitsch PetscInt *pintCells; 4399a4a685f2SJacob Faibussowitsch PetscReal *prealVC; 4400a4a685f2SJacob Faibussowitsch 4401a4a685f2SJacob Faibussowitsch PetscFunctionBegin; 44022c71b3e2SJacob Faibussowitsch PetscCheckFalse(sizeof(int) > sizeof(PetscInt),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)); 4403a4a685f2SJacob Faibussowitsch if (sizeof(int) == sizeof(PetscInt)) { 4404a4a685f2SJacob Faibussowitsch pintCells = (PetscInt *) cells; 4405a4a685f2SJacob Faibussowitsch } else { 4406a4a685f2SJacob Faibussowitsch ierr = PetscMalloc1(numCells*numCorners, &pintCells);CHKERRQ(ierr); 4407a4a685f2SJacob Faibussowitsch for (i = 0; i < numCells*numCorners; i++) { 4408a4a685f2SJacob Faibussowitsch pintCells[i] = (PetscInt) cells[i]; 4409a4a685f2SJacob Faibussowitsch } 4410a4a685f2SJacob Faibussowitsch } 44112c71b3e2SJacob Faibussowitsch PetscCheckFalse(sizeof(double) > sizeof(PetscReal),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)); 4412a4a685f2SJacob Faibussowitsch if (sizeof(double) == sizeof(PetscReal)) { 4413a4a685f2SJacob Faibussowitsch prealVC = (PetscReal *) vertexCoords; 4414a4a685f2SJacob Faibussowitsch } else { 4415a4a685f2SJacob Faibussowitsch ierr = PetscMalloc1(numVertices*spaceDim, &prealVC);CHKERRQ(ierr); 4416a4a685f2SJacob Faibussowitsch for (i = 0; i < numVertices*spaceDim; i++) { 4417a4a685f2SJacob Faibussowitsch prealVC[i] = (PetscReal) vertexCoords[i]; 4418a4a685f2SJacob Faibussowitsch } 4419a4a685f2SJacob Faibussowitsch } 4420a4a685f2SJacob Faibussowitsch ierr = DMPlexCreateFromCellListPetsc(comm, dim, numCells, numVertices, numCorners, interpolate, pintCells, spaceDim, prealVC, dm);CHKERRQ(ierr); 4421a4a685f2SJacob Faibussowitsch if (sizeof(int) != sizeof(PetscInt)) { 4422a4a685f2SJacob Faibussowitsch ierr = PetscFree(pintCells);CHKERRQ(ierr); 4423a4a685f2SJacob Faibussowitsch } 4424a4a685f2SJacob Faibussowitsch if (sizeof(double) != sizeof(PetscReal)) { 4425a4a685f2SJacob Faibussowitsch ierr = PetscFree(prealVC);CHKERRQ(ierr); 4426a4a685f2SJacob Faibussowitsch } 4427a4a685f2SJacob Faibussowitsch PetscFunctionReturn(0); 4428a4a685f2SJacob Faibussowitsch } 4429a4a685f2SJacob Faibussowitsch 4430a4a685f2SJacob Faibussowitsch /*@ 4431939f6067SMatthew 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 4432939f6067SMatthew G. Knepley 4433939f6067SMatthew G. Knepley Input Parameters: 4434c73cfb54SMatthew G. Knepley + dm - The empty DM object, usually from DMCreate() and DMSetDimension() 4435939f6067SMatthew G. Knepley . depth - The depth of the DAG 4436367003a6SStefano Zampini . numPoints - Array of size depth + 1 containing the number of points at each depth 4437939f6067SMatthew G. Knepley . coneSize - The cone size of each point 4438939f6067SMatthew G. Knepley . cones - The concatenation of the cone points for each point, the cone list must be oriented correctly for each point 4439939f6067SMatthew G. Knepley . coneOrientations - The orientation of each cone point 4440367003a6SStefano Zampini - vertexCoords - An array of numPoints[0]*spacedim numbers representing the coordinates of each vertex, with spacedim the value set via DMSetCoordinateDim() 4441939f6067SMatthew G. Knepley 4442939f6067SMatthew G. Knepley Output Parameter: 4443939f6067SMatthew G. Knepley . dm - The DM 4444939f6067SMatthew G. Knepley 4445939f6067SMatthew G. Knepley Note: Two triangles sharing a face would have input 4446939f6067SMatthew G. Knepley $ depth = 1, numPoints = [4 2], coneSize = [3 3 0 0 0 0] 4447939f6067SMatthew G. Knepley $ cones = [2 3 4 3 5 4], coneOrientations = [0 0 0 0 0 0] 4448939f6067SMatthew G. Knepley $ vertexCoords = [-1.0 0.0 0.0 -1.0 0.0 1.0 1.0 0.0] 4449939f6067SMatthew G. Knepley $ 4450939f6067SMatthew G. Knepley which would result in the DMPlex 4451939f6067SMatthew G. Knepley $ 4452939f6067SMatthew G. Knepley $ 4 4453939f6067SMatthew G. Knepley $ / | \ 4454939f6067SMatthew G. Knepley $ / | \ 4455939f6067SMatthew G. Knepley $ / | \ 4456939f6067SMatthew G. Knepley $ 2 0 | 1 5 4457939f6067SMatthew G. Knepley $ \ | / 4458939f6067SMatthew G. Knepley $ \ | / 4459939f6067SMatthew G. Knepley $ \ | / 4460939f6067SMatthew G. Knepley $ 3 4461939f6067SMatthew G. Knepley $ 4462a4a685f2SJacob Faibussowitsch $ Notice that all points are numbered consecutively, unlike DMPlexCreateFromCellListPetsc() 4463939f6067SMatthew G. Knepley 4464939f6067SMatthew G. Knepley Level: advanced 4465939f6067SMatthew G. Knepley 4466a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromCellListPetsc(), DMPlexCreate() 4467939f6067SMatthew G. Knepley @*/ 44689298eaa6SMatthew G Knepley PetscErrorCode DMPlexCreateFromDAG(DM dm, PetscInt depth, const PetscInt numPoints[], const PetscInt coneSize[], const PetscInt cones[], const PetscInt coneOrientations[], const PetscScalar vertexCoords[]) 44699298eaa6SMatthew G Knepley { 44709298eaa6SMatthew G Knepley Vec coordinates; 44719298eaa6SMatthew G Knepley PetscSection coordSection; 44729298eaa6SMatthew G Knepley PetscScalar *coords; 4473811e8653SToby Isaac PetscInt coordSize, firstVertex = -1, pStart = 0, pEnd = 0, p, v, dim, dimEmbed, d, off; 44749298eaa6SMatthew G Knepley PetscErrorCode ierr; 44759298eaa6SMatthew G Knepley 44769298eaa6SMatthew G Knepley PetscFunctionBegin; 4477c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 4478811e8653SToby Isaac ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr); 44792c71b3e2SJacob Faibussowitsch PetscCheckFalse(dimEmbed < dim,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Embedding dimension %D cannot be less than intrinsic dimension %d",dimEmbed,dim); 44809298eaa6SMatthew G Knepley for (d = 0; d <= depth; ++d) pEnd += numPoints[d]; 44819298eaa6SMatthew G Knepley ierr = DMPlexSetChart(dm, pStart, pEnd);CHKERRQ(ierr); 44829298eaa6SMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 44839298eaa6SMatthew G Knepley ierr = DMPlexSetConeSize(dm, p, coneSize[p-pStart]);CHKERRQ(ierr); 448497e052ccSToby Isaac if (firstVertex < 0 && !coneSize[p - pStart]) { 448597e052ccSToby Isaac firstVertex = p - pStart; 44869298eaa6SMatthew G Knepley } 448797e052ccSToby Isaac } 44882c71b3e2SJacob Faibussowitsch PetscCheckFalse(firstVertex < 0 && numPoints[0],PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Expected %D vertices but could not find any", numPoints[0]); 44899298eaa6SMatthew G Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 44909298eaa6SMatthew G Knepley for (p = pStart, off = 0; p < pEnd; off += coneSize[p-pStart], ++p) { 44919298eaa6SMatthew G Knepley ierr = DMPlexSetCone(dm, p, &cones[off]);CHKERRQ(ierr); 44929298eaa6SMatthew G Knepley ierr = DMPlexSetConeOrientation(dm, p, &coneOrientations[off]);CHKERRQ(ierr); 44939298eaa6SMatthew G Knepley } 44949298eaa6SMatthew G Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 44959298eaa6SMatthew G Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 44969298eaa6SMatthew G Knepley /* Build coordinates */ 4497c2166f76SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 44989298eaa6SMatthew G Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 4499811e8653SToby Isaac ierr = PetscSectionSetFieldComponents(coordSection, 0, dimEmbed);CHKERRQ(ierr); 45009298eaa6SMatthew G Knepley ierr = PetscSectionSetChart(coordSection, firstVertex, firstVertex+numPoints[0]);CHKERRQ(ierr); 45019298eaa6SMatthew G Knepley for (v = firstVertex; v < firstVertex+numPoints[0]; ++v) { 4502811e8653SToby Isaac ierr = PetscSectionSetDof(coordSection, v, dimEmbed);CHKERRQ(ierr); 4503811e8653SToby Isaac ierr = PetscSectionSetFieldDof(coordSection, v, 0, dimEmbed);CHKERRQ(ierr); 45049298eaa6SMatthew G Knepley } 45059298eaa6SMatthew G Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 45069298eaa6SMatthew G Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 45078b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 45086f8cbbeeSMatthew G Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 45099298eaa6SMatthew G Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 45108b9ced59SLisandro Dalcin ierr = VecSetBlockSize(coordinates, dimEmbed);CHKERRQ(ierr); 45112eb5907fSJed Brown ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 45129318fe57SMatthew G. Knepley if (vertexCoords) { 45139298eaa6SMatthew G Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 45149298eaa6SMatthew G Knepley for (v = 0; v < numPoints[0]; ++v) { 45159298eaa6SMatthew G Knepley PetscInt off; 45169298eaa6SMatthew G Knepley 45179298eaa6SMatthew G Knepley ierr = PetscSectionGetOffset(coordSection, v+firstVertex, &off);CHKERRQ(ierr); 4518811e8653SToby Isaac for (d = 0; d < dimEmbed; ++d) { 4519811e8653SToby Isaac coords[off+d] = vertexCoords[v*dimEmbed+d]; 45209298eaa6SMatthew G Knepley } 45219298eaa6SMatthew G Knepley } 45229318fe57SMatthew G. Knepley } 45239298eaa6SMatthew G Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 45249298eaa6SMatthew G Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 45259298eaa6SMatthew G Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 45269298eaa6SMatthew G Knepley PetscFunctionReturn(0); 45279298eaa6SMatthew G Knepley } 45288415267dSToby Isaac 4529ca522641SMatthew G. Knepley /*@C 45308ca92349SMatthew G. Knepley DMPlexCreateCellVertexFromFile - Create a DMPlex mesh from a simple cell-vertex file. 45318ca92349SMatthew G. Knepley 45328ca92349SMatthew G. Knepley + comm - The MPI communicator 45338ca92349SMatthew G. Knepley . filename - Name of the .dat file 45348ca92349SMatthew G. Knepley - interpolate - Create faces and edges in the mesh 45358ca92349SMatthew G. Knepley 45368ca92349SMatthew G. Knepley Output Parameter: 45378ca92349SMatthew G. Knepley . dm - The DM object representing the mesh 45388ca92349SMatthew G. Knepley 45398ca92349SMatthew G. Knepley Note: The format is the simplest possible: 45408ca92349SMatthew G. Knepley $ Ne 45418ca92349SMatthew G. Knepley $ v0 v1 ... vk 45428ca92349SMatthew G. Knepley $ Nv 45438ca92349SMatthew G. Knepley $ x y z marker 45448ca92349SMatthew G. Knepley 45458ca92349SMatthew G. Knepley Level: beginner 45468ca92349SMatthew G. Knepley 45478ca92349SMatthew G. Knepley .seealso: DMPlexCreateFromFile(), DMPlexCreateMedFromFile(), DMPlexCreateGmsh(), DMPlexCreate() 45488ca92349SMatthew G. Knepley @*/ 45498ca92349SMatthew G. Knepley PetscErrorCode DMPlexCreateCellVertexFromFile(MPI_Comm comm, const char filename[], PetscBool interpolate, DM *dm) 45508ca92349SMatthew G. Knepley { 45518ca92349SMatthew G. Knepley DMLabel marker; 45528ca92349SMatthew G. Knepley PetscViewer viewer; 45538ca92349SMatthew G. Knepley Vec coordinates; 45548ca92349SMatthew G. Knepley PetscSection coordSection; 45558ca92349SMatthew G. Knepley PetscScalar *coords; 45568ca92349SMatthew G. Knepley char line[PETSC_MAX_PATH_LEN]; 45578ca92349SMatthew G. Knepley PetscInt dim = 3, cdim = 3, coordSize, v, c, d; 45588ca92349SMatthew G. Knepley PetscMPIInt rank; 4559f8d5e320SMatthew G. Knepley int snum, Nv, Nc, Ncn, Nl; 45608ca92349SMatthew G. Knepley PetscErrorCode ierr; 45618ca92349SMatthew G. Knepley 45628ca92349SMatthew G. Knepley PetscFunctionBegin; 4563ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 45648ca92349SMatthew G. Knepley ierr = PetscViewerCreate(comm, &viewer);CHKERRQ(ierr); 45658ca92349SMatthew G. Knepley ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr); 45668ca92349SMatthew G. Knepley ierr = PetscViewerFileSetMode(viewer, FILE_MODE_READ);CHKERRQ(ierr); 45678ca92349SMatthew G. Knepley ierr = PetscViewerFileSetName(viewer, filename);CHKERRQ(ierr); 4568dd400576SPatrick Sanan if (rank == 0) { 4569f8d5e320SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 4, NULL, PETSC_STRING);CHKERRQ(ierr); 4570f8d5e320SMatthew G. Knepley snum = sscanf(line, "%d %d %d %d", &Nc, &Nv, &Ncn, &Nl); 45712c71b3e2SJacob Faibussowitsch PetscCheckFalse(snum != 4,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 457225ce1634SJed Brown } else { 4573f8d5e320SMatthew G. Knepley Nc = Nv = Ncn = Nl = 0; 45748ca92349SMatthew G. Knepley } 45758ca92349SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 45768ca92349SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 45778ca92349SMatthew G. Knepley ierr = DMPlexSetChart(*dm, 0, Nc+Nv);CHKERRQ(ierr); 45788ca92349SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 45798ca92349SMatthew G. Knepley ierr = DMSetCoordinateDim(*dm, cdim);CHKERRQ(ierr); 45808ca92349SMatthew G. Knepley /* Read topology */ 4581dd400576SPatrick Sanan if (rank == 0) { 4582f8d5e320SMatthew G. Knepley char format[PETSC_MAX_PATH_LEN]; 4583f8d5e320SMatthew G. Knepley PetscInt cone[8]; 45848ca92349SMatthew G. Knepley int vbuf[8], v; 45858ca92349SMatthew G. Knepley 4586f8d5e320SMatthew G. Knepley for (c = 0; c < Ncn; ++c) {format[c*3+0] = '%'; format[c*3+1] = 'd'; format[c*3+2] = ' ';} 4587f8d5e320SMatthew G. Knepley format[Ncn*3-1] = '\0'; 4588f8d5e320SMatthew G. Knepley for (c = 0; c < Nc; ++c) {ierr = DMPlexSetConeSize(*dm, c, Ncn);CHKERRQ(ierr);} 45898ca92349SMatthew G. Knepley ierr = DMSetUp(*dm);CHKERRQ(ierr); 45908ca92349SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 4591f8d5e320SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, Ncn, NULL, PETSC_STRING);CHKERRQ(ierr); 4592f8d5e320SMatthew G. Knepley switch (Ncn) { 4593f8d5e320SMatthew G. Knepley case 2: snum = sscanf(line, format, &vbuf[0], &vbuf[1]);break; 4594f8d5e320SMatthew G. Knepley case 3: snum = sscanf(line, format, &vbuf[0], &vbuf[1], &vbuf[2]);break; 4595f8d5e320SMatthew G. Knepley case 4: snum = sscanf(line, format, &vbuf[0], &vbuf[1], &vbuf[2], &vbuf[3]);break; 4596f8d5e320SMatthew G. Knepley case 6: snum = sscanf(line, format, &vbuf[0], &vbuf[1], &vbuf[2], &vbuf[3], &vbuf[4], &vbuf[5]);break; 4597f8d5e320SMatthew G. Knepley case 8: snum = sscanf(line, format, &vbuf[0], &vbuf[1], &vbuf[2], &vbuf[3], &vbuf[4], &vbuf[5], &vbuf[6], &vbuf[7]);break; 459898921bdaSJacob Faibussowitsch default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No cell shape with %D vertices", Ncn); 4599f8d5e320SMatthew G. Knepley } 46002c71b3e2SJacob Faibussowitsch PetscCheckFalse(snum != Ncn,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 4601f8d5e320SMatthew G. Knepley for (v = 0; v < Ncn; ++v) cone[v] = vbuf[v] + Nc; 46028ca92349SMatthew G. Knepley /* Hexahedra are inverted */ 4603f8d5e320SMatthew G. Knepley if (Ncn == 8) { 46048ca92349SMatthew G. Knepley PetscInt tmp = cone[1]; 46058ca92349SMatthew G. Knepley cone[1] = cone[3]; 46068ca92349SMatthew G. Knepley cone[3] = tmp; 46078ca92349SMatthew G. Knepley } 46088ca92349SMatthew G. Knepley ierr = DMPlexSetCone(*dm, c, cone);CHKERRQ(ierr); 46098ca92349SMatthew G. Knepley } 46108ca92349SMatthew G. Knepley } 46118ca92349SMatthew G. Knepley ierr = DMPlexSymmetrize(*dm);CHKERRQ(ierr); 46128ca92349SMatthew G. Knepley ierr = DMPlexStratify(*dm);CHKERRQ(ierr); 46138ca92349SMatthew G. Knepley /* Read coordinates */ 46148ca92349SMatthew G. Knepley ierr = DMGetCoordinateSection(*dm, &coordSection);CHKERRQ(ierr); 46158ca92349SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 46168ca92349SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, cdim);CHKERRQ(ierr); 46178ca92349SMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, Nc, Nc + Nv);CHKERRQ(ierr); 46188ca92349SMatthew G. Knepley for (v = Nc; v < Nc+Nv; ++v) { 46198ca92349SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, cdim);CHKERRQ(ierr); 46208ca92349SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, cdim);CHKERRQ(ierr); 46218ca92349SMatthew G. Knepley } 46228ca92349SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 46238ca92349SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 46248ca92349SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 46258ca92349SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 46268ca92349SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 46278ca92349SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, cdim);CHKERRQ(ierr); 46288ca92349SMatthew G. Knepley ierr = VecSetType(coordinates, VECSTANDARD);CHKERRQ(ierr); 46298ca92349SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 4630dd400576SPatrick Sanan if (rank == 0) { 4631f8d5e320SMatthew G. Knepley char format[PETSC_MAX_PATH_LEN]; 46328ca92349SMatthew G. Knepley double x[3]; 4633f8d5e320SMatthew G. Knepley int l, val[3]; 46348ca92349SMatthew G. Knepley 4635f8d5e320SMatthew G. Knepley if (Nl) { 4636f8d5e320SMatthew G. Knepley for (l = 0; l < Nl; ++l) {format[l*3+0] = '%'; format[l*3+1] = 'd'; format[l*3+2] = ' ';} 4637f8d5e320SMatthew G. Knepley format[Nl*3-1] = '\0'; 46388ca92349SMatthew G. Knepley ierr = DMCreateLabel(*dm, "marker");CHKERRQ(ierr); 46398ca92349SMatthew G. Knepley ierr = DMGetLabel(*dm, "marker", &marker);CHKERRQ(ierr); 4640f8d5e320SMatthew G. Knepley } 46418ca92349SMatthew G. Knepley for (v = 0; v < Nv; ++v) { 4642f8d5e320SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 3+Nl, NULL, PETSC_STRING);CHKERRQ(ierr); 4643f8d5e320SMatthew G. Knepley snum = sscanf(line, "%lg %lg %lg", &x[0], &x[1], &x[2]); 46442c71b3e2SJacob Faibussowitsch PetscCheckFalse(snum != 3,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 4645f8d5e320SMatthew G. Knepley switch (Nl) { 4646f8d5e320SMatthew G. Knepley case 0: snum = 0;break; 4647f8d5e320SMatthew G. Knepley case 1: snum = sscanf(line, format, &val[0]);break; 4648f8d5e320SMatthew G. Knepley case 2: snum = sscanf(line, format, &val[0], &val[1]);break; 4649f8d5e320SMatthew G. Knepley case 3: snum = sscanf(line, format, &val[0], &val[1], &val[2]);break; 465098921bdaSJacob Faibussowitsch default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Request support for %D labels", Nl); 4651f8d5e320SMatthew G. Knepley } 46522c71b3e2SJacob Faibussowitsch PetscCheckFalse(snum != Nl,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 46538ca92349SMatthew G. Knepley for (d = 0; d < cdim; ++d) coords[v*cdim+d] = x[d]; 4654f8d5e320SMatthew G. Knepley for (l = 0; l < Nl; ++l) {ierr = DMLabelSetValue(marker, v+Nc, val[l]);CHKERRQ(ierr);} 46558ca92349SMatthew G. Knepley } 46568ca92349SMatthew G. Knepley } 46578ca92349SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 46588ca92349SMatthew G. Knepley ierr = DMSetCoordinatesLocal(*dm, coordinates);CHKERRQ(ierr); 46598ca92349SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 46608ca92349SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 46618ca92349SMatthew G. Knepley if (interpolate) { 46628ca92349SMatthew G. Knepley DM idm; 46638ca92349SMatthew G. Knepley DMLabel bdlabel; 46648ca92349SMatthew G. Knepley 46658ca92349SMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 46668ca92349SMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 46678ca92349SMatthew G. Knepley *dm = idm; 46688ca92349SMatthew G. Knepley 4669f8d5e320SMatthew G. Knepley if (!Nl) { 4670f8d5e320SMatthew G. Knepley ierr = DMCreateLabel(*dm, "marker");CHKERRQ(ierr); 46718ca92349SMatthew G. Knepley ierr = DMGetLabel(*dm, "marker", &bdlabel);CHKERRQ(ierr); 46728ca92349SMatthew G. Knepley ierr = DMPlexMarkBoundaryFaces(*dm, PETSC_DETERMINE, bdlabel);CHKERRQ(ierr); 46738ca92349SMatthew G. Knepley ierr = DMPlexLabelComplete(*dm, bdlabel);CHKERRQ(ierr); 46748ca92349SMatthew G. Knepley } 4675f8d5e320SMatthew G. Knepley } 46768ca92349SMatthew G. Knepley PetscFunctionReturn(0); 46778ca92349SMatthew G. Knepley } 46788ca92349SMatthew G. Knepley 46798ca92349SMatthew G. Knepley /*@C 4680ca522641SMatthew G. Knepley DMPlexCreateFromFile - This takes a filename and produces a DM 4681ca522641SMatthew G. Knepley 4682ca522641SMatthew G. Knepley Input Parameters: 4683ca522641SMatthew G. Knepley + comm - The communicator 4684ca522641SMatthew G. Knepley . filename - A file name 4685cd7e8a5eSksagiyam . plexname - The object name of the resulting DM, also used for intra-datafile lookup by some formats 4686ca522641SMatthew G. Knepley - interpolate - Flag to create intermediate mesh pieces (edges, faces) 4687ca522641SMatthew G. Knepley 4688ca522641SMatthew G. Knepley Output Parameter: 4689ca522641SMatthew G. Knepley . dm - The DM 4690ca522641SMatthew G. Knepley 469102ef0d99SVaclav Hapla Options Database Keys: 469202ef0d99SVaclav Hapla . -dm_plex_create_from_hdf5_xdmf - use the PETSC_VIEWER_HDF5_XDMF format for reading HDF5 469302ef0d99SVaclav Hapla 4694bca97951SVaclav Hapla Use -dm_plex_create_ prefix to pass options to the internal PetscViewer, e.g. 4695bca97951SVaclav Hapla $ -dm_plex_create_viewer_hdf5_collective 4696bca97951SVaclav Hapla 4697cd7e8a5eSksagiyam Notes: 4698cd7e8a5eSksagiyam Using PETSCVIEWERHDF5 type with PETSC_VIEWER_HDF5_PETSC format, one can save multiple DMPlex 4699cd7e8a5eSksagiyam meshes in a single HDF5 file. This in turn requires one to name the DMPlex object with PetscObjectSetName() 4700cd7e8a5eSksagiyam before saving it with DMView() and before loading it with DMLoad() for identification of the mesh object. 4701cd7e8a5eSksagiyam The input parameter name is thus used to name the DMPlex object when DMPlexCreateFromFile() internally 4702cd7e8a5eSksagiyam calls DMLoad(). Currently, name is ignored for other viewer types and/or formats. 4703cd7e8a5eSksagiyam 4704ca522641SMatthew G. Knepley Level: beginner 4705ca522641SMatthew G. Knepley 4706cd7e8a5eSksagiyam .seealso: DMPlexCreateFromDAG(), DMPlexCreateFromCellListPetsc(), DMPlexCreate(), PetscObjectSetName(), DMView(), DMLoad() 4707ca522641SMatthew G. Knepley @*/ 4708cd7e8a5eSksagiyam PetscErrorCode DMPlexCreateFromFile(MPI_Comm comm, const char filename[], const char plexname[], PetscBool interpolate, DM *dm) 4709ca522641SMatthew G. Knepley { 4710ca522641SMatthew G. Knepley const char *extGmsh = ".msh"; 4711de78e4feSLisandro Dalcin const char *extGmsh2 = ".msh2"; 4712de78e4feSLisandro Dalcin const char *extGmsh4 = ".msh4"; 4713ca522641SMatthew G. Knepley const char *extCGNS = ".cgns"; 4714ca522641SMatthew G. Knepley const char *extExodus = ".exo"; 471590c68965SMatthew G. Knepley const char *extGenesis = ".gen"; 47162f0bd6dcSMichael Lange const char *extFluent = ".cas"; 4717cc2f8f65SMatthew G. Knepley const char *extHDF5 = ".h5"; 4718707dd687SMichael Lange const char *extMed = ".med"; 4719f2801cd6SMatthew G. Knepley const char *extPLY = ".ply"; 4720c1cad2e7SMatthew G. Knepley const char *extEGADSLite = ".egadslite"; 4721c1cad2e7SMatthew G. Knepley const char *extEGADS = ".egads"; 4722c1cad2e7SMatthew G. Knepley const char *extIGES = ".igs"; 4723c1cad2e7SMatthew G. Knepley const char *extSTEP = ".stp"; 47248ca92349SMatthew G. Knepley const char *extCV = ".dat"; 4725ca522641SMatthew G. Knepley size_t len; 4726c1cad2e7SMatthew G. Knepley PetscBool isGmsh, isGmsh2, isGmsh4, isCGNS, isExodus, isGenesis, isFluent, isHDF5, isMed, isPLY, isEGADSLite, isEGADS, isIGES, isSTEP, isCV; 4727ca522641SMatthew G. Knepley PetscMPIInt rank; 4728ca522641SMatthew G. Knepley PetscErrorCode ierr; 4729ca522641SMatthew G. Knepley 4730ca522641SMatthew G. Knepley PetscFunctionBegin; 47315d80c0bfSVaclav Hapla PetscValidCharPointer(filename, 2); 47320d862eaeSPierre Jolivet if (plexname) PetscValidCharPointer(plexname, 3); 4733cd7e8a5eSksagiyam PetscValidPointer(dm, 5); 4734f1f45c63SVaclav Hapla ierr = DMInitializePackage();CHKERRQ(ierr); 4735f1f45c63SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_CreateFromFile,0,0,0,0);CHKERRQ(ierr); 4736ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 4737ca522641SMatthew G. Knepley ierr = PetscStrlen(filename, &len);CHKERRQ(ierr); 47382c71b3e2SJacob Faibussowitsch PetscCheckFalse(!len,comm, PETSC_ERR_ARG_WRONG, "Filename must be a valid path"); 4739ca522641SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extGmsh, 4, &isGmsh);CHKERRQ(ierr); 4740de78e4feSLisandro Dalcin ierr = PetscStrncmp(&filename[PetscMax(0,len-5)], extGmsh2, 5, &isGmsh2);CHKERRQ(ierr); 4741de78e4feSLisandro Dalcin ierr = PetscStrncmp(&filename[PetscMax(0,len-5)], extGmsh4, 5, &isGmsh4);CHKERRQ(ierr); 4742ca522641SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-5)], extCGNS, 5, &isCGNS);CHKERRQ(ierr); 4743ca522641SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extExodus, 4, &isExodus);CHKERRQ(ierr); 474490c68965SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extGenesis, 4, &isGenesis);CHKERRQ(ierr); 47452f0bd6dcSMichael Lange ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extFluent, 4, &isFluent);CHKERRQ(ierr); 4746cc2f8f65SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-3)], extHDF5, 3, &isHDF5);CHKERRQ(ierr); 4747707dd687SMichael Lange ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extMed, 4, &isMed);CHKERRQ(ierr); 4748f2801cd6SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extPLY, 4, &isPLY);CHKERRQ(ierr); 4749c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-10)], extEGADSLite, 10, &isEGADSLite);CHKERRQ(ierr); 4750c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-6)], extEGADS, 6, &isEGADS);CHKERRQ(ierr); 4751c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extIGES, 4, &isIGES);CHKERRQ(ierr); 4752c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extSTEP, 4, &isSTEP);CHKERRQ(ierr); 47538ca92349SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extCV, 4, &isCV);CHKERRQ(ierr); 4754de78e4feSLisandro Dalcin if (isGmsh || isGmsh2 || isGmsh4) { 47557d282ae0SMichael Lange ierr = DMPlexCreateGmshFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4756ca522641SMatthew G. Knepley } else if (isCGNS) { 4757ca522641SMatthew G. Knepley ierr = DMPlexCreateCGNSFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 475890c68965SMatthew G. Knepley } else if (isExodus || isGenesis) { 4759ca522641SMatthew G. Knepley ierr = DMPlexCreateExodusFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 47602f0bd6dcSMichael Lange } else if (isFluent) { 47612f0bd6dcSMichael Lange ierr = DMPlexCreateFluentFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4762cc2f8f65SMatthew G. Knepley } else if (isHDF5) { 47639c48423bSVaclav Hapla PetscBool load_hdf5_xdmf = PETSC_FALSE; 4764cc2f8f65SMatthew G. Knepley PetscViewer viewer; 4765cc2f8f65SMatthew G. Knepley 476643b242b4SVaclav 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 */ 476743b242b4SVaclav Hapla ierr = PetscStrncmp(&filename[PetscMax(0,len-8)], ".xdmf", 5, &load_hdf5_xdmf);CHKERRQ(ierr); 47689c48423bSVaclav Hapla ierr = PetscOptionsGetBool(NULL, NULL, "-dm_plex_create_from_hdf5_xdmf", &load_hdf5_xdmf, NULL);CHKERRQ(ierr); 4769cc2f8f65SMatthew G. Knepley ierr = PetscViewerCreate(comm, &viewer);CHKERRQ(ierr); 4770cc2f8f65SMatthew G. Knepley ierr = PetscViewerSetType(viewer, PETSCVIEWERHDF5);CHKERRQ(ierr); 4771bca97951SVaclav Hapla ierr = PetscViewerSetOptionsPrefix(viewer, "dm_plex_create_");CHKERRQ(ierr); 4772bca97951SVaclav Hapla ierr = PetscViewerSetFromOptions(viewer);CHKERRQ(ierr); 4773cc2f8f65SMatthew G. Knepley ierr = PetscViewerFileSetMode(viewer, FILE_MODE_READ);CHKERRQ(ierr); 4774cc2f8f65SMatthew G. Knepley ierr = PetscViewerFileSetName(viewer, filename);CHKERRQ(ierr); 4775cd7e8a5eSksagiyam 4776cc2f8f65SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 4777cd7e8a5eSksagiyam ierr = PetscObjectSetName((PetscObject)(*dm), plexname);CHKERRQ(ierr); 4778cc2f8f65SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 47799c48423bSVaclav Hapla if (load_hdf5_xdmf) {ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_HDF5_XDMF);CHKERRQ(ierr);} 4780cc2f8f65SMatthew G. Knepley ierr = DMLoad(*dm, viewer);CHKERRQ(ierr); 47819c48423bSVaclav Hapla if (load_hdf5_xdmf) {ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);} 4782cc2f8f65SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 47835fd9971aSMatthew G. Knepley 47845fd9971aSMatthew G. Knepley if (interpolate) { 47855fd9971aSMatthew G. Knepley DM idm; 47865fd9971aSMatthew G. Knepley 47875fd9971aSMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 47885fd9971aSMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 47895fd9971aSMatthew G. Knepley *dm = idm; 47905fd9971aSMatthew G. Knepley } 4791707dd687SMichael Lange } else if (isMed) { 4792707dd687SMichael Lange ierr = DMPlexCreateMedFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4793f2801cd6SMatthew G. Knepley } else if (isPLY) { 4794f2801cd6SMatthew G. Knepley ierr = DMPlexCreatePLYFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4795c1cad2e7SMatthew G. Knepley } else if (isEGADSLite || isEGADS || isIGES || isSTEP) { 4796c1cad2e7SMatthew G. Knepley if (isEGADSLite) {ierr = DMPlexCreateEGADSLiteFromFile(comm, filename, dm);CHKERRQ(ierr);} 4797c1cad2e7SMatthew G. Knepley else {ierr = DMPlexCreateEGADSFromFile(comm, filename, dm);CHKERRQ(ierr);} 47987bee2925SMatthew Knepley if (!interpolate) { 47997bee2925SMatthew Knepley DM udm; 48007bee2925SMatthew Knepley 48017bee2925SMatthew Knepley ierr = DMPlexUninterpolate(*dm, &udm);CHKERRQ(ierr); 48027bee2925SMatthew Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 48037bee2925SMatthew Knepley *dm = udm; 48047bee2925SMatthew Knepley } 48058ca92349SMatthew G. Knepley } else if (isCV) { 48068ca92349SMatthew G. Knepley ierr = DMPlexCreateCellVertexFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 480798921bdaSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot load file %s: unrecognized extension", filename); 4808ed5e4e85SVaclav Hapla ierr = PetscStrlen(plexname, &len);CHKERRQ(ierr); 4809ed5e4e85SVaclav Hapla if (len) {ierr = PetscObjectSetName((PetscObject)(*dm), plexname);CHKERRQ(ierr);} 4810f1f45c63SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_CreateFromFile,0,0,0,0);CHKERRQ(ierr); 4811ca522641SMatthew G. Knepley PetscFunctionReturn(0); 4812ca522641SMatthew G. Knepley } 4813