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> 5b7f5c055SJed Brown #include <petsc/private/kernels/blockmatmult.h> 6b7f5c055SJed 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 2207b7f5c055SJed Brown typedef void (*TPSEvaluateFunc)(const PetscReal[], PetscReal*, PetscReal[], PetscReal(*)[3]); 2208b7f5c055SJed Brown 2209b7f5c055SJed Brown /* 2210b7f5c055SJed Brown The Schwarz P implicit surface is 2211b7f5c055SJed Brown 2212b7f5c055SJed Brown f(x) = cos(x0) + cos(x1) + cos(x2) = 0 2213b7f5c055SJed Brown */ 2214b7f5c055SJed Brown static void TPSEvaluate_SchwarzP(const PetscReal y[3], PetscReal *f, PetscReal grad[], PetscReal (*hess)[3]) 2215b7f5c055SJed Brown { 2216b7f5c055SJed Brown PetscReal c[3] = {PetscCosReal(y[0] * PETSC_PI), PetscCosReal(y[1] * PETSC_PI), PetscCosReal(y[2] * PETSC_PI)}; 2217b7f5c055SJed Brown PetscReal g[3] = {-PetscSinReal(y[0] * PETSC_PI), -PetscSinReal(y[1] * PETSC_PI), -PetscSinReal(y[2] * PETSC_PI)}; 2218b7f5c055SJed Brown f[0] = c[0] + c[1] + c[2]; 2219b7f5c055SJed Brown for (PetscInt i=0; i<3; i++) { 2220b7f5c055SJed Brown grad[i] = PETSC_PI * g[i]; 2221b7f5c055SJed Brown for (PetscInt j=0; j<3; j++) { 2222b7f5c055SJed Brown hess[i][j] = (i == j) ? -PetscSqr(PETSC_PI) * c[i] : 0.; 2223b7f5c055SJed Brown } 2224b7f5c055SJed Brown } 2225b7f5c055SJed Brown } 2226b7f5c055SJed Brown 2227b7f5c055SJed Brown /* 2228b7f5c055SJed Brown The Gyroid implicit surface is 2229b7f5c055SJed Brown 2230b7f5c055SJed 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) 2231b7f5c055SJed Brown 2232b7f5c055SJed Brown */ 2233b7f5c055SJed Brown static void TPSEvaluate_Gyroid(const PetscReal y[3], PetscReal *f, PetscReal grad[], PetscReal (*hess)[3]) 2234b7f5c055SJed Brown { 2235b7f5c055SJed Brown PetscReal s[3] = {PetscSinReal(PETSC_PI * y[0]), PetscSinReal(PETSC_PI * (y[1] + .5)), PetscSinReal(PETSC_PI * (y[2] + .25))}; 2236b7f5c055SJed Brown PetscReal c[3] = {PetscCosReal(PETSC_PI * y[0]), PetscCosReal(PETSC_PI * (y[1] + .5)), PetscCosReal(PETSC_PI * (y[2] + .25))}; 2237b7f5c055SJed Brown f[0] = s[0] * c[1] + s[1] * c[2] + s[2] * c[0]; 2238b7f5c055SJed Brown grad[0] = PETSC_PI * (c[0] * c[1] - s[2] * s[0]); 2239b7f5c055SJed Brown grad[1] = PETSC_PI * (c[1] * c[2] - s[0] * s[1]); 2240b7f5c055SJed Brown grad[2] = PETSC_PI * (c[2] * c[0] - s[1] * s[2]); 2241b7f5c055SJed Brown hess[0][0] = -PetscSqr(PETSC_PI) * (s[0] * c[1] + s[2] * c[0]); 2242b7f5c055SJed Brown hess[0][1] = -PetscSqr(PETSC_PI) * (c[0] * s[1]); 2243b7f5c055SJed Brown hess[0][2] = -PetscSqr(PETSC_PI) * (c[2] * s[0]); 2244b7f5c055SJed Brown hess[1][0] = -PetscSqr(PETSC_PI) * (s[1] * c[2] + s[0] * c[1]); 2245b7f5c055SJed Brown hess[1][1] = -PetscSqr(PETSC_PI) * (c[1] * s[2]); 2246b7f5c055SJed Brown hess[2][2] = -PetscSqr(PETSC_PI) * (c[0] * s[1]); 2247b7f5c055SJed Brown hess[2][0] = -PetscSqr(PETSC_PI) * (s[2] * c[0] + s[1] * c[2]); 2248b7f5c055SJed Brown hess[2][1] = -PetscSqr(PETSC_PI) * (c[2] * s[0]); 2249b7f5c055SJed Brown hess[2][2] = -PetscSqr(PETSC_PI) * (c[1] * s[2]); 2250b7f5c055SJed Brown } 2251b7f5c055SJed Brown 2252b7f5c055SJed Brown /* 2253b7f5c055SJed Brown We wish to solve 2254b7f5c055SJed Brown 2255b7f5c055SJed Brown min_y || y - x ||^2 subject to f(y) = 0 2256b7f5c055SJed Brown 2257b7f5c055SJed Brown Let g(y) = grad(f). The minimization problem is equivalent to asking to satisfy 2258b7f5c055SJed 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 2259b7f5c055SJed Brown tangent space and ask for both components in the tangent space to be zero. 2260b7f5c055SJed Brown 2261b7f5c055SJed Brown Take g to be a column vector and compute the "full QR" factorization Q R = g, 2262b7f5c055SJed Brown where Q = I - 2 n n^T is a symmetric orthogonal matrix. 2263b7f5c055SJed Brown The first column of Q is parallel to g so the remaining two columns span the null space. 2264b7f5c055SJed Brown Let Qn = Q[:,1:] be those remaining columns. Then Qn Qn^T is an orthogonal projector into the tangent space. 2265b7f5c055SJed Brown Since Q is symmetric, this is equivalent to multipyling by Q and taking the last two entries. 2266b7f5c055SJed Brown In total, we have a system of 3 equations in 3 unknowns: 2267b7f5c055SJed Brown 2268b7f5c055SJed Brown f(y) = 0 1 equation 2269b7f5c055SJed Brown Qn^T (y - x) = 0 2 equations 2270b7f5c055SJed Brown 2271b7f5c055SJed Brown Here, we compute the residual and Jacobian of this system. 2272b7f5c055SJed Brown */ 2273b7f5c055SJed Brown static void TPSNearestPointResJac(TPSEvaluateFunc feval, const PetscScalar x[], const PetscScalar y[], PetscScalar res[], PetscScalar J[]) 2274b7f5c055SJed Brown { 2275b7f5c055SJed Brown PetscReal yreal[3] = {PetscRealPart(y[0]), PetscRealPart(y[1]), PetscRealPart(y[2])}; 2276b7f5c055SJed Brown PetscReal d[3] = {PetscRealPart(y[0] - x[0]), PetscRealPart(y[1] - x[1]), PetscRealPart(y[2] - x[2])}; 2277b7f5c055SJed Brown PetscReal f, grad[3], n[3], n_y[3][3], norm, norm_y[3], nd, nd_y[3], sign; 2278b7f5c055SJed Brown 2279b7f5c055SJed Brown feval(yreal, &f, grad, n_y); 2280b7f5c055SJed Brown 2281b7f5c055SJed Brown for (PetscInt i=0; i<3; i++) n[i] = grad[i]; 2282b7f5c055SJed Brown norm = PetscSqrtReal(PetscSqr(n[0]) + PetscSqr(n[1]) + PetscSqr(n[2])); 2283b7f5c055SJed Brown for (PetscInt i=0; i<3; i++) { 2284b7f5c055SJed Brown norm_y[i] = 1. / norm * n[i] * n_y[i][i]; 2285b7f5c055SJed Brown } 2286b7f5c055SJed Brown 2287b7f5c055SJed Brown // Define the Householder reflector 2288b7f5c055SJed Brown sign = n[0] >= 0 ? 1. : -1.; 2289b7f5c055SJed Brown n[0] += norm * sign; 2290b7f5c055SJed Brown for (PetscInt i=0; i<3; i++) n_y[0][i] += norm_y[i] * sign; 2291b7f5c055SJed Brown 2292b7f5c055SJed Brown norm = PetscSqrtReal(PetscSqr(n[0]) + PetscSqr(n[1]) + PetscSqr(n[2])); 2293b7f5c055SJed Brown norm_y[0] = 1. / norm * (n[0] * n_y[0][0]); 2294b7f5c055SJed Brown norm_y[1] = 1. / norm * (n[0] * n_y[0][1] + n[1] * n_y[1][1]); 2295b7f5c055SJed Brown norm_y[2] = 1. / norm * (n[0] * n_y[0][2] + n[2] * n_y[2][2]); 2296b7f5c055SJed Brown 2297b7f5c055SJed Brown for (PetscInt i=0; i<3; i++) { 2298b7f5c055SJed Brown n[i] /= norm; 2299b7f5c055SJed Brown for (PetscInt j=0; j<3; j++) { 2300b7f5c055SJed Brown // note that n[i] is n_old[i]/norm when executing the code below 2301b7f5c055SJed Brown n_y[i][j] = n_y[i][j] / norm - n[i] / norm * norm_y[j]; 2302b7f5c055SJed Brown } 2303b7f5c055SJed Brown } 2304b7f5c055SJed Brown 2305b7f5c055SJed Brown nd = n[0] * d[0] + n[1] * d[1] + n[2] * d[2]; 2306b7f5c055SJed 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]; 2307b7f5c055SJed Brown 2308b7f5c055SJed Brown res[0] = f; 2309b7f5c055SJed Brown res[1] = d[1] - 2 * n[1] * nd; 2310b7f5c055SJed Brown res[2] = d[2] - 2 * n[2] * nd; 2311b7f5c055SJed Brown // J[j][i] is J_{ij} (column major) 2312b7f5c055SJed Brown for (PetscInt j=0; j<3; j++) { 2313b7f5c055SJed Brown J[0 + j*3] = grad[j]; 2314b7f5c055SJed Brown J[1 + j*3] = (j == 1)*1. - 2 * (n_y[1][j] * nd + n[1] * nd_y[j]); 2315b7f5c055SJed Brown J[2 + j*3] = (j == 2)*1. - 2 * (n_y[2][j] * nd + n[2] * nd_y[j]); 2316b7f5c055SJed Brown } 2317b7f5c055SJed Brown } 2318b7f5c055SJed Brown 2319b7f5c055SJed Brown /* 2320b7f5c055SJed Brown Project x to the nearest point on the implicit surface using Newton's method. 2321b7f5c055SJed Brown */ 2322b7f5c055SJed Brown static PetscErrorCode TPSNearestPoint(TPSEvaluateFunc feval, PetscScalar x[]) 2323b7f5c055SJed Brown { 2324b7f5c055SJed Brown PetscScalar y[3] = {x[0], x[1], x[2]}; // Initial guess 2325b7f5c055SJed Brown PetscErrorCode ierr; 2326b7f5c055SJed Brown 2327b7f5c055SJed Brown PetscFunctionBegin; 2328b7f5c055SJed Brown for (PetscInt iter=0; iter<10; iter++) { 2329b7f5c055SJed Brown PetscScalar res[3], J[9]; 2330b7f5c055SJed Brown PetscReal resnorm; 2331b7f5c055SJed Brown TPSNearestPointResJac(feval, x, y, res, J); 2332b7f5c055SJed Brown resnorm = PetscSqrtReal(PetscSqr(PetscRealPart(res[0])) + PetscSqr(PetscRealPart(res[1])) + PetscSqr(PetscRealPart(res[2]))); 2333b7f5c055SJed Brown if (0) { // Turn on this monitor if you need to confirm quadratic convergence 2334b7f5c055SJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, "[%D] res [%g %g %g]\n", iter, PetscRealPart(res[0]), PetscRealPart(res[1]), PetscRealPart(res[2]));CHKERRQ(ierr); 2335b7f5c055SJed Brown } 2336b7f5c055SJed Brown if (resnorm < PETSC_SMALL) break; 2337b7f5c055SJed Brown 2338b7f5c055SJed Brown // Take the Newton step 2339b7f5c055SJed Brown ierr = PetscKernel_A_gets_inverse_A_3(J, 0., PETSC_FALSE, NULL);CHKERRQ(ierr); 2340b7f5c055SJed Brown PetscKernel_v_gets_v_minus_A_times_w_3(y, J, res); 2341b7f5c055SJed Brown } 2342b7f5c055SJed Brown for (PetscInt i=0; i<3; i++) x[i] = y[i]; 2343b7f5c055SJed Brown PetscFunctionReturn(0); 2344b7f5c055SJed Brown } 2345b7f5c055SJed Brown 2346b7f5c055SJed Brown const char *const DMPlexTPSTypes[] = {"SCHWARZ_P", "GYROID", "DMPlexTPSType", "DMPLEX_TPS_", NULL}; 2347b7f5c055SJed Brown 2348*1436d7faSJed Brown static PetscErrorCode DMPlexCreateTPSMesh_Internal(DM dm, DMPlexTPSType tpstype, const PetscInt extent[], const DMBoundaryType periodic[], PetscBool tps_distribute, PetscInt refinements, PetscInt layers, PetscReal thickness) 2349b7f5c055SJed Brown { 2350b7f5c055SJed Brown PetscErrorCode ierr; 2351b7f5c055SJed Brown PetscMPIInt rank; 2352b7f5c055SJed Brown PetscInt topoDim = 2, spaceDim = 3, numFaces = 0, numVertices = 0, numEdges = 0; 2353b7f5c055SJed Brown PetscInt (*edges)[2] = NULL, *edgeSets = NULL; 2354b7f5c055SJed Brown PetscInt *cells_flat = NULL; 2355b7f5c055SJed Brown PetscReal *vtxCoords = NULL; 2356b7f5c055SJed Brown TPSEvaluateFunc evalFunc = NULL; 2357b7f5c055SJed Brown DMLabel label; 2358b7f5c055SJed Brown 2359b7f5c055SJed Brown PetscFunctionBegin; 2360b7f5c055SJed Brown ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 2361b7f5c055SJed 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); 2362b7f5c055SJed Brown switch (tpstype) { 2363b7f5c055SJed Brown case DMPLEX_TPS_SCHWARZ_P: 2364b7f5c055SJed 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"); 2365b7f5c055SJed Brown if (!rank) { 2366b7f5c055SJed Brown PetscInt (*cells)[6][4][4] = NULL; // [junction, junction-face, cell, conn] 2367b7f5c055SJed Brown PetscInt Njunctions = 0, Ncuts = 0, Npipes[3], vcount; 2368b7f5c055SJed Brown PetscReal L = 1; 2369b7f5c055SJed Brown 2370b7f5c055SJed Brown Npipes[0] = (extent[0] + 1) * extent[1] * extent[2]; 2371b7f5c055SJed Brown Npipes[1] = extent[0] * (extent[1] + 1) * extent[2]; 2372b7f5c055SJed Brown Npipes[2] = extent[0] * extent[1] * (extent[2] + 1); 2373b7f5c055SJed Brown Njunctions = extent[0] * extent[1] * extent[2]; 2374b7f5c055SJed Brown Ncuts = 2 * (extent[0] * extent[1] + extent[1] * extent[2] + extent[2] * extent[0]); 2375b7f5c055SJed Brown numVertices = 4 * (Npipes[0] + Npipes[1] + Npipes[2]) + 8 * Njunctions; 2376b7f5c055SJed Brown ierr = PetscMalloc1(3*numVertices, &vtxCoords);CHKERRQ(ierr); 2377b7f5c055SJed Brown ierr = PetscMalloc1(Njunctions, &cells);CHKERRQ(ierr); 2378b7f5c055SJed Brown ierr = PetscMalloc1(Ncuts*4, &edges);CHKERRQ(ierr); 2379b7f5c055SJed Brown ierr = PetscMalloc1(Ncuts*4, &edgeSets);CHKERRQ(ierr); 2380b7f5c055SJed Brown // x-normal pipes 2381b7f5c055SJed Brown vcount = 0; 2382b7f5c055SJed Brown for (PetscInt i=0; i<extent[0]+1; i++) { 2383b7f5c055SJed Brown for (PetscInt j=0; j<extent[1]; j++) { 2384b7f5c055SJed Brown for (PetscInt k=0; k<extent[2]; k++) { 2385b7f5c055SJed Brown for (PetscInt l=0; l<4; l++) { 2386b7f5c055SJed Brown vtxCoords[vcount++] = (2*i - 1) * L; 2387b7f5c055SJed Brown vtxCoords[vcount++] = 2 * j * L + PetscCosReal((2*l + 1) * PETSC_PI / 4) * L / 2; 2388b7f5c055SJed Brown vtxCoords[vcount++] = 2 * k * L + PetscSinReal((2*l + 1) * PETSC_PI / 4) * L / 2; 2389b7f5c055SJed Brown } 2390b7f5c055SJed Brown } 2391b7f5c055SJed Brown } 2392b7f5c055SJed Brown } 2393b7f5c055SJed Brown // y-normal pipes 2394b7f5c055SJed Brown for (PetscInt i=0; i<extent[0]; i++) { 2395b7f5c055SJed Brown for (PetscInt j=0; j<extent[1]+1; j++) { 2396b7f5c055SJed Brown for (PetscInt k=0; k<extent[2]; k++) { 2397b7f5c055SJed Brown for (PetscInt l=0; l<4; l++) { 2398b7f5c055SJed Brown vtxCoords[vcount++] = 2 * i * L + PetscSinReal((2*l + 1) * PETSC_PI / 4) * L / 2; 2399b7f5c055SJed Brown vtxCoords[vcount++] = (2*j - 1) * L; 2400b7f5c055SJed Brown vtxCoords[vcount++] = 2 * k * L + PetscCosReal((2*l + 1) * PETSC_PI / 4) * L / 2; 2401b7f5c055SJed Brown } 2402b7f5c055SJed Brown } 2403b7f5c055SJed Brown } 2404b7f5c055SJed Brown } 2405b7f5c055SJed Brown // z-normal pipes 2406b7f5c055SJed Brown for (PetscInt i=0; i<extent[0]; i++) { 2407b7f5c055SJed Brown for (PetscInt j=0; j<extent[1]; j++) { 2408b7f5c055SJed Brown for (PetscInt k=0; k<extent[2]+1; k++) { 2409b7f5c055SJed Brown for (PetscInt l=0; l<4; l++) { 2410b7f5c055SJed Brown vtxCoords[vcount++] = 2 * i * L + PetscCosReal((2*l + 1) * PETSC_PI / 4) * L / 2; 2411b7f5c055SJed Brown vtxCoords[vcount++] = 2 * j * L + PetscSinReal((2*l + 1) * PETSC_PI / 4) * L / 2; 2412b7f5c055SJed Brown vtxCoords[vcount++] = (2*k - 1) * L; 2413b7f5c055SJed Brown } 2414b7f5c055SJed Brown } 2415b7f5c055SJed Brown } 2416b7f5c055SJed Brown } 2417b7f5c055SJed Brown // junctions 2418b7f5c055SJed Brown for (PetscInt i=0; i<extent[0]; i++) { 2419b7f5c055SJed Brown for (PetscInt j=0; j<extent[1]; j++) { 2420b7f5c055SJed Brown for (PetscInt k=0; k<extent[2]; k++) { 2421b7f5c055SJed Brown const PetscInt J = (i*extent[1] + j)*extent[2] + k, Jvoff = (Npipes[0] + Npipes[1] + Npipes[2])*4 + J*8; 2422b7f5c055SJed Brown PetscCheck(vcount / 3 == Jvoff, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected vertex count"); 2423b7f5c055SJed Brown for (PetscInt ii=0; ii<2; ii++) { 2424b7f5c055SJed Brown for (PetscInt jj=0; jj<2; jj++) { 2425b7f5c055SJed Brown for (PetscInt kk=0; kk<2; kk++) { 2426b7f5c055SJed Brown double Ls = (1 - sqrt(2) / 4) * L; 2427b7f5c055SJed Brown vtxCoords[vcount++] = 2*i*L + (2*ii-1) * Ls; 2428b7f5c055SJed Brown vtxCoords[vcount++] = 2*j*L + (2*jj-1) * Ls; 2429b7f5c055SJed Brown vtxCoords[vcount++] = 2*k*L + (2*kk-1) * Ls; 2430b7f5c055SJed Brown } 2431b7f5c055SJed Brown } 2432b7f5c055SJed Brown } 2433b7f5c055SJed Brown const PetscInt jfaces[3][2][4] = { 2434b7f5c055SJed Brown {{3,1,0,2}, {7,5,4,6}}, // x-aligned 2435b7f5c055SJed Brown {{5,4,0,1}, {7,6,2,3}}, // y-aligned 2436b7f5c055SJed Brown {{6,2,0,4}, {7,3,1,5}} // z-aligned 2437b7f5c055SJed Brown }; 2438b7f5c055SJed Brown const PetscInt pipe_lo[3] = { // vertex numbers of pipes 2439b7f5c055SJed Brown ((i * extent[1] + j) * extent[2] + k)*4, 2440b7f5c055SJed Brown ((i * (extent[1] + 1) + j) * extent[2] + k + Npipes[0])*4, 2441b7f5c055SJed Brown ((i * extent[1] + j) * (extent[2]+1) + k + Npipes[0] + Npipes[1])*4 2442b7f5c055SJed Brown }; 2443b7f5c055SJed Brown const PetscInt pipe_hi[3] = { // vertex numbers of pipes 2444b7f5c055SJed Brown (((i + 1) * extent[1] + j) * extent[2] + k)*4, 2445b7f5c055SJed Brown ((i * (extent[1] + 1) + j + 1) * extent[2] + k + Npipes[0])*4, 2446b7f5c055SJed Brown ((i * extent[1] + j) * (extent[2]+1) + k + 1 + Npipes[0] + Npipes[1])*4 2447b7f5c055SJed Brown }; 2448b7f5c055SJed Brown for (PetscInt dir=0; dir<3; dir++) { // x,y,z 2449b7f5c055SJed Brown const PetscInt ijk[3] = {i, j, k}; 2450b7f5c055SJed Brown for (PetscInt l=0; l<4; l++) { // rotations 2451b7f5c055SJed Brown cells[J][dir*2+0][l][0] = pipe_lo[dir] + l; 2452b7f5c055SJed Brown cells[J][dir*2+0][l][1] = Jvoff + jfaces[dir][0][l]; 2453b7f5c055SJed Brown cells[J][dir*2+0][l][2] = Jvoff + jfaces[dir][0][(l-1+4)%4]; 2454b7f5c055SJed Brown cells[J][dir*2+0][l][3] = pipe_lo[dir] + (l-1+4)%4; 2455b7f5c055SJed Brown cells[J][dir*2+1][l][0] = Jvoff + jfaces[dir][1][l]; 2456b7f5c055SJed Brown cells[J][dir*2+1][l][1] = pipe_hi[dir] + l; 2457b7f5c055SJed Brown cells[J][dir*2+1][l][2] = pipe_hi[dir] + (l-1+4)%4; 2458b7f5c055SJed Brown cells[J][dir*2+1][l][3] = Jvoff + jfaces[dir][1][(l-1+4)%4]; 2459b7f5c055SJed Brown if (ijk[dir] == 0) { 2460b7f5c055SJed Brown edges[numEdges][0] = pipe_lo[dir] + l; 2461b7f5c055SJed Brown edges[numEdges][1] = pipe_lo[dir] + (l+1) % 4; 2462b7f5c055SJed Brown edgeSets[numEdges] = dir*2 + 1; 2463b7f5c055SJed Brown numEdges++; 2464b7f5c055SJed Brown } 2465b7f5c055SJed Brown if (ijk[dir] + 1 == extent[dir]) { 2466b7f5c055SJed Brown edges[numEdges][0] = pipe_hi[dir] + l; 2467b7f5c055SJed Brown edges[numEdges][1] = pipe_hi[dir] + (l+1) % 4; 2468b7f5c055SJed Brown edgeSets[numEdges] = dir*2 + 2; 2469b7f5c055SJed Brown numEdges++; 2470b7f5c055SJed Brown } 2471b7f5c055SJed Brown } 2472b7f5c055SJed Brown } 2473b7f5c055SJed Brown } 2474b7f5c055SJed Brown } 2475b7f5c055SJed Brown } 2476b7f5c055SJed Brown PetscCheck(numEdges == Ncuts * 4, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge count %D incompatible with number of cuts %D", numEdges, Ncuts); 2477b7f5c055SJed Brown numFaces = 24 * Njunctions; 2478b7f5c055SJed Brown cells_flat = cells[0][0][0]; 2479b7f5c055SJed Brown } 2480b7f5c055SJed Brown evalFunc = TPSEvaluate_SchwarzP; 2481b7f5c055SJed Brown break; 2482b7f5c055SJed Brown case DMPLEX_TPS_GYROID: 2483b7f5c055SJed Brown if (!rank) { 2484b7f5c055SJed Brown // This is a coarse mesh approximation of the gyroid shifted to being the zero of the level set 2485b7f5c055SJed Brown // 2486b7f5c055SJed 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) 2487b7f5c055SJed Brown // 2488b7f5c055SJed Brown // on the cell [0,2]^3. 2489b7f5c055SJed Brown // 2490b7f5c055SJed Brown // Think about dividing that cell into four columns, and focus on the column [0,1]x[0,1]x[0,2]. 2491b7f5c055SJed Brown // If you looked at the gyroid in that column at different slices of z you would see that it kind of spins 2492b7f5c055SJed Brown // like a boomerang: 2493b7f5c055SJed Brown // 2494b7f5c055SJed Brown // z = 0 z = 1/4 z = 1/2 z = 3/4 // 2495b7f5c055SJed Brown // ----- ------- ------- ------- // 2496b7f5c055SJed Brown // // 2497b7f5c055SJed Brown // + + + + + + + \ + // 2498b7f5c055SJed Brown // \ / \ // 2499b7f5c055SJed Brown // \ `-_ _-' / } // 2500b7f5c055SJed Brown // *-_ `-' _-' / // 2501b7f5c055SJed Brown // + `-+ + + +-' + + / + // 2502b7f5c055SJed Brown // // 2503b7f5c055SJed Brown // // 2504b7f5c055SJed Brown // z = 1 z = 5/4 z = 3/2 z = 7/4 // 2505b7f5c055SJed Brown // ----- ------- ------- ------- // 2506b7f5c055SJed Brown // // 2507b7f5c055SJed Brown // +-_ + + + + _-+ + / + // 2508b7f5c055SJed Brown // `-_ _-_ _-` / // 2509b7f5c055SJed Brown // \ _-' `-_ / { // 2510b7f5c055SJed Brown // \ / \ // 2511b7f5c055SJed Brown // + + + + + + + \ + // 2512b7f5c055SJed Brown // 2513b7f5c055SJed Brown // 2514b7f5c055SJed Brown // This course mesh approximates each of these slices by two line segments, 2515b7f5c055SJed Brown // and then connects the segments in consecutive layers with quadrilateral faces. 2516b7f5c055SJed Brown // All of the end points of the segments are multiples of 1/4 except for the 2517b7f5c055SJed Brown // point * in the picture for z = 0 above and the similar points in other layers. 2518b7f5c055SJed Brown // That point is at (gamma, gamma, 0), where gamma is calculated below. 2519b7f5c055SJed Brown // 2520b7f5c055SJed Brown // The column [1,2]x[1,2]x[0,2] looks the same as this column; 2521b7f5c055SJed Brown // The columns [1,2]x[0,1]x[0,2] and [0,1]x[1,2]x[0,2] are mirror images. 2522b7f5c055SJed Brown // 2523b7f5c055SJed Brown // As for how this method turned into the names given to the vertices: 2524b7f5c055SJed Brown // that was not systematic, it was just the way it worked out in my handwritten notes. 2525b7f5c055SJed Brown 2526b7f5c055SJed Brown PetscInt facesPerBlock = 64; 2527b7f5c055SJed Brown PetscInt vertsPerBlock = 56; 2528b7f5c055SJed Brown PetscInt extentPlus[3]; 2529b7f5c055SJed Brown PetscInt numBlocks, numBlocksPlus; 2530b7f5c055SJed Brown const PetscInt A = 0, B = 1, C = 2, D = 3, E = 4, F = 5, G = 6, H = 7, 2531b7f5c055SJed Brown II = 8, J = 9, K = 10, L = 11, M = 12, N = 13, O = 14, P = 15, 2532b7f5c055SJed Brown Q = 16, R = 17, S = 18, T = 19, U = 20, V = 21, W = 22, X = 23, 2533b7f5c055SJed Brown Y = 24, Z = 25, Ap = 26, Bp = 27, Cp = 28, Dp = 29, Ep = 30, Fp = 31, 2534b7f5c055SJed Brown Gp = 32, Hp = 33, Ip = 34, Jp = 35, Kp = 36, Lp = 37, Mp = 38, Np = 39, 2535b7f5c055SJed Brown Op = 40, Pp = 41, Qp = 42, Rp = 43, Sp = 44, Tp = 45, Up = 46, Vp = 47, 2536b7f5c055SJed Brown Wp = 48, Xp = 49, Yp = 50, Zp = 51, Aq = 52, Bq = 53, Cq = 54, Dq = 55; 2537b7f5c055SJed Brown const PetscInt pattern[64][4] = 2538b7f5c055SJed Brown { /* face to vertex within the coarse discretization of a single gyroid block */ 2539b7f5c055SJed Brown /* layer 0 */ 2540b7f5c055SJed 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}, 2541b7f5c055SJed Brown /* layer 1 */ 2542b7f5c055SJed 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}, 2543b7f5c055SJed Brown /* layer 2 */ 2544b7f5c055SJed 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}, 2545b7f5c055SJed Brown /* layer 3 */ 2546b7f5c055SJed 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}, 2547b7f5c055SJed Brown /* layer 4 */ 2548b7f5c055SJed 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}, 2549b7f5c055SJed Brown /* layer 5 */ 2550b7f5c055SJed 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}, 2551b7f5c055SJed Brown /* layer 6 */ 2552b7f5c055SJed 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}, 2553b7f5c055SJed Brown /* layer 7 (the top is the periodic image of the bottom of layer 0) */ 2554b7f5c055SJed 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} 2555b7f5c055SJed Brown }; 2556b7f5c055SJed Brown const PetscReal gamma = PetscAcosReal((PetscSqrtReal(3.)-1.) / PetscSqrtReal(2.)) / PETSC_PI; 2557b7f5c055SJed Brown const PetscReal patternCoords[56][3] = 2558b7f5c055SJed Brown { 2559b7f5c055SJed Brown /* A */ {1.,0.,0.}, 2560b7f5c055SJed Brown /* B */ {0.,1.,0.}, 2561b7f5c055SJed Brown /* C */ {gamma,gamma,0.}, 2562b7f5c055SJed Brown /* D */ {1+gamma,1-gamma,0.}, 2563b7f5c055SJed Brown /* E */ {2-gamma,2-gamma,0.}, 2564b7f5c055SJed Brown /* F */ {1-gamma,1+gamma,0.}, 2565b7f5c055SJed Brown 2566b7f5c055SJed Brown /* G */ {.5,0,.25}, 2567b7f5c055SJed Brown /* H */ {1.5,0.,.25}, 2568b7f5c055SJed Brown /* II */ {.5,1.,.25}, 2569b7f5c055SJed Brown /* J */ {1.5,1.,.25}, 2570b7f5c055SJed Brown /* K */ {.25,.5,.25}, 2571b7f5c055SJed Brown /* L */ {1.25,.5,.25}, 2572b7f5c055SJed Brown /* M */ {.75,1.5,.25}, 2573b7f5c055SJed Brown /* N */ {1.75,1.5,.25}, 2574b7f5c055SJed Brown 2575b7f5c055SJed Brown /* O */ {0.,0.,.5}, 2576b7f5c055SJed Brown /* P */ {1.,1.,.5}, 2577b7f5c055SJed Brown /* Q */ {gamma,1-gamma,.5}, 2578b7f5c055SJed Brown /* R */ {1+gamma,gamma,.5}, 2579b7f5c055SJed Brown /* S */ {2-gamma,1+gamma,.5}, 2580b7f5c055SJed Brown /* T */ {1-gamma,2-gamma,.5}, 2581b7f5c055SJed Brown 2582b7f5c055SJed Brown /* U */ {0.,.5,.75}, 2583b7f5c055SJed Brown /* V */ {0.,1.5,.75}, 2584b7f5c055SJed Brown /* W */ {1.,.5,.75}, 2585b7f5c055SJed Brown /* X */ {1.,1.5,.75}, 2586b7f5c055SJed Brown /* Y */ {.5,.75,.75}, 2587b7f5c055SJed Brown /* Z */ {.5,1.75,.75}, 2588b7f5c055SJed Brown /* Ap */ {1.5,.25,.75}, 2589b7f5c055SJed Brown /* Bp */ {1.5,1.25,.75}, 2590b7f5c055SJed Brown 2591b7f5c055SJed Brown /* Cp */ {1.,0.,1.}, 2592b7f5c055SJed Brown /* Dp */ {0.,1.,1.}, 2593b7f5c055SJed Brown /* Ep */ {1-gamma,1-gamma,1.}, 2594b7f5c055SJed Brown /* Fp */ {1+gamma,1+gamma,1.}, 2595b7f5c055SJed Brown /* Gp */ {2-gamma,gamma,1.}, 2596b7f5c055SJed Brown /* Hp */ {gamma,2-gamma,1.}, 2597b7f5c055SJed Brown 2598b7f5c055SJed Brown /* Ip */ {.5,0.,1.25}, 2599b7f5c055SJed Brown /* Jp */ {1.5,0.,1.25}, 2600b7f5c055SJed Brown /* Kp */ {.5,1.,1.25}, 2601b7f5c055SJed Brown /* Lp */ {1.5,1.,1.25}, 2602b7f5c055SJed Brown /* Mp */ {.75,.5,1.25}, 2603b7f5c055SJed Brown /* Np */ {1.75,.5,1.25}, 2604b7f5c055SJed Brown /* Op */ {.25,1.5,1.25}, 2605b7f5c055SJed Brown /* Pp */ {1.25,1.5,1.25}, 2606b7f5c055SJed Brown 2607b7f5c055SJed Brown /* Qp */ {0.,0.,1.5}, 2608b7f5c055SJed Brown /* Rp */ {1.,1.,1.5}, 2609b7f5c055SJed Brown /* Sp */ {1-gamma,gamma,1.5}, 2610b7f5c055SJed Brown /* Tp */ {2-gamma,1-gamma,1.5}, 2611b7f5c055SJed Brown /* Up */ {1+gamma,2-gamma,1.5}, 2612b7f5c055SJed Brown /* Vp */ {gamma,1+gamma,1.5}, 2613b7f5c055SJed Brown 2614b7f5c055SJed Brown /* Wp */ {0.,.5,1.75}, 2615b7f5c055SJed Brown /* Xp */ {0.,1.5,1.75}, 2616b7f5c055SJed Brown /* Yp */ {1.,.5,1.75}, 2617b7f5c055SJed Brown /* Zp */ {1.,1.5,1.75}, 2618b7f5c055SJed Brown /* Aq */ {.5,.25,1.75}, 2619b7f5c055SJed Brown /* Bq */ {.5,1.25,1.75}, 2620b7f5c055SJed Brown /* Cq */ {1.5,.75,1.75}, 2621b7f5c055SJed Brown /* Dq */ {1.5,1.75,1.75}, 2622b7f5c055SJed Brown }; 2623b7f5c055SJed Brown PetscInt (*cells)[64][4] = NULL; 2624b7f5c055SJed Brown PetscBool *seen; 2625b7f5c055SJed Brown PetscInt *vertToTrueVert; 2626b7f5c055SJed Brown PetscInt count; 2627b7f5c055SJed Brown 2628b7f5c055SJed Brown for (PetscInt i = 0; i < 3; i++) extentPlus[i] = extent[i] + 1; 2629b7f5c055SJed Brown numBlocks = 1; 2630b7f5c055SJed Brown for (PetscInt i = 0; i < 3; i++) numBlocks *= extent[i]; 2631b7f5c055SJed Brown numBlocksPlus = 1; 2632b7f5c055SJed Brown for (PetscInt i = 0; i < 3; i++) numBlocksPlus *= extentPlus[i]; 2633b7f5c055SJed Brown numFaces = numBlocks * facesPerBlock; 2634b7f5c055SJed Brown ierr = PetscMalloc1(numBlocks, &cells);CHKERRQ(ierr); 2635b7f5c055SJed Brown ierr = PetscCalloc1(numBlocksPlus * vertsPerBlock,&seen);CHKERRQ(ierr); 2636b7f5c055SJed Brown for (PetscInt k = 0; k < extent[2]; k++) { 2637b7f5c055SJed Brown for (PetscInt j = 0; j < extent[1]; j++) { 2638b7f5c055SJed Brown for (PetscInt i = 0; i < extent[0]; i++) { 2639b7f5c055SJed Brown for (PetscInt f = 0; f < facesPerBlock; f++) { 2640b7f5c055SJed Brown for (PetscInt v = 0; v < 4; v++) { 2641b7f5c055SJed Brown PetscInt vertRaw = pattern[f][v]; 2642b7f5c055SJed Brown PetscInt blockidx = vertRaw / 56; 2643b7f5c055SJed Brown PetscInt patternvert = vertRaw % 56; 2644b7f5c055SJed Brown PetscInt xplus = (blockidx & 1); 2645b7f5c055SJed Brown PetscInt yplus = (blockidx & 2) >> 1; 2646b7f5c055SJed Brown PetscInt zplus = (blockidx & 4) >> 2; 2647b7f5c055SJed Brown PetscInt zcoord = (periodic && periodic[2] == DM_BOUNDARY_PERIODIC) ? ((k + zplus) % extent[2]) : (k + zplus); 2648b7f5c055SJed Brown PetscInt ycoord = (periodic && periodic[1] == DM_BOUNDARY_PERIODIC) ? ((j + yplus) % extent[1]) : (j + yplus); 2649b7f5c055SJed Brown PetscInt xcoord = (periodic && periodic[0] == DM_BOUNDARY_PERIODIC) ? ((i + xplus) % extent[0]) : (i + xplus); 2650b7f5c055SJed Brown PetscInt vert = ((zcoord * extentPlus[1] + ycoord) * extentPlus[0] + xcoord) * 56 + patternvert; 2651b7f5c055SJed Brown 2652b7f5c055SJed Brown cells[(k * extent[1] + j) * extent[0] + i][f][v] = vert; 2653b7f5c055SJed Brown seen[vert] = PETSC_TRUE; 2654b7f5c055SJed Brown } 2655b7f5c055SJed Brown } 2656b7f5c055SJed Brown } 2657b7f5c055SJed Brown } 2658b7f5c055SJed Brown } 2659b7f5c055SJed Brown for (PetscInt i = 0; i < numBlocksPlus * vertsPerBlock; i++) if (seen[i]) numVertices++; 2660b7f5c055SJed Brown count = 0; 2661b7f5c055SJed Brown ierr = PetscMalloc1(numBlocksPlus * vertsPerBlock, &vertToTrueVert);CHKERRQ(ierr); 2662b7f5c055SJed Brown ierr = PetscMalloc1(numVertices * 3, &vtxCoords);CHKERRQ(ierr); 2663b7f5c055SJed Brown for (PetscInt i = 0; i < numBlocksPlus * vertsPerBlock; i++) vertToTrueVert[i] = -1; 2664b7f5c055SJed Brown for (PetscInt k = 0; k < extentPlus[2]; k++) { 2665b7f5c055SJed Brown for (PetscInt j = 0; j < extentPlus[1]; j++) { 2666b7f5c055SJed Brown for (PetscInt i = 0; i < extentPlus[0]; i++) { 2667b7f5c055SJed Brown for (PetscInt v = 0; v < vertsPerBlock; v++) { 2668b7f5c055SJed Brown PetscInt vIdx = ((k * extentPlus[1] + j) * extentPlus[0] + i) * vertsPerBlock + v; 2669b7f5c055SJed Brown 2670b7f5c055SJed Brown if (seen[vIdx]) { 2671b7f5c055SJed Brown PetscInt thisVert; 2672b7f5c055SJed Brown 2673b7f5c055SJed Brown vertToTrueVert[vIdx] = thisVert = count++; 2674b7f5c055SJed Brown 2675b7f5c055SJed Brown for (PetscInt d = 0; d < 3; d++) vtxCoords[3 * thisVert + d] = patternCoords[v][d]; 2676b7f5c055SJed Brown vtxCoords[3 * thisVert + 0] += i * 2; 2677b7f5c055SJed Brown vtxCoords[3 * thisVert + 1] += j * 2; 2678b7f5c055SJed Brown vtxCoords[3 * thisVert + 2] += k * 2; 2679b7f5c055SJed Brown } 2680b7f5c055SJed Brown } 2681b7f5c055SJed Brown } 2682b7f5c055SJed Brown } 2683b7f5c055SJed Brown } 2684b7f5c055SJed Brown for (PetscInt i = 0; i < numBlocks; i++) { 2685b7f5c055SJed Brown for (PetscInt f = 0; f < facesPerBlock; f++) { 2686b7f5c055SJed Brown for (PetscInt v = 0; v < 4; v++) { 2687b7f5c055SJed Brown cells[i][f][v] = vertToTrueVert[cells[i][f][v]]; 2688b7f5c055SJed Brown } 2689b7f5c055SJed Brown } 2690b7f5c055SJed Brown } 2691b7f5c055SJed Brown ierr = PetscFree(vertToTrueVert);CHKERRQ(ierr); 2692b7f5c055SJed Brown ierr = PetscFree(seen);CHKERRQ(ierr); 2693b7f5c055SJed Brown cells_flat = cells[0][0]; 2694b7f5c055SJed Brown numEdges = 0; 2695b7f5c055SJed Brown for (PetscInt i = 0; i < numFaces; i++) { 2696b7f5c055SJed Brown for (PetscInt e = 0; e < 4; e++) { 2697b7f5c055SJed Brown PetscInt ev[] = {cells_flat[i*4 + e], cells_flat[i*4 + ((e+1)%4)]}; 2698b7f5c055SJed Brown const PetscReal *evCoords[] = {&vtxCoords[3*ev[0]], &vtxCoords[3*ev[1]]}; 2699b7f5c055SJed Brown 2700b7f5c055SJed Brown for (PetscInt d = 0; d < 3; d++) { 2701b7f5c055SJed Brown if (!periodic || periodic[0] != DM_BOUNDARY_PERIODIC) { 2702b7f5c055SJed Brown if (evCoords[0][d] == 0. && evCoords[1][d] == 0.) numEdges++; 2703b7f5c055SJed Brown if (evCoords[0][d] == 2.*extent[d] && evCoords[1][d] == 2.*extent[d]) numEdges++; 2704b7f5c055SJed Brown } 2705b7f5c055SJed Brown } 2706b7f5c055SJed Brown } 2707b7f5c055SJed Brown } 2708b7f5c055SJed Brown ierr = PetscMalloc1(numEdges, &edges);CHKERRQ(ierr); 2709b7f5c055SJed Brown ierr = PetscMalloc1(numEdges, &edgeSets);CHKERRQ(ierr); 2710b7f5c055SJed Brown for (PetscInt edge = 0, i = 0; i < numFaces; i++) { 2711b7f5c055SJed Brown for (PetscInt e = 0; e < 4; e++) { 2712b7f5c055SJed Brown PetscInt ev[] = {cells_flat[i*4 + e], cells_flat[i*4 + ((e+1)%4)]}; 2713b7f5c055SJed Brown const PetscReal *evCoords[] = {&vtxCoords[3*ev[0]], &vtxCoords[3*ev[1]]}; 2714b7f5c055SJed Brown 2715b7f5c055SJed Brown for (PetscInt d = 0; d < 3; d++) { 2716b7f5c055SJed Brown if (!periodic || periodic[d] != DM_BOUNDARY_PERIODIC) { 2717b7f5c055SJed Brown if (evCoords[0][d] == 0. && evCoords[1][d] == 0.) { 2718b7f5c055SJed Brown edges[edge][0] = ev[0]; 2719b7f5c055SJed Brown edges[edge][1] = ev[1]; 2720b7f5c055SJed Brown edgeSets[edge++] = 2 * d; 2721b7f5c055SJed Brown } 2722b7f5c055SJed Brown if (evCoords[0][d] == 2.*extent[d] && evCoords[1][d] == 2.*extent[d]) { 2723b7f5c055SJed Brown edges[edge][0] = ev[0]; 2724b7f5c055SJed Brown edges[edge][1] = ev[1]; 2725b7f5c055SJed Brown edgeSets[edge++] = 2 * d + 1; 2726b7f5c055SJed Brown } 2727b7f5c055SJed Brown } 2728b7f5c055SJed Brown } 2729b7f5c055SJed Brown } 2730b7f5c055SJed Brown } 2731b7f5c055SJed Brown } 2732b7f5c055SJed Brown evalFunc = TPSEvaluate_Gyroid; 2733b7f5c055SJed Brown break; 2734b7f5c055SJed Brown } 2735b7f5c055SJed Brown 2736b7f5c055SJed Brown ierr = DMSetDimension(dm, topoDim);CHKERRQ(ierr); 2737b7f5c055SJed Brown if (!rank) {ierr = DMPlexBuildFromCellList(dm, numFaces, numVertices, 4, cells_flat);CHKERRQ(ierr);} 2738b7f5c055SJed Brown else {ierr = DMPlexBuildFromCellList(dm, 0, 0, 0, NULL);CHKERRQ(ierr);} 2739b7f5c055SJed Brown ierr = PetscFree(cells_flat);CHKERRQ(ierr); 2740b7f5c055SJed Brown { 2741b7f5c055SJed Brown DM idm; 2742b7f5c055SJed Brown ierr = DMPlexInterpolate(dm, &idm);CHKERRQ(ierr); 2743b7f5c055SJed Brown ierr = DMPlexReplace_Static(dm, &idm);CHKERRQ(ierr); 2744b7f5c055SJed Brown } 2745b7f5c055SJed Brown if (!rank) {ierr = DMPlexBuildCoordinatesFromCellList(dm, spaceDim, vtxCoords);CHKERRQ(ierr);} 2746b7f5c055SJed Brown else {ierr = DMPlexBuildCoordinatesFromCellList(dm, spaceDim, NULL);CHKERRQ(ierr);} 2747b7f5c055SJed Brown ierr = PetscFree(vtxCoords);CHKERRQ(ierr); 2748b7f5c055SJed Brown 2749b7f5c055SJed Brown ierr = DMCreateLabel(dm, "Face Sets");CHKERRQ(ierr); 2750b7f5c055SJed Brown ierr = DMGetLabel(dm, "Face Sets", &label);CHKERRQ(ierr); 2751b7f5c055SJed Brown for (PetscInt e=0; e<numEdges; e++) { 2752b7f5c055SJed Brown PetscInt njoin; 2753b7f5c055SJed Brown const PetscInt *join, verts[] = {numFaces + edges[e][0], numFaces + edges[e][1]}; 2754b7f5c055SJed Brown ierr = DMPlexGetJoin(dm, 2, verts, &njoin, &join);CHKERRQ(ierr); 2755b7f5c055SJed Brown PetscCheck(njoin == 1, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Expected unique join of vertices %D and %D", edges[e][0], edges[e][1]); 2756b7f5c055SJed Brown ierr = DMLabelSetValue(label, join[0], edgeSets[e]);CHKERRQ(ierr); 2757b7f5c055SJed Brown ierr = DMPlexRestoreJoin(dm, 2, verts, &njoin, &join);CHKERRQ(ierr); 2758b7f5c055SJed Brown } 2759b7f5c055SJed Brown ierr = PetscFree(edges);CHKERRQ(ierr); 2760b7f5c055SJed Brown ierr = PetscFree(edgeSets);CHKERRQ(ierr); 2761*1436d7faSJed Brown if (tps_distribute) { 2762*1436d7faSJed Brown DM pdm = NULL; 2763*1436d7faSJed Brown PetscPartitioner part; 2764*1436d7faSJed Brown 2765*1436d7faSJed Brown ierr = DMPlexGetPartitioner(dm, &part);CHKERRQ(ierr); 2766*1436d7faSJed Brown ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); 2767*1436d7faSJed Brown ierr = DMPlexDistribute(dm, 0, NULL, &pdm);CHKERRQ(ierr); 2768*1436d7faSJed Brown if (pdm) { 2769*1436d7faSJed Brown ierr = DMPlexReplace_Static(dm, &pdm);CHKERRQ(ierr); 2770*1436d7faSJed Brown } 2771*1436d7faSJed Brown // Do not auto-distribute again 2772*1436d7faSJed Brown ierr = DMPlexDistributeSetDefault(dm, PETSC_FALSE);CHKERRQ(ierr); 2773*1436d7faSJed Brown } 2774b7f5c055SJed Brown 2775b7f5c055SJed Brown ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr); 2776b7f5c055SJed Brown for (PetscInt refine=0; refine<refinements; refine++) { 2777b7f5c055SJed Brown PetscInt m; 2778b7f5c055SJed Brown DM dmf; 2779b7f5c055SJed Brown Vec X; 2780b7f5c055SJed Brown PetscScalar *x; 2781b7f5c055SJed Brown ierr = DMRefine(dm, MPI_COMM_NULL, &dmf);CHKERRQ(ierr); 2782b7f5c055SJed Brown ierr = DMPlexReplace_Static(dm, &dmf);CHKERRQ(ierr); 2783b7f5c055SJed Brown 2784b7f5c055SJed Brown ierr = DMGetCoordinatesLocal(dm, &X);CHKERRQ(ierr); 2785b7f5c055SJed Brown ierr = VecGetLocalSize(X, &m);CHKERRQ(ierr); 2786b7f5c055SJed Brown ierr = VecGetArray(X, &x);CHKERRQ(ierr); 2787b7f5c055SJed Brown for (PetscInt i=0; i<m; i+=3) { 2788b7f5c055SJed Brown ierr = TPSNearestPoint(evalFunc, &x[i]);CHKERRQ(ierr); 2789b7f5c055SJed Brown } 2790b7f5c055SJed Brown ierr = VecRestoreArray(X, &x);CHKERRQ(ierr); 2791b7f5c055SJed Brown } 2792b7f5c055SJed Brown 2793b7f5c055SJed Brown // Face Sets has already been propagated to new vertices during refinement; this propagates to the initial vertices. 2794b7f5c055SJed Brown ierr = DMGetLabel(dm, "Face Sets", &label);CHKERRQ(ierr); 2795b7f5c055SJed Brown ierr = DMPlexLabelComplete(dm, label);CHKERRQ(ierr); 2796b7f5c055SJed Brown 2797b7f5c055SJed Brown if (thickness > 0) { 2798b7f5c055SJed Brown DM dm3; 2799b7f5c055SJed Brown ierr = DMPlexExtrude(dm, layers, thickness, PETSC_FALSE, PETSC_TRUE, NULL, NULL, &dm3);CHKERRQ(ierr); 2800b7f5c055SJed Brown ierr = DMPlexReplace_Static(dm, &dm3);CHKERRQ(ierr); 2801b7f5c055SJed Brown } 2802b7f5c055SJed Brown PetscFunctionReturn(0); 2803b7f5c055SJed Brown } 2804b7f5c055SJed Brown 2805b7f5c055SJed Brown /*@ 2806b7f5c055SJed Brown DMPlexCreateTPSMesh - Create a distributed, interpolated mesh of a triply-periodic surface 2807b7f5c055SJed Brown 2808b7f5c055SJed Brown Collective 2809b7f5c055SJed Brown 2810b7f5c055SJed Brown Input Parameters: 2811b7f5c055SJed Brown + comm - The communicator for the DM object 2812b7f5c055SJed Brown . tpstype - Type of triply-periodic surface 2813b7f5c055SJed Brown . extent - Array of length 3 containing number of periods in each direction 2814b7f5c055SJed Brown . periodic - array of length 3 with periodicity, or NULL for non-periodic 2815*1436d7faSJed Brown . tps_distribute - Distribute 2D manifold mesh prior to refinement and extrusion (more scalable) 2816*1436d7faSJed Brown - refinements - Number of factor-of-2 refinements of 2D manifold mesh 2817*1436d7faSJed Brown . layers - Number of cell layers extruded in normal direction 2818b7f5c055SJed Brown . thickness - Thickness in normal direction 2819b7f5c055SJed Brown 2820b7f5c055SJed Brown Output Parameter: 2821b7f5c055SJed Brown . dm - The DM object 2822b7f5c055SJed Brown 2823b7f5c055SJed Brown Notes: 2824b7f5c055SJed 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. 2825b7f5c055SJed Brown https://en.wikipedia.org/wiki/Schwarz_minimal_surface#Schwarz_P_(%22Primitive%22) and can be cut with "clean" boundaries. 2826b7f5c055SJed 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. 2827b7f5c055SJed Brown Our implementation creates a very coarse mesh of the surface and refines (by 4-way splitting) as many times as requested. 2828b7f5c055SJed Brown On each refinement, all vertices are projected to their nearest point on the surface. 2829b7f5c055SJed Brown This projection could readily be extended to related surfaces. 2830b7f5c055SJed Brown 2831b7f5c055SJed Brown The face (edge) sets for the Schwarz P surface are numbered 1(-x), 2(+x), 3(-y), 4(+y), 5(-z), 6(+z). 2832b7f5c055SJed Brown When the mesh is refined, "Face Sets" contain the new vertices (created during refinement). Use DMPlexLabelComplete() to propagate to coarse-level vertices. 2833b7f5c055SJed Brown 2834b7f5c055SJed Brown References: 2835b7f5c055SJed 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 2836b7f5c055SJed Brown 2837b7f5c055SJed Brown Developer Notes: 2838b7f5c055SJed Brown The Gyroid mesh does not currently mark boundary sets. 2839b7f5c055SJed Brown 2840b7f5c055SJed Brown Level: beginner 2841b7f5c055SJed Brown 2842b7f5c055SJed Brown .seealso: DMPlexCreateSphereMesh(), DMSetType(), DMCreate() 2843b7f5c055SJed Brown @*/ 2844*1436d7faSJed Brown PetscErrorCode DMPlexCreateTPSMesh(MPI_Comm comm, DMPlexTPSType tpstype, const PetscInt extent[], const DMBoundaryType periodic[], PetscBool tps_distribute, PetscInt refinements, PetscInt layers, PetscReal thickness, DM *dm) 2845b7f5c055SJed Brown { 2846b7f5c055SJed Brown PetscErrorCode ierr; 2847b7f5c055SJed Brown 2848b7f5c055SJed Brown PetscFunctionBegin; 2849b7f5c055SJed Brown ierr = DMCreate(comm, dm);CHKERRQ(ierr); 2850b7f5c055SJed Brown ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 2851*1436d7faSJed Brown ierr = DMPlexCreateTPSMesh_Internal(*dm, tpstype, extent, periodic, tps_distribute, refinements, layers, thickness);CHKERRQ(ierr); 2852b7f5c055SJed Brown PetscFunctionReturn(0); 2853b7f5c055SJed Brown } 2854b7f5c055SJed Brown 28559318fe57SMatthew G. Knepley /*@ 28569318fe57SMatthew G. Knepley DMPlexCreateSphereMesh - Creates a mesh on the d-dimensional sphere, S^d. 28579318fe57SMatthew G. Knepley 28589318fe57SMatthew G. Knepley Collective 28599318fe57SMatthew G. Knepley 28609318fe57SMatthew G. Knepley Input Parameters: 28619318fe57SMatthew G. Knepley + comm - The communicator for the DM object 28629318fe57SMatthew G. Knepley . dim - The dimension 28639318fe57SMatthew G. Knepley . simplex - Use simplices, or tensor product cells 28649318fe57SMatthew G. Knepley - R - The radius 28659318fe57SMatthew G. Knepley 28669318fe57SMatthew G. Knepley Output Parameter: 28679318fe57SMatthew G. Knepley . dm - The DM object 28689318fe57SMatthew G. Knepley 28699318fe57SMatthew G. Knepley Level: beginner 28709318fe57SMatthew G. Knepley 28719318fe57SMatthew G. Knepley .seealso: DMPlexCreateBallMesh(), DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 28729318fe57SMatthew G. Knepley @*/ 28739318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateSphereMesh(MPI_Comm comm, PetscInt dim, PetscBool simplex, PetscReal R, DM *dm) 28749318fe57SMatthew G. Knepley { 28759318fe57SMatthew G. Knepley PetscErrorCode ierr; 28769318fe57SMatthew G. Knepley 28779318fe57SMatthew G. Knepley PetscFunctionBegin; 28789318fe57SMatthew G. Knepley PetscValidPointer(dm, 5); 28799318fe57SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 28809318fe57SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 28819318fe57SMatthew G. Knepley ierr = DMPlexCreateSphereMesh_Internal(*dm, dim, simplex, R);CHKERRQ(ierr); 28829318fe57SMatthew G. Knepley PetscFunctionReturn(0); 28839318fe57SMatthew G. Knepley } 28849318fe57SMatthew G. Knepley 28859318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBallMesh_Internal(DM dm, PetscInt dim, PetscReal R) 28869318fe57SMatthew G. Knepley { 28879318fe57SMatthew G. Knepley DM sdm, vol; 28889318fe57SMatthew G. Knepley DMLabel bdlabel; 28899318fe57SMatthew G. Knepley PetscErrorCode ierr; 28909318fe57SMatthew G. Knepley 28919318fe57SMatthew G. Knepley PetscFunctionBegin; 28929318fe57SMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject) dm), &sdm);CHKERRQ(ierr); 28939318fe57SMatthew G. Knepley ierr = DMSetType(sdm, DMPLEX);CHKERRQ(ierr); 28949318fe57SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) sdm, "bd_");CHKERRQ(ierr); 28959318fe57SMatthew G. Knepley ierr = DMPlexCreateSphereMesh_Internal(sdm, dim-1, PETSC_TRUE, R);CHKERRQ(ierr); 28969318fe57SMatthew G. Knepley ierr = DMSetFromOptions(sdm);CHKERRQ(ierr); 28979318fe57SMatthew G. Knepley ierr = DMViewFromOptions(sdm, NULL, "-dm_view");CHKERRQ(ierr); 28989318fe57SMatthew G. Knepley ierr = DMPlexGenerate(sdm, NULL, PETSC_TRUE, &vol);CHKERRQ(ierr); 28999318fe57SMatthew G. Knepley ierr = DMDestroy(&sdm);CHKERRQ(ierr); 29009318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &vol);CHKERRQ(ierr); 29019318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm, "marker");CHKERRQ(ierr); 29029318fe57SMatthew G. Knepley ierr = DMGetLabel(dm, "marker", &bdlabel);CHKERRQ(ierr); 29039318fe57SMatthew G. Knepley ierr = DMPlexMarkBoundaryFaces(dm, PETSC_DETERMINE, bdlabel);CHKERRQ(ierr); 29049318fe57SMatthew G. Knepley ierr = DMPlexLabelComplete(dm, bdlabel);CHKERRQ(ierr); 290551a74b61SMatthew G. Knepley PetscFunctionReturn(0); 290651a74b61SMatthew G. Knepley } 290751a74b61SMatthew G. Knepley 290851a74b61SMatthew G. Knepley /*@ 290951a74b61SMatthew G. Knepley DMPlexCreateBallMesh - Creates a simplex mesh on the d-dimensional ball, B^d. 291051a74b61SMatthew G. Knepley 291151a74b61SMatthew G. Knepley Collective 291251a74b61SMatthew G. Knepley 291351a74b61SMatthew G. Knepley Input Parameters: 291451a74b61SMatthew G. Knepley + comm - The communicator for the DM object 291551a74b61SMatthew G. Knepley . dim - The dimension 291651a74b61SMatthew G. Knepley - R - The radius 291751a74b61SMatthew G. Knepley 291851a74b61SMatthew G. Knepley Output Parameter: 291951a74b61SMatthew G. Knepley . dm - The DM object 292051a74b61SMatthew G. Knepley 292151a74b61SMatthew G. Knepley Options Database Keys: 292251a74b61SMatthew G. Knepley - bd_dm_refine - This will refine the surface mesh preserving the sphere geometry 292351a74b61SMatthew G. Knepley 292451a74b61SMatthew G. Knepley Level: beginner 292551a74b61SMatthew G. Knepley 292651a74b61SMatthew G. Knepley .seealso: DMPlexCreateSphereMesh(), DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 292751a74b61SMatthew G. Knepley @*/ 292851a74b61SMatthew G. Knepley PetscErrorCode DMPlexCreateBallMesh(MPI_Comm comm, PetscInt dim, PetscReal R, DM *dm) 292951a74b61SMatthew G. Knepley { 293051a74b61SMatthew G. Knepley PetscErrorCode ierr; 293151a74b61SMatthew G. Knepley 293251a74b61SMatthew G. Knepley PetscFunctionBegin; 29339318fe57SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 29349318fe57SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 29359318fe57SMatthew G. Knepley ierr = DMPlexCreateBallMesh_Internal(*dm, dim, R);CHKERRQ(ierr); 29362829fed8SMatthew G. Knepley PetscFunctionReturn(0); 29372829fed8SMatthew G. Knepley } 29382829fed8SMatthew G. Knepley 29399318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateReferenceCell_Internal(DM rdm, DMPolytopeType ct) 29400a6ba040SMatthew G. Knepley { 29410a6ba040SMatthew G. Knepley PetscErrorCode ierr; 29420a6ba040SMatthew G. Knepley 29430a6ba040SMatthew G. Knepley PetscFunctionBegin; 29449318fe57SMatthew G. Knepley switch (ct) { 29459318fe57SMatthew G. Knepley case DM_POLYTOPE_POINT: 29469318fe57SMatthew G. Knepley { 29479318fe57SMatthew G. Knepley PetscInt numPoints[1] = {1}; 29489318fe57SMatthew G. Knepley PetscInt coneSize[1] = {0}; 29499318fe57SMatthew G. Knepley PetscInt cones[1] = {0}; 29509318fe57SMatthew G. Knepley PetscInt coneOrientations[1] = {0}; 29519318fe57SMatthew G. Knepley PetscScalar vertexCoords[1] = {0.0}; 29529318fe57SMatthew G. Knepley 29539318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 0);CHKERRQ(ierr); 29549318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 0, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 29559318fe57SMatthew G. Knepley } 29569318fe57SMatthew G. Knepley break; 29579318fe57SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 29589318fe57SMatthew G. Knepley { 29599318fe57SMatthew G. Knepley PetscInt numPoints[2] = {2, 1}; 29609318fe57SMatthew G. Knepley PetscInt coneSize[3] = {2, 0, 0}; 29619318fe57SMatthew G. Knepley PetscInt cones[2] = {1, 2}; 29629318fe57SMatthew G. Knepley PetscInt coneOrientations[2] = {0, 0}; 29639318fe57SMatthew G. Knepley PetscScalar vertexCoords[2] = {-1.0, 1.0}; 29649318fe57SMatthew G. Knepley 29659318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 1);CHKERRQ(ierr); 29669318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 29679318fe57SMatthew G. Knepley } 29689318fe57SMatthew G. Knepley break; 2969b5a892a1SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 2970b5a892a1SMatthew G. Knepley { 2971b5a892a1SMatthew G. Knepley PetscInt numPoints[2] = {2, 1}; 2972b5a892a1SMatthew G. Knepley PetscInt coneSize[3] = {2, 0, 0}; 2973b5a892a1SMatthew G. Knepley PetscInt cones[2] = {1, 2}; 2974b5a892a1SMatthew G. Knepley PetscInt coneOrientations[2] = {0, 0}; 2975b5a892a1SMatthew G. Knepley PetscScalar vertexCoords[2] = {-1.0, 1.0}; 2976b5a892a1SMatthew G. Knepley 2977b5a892a1SMatthew G. Knepley ierr = DMSetDimension(rdm, 1);CHKERRQ(ierr); 2978b5a892a1SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 2979b5a892a1SMatthew G. Knepley } 2980b5a892a1SMatthew G. Knepley break; 29819318fe57SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 29829318fe57SMatthew G. Knepley { 29839318fe57SMatthew G. Knepley PetscInt numPoints[2] = {3, 1}; 29849318fe57SMatthew G. Knepley PetscInt coneSize[4] = {3, 0, 0, 0}; 29859318fe57SMatthew G. Knepley PetscInt cones[3] = {1, 2, 3}; 29869318fe57SMatthew G. Knepley PetscInt coneOrientations[3] = {0, 0, 0}; 29879318fe57SMatthew G. Knepley PetscScalar vertexCoords[6] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0}; 29889318fe57SMatthew G. Knepley 29899318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 2);CHKERRQ(ierr); 29909318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 29919318fe57SMatthew G. Knepley } 29929318fe57SMatthew G. Knepley break; 29939318fe57SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 29949318fe57SMatthew G. Knepley { 29959318fe57SMatthew G. Knepley PetscInt numPoints[2] = {4, 1}; 29969318fe57SMatthew G. Knepley PetscInt coneSize[5] = {4, 0, 0, 0, 0}; 29979318fe57SMatthew G. Knepley PetscInt cones[4] = {1, 2, 3, 4}; 29989318fe57SMatthew G. Knepley PetscInt coneOrientations[4] = {0, 0, 0, 0}; 29999318fe57SMatthew G. Knepley PetscScalar vertexCoords[8] = {-1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0}; 30009318fe57SMatthew G. Knepley 30019318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 2);CHKERRQ(ierr); 30029318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 30039318fe57SMatthew G. Knepley } 30049318fe57SMatthew G. Knepley break; 30059318fe57SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 30069318fe57SMatthew G. Knepley { 30079318fe57SMatthew G. Knepley PetscInt numPoints[2] = {4, 1}; 30089318fe57SMatthew G. Knepley PetscInt coneSize[5] = {4, 0, 0, 0, 0}; 30099318fe57SMatthew G. Knepley PetscInt cones[4] = {1, 2, 3, 4}; 30109318fe57SMatthew G. Knepley PetscInt coneOrientations[4] = {0, 0, 0, 0}; 30119318fe57SMatthew G. Knepley PetscScalar vertexCoords[8] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0}; 30129318fe57SMatthew G. Knepley 30139318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 2);CHKERRQ(ierr); 30149318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 30159318fe57SMatthew G. Knepley } 30169318fe57SMatthew G. Knepley break; 30179318fe57SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 30189318fe57SMatthew G. Knepley { 30199318fe57SMatthew G. Knepley PetscInt numPoints[2] = {4, 1}; 30209318fe57SMatthew G. Knepley PetscInt coneSize[5] = {4, 0, 0, 0, 0}; 3021f0edb160SMatthew G. Knepley PetscInt cones[4] = {1, 2, 3, 4}; 30229318fe57SMatthew G. Knepley PetscInt coneOrientations[4] = {0, 0, 0, 0}; 3023f0edb160SMatthew 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}; 30249318fe57SMatthew G. Knepley 30259318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 30269318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 30279318fe57SMatthew G. Knepley } 30289318fe57SMatthew G. Knepley break; 30299318fe57SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 30309318fe57SMatthew G. Knepley { 30319318fe57SMatthew G. Knepley PetscInt numPoints[2] = {8, 1}; 30329318fe57SMatthew G. Knepley PetscInt coneSize[9] = {8, 0, 0, 0, 0, 0, 0, 0, 0}; 3033f0edb160SMatthew G. Knepley PetscInt cones[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 30349318fe57SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 3035f0edb160SMatthew 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, 30369318fe57SMatthew 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}; 30379318fe57SMatthew G. Knepley 30389318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 30399318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 30409318fe57SMatthew G. Knepley } 30419318fe57SMatthew G. Knepley break; 30429318fe57SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 30439318fe57SMatthew G. Knepley { 30449318fe57SMatthew G. Knepley PetscInt numPoints[2] = {6, 1}; 30459318fe57SMatthew G. Knepley PetscInt coneSize[7] = {6, 0, 0, 0, 0, 0, 0}; 3046f0edb160SMatthew G. Knepley PetscInt cones[6] = {1, 2, 3, 4, 5, 6}; 30479318fe57SMatthew G. Knepley PetscInt coneOrientations[6] = {0, 0, 0, 0, 0, 0}; 3048f0edb160SMatthew G. Knepley PetscScalar vertexCoords[18] = {-1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 30499318fe57SMatthew G. Knepley -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0}; 30509318fe57SMatthew G. Knepley 30519318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 30529318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 30539318fe57SMatthew G. Knepley } 30549318fe57SMatthew G. Knepley break; 30559318fe57SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 30569318fe57SMatthew G. Knepley { 30579318fe57SMatthew G. Knepley PetscInt numPoints[2] = {6, 1}; 30589318fe57SMatthew G. Knepley PetscInt coneSize[7] = {6, 0, 0, 0, 0, 0, 0}; 30599318fe57SMatthew G. Knepley PetscInt cones[6] = {1, 2, 3, 4, 5, 6}; 30609318fe57SMatthew G. Knepley PetscInt coneOrientations[6] = {0, 0, 0, 0, 0, 0}; 30619318fe57SMatthew G. Knepley PetscScalar vertexCoords[18] = {-1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 30629318fe57SMatthew G. Knepley -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0}; 30639318fe57SMatthew G. Knepley 30649318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 30659318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 30669318fe57SMatthew G. Knepley } 30679318fe57SMatthew G. Knepley break; 30689318fe57SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 30699318fe57SMatthew G. Knepley { 30709318fe57SMatthew G. Knepley PetscInt numPoints[2] = {8, 1}; 30719318fe57SMatthew G. Knepley PetscInt coneSize[9] = {8, 0, 0, 0, 0, 0, 0, 0, 0}; 30729318fe57SMatthew G. Knepley PetscInt cones[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 30739318fe57SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 30749318fe57SMatthew 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, 30759318fe57SMatthew 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}; 30769318fe57SMatthew G. Knepley 30779318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 30789318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 30799318fe57SMatthew G. Knepley } 30809318fe57SMatthew G. Knepley break; 30819318fe57SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 30829318fe57SMatthew G. Knepley { 30839318fe57SMatthew G. Knepley PetscInt numPoints[2] = {5, 1}; 30849318fe57SMatthew G. Knepley PetscInt coneSize[6] = {5, 0, 0, 0, 0, 0}; 3085f0edb160SMatthew G. Knepley PetscInt cones[5] = {1, 2, 3, 4, 5}; 30869318fe57SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 3087f0edb160SMatthew 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, 30889318fe57SMatthew G. Knepley 0.0, 0.0, 1.0}; 30899318fe57SMatthew G. Knepley 30909318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 30919318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 30929318fe57SMatthew G. Knepley } 30939318fe57SMatthew G. Knepley break; 309498921bdaSJacob Faibussowitsch default: SETERRQ(PetscObjectComm((PetscObject) rdm), PETSC_ERR_ARG_WRONG, "Cannot create reference cell for cell type %s", DMPolytopeTypes[ct]); 30959318fe57SMatthew G. Knepley } 30969318fe57SMatthew G. Knepley { 30979318fe57SMatthew G. Knepley PetscInt Nv, v; 30989318fe57SMatthew G. Knepley 30999318fe57SMatthew G. Knepley /* Must create the celltype label here so that we do not automatically try to compute the types */ 31009318fe57SMatthew G. Knepley ierr = DMCreateLabel(rdm, "celltype");CHKERRQ(ierr); 31019318fe57SMatthew G. Knepley ierr = DMPlexSetCellType(rdm, 0, ct);CHKERRQ(ierr); 31029318fe57SMatthew G. Knepley ierr = DMPlexGetChart(rdm, NULL, &Nv);CHKERRQ(ierr); 31039318fe57SMatthew G. Knepley for (v = 1; v < Nv; ++v) {ierr = DMPlexSetCellType(rdm, v, DM_POLYTOPE_POINT);CHKERRQ(ierr);} 31049318fe57SMatthew G. Knepley } 31059318fe57SMatthew G. Knepley ierr = DMPlexInterpolateInPlace_Internal(rdm);CHKERRQ(ierr); 3106b7f6ffafSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) rdm, DMPolytopeTypes[ct]);CHKERRQ(ierr); 31070a6ba040SMatthew G. Knepley PetscFunctionReturn(0); 31080a6ba040SMatthew G. Knepley } 31090a6ba040SMatthew G. Knepley 31109318fe57SMatthew G. Knepley /*@ 31119318fe57SMatthew G. Knepley DMPlexCreateReferenceCell - Create a DMPLEX with the appropriate FEM reference cell 31129318fe57SMatthew G. Knepley 31139318fe57SMatthew G. Knepley Collective 31149318fe57SMatthew G. Knepley 31159318fe57SMatthew G. Knepley Input Parameters: 31169318fe57SMatthew G. Knepley + comm - The communicator 31179318fe57SMatthew G. Knepley - ct - The cell type of the reference cell 31189318fe57SMatthew G. Knepley 31199318fe57SMatthew G. Knepley Output Parameter: 31209318fe57SMatthew G. Knepley . refdm - The reference cell 31219318fe57SMatthew G. Knepley 31229318fe57SMatthew G. Knepley Level: intermediate 31239318fe57SMatthew G. Knepley 31249318fe57SMatthew G. Knepley .seealso: DMPlexCreateReferenceCell(), DMPlexCreateBoxMesh() 31259318fe57SMatthew G. Knepley @*/ 31269318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateReferenceCell(MPI_Comm comm, DMPolytopeType ct, DM *refdm) 31270a6ba040SMatthew G. Knepley { 31280a6ba040SMatthew G. Knepley PetscErrorCode ierr; 31290a6ba040SMatthew G. Knepley 31300a6ba040SMatthew G. Knepley PetscFunctionBegin; 31319318fe57SMatthew G. Knepley ierr = DMCreate(comm, refdm);CHKERRQ(ierr); 31329318fe57SMatthew G. Knepley ierr = DMSetType(*refdm, DMPLEX);CHKERRQ(ierr); 31339318fe57SMatthew G. Knepley ierr = DMPlexCreateReferenceCell_Internal(*refdm, ct);CHKERRQ(ierr); 31349318fe57SMatthew G. Knepley PetscFunctionReturn(0); 31359318fe57SMatthew G. Knepley } 313679a015ccSMatthew G. Knepley 31379318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoundaryLabel_Private(DM dm, const char name[]) 31389318fe57SMatthew G. Knepley { 31399318fe57SMatthew G. Knepley DM plex; 31409318fe57SMatthew G. Knepley DMLabel label; 31419318fe57SMatthew G. Knepley PetscBool hasLabel; 31429318fe57SMatthew G. Knepley PetscErrorCode ierr; 31430a6ba040SMatthew G. Knepley 31449318fe57SMatthew G. Knepley PetscFunctionBeginUser; 31459318fe57SMatthew G. Knepley ierr = DMHasLabel(dm, name, &hasLabel);CHKERRQ(ierr); 31469318fe57SMatthew G. Knepley if (hasLabel) PetscFunctionReturn(0); 31479318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm, name);CHKERRQ(ierr); 31489318fe57SMatthew G. Knepley ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 31499318fe57SMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 31509318fe57SMatthew G. Knepley ierr = DMPlexMarkBoundaryFaces(plex, 1, label);CHKERRQ(ierr); 31519318fe57SMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 31529318fe57SMatthew G. Knepley PetscFunctionReturn(0); 31539318fe57SMatthew G. Knepley } 3154acdc6f61SToby Isaac 3155b7f5c055SJed Brown const char * const DMPlexShapes[] = {"box", "box_surface", "ball", "sphere", "cylinder", "schwarz_p", "gyroid", "unknown", "DMPlexShape", "DM_SHAPE_", NULL}; 31569318fe57SMatthew G. Knepley 315761a622f3SMatthew G. Knepley static PetscErrorCode DMPlexCreateFromOptions_Internal(PetscOptionItems *PetscOptionsObject, PetscBool *useCoordSpace, DM dm) 31589318fe57SMatthew G. Knepley { 31599318fe57SMatthew G. Knepley DMPlexShape shape = DM_SHAPE_BOX; 31609318fe57SMatthew G. Knepley DMPolytopeType cell = DM_POLYTOPE_TRIANGLE; 31619318fe57SMatthew G. Knepley PetscInt dim = 2; 31629318fe57SMatthew G. Knepley PetscBool simplex = PETSC_TRUE, interpolate = PETSC_TRUE, adjCone = PETSC_FALSE, adjClosure = PETSC_TRUE, refDomain = PETSC_FALSE; 3163cd7e8a5eSksagiyam PetscBool flg, flg2, fflg, bdfflg, nameflg; 31649318fe57SMatthew G. Knepley MPI_Comm comm; 3165ed5e4e85SVaclav Hapla char filename[PETSC_MAX_PATH_LEN] = "<unspecified>"; 3166ed5e4e85SVaclav Hapla char bdFilename[PETSC_MAX_PATH_LEN] = "<unspecified>"; 3167ed5e4e85SVaclav Hapla char plexname[PETSC_MAX_PATH_LEN] = ""; 31689318fe57SMatthew G. Knepley PetscErrorCode ierr; 31699318fe57SMatthew G. Knepley 31709318fe57SMatthew G. Knepley PetscFunctionBegin; 31719318fe57SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 31729318fe57SMatthew G. Knepley /* TODO Turn this into a registration interface */ 31739318fe57SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_filename", "File containing a mesh", "DMPlexCreateFromFile", filename, filename, sizeof(filename), &fflg);CHKERRQ(ierr); 31749318fe57SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_boundary_filename", "File containing a mesh boundary", "DMPlexCreateFromFile", bdFilename, bdFilename, sizeof(bdFilename), &bdfflg);CHKERRQ(ierr); 3175cd7e8a5eSksagiyam ierr = PetscOptionsString("-dm_plex_name", "Name of the mesh in the file", "DMPlexCreateFromFile", plexname, plexname, sizeof(plexname), &nameflg);CHKERRQ(ierr); 31769318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_cell", "Cell shape", "", DMPolytopeTypes, (PetscEnum) cell, (PetscEnum *) &cell, NULL);CHKERRQ(ierr); 31779318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_reference_cell_domain", "Use a reference cell domain", "", refDomain, &refDomain, NULL);CHKERRQ(ierr); 31789318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_shape", "Shape for built-in mesh", "", DMPlexShapes, (PetscEnum) shape, (PetscEnum *) &shape, &flg);CHKERRQ(ierr); 31799318fe57SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_plex_dim", "Topological dimension of the mesh", "DMGetDimension", dim, &dim, &flg, 0);CHKERRQ(ierr); 31802c71b3e2SJacob Faibussowitsch PetscCheckFalse((dim < 0) || (dim > 3),comm, PETSC_ERR_ARG_OUTOFRANGE, "Dimension %D should be in [1, 3]", dim); 31819318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_simplex", "Mesh cell shape", "", simplex, &simplex, &flg);CHKERRQ(ierr); 31829318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_interpolate", "Flag to create edges and faces automatically", "", interpolate, &interpolate, &flg);CHKERRQ(ierr); 31839318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_adj_cone", "Set adjacency direction", "DMSetBasicAdjacency", adjCone, &adjCone, &flg);CHKERRQ(ierr); 31849318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_adj_closure", "Set adjacency size", "DMSetBasicAdjacency", adjClosure, &adjClosure, &flg2);CHKERRQ(ierr); 31859318fe57SMatthew G. Knepley if (flg || flg2) {ierr = DMSetBasicAdjacency(dm, adjCone, adjClosure);CHKERRQ(ierr);} 31869318fe57SMatthew G. Knepley 318761a622f3SMatthew G. Knepley switch (cell) { 318861a622f3SMatthew G. Knepley case DM_POLYTOPE_POINT: 318961a622f3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 319061a622f3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 319161a622f3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 319261a622f3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 319361a622f3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 319461a622f3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 319561a622f3SMatthew G. Knepley *useCoordSpace = PETSC_TRUE;break; 319661a622f3SMatthew G. Knepley default: *useCoordSpace = PETSC_FALSE;break; 319761a622f3SMatthew G. Knepley } 319861a622f3SMatthew G. Knepley 31999318fe57SMatthew G. Knepley if (fflg) { 32009318fe57SMatthew G. Knepley DM dmnew; 32019318fe57SMatthew G. Knepley 3202cd7e8a5eSksagiyam ierr = DMPlexCreateFromFile(PetscObjectComm((PetscObject) dm), filename, plexname, interpolate, &dmnew);CHKERRQ(ierr); 3203e600fa54SMatthew G. Knepley ierr = DMPlexCopy_Internal(dm, PETSC_FALSE, dmnew);CHKERRQ(ierr); 32049318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &dmnew);CHKERRQ(ierr); 32059318fe57SMatthew G. Knepley } else if (refDomain) { 32069318fe57SMatthew G. Knepley ierr = DMPlexCreateReferenceCell_Internal(dm, cell);CHKERRQ(ierr); 32079318fe57SMatthew G. Knepley } else if (bdfflg) { 32089318fe57SMatthew G. Knepley DM bdm, dmnew; 32099318fe57SMatthew G. Knepley 3210cd7e8a5eSksagiyam ierr = DMPlexCreateFromFile(PetscObjectComm((PetscObject) dm), bdFilename, plexname, interpolate, &bdm);CHKERRQ(ierr); 32119318fe57SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) bdm, "bd_");CHKERRQ(ierr); 32129318fe57SMatthew G. Knepley ierr = DMSetFromOptions(bdm);CHKERRQ(ierr); 32139318fe57SMatthew G. Knepley ierr = DMPlexGenerate(bdm, NULL, interpolate, &dmnew);CHKERRQ(ierr); 32149318fe57SMatthew G. Knepley ierr = DMDestroy(&bdm);CHKERRQ(ierr); 3215e600fa54SMatthew G. Knepley ierr = DMPlexCopy_Internal(dm, PETSC_FALSE, dmnew);CHKERRQ(ierr); 32169318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &dmnew);CHKERRQ(ierr); 32179318fe57SMatthew G. Knepley } else { 32189318fe57SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) dm, DMPlexShapes[shape]);CHKERRQ(ierr); 32199318fe57SMatthew G. Knepley switch (shape) { 32209318fe57SMatthew G. Knepley case DM_SHAPE_BOX: 32219318fe57SMatthew G. Knepley { 32229318fe57SMatthew G. Knepley PetscInt faces[3] = {0, 0, 0}; 32239318fe57SMatthew G. Knepley PetscReal lower[3] = {0, 0, 0}; 32249318fe57SMatthew G. Knepley PetscReal upper[3] = {1, 1, 1}; 32259318fe57SMatthew G. Knepley DMBoundaryType bdt[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE}; 32269318fe57SMatthew G. Knepley PetscInt i, n; 32279318fe57SMatthew G. Knepley 32289318fe57SMatthew G. Knepley n = dim; 32299318fe57SMatthew G. Knepley for (i = 0; i < dim; ++i) faces[i] = (dim == 1 ? 1 : 4-dim); 32309318fe57SMatthew G. Knepley ierr = PetscOptionsIntArray("-dm_plex_box_faces", "Number of faces along each dimension", "", faces, &n, &flg);CHKERRQ(ierr); 32319318fe57SMatthew G. Knepley n = 3; 32329318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_lower", "Lower left corner of box", "", lower, &n, &flg);CHKERRQ(ierr); 32332c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && (n != dim),comm, PETSC_ERR_ARG_SIZ, "Lower box point had %D values, should have been %D", n, dim); 32349318fe57SMatthew G. Knepley n = 3; 32359318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_upper", "Upper right corner of box", "", upper, &n, &flg);CHKERRQ(ierr); 32362c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && (n != dim),comm, PETSC_ERR_ARG_SIZ, "Upper box point had %D values, should have been %D", n, dim); 32379318fe57SMatthew G. Knepley n = 3; 32389318fe57SMatthew G. Knepley ierr = PetscOptionsEnumArray("-dm_plex_box_bd", "Boundary type for each dimension", "", DMBoundaryTypes, (PetscEnum *) bdt, &n, &flg);CHKERRQ(ierr); 32392c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && (n != dim),comm, PETSC_ERR_ARG_SIZ, "Box boundary types had %D values, should have been %D", n, dim); 32409318fe57SMatthew G. Knepley switch (cell) { 324161a622f3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 3242d410b0cfSMatthew G. Knepley ierr = DMPlexCreateWedgeBoxMesh_Internal(dm, faces, lower, upper, bdt);CHKERRQ(ierr); 3243d410b0cfSMatthew G. Knepley if (!interpolate) { 3244d410b0cfSMatthew G. Knepley DM udm; 3245d410b0cfSMatthew G. Knepley 3246d410b0cfSMatthew G. Knepley ierr = DMPlexUninterpolate(dm, &udm);CHKERRQ(ierr); 3247d410b0cfSMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &udm);CHKERRQ(ierr); 3248d410b0cfSMatthew G. Knepley } 32499318fe57SMatthew G. Knepley break; 32509318fe57SMatthew G. Knepley default: 32519318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxMesh_Internal(dm, dim, simplex, faces, lower, upper, bdt, interpolate);CHKERRQ(ierr); 32529318fe57SMatthew G. Knepley break; 32539318fe57SMatthew G. Knepley } 32549318fe57SMatthew G. Knepley } 32559318fe57SMatthew G. Knepley break; 32569318fe57SMatthew G. Knepley case DM_SHAPE_BOX_SURFACE: 32579318fe57SMatthew G. Knepley { 32589318fe57SMatthew G. Knepley PetscInt faces[3] = {0, 0, 0}; 32599318fe57SMatthew G. Knepley PetscReal lower[3] = {0, 0, 0}; 32609318fe57SMatthew G. Knepley PetscReal upper[3] = {1, 1, 1}; 32619318fe57SMatthew G. Knepley PetscInt i, n; 32629318fe57SMatthew G. Knepley 32639318fe57SMatthew G. Knepley n = dim+1; 32649318fe57SMatthew G. Knepley for (i = 0; i < dim+1; ++i) faces[i] = (dim+1 == 1 ? 1 : 4-(dim+1)); 32659318fe57SMatthew G. Knepley ierr = PetscOptionsIntArray("-dm_plex_box_faces", "Number of faces along each dimension", "", faces, &n, &flg);CHKERRQ(ierr); 32669318fe57SMatthew G. Knepley n = 3; 32679318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_lower", "Lower left corner of box", "", lower, &n, &flg);CHKERRQ(ierr); 32682c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && (n != dim+1),comm, PETSC_ERR_ARG_SIZ, "Lower box point had %D values, should have been %D", n, dim+1); 32699318fe57SMatthew G. Knepley n = 3; 32709318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_upper", "Upper right corner of box", "", upper, &n, &flg);CHKERRQ(ierr); 32712c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && (n != dim+1),comm, PETSC_ERR_ARG_SIZ, "Upper box point had %D values, should have been %D", n, dim+1); 32729318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxSurfaceMesh_Internal(dm, dim+1, faces, lower, upper, interpolate);CHKERRQ(ierr); 32739318fe57SMatthew G. Knepley } 32749318fe57SMatthew G. Knepley break; 32759318fe57SMatthew G. Knepley case DM_SHAPE_SPHERE: 32769318fe57SMatthew G. Knepley { 32779318fe57SMatthew G. Knepley PetscReal R = 1.0; 32789318fe57SMatthew G. Knepley 32799318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_sphere_radius", "Radius of the sphere", "", R, &R, &flg);CHKERRQ(ierr); 32809318fe57SMatthew G. Knepley ierr = DMPlexCreateSphereMesh_Internal(dm, dim, simplex, R);CHKERRQ(ierr); 32819318fe57SMatthew G. Knepley } 32829318fe57SMatthew G. Knepley break; 32839318fe57SMatthew G. Knepley case DM_SHAPE_BALL: 32849318fe57SMatthew G. Knepley { 32859318fe57SMatthew G. Knepley PetscReal R = 1.0; 32869318fe57SMatthew G. Knepley 32879318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_ball_radius", "Radius of the ball", "", R, &R, &flg);CHKERRQ(ierr); 32889318fe57SMatthew G. Knepley ierr = DMPlexCreateBallMesh_Internal(dm, dim, R);CHKERRQ(ierr); 32899318fe57SMatthew G. Knepley } 32909318fe57SMatthew G. Knepley break; 32919318fe57SMatthew G. Knepley case DM_SHAPE_CYLINDER: 32929318fe57SMatthew G. Knepley { 32939318fe57SMatthew G. Knepley DMBoundaryType bdt = DM_BOUNDARY_NONE; 32949318fe57SMatthew G. Knepley PetscInt Nw = 6; 32959318fe57SMatthew G. Knepley 32969318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_cylinder_bd", "Boundary type in the z direction", "", DMBoundaryTypes, (PetscEnum) bdt, (PetscEnum *) &bdt, NULL);CHKERRQ(ierr); 329761a622f3SMatthew G. Knepley ierr = PetscOptionsInt("-dm_plex_cylinder_num_wedges", "Number of wedges around the cylinder", "", Nw, &Nw, NULL);CHKERRQ(ierr); 32989318fe57SMatthew G. Knepley switch (cell) { 329961a622f3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 33009318fe57SMatthew G. Knepley ierr = DMPlexCreateWedgeCylinderMesh_Internal(dm, Nw, interpolate);CHKERRQ(ierr); 33019318fe57SMatthew G. Knepley break; 33029318fe57SMatthew G. Knepley default: 33039318fe57SMatthew G. Knepley ierr = DMPlexCreateHexCylinderMesh_Internal(dm, bdt);CHKERRQ(ierr); 33049318fe57SMatthew G. Knepley break; 33059318fe57SMatthew G. Knepley } 33069318fe57SMatthew G. Knepley } 33079318fe57SMatthew G. Knepley break; 3308b7f5c055SJed Brown case DM_SHAPE_SCHWARZ_P: // fallthrough 3309b7f5c055SJed Brown case DM_SHAPE_GYROID: 3310b7f5c055SJed Brown { 3311b7f5c055SJed Brown PetscInt extent[3] = {1,1,1}, refine = 0, layers = 0, three; 3312b7f5c055SJed Brown PetscReal thickness = 0.; 3313b7f5c055SJed Brown DMBoundaryType periodic[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE}; 3314b7f5c055SJed Brown DMPlexTPSType tps_type = shape == DM_SHAPE_SCHWARZ_P ? DMPLEX_TPS_SCHWARZ_P : DMPLEX_TPS_GYROID; 3315*1436d7faSJed Brown PetscBool tps_distribute; 3316b7f5c055SJed Brown ierr = PetscOptionsIntArray("-dm_plex_tps_extent", "Number of replicas for each of three dimensions", NULL, extent, (three=3, &three), NULL);CHKERRQ(ierr); 3317b7f5c055SJed Brown ierr = PetscOptionsInt("-dm_plex_tps_refine", "Number of refinements", NULL, refine, &refine, NULL);CHKERRQ(ierr); 3318b7f5c055SJed Brown ierr = PetscOptionsEnumArray("-dm_plex_tps_periodic", "Periodicity in each of three dimensions", NULL, DMBoundaryTypes, (PetscEnum*)periodic, (three=3, &three), NULL);CHKERRQ(ierr); 3319b7f5c055SJed Brown ierr = PetscOptionsInt("-dm_plex_tps_layers", "Number of layers in volumetric extrusion (or zero to not extrude)", NULL, layers, &layers, NULL);CHKERRQ(ierr); 3320b7f5c055SJed Brown ierr = PetscOptionsReal("-dm_plex_tps_thickness", "Thickness of volumetric extrusion", NULL, thickness, &thickness, NULL);CHKERRQ(ierr); 3321*1436d7faSJed Brown ierr = DMPlexDistributeGetDefault(dm, &tps_distribute);CHKERRQ(ierr); 3322*1436d7faSJed Brown ierr = PetscOptionsBool("-dm_plex_tps_distribute", "Distribute the 2D mesh prior to refinement and extrusion", NULL, tps_distribute, &tps_distribute, NULL);CHKERRQ(ierr); 3323*1436d7faSJed Brown ierr = DMPlexCreateTPSMesh_Internal(dm, tps_type, extent, periodic, tps_distribute, refine, layers, thickness);CHKERRQ(ierr); 3324b7f5c055SJed Brown } 3325b7f5c055SJed Brown break; 332698921bdaSJacob Faibussowitsch default: SETERRQ(comm, PETSC_ERR_SUP, "Domain shape %s is unsupported", DMPlexShapes[shape]); 33279318fe57SMatthew G. Knepley } 33289318fe57SMatthew G. Knepley } 33299318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr); 3330ed5e4e85SVaclav Hapla if (!((PetscObject)dm)->name && nameflg) { 3331ed5e4e85SVaclav Hapla ierr = PetscObjectSetName((PetscObject)dm, plexname);CHKERRQ(ierr); 3332ed5e4e85SVaclav Hapla } 33330a6ba040SMatthew G. Knepley PetscFunctionReturn(0); 33340a6ba040SMatthew G. Knepley } 33350a6ba040SMatthew G. Knepley 333647920aaeSMatthew G. Knepley PetscErrorCode DMSetFromOptions_NonRefinement_Plex(PetscOptionItems *PetscOptionsObject, DM dm) 33370a6ba040SMatthew G. Knepley { 33380a6ba040SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 3339c0f0dcc3SMatthew G. Knepley PetscBool flg; 33409318fe57SMatthew G. Knepley char bdLabel[PETSC_MAX_PATH_LEN]; 33410a6ba040SMatthew G. Knepley PetscErrorCode ierr; 33420a6ba040SMatthew G. Knepley 33430a6ba040SMatthew G. Knepley PetscFunctionBegin; 33440a6ba040SMatthew G. Knepley /* Handle viewing */ 33450c77aedcSMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_print_set_values", "Output all set values info", "DMPlexMatSetClosure", PETSC_FALSE, &mesh->printSetValues, NULL);CHKERRQ(ierr); 33465a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_plex_print_fem", "Debug output level all fem computations", "DMPlexSNESComputeResidualFEM", 0, &mesh->printFEM, NULL,0);CHKERRQ(ierr); 33470c77aedcSMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_print_tol", "Tolerance for FEM output", "DMPlexSNESComputeResidualFEM", mesh->printTol, &mesh->printTol, NULL);CHKERRQ(ierr); 33485a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_plex_print_l2", "Debug output level all L2 diff computations", "DMComputeL2Diff", 0, &mesh->printL2, NULL,0);CHKERRQ(ierr); 3349c0f0dcc3SMatthew G. Knepley ierr = DMMonitorSetFromOptions(dm, "-dm_plex_monitor_throughput", "Monitor the simulation throughput", "DMPlexMonitorThroughput", DMPlexMonitorThroughput, NULL, &flg);CHKERRQ(ierr); 3350c0f0dcc3SMatthew G. Knepley if (flg) {ierr = PetscLogDefaultBegin();CHKERRQ(ierr);} 33519318fe57SMatthew G. Knepley /* Labeling */ 33529318fe57SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_boundary_label", "Label to mark the mesh boundary", "", bdLabel, bdLabel, sizeof(bdLabel), &flg);CHKERRQ(ierr); 33539318fe57SMatthew G. Knepley if (flg) {ierr = DMPlexCreateBoundaryLabel_Private(dm, bdLabel);CHKERRQ(ierr);} 3354953fc75cSMatthew G. Knepley /* Point Location */ 33550c77aedcSMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_hash_location", "Use grid hashing for point location", "DMInterpolate", PETSC_FALSE, &mesh->useHashLocation, NULL);CHKERRQ(ierr); 33560848f4b5SMatthew G. Knepley /* Partitioning and distribution */ 335798ba2d7fSLawrence 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); 33582e62ab5aSMatthew G. Knepley /* Generation and remeshing */ 33590c77aedcSMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_remesh_bd", "Allow changes to the boundary on remeshing", "DMAdapt", PETSC_FALSE, &mesh->remeshBd, NULL);CHKERRQ(ierr); 3360b29cfa1cSToby Isaac /* Projection behavior */ 33615a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_plex_max_projection_height", "Maxmimum mesh point height used to project locally", "DMPlexSetMaxProjectionHeight", 0, &mesh->maxProjectionHeight, NULL,0);CHKERRQ(ierr); 336264141f95SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_regular_refinement", "Use special nested projection algorithm for regular refinement", "DMPlexSetRegularRefinement", mesh->regularRefinement, &mesh->regularRefinement, NULL);CHKERRQ(ierr); 3363f12cf164SMatthew G. Knepley /* Checking structure */ 3364f12cf164SMatthew G. Knepley { 3365e902f1eaSVaclav Hapla PetscBool flg = PETSC_FALSE, flg2 = PETSC_FALSE, all = PETSC_FALSE; 3366f12cf164SMatthew G. Knepley 3367e902f1eaSVaclav Hapla ierr = PetscOptionsBool("-dm_plex_check_all", "Perform all checks", NULL, PETSC_FALSE, &all, &flg2);CHKERRQ(ierr); 3368f12cf164SMatthew 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); 3369e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckSymmetry(dm);CHKERRQ(ierr);} 337025c50c26SVaclav 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); 3371e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckSkeleton(dm, 0);CHKERRQ(ierr);} 337225c50c26SVaclav 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); 3373e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckFaces(dm, 0);CHKERRQ(ierr);} 3374f12cf164SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_check_geometry", "Check that cells have positive volume", "DMPlexCheckGeometry", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 3375e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckGeometry(dm);CHKERRQ(ierr);} 337675ebff7aSVaclav Hapla ierr = PetscOptionsBool("-dm_plex_check_pointsf", "Check some necessary conditions for PointSF", "DMPlexCheckPointSF", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 3377e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckPointSF(dm);CHKERRQ(ierr);} 337875ebff7aSVaclav 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); 3379e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckInterfaceCones(dm);CHKERRQ(ierr);} 3380412e9a14SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_check_cell_shape", "Check cell shape", "DMPlexCheckCellShape", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 3381412e9a14SMatthew G. Knepley if (flg && flg2) {ierr = DMPlexCheckCellShape(dm, PETSC_TRUE, PETSC_DETERMINE);CHKERRQ(ierr);} 3382f12cf164SMatthew G. Knepley } 33839318fe57SMatthew G. Knepley { 33849318fe57SMatthew G. Knepley PetscReal scale = 1.0; 33854f3833eaSMatthew G. Knepley 33869318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_scale", "Scale factor for mesh coordinates", "DMPlexScale", scale, &scale, &flg);CHKERRQ(ierr); 33879318fe57SMatthew G. Knepley if (flg) { 33889318fe57SMatthew G. Knepley Vec coordinates, coordinatesLocal; 33899318fe57SMatthew G. Knepley 33909318fe57SMatthew G. Knepley ierr = DMGetCoordinates(dm, &coordinates);CHKERRQ(ierr); 33919318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinatesLocal);CHKERRQ(ierr); 33929318fe57SMatthew G. Knepley ierr = VecScale(coordinates, scale);CHKERRQ(ierr); 33939318fe57SMatthew G. Knepley ierr = VecScale(coordinatesLocal, scale);CHKERRQ(ierr); 33949318fe57SMatthew G. Knepley } 33959318fe57SMatthew G. Knepley } 33964f3833eaSMatthew G. Knepley ierr = PetscPartitionerSetFromOptions(mesh->partitioner);CHKERRQ(ierr); 339768d4fef7SMatthew G. Knepley PetscFunctionReturn(0); 339868d4fef7SMatthew G. Knepley } 339968d4fef7SMatthew G. Knepley 340046fa42a0SMatthew G. Knepley static PetscErrorCode DMSetFromOptions_Plex(PetscOptionItems *PetscOptionsObject,DM dm) 340168d4fef7SMatthew G. Knepley { 3402bdf63967SMatthew G. Knepley PetscFunctionList ordlist; 3403bdf63967SMatthew G. Knepley char oname[256]; 3404d410b0cfSMatthew G. Knepley PetscReal volume = -1.0; 34059318fe57SMatthew G. Knepley PetscInt prerefine = 0, refine = 0, r, coarsen = 0, overlap = 0, extLayers = 0, dim; 3406e600fa54SMatthew 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; 340768d4fef7SMatthew G. Knepley PetscErrorCode ierr; 340868d4fef7SMatthew G. Knepley 340968d4fef7SMatthew G. Knepley PetscFunctionBegin; 3410064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 34111a1499c8SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"DMPlex Options");CHKERRQ(ierr); 34129318fe57SMatthew G. Knepley /* Handle automatic creation */ 34139318fe57SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 341461a622f3SMatthew G. Knepley if (dim < 0) {ierr = DMPlexCreateFromOptions_Internal(PetscOptionsObject, &coordSpace, dm);CHKERRQ(ierr);created = PETSC_TRUE;} 3415d89e6e46SMatthew G. Knepley /* Handle interpolation before distribution */ 3416d89e6e46SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_interpolate_pre", "Flag to interpolate mesh before distribution", "", interpolate, &interpolate, &flg);CHKERRQ(ierr); 3417d89e6e46SMatthew G. Knepley if (flg) { 3418d89e6e46SMatthew G. Knepley DMPlexInterpolatedFlag interpolated; 3419d89e6e46SMatthew G. Knepley 3420d89e6e46SMatthew G. Knepley ierr = DMPlexIsInterpolated(dm, &interpolated);CHKERRQ(ierr); 3421d89e6e46SMatthew G. Knepley if (interpolated == DMPLEX_INTERPOLATED_FULL && !interpolate) { 3422d89e6e46SMatthew G. Knepley DM udm; 3423d89e6e46SMatthew G. Knepley 3424d89e6e46SMatthew G. Knepley ierr = DMPlexUninterpolate(dm, &udm);CHKERRQ(ierr); 3425d89e6e46SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &udm);CHKERRQ(ierr); 3426d89e6e46SMatthew G. Knepley } else if (interpolated != DMPLEX_INTERPOLATED_FULL && interpolate) { 3427d89e6e46SMatthew G. Knepley DM idm; 3428d89e6e46SMatthew G. Knepley 3429d89e6e46SMatthew G. Knepley ierr = DMPlexInterpolate(dm, &idm);CHKERRQ(ierr); 3430d89e6e46SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &idm);CHKERRQ(ierr); 3431d89e6e46SMatthew G. Knepley } 3432d89e6e46SMatthew G. Knepley } 34339b44eab4SMatthew G. Knepley /* Handle DMPlex refinement before distribution */ 3434c1cad2e7SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_ignore_model", "Flag to ignore the geometry model when refining", "DMCreate", ignoreModel, &ignoreModel, &flg);CHKERRQ(ierr); 3435c1cad2e7SMatthew G. Knepley if (flg) {((DM_Plex *) dm->data)->ignoreModel = ignoreModel;} 3436250712c9SMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &uniformOrig);CHKERRQ(ierr); 34379318fe57SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_refine_pre", "The number of refinements before distribution", "DMCreate", prerefine, &prerefine, NULL,0);CHKERRQ(ierr); 343861a622f3SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_remap_pre", "Flag to control coordinate remapping", "DMCreate", remap, &remap, NULL);CHKERRQ(ierr); 3439250712c9SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_uniform_pre", "Flag for uniform refinement before distribution", "DMCreate", uniform, &uniform, &flg);CHKERRQ(ierr); 3440250712c9SMatthew G. Knepley if (flg) {ierr = DMPlexSetRefinementUniform(dm, uniform);CHKERRQ(ierr);} 3441250712c9SMatthew G. Knepley ierr = PetscOptionsReal("-dm_refine_volume_limit_pre", "The maximum cell volume after refinement before distribution", "DMCreate", volume, &volume, &flg);CHKERRQ(ierr); 34429318fe57SMatthew G. Knepley if (flg) { 34439318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, PETSC_FALSE);CHKERRQ(ierr); 34449318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementLimit(dm, volume);CHKERRQ(ierr); 34459318fe57SMatthew G. Knepley prerefine = PetscMax(prerefine, 1); 34469318fe57SMatthew G. Knepley } 34479b44eab4SMatthew G. Knepley for (r = 0; r < prerefine; ++r) { 34489b44eab4SMatthew G. Knepley DM rdm; 34499b44eab4SMatthew G. Knepley PetscPointFunc coordFunc = ((DM_Plex*) dm->data)->coordFunc; 34509b44eab4SMatthew G. Knepley 34519b44eab4SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 34529b44eab4SMatthew G. Knepley ierr = DMRefine(dm, PetscObjectComm((PetscObject) dm), &rdm);CHKERRQ(ierr); 34539318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &rdm);CHKERRQ(ierr); 34549b44eab4SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 345561a622f3SMatthew G. Knepley if (coordFunc && remap) { 34569b44eab4SMatthew G. Knepley ierr = DMPlexRemapGeometry(dm, 0.0, coordFunc);CHKERRQ(ierr); 34579b44eab4SMatthew G. Knepley ((DM_Plex*) dm->data)->coordFunc = coordFunc; 34589b44eab4SMatthew G. Knepley } 34599b44eab4SMatthew G. Knepley } 3460250712c9SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, uniformOrig);CHKERRQ(ierr); 34619318fe57SMatthew G. Knepley /* Handle DMPlex extrusion before distribution */ 3462d410b0cfSMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_extrude", "The number of layers to extrude", "", extLayers, &extLayers, NULL, 0);CHKERRQ(ierr); 34639318fe57SMatthew G. Knepley if (extLayers) { 34649318fe57SMatthew G. Knepley DM edm; 34659318fe57SMatthew G. Knepley 3466d410b0cfSMatthew G. Knepley ierr = DMExtrude(dm, extLayers, &edm);CHKERRQ(ierr); 34679318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &edm);CHKERRQ(ierr); 346848d16a33SMatthew G. Knepley ((DM_Plex *) dm->data)->coordFunc = NULL; 3469d410b0cfSMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 3470d410b0cfSMatthew G. Knepley extLayers = 0; 34719318fe57SMatthew G. Knepley } 3472bdf63967SMatthew G. Knepley /* Handle DMPlex reordering before distribution */ 3473bdf63967SMatthew G. Knepley ierr = MatGetOrderingList(&ordlist);CHKERRQ(ierr); 3474bdf63967SMatthew G. Knepley ierr = PetscOptionsFList("-dm_plex_reorder", "Set mesh reordering type", "DMPlexGetOrdering", ordlist, MATORDERINGNATURAL, oname, sizeof(oname), &flg);CHKERRQ(ierr); 3475bdf63967SMatthew G. Knepley if (flg) { 3476bdf63967SMatthew G. Knepley DM pdm; 3477bdf63967SMatthew G. Knepley IS perm; 3478bdf63967SMatthew G. Knepley 3479bdf63967SMatthew G. Knepley ierr = DMPlexGetOrdering(dm, oname, NULL, &perm);CHKERRQ(ierr); 3480bdf63967SMatthew G. Knepley ierr = DMPlexPermute(dm, perm, &pdm);CHKERRQ(ierr); 3481bdf63967SMatthew G. Knepley ierr = ISDestroy(&perm);CHKERRQ(ierr); 3482bdf63967SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &pdm);CHKERRQ(ierr); 3483bdf63967SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 3484bdf63967SMatthew G. Knepley } 34859b44eab4SMatthew G. Knepley /* Handle DMPlex distribution */ 3486e600fa54SMatthew G. Knepley ierr = DMPlexDistributeGetDefault(dm, &distribute);CHKERRQ(ierr); 34879b44eab4SMatthew G. Knepley ierr = PetscOptionsBool("-dm_distribute", "Flag to redistribute a mesh among processes", "DMCreate", distribute, &distribute, NULL);CHKERRQ(ierr); 34889b44eab4SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_distribute_overlap", "The size of the overlap halo", "DMCreate", overlap, &overlap, NULL, 0);CHKERRQ(ierr); 34899b44eab4SMatthew G. Knepley if (distribute) { 34909b44eab4SMatthew G. Knepley DM pdm = NULL; 34919b44eab4SMatthew G. Knepley PetscPartitioner part; 34929b44eab4SMatthew G. Knepley 34939b44eab4SMatthew G. Knepley ierr = DMPlexGetPartitioner(dm, &part);CHKERRQ(ierr); 34949b44eab4SMatthew G. Knepley ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); 34959b44eab4SMatthew G. Knepley ierr = DMPlexDistribute(dm, overlap, NULL, &pdm);CHKERRQ(ierr); 34969b44eab4SMatthew G. Knepley if (pdm) { 34979318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &pdm);CHKERRQ(ierr); 34989b44eab4SMatthew G. Knepley } 34999b44eab4SMatthew G. Knepley } 35009318fe57SMatthew G. Knepley /* Create coordinate space */ 35019318fe57SMatthew G. Knepley if (created) { 350261a622f3SMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) dm->data; 35039318fe57SMatthew G. Knepley PetscInt degree = 1; 350461a622f3SMatthew G. Knepley PetscBool periodic, flg; 35059318fe57SMatthew G. Knepley 350661a622f3SMatthew G. Knepley ierr = PetscOptionsBool("-dm_coord_space", "Use an FEM space for coordinates", "", coordSpace, &coordSpace, &flg);CHKERRQ(ierr); 35079318fe57SMatthew G. Knepley ierr = PetscOptionsInt("-dm_coord_petscspace_degree", "FEM degree for coordinate space", "", degree, °ree, NULL);CHKERRQ(ierr); 350861a622f3SMatthew G. Knepley if (coordSpace) {ierr = DMPlexCreateCoordinateSpace(dm, degree, mesh->coordFunc);CHKERRQ(ierr);} 350961a622f3SMatthew G. Knepley if (flg && !coordSpace) { 351061a622f3SMatthew G. Knepley DM cdm; 351161a622f3SMatthew G. Knepley PetscDS cds; 351261a622f3SMatthew G. Knepley PetscObject obj; 351361a622f3SMatthew G. Knepley PetscClassId id; 351461a622f3SMatthew G. Knepley 351561a622f3SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 351661a622f3SMatthew G. Knepley ierr = DMGetDS(cdm, &cds);CHKERRQ(ierr); 351761a622f3SMatthew G. Knepley ierr = PetscDSGetDiscretization(cds, 0, &obj);CHKERRQ(ierr); 351861a622f3SMatthew G. Knepley ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 351961a622f3SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 352061a622f3SMatthew G. Knepley PetscContainer dummy; 352161a622f3SMatthew G. Knepley 352261a622f3SMatthew G. Knepley ierr = PetscContainerCreate(PETSC_COMM_SELF, &dummy);CHKERRQ(ierr); 352361a622f3SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) dummy, "coordinates");CHKERRQ(ierr); 352461a622f3SMatthew G. Knepley ierr = DMSetField(cdm, 0, NULL, (PetscObject) dummy);CHKERRQ(ierr); 352561a622f3SMatthew G. Knepley ierr = PetscContainerDestroy(&dummy);CHKERRQ(ierr); 352661a622f3SMatthew G. Knepley ierr = DMClearDS(cdm);CHKERRQ(ierr); 352761a622f3SMatthew G. Knepley } 352861a622f3SMatthew G. Knepley mesh->coordFunc = NULL; 352961a622f3SMatthew G. Knepley } 35309318fe57SMatthew G. Knepley ierr = DMLocalizeCoordinates(dm);CHKERRQ(ierr); 353161a622f3SMatthew G. Knepley ierr = DMGetPeriodicity(dm, &periodic, NULL, NULL, NULL);CHKERRQ(ierr); 353261a622f3SMatthew G. Knepley if (periodic) {ierr = DMSetPeriodicity(dm, PETSC_TRUE, NULL, NULL, NULL);CHKERRQ(ierr);} 35339318fe57SMatthew G. Knepley } 353468d4fef7SMatthew G. Knepley /* Handle DMPlex refinement */ 353561a622f3SMatthew G. Knepley remap = PETSC_TRUE; 35365a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_refine", "The number of uniform refinements", "DMCreate", refine, &refine, NULL,0);CHKERRQ(ierr); 353761a622f3SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_remap", "Flag to control coordinate remapping", "DMCreate", remap, &remap, NULL);CHKERRQ(ierr); 35385a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_refine_hierarchy", "The number of uniform refinements", "DMCreate", refine, &refine, &isHierarchy,0);CHKERRQ(ierr); 3539b6a0289aSMatthew G. Knepley if (refine) {ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr);} 354068d4fef7SMatthew G. Knepley if (refine && isHierarchy) { 3541acdc6f61SToby Isaac DM *dms, coarseDM; 354268d4fef7SMatthew G. Knepley 3543acdc6f61SToby Isaac ierr = DMGetCoarseDM(dm, &coarseDM);CHKERRQ(ierr); 3544acdc6f61SToby Isaac ierr = PetscObjectReference((PetscObject)coarseDM);CHKERRQ(ierr); 354568d4fef7SMatthew G. Knepley ierr = PetscMalloc1(refine,&dms);CHKERRQ(ierr); 354668d4fef7SMatthew G. Knepley ierr = DMRefineHierarchy(dm, refine, dms);CHKERRQ(ierr); 354768d4fef7SMatthew G. Knepley /* Total hack since we do not pass in a pointer */ 354868d4fef7SMatthew G. Knepley ierr = DMPlexSwap_Static(dm, dms[refine-1]);CHKERRQ(ierr); 354968d4fef7SMatthew G. Knepley if (refine == 1) { 3550a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dm, dms[0]);CHKERRQ(ierr); 35510aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dm, PETSC_TRUE);CHKERRQ(ierr); 355268d4fef7SMatthew G. Knepley } else { 3553a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dm, dms[refine-2]);CHKERRQ(ierr); 35540aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dm, PETSC_TRUE);CHKERRQ(ierr); 3555a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dms[0], dms[refine-1]);CHKERRQ(ierr); 35560aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dms[0], PETSC_TRUE);CHKERRQ(ierr); 355768d4fef7SMatthew G. Knepley } 3558acdc6f61SToby Isaac ierr = DMSetCoarseDM(dms[refine-1], coarseDM);CHKERRQ(ierr); 3559acdc6f61SToby Isaac ierr = PetscObjectDereference((PetscObject)coarseDM);CHKERRQ(ierr); 356068d4fef7SMatthew G. Knepley /* Free DMs */ 356168d4fef7SMatthew G. Knepley for (r = 0; r < refine; ++r) { 3562547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dms[r]);CHKERRQ(ierr); 356368d4fef7SMatthew G. Knepley ierr = DMDestroy(&dms[r]);CHKERRQ(ierr); 356468d4fef7SMatthew G. Knepley } 356568d4fef7SMatthew G. Knepley ierr = PetscFree(dms);CHKERRQ(ierr); 356668d4fef7SMatthew G. Knepley } else { 356768d4fef7SMatthew G. Knepley for (r = 0; r < refine; ++r) { 35689318fe57SMatthew G. Knepley DM rdm; 356951a74b61SMatthew G. Knepley PetscPointFunc coordFunc = ((DM_Plex*) dm->data)->coordFunc; 357068d4fef7SMatthew G. Knepley 35711a1499c8SBarry Smith ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 35729318fe57SMatthew G. Knepley ierr = DMRefine(dm, PetscObjectComm((PetscObject) dm), &rdm);CHKERRQ(ierr); 357368d4fef7SMatthew G. Knepley /* Total hack since we do not pass in a pointer */ 35749318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &rdm);CHKERRQ(ierr); 3575547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 357661a622f3SMatthew G. Knepley if (coordFunc && remap) { 357751a74b61SMatthew G. Knepley ierr = DMPlexRemapGeometry(dm, 0.0, coordFunc);CHKERRQ(ierr); 357851a74b61SMatthew G. Knepley ((DM_Plex*) dm->data)->coordFunc = coordFunc; 357951a74b61SMatthew G. Knepley } 358068d4fef7SMatthew G. Knepley } 358168d4fef7SMatthew G. Knepley } 35823cf6fe12SMatthew G. Knepley /* Handle DMPlex coarsening */ 35835a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_coarsen", "Coarsen the mesh", "DMCreate", coarsen, &coarsen, NULL,0);CHKERRQ(ierr); 35845a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_coarsen_hierarchy", "The number of coarsenings", "DMCreate", coarsen, &coarsen, &isHierarchy,0);CHKERRQ(ierr); 3585b653a561SMatthew G. Knepley if (coarsen && isHierarchy) { 3586b653a561SMatthew G. Knepley DM *dms; 3587b653a561SMatthew G. Knepley 3588b653a561SMatthew G. Knepley ierr = PetscMalloc1(coarsen, &dms);CHKERRQ(ierr); 3589b653a561SMatthew G. Knepley ierr = DMCoarsenHierarchy(dm, coarsen, dms);CHKERRQ(ierr); 3590b653a561SMatthew G. Knepley /* Free DMs */ 3591b653a561SMatthew G. Knepley for (r = 0; r < coarsen; ++r) { 3592547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dms[r]);CHKERRQ(ierr); 3593b653a561SMatthew G. Knepley ierr = DMDestroy(&dms[r]);CHKERRQ(ierr); 3594b653a561SMatthew G. Knepley } 3595b653a561SMatthew G. Knepley ierr = PetscFree(dms);CHKERRQ(ierr); 3596b653a561SMatthew G. Knepley } else { 3597b653a561SMatthew G. Knepley for (r = 0; r < coarsen; ++r) { 35989318fe57SMatthew G. Knepley DM cdm; 35999318fe57SMatthew G. Knepley PetscPointFunc coordFunc = ((DM_Plex*) dm->data)->coordFunc; 36003cf6fe12SMatthew G. Knepley 36013cf6fe12SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 36029318fe57SMatthew G. Knepley ierr = DMCoarsen(dm, PetscObjectComm((PetscObject) dm), &cdm);CHKERRQ(ierr); 36033cf6fe12SMatthew G. Knepley /* Total hack since we do not pass in a pointer */ 36049318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &cdm);CHKERRQ(ierr); 3605547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 36069318fe57SMatthew G. Knepley if (coordFunc) { 36079318fe57SMatthew G. Knepley ierr = DMPlexRemapGeometry(dm, 0.0, coordFunc);CHKERRQ(ierr); 36089318fe57SMatthew G. Knepley ((DM_Plex*) dm->data)->coordFunc = coordFunc; 36099318fe57SMatthew G. Knepley } 36103cf6fe12SMatthew G. Knepley } 3611b653a561SMatthew G. Knepley } 3612909dfd52SMatthew G. Knepley /* Handle ghost cells */ 3613909dfd52SMatthew 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); 3614909dfd52SMatthew G. Knepley if (ghostCells) { 3615909dfd52SMatthew G. Knepley DM gdm; 3616909dfd52SMatthew G. Knepley char lname[PETSC_MAX_PATH_LEN]; 3617909dfd52SMatthew G. Knepley 3618909dfd52SMatthew G. Knepley lname[0] = '\0'; 3619909dfd52SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_fv_ghost_cells_label", "Label name for ghost cells boundary", "DMCreate", lname, lname, sizeof(lname), &flg);CHKERRQ(ierr); 3620909dfd52SMatthew G. Knepley ierr = DMPlexConstructGhostCells(dm, flg ? lname : NULL, NULL, &gdm);CHKERRQ(ierr); 3621909dfd52SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &gdm);CHKERRQ(ierr); 3622909dfd52SMatthew G. Knepley } 36233cf6fe12SMatthew G. Knepley /* Handle */ 36241a1499c8SBarry Smith ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 36250a6ba040SMatthew G. Knepley ierr = PetscOptionsTail();CHKERRQ(ierr); 36260a6ba040SMatthew G. Knepley PetscFunctionReturn(0); 36270a6ba040SMatthew G. Knepley } 36280a6ba040SMatthew G. Knepley 3629552f7358SJed Brown static PetscErrorCode DMCreateGlobalVector_Plex(DM dm,Vec *vec) 3630552f7358SJed Brown { 3631552f7358SJed Brown PetscErrorCode ierr; 3632552f7358SJed Brown 3633552f7358SJed Brown PetscFunctionBegin; 3634552f7358SJed Brown ierr = DMCreateGlobalVector_Section_Private(dm,vec);CHKERRQ(ierr); 3635552f7358SJed Brown /* ierr = VecSetOperation(*vec, VECOP_DUPLICATE, (void(*)(void)) VecDuplicate_MPI_DM);CHKERRQ(ierr); */ 3636552f7358SJed Brown ierr = VecSetOperation(*vec, VECOP_VIEW, (void (*)(void)) VecView_Plex);CHKERRQ(ierr); 3637d930f514SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_VIEWNATIVE, (void (*)(void)) VecView_Plex_Native);CHKERRQ(ierr); 36382c40f234SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_LOAD, (void (*)(void)) VecLoad_Plex);CHKERRQ(ierr); 3639d930f514SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_LOADNATIVE, (void (*)(void)) VecLoad_Plex_Native);CHKERRQ(ierr); 3640552f7358SJed Brown PetscFunctionReturn(0); 3641552f7358SJed Brown } 3642552f7358SJed Brown 3643552f7358SJed Brown static PetscErrorCode DMCreateLocalVector_Plex(DM dm,Vec *vec) 3644552f7358SJed Brown { 3645552f7358SJed Brown PetscErrorCode ierr; 3646552f7358SJed Brown 3647552f7358SJed Brown PetscFunctionBegin; 3648552f7358SJed Brown ierr = DMCreateLocalVector_Section_Private(dm,vec);CHKERRQ(ierr); 3649552f7358SJed Brown ierr = VecSetOperation(*vec, VECOP_VIEW, (void (*)(void)) VecView_Plex_Local);CHKERRQ(ierr); 36502c40f234SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_LOAD, (void (*)(void)) VecLoad_Plex_Local);CHKERRQ(ierr); 3651552f7358SJed Brown PetscFunctionReturn(0); 3652552f7358SJed Brown } 3653552f7358SJed Brown 3654793f3fe5SMatthew G. Knepley static PetscErrorCode DMGetDimPoints_Plex(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 3655793f3fe5SMatthew G. Knepley { 3656793f3fe5SMatthew G. Knepley PetscInt depth, d; 3657793f3fe5SMatthew G. Knepley PetscErrorCode ierr; 3658793f3fe5SMatthew G. Knepley 3659793f3fe5SMatthew G. Knepley PetscFunctionBegin; 3660793f3fe5SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3661793f3fe5SMatthew G. Knepley if (depth == 1) { 3662793f3fe5SMatthew G. Knepley ierr = DMGetDimension(dm, &d);CHKERRQ(ierr); 3663793f3fe5SMatthew G. Knepley if (dim == 0) {ierr = DMPlexGetDepthStratum(dm, dim, pStart, pEnd);CHKERRQ(ierr);} 3664793f3fe5SMatthew G. Knepley else if (dim == d) {ierr = DMPlexGetDepthStratum(dm, 1, pStart, pEnd);CHKERRQ(ierr);} 3665793f3fe5SMatthew G. Knepley else {*pStart = 0; *pEnd = 0;} 3666793f3fe5SMatthew G. Knepley } else { 3667793f3fe5SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, dim, pStart, pEnd);CHKERRQ(ierr); 3668793f3fe5SMatthew G. Knepley } 3669793f3fe5SMatthew G. Knepley PetscFunctionReturn(0); 3670793f3fe5SMatthew G. Knepley } 3671793f3fe5SMatthew G. Knepley 367228d58a37SPierre Jolivet static PetscErrorCode DMGetNeighbors_Plex(DM dm, PetscInt *nranks, const PetscMPIInt *ranks[]) 3673502a2867SDave May { 3674502a2867SDave May PetscSF sf; 36750a19bb7dSprj- PetscInt niranks, njranks, n; 36760a19bb7dSprj- const PetscMPIInt *iranks, *jranks; 36770a19bb7dSprj- DM_Plex *data = (DM_Plex*) dm->data; 36782f356facSMatthew G. Knepley PetscErrorCode ierr; 3679502a2867SDave May 36802f356facSMatthew G. Knepley PetscFunctionBegin; 3681502a2867SDave May ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 36820a19bb7dSprj- if (!data->neighbors) { 368307a779feSPierre Jolivet ierr = PetscSFSetUp(sf);CHKERRQ(ierr); 36840a19bb7dSprj- ierr = PetscSFGetRootRanks(sf, &njranks, &jranks, NULL, NULL, NULL);CHKERRQ(ierr); 36850a19bb7dSprj- ierr = PetscSFGetLeafRanks(sf, &niranks, &iranks, NULL, NULL);CHKERRQ(ierr); 36860a19bb7dSprj- ierr = PetscMalloc1(njranks + niranks + 1, &data->neighbors);CHKERRQ(ierr); 36870a19bb7dSprj- ierr = PetscArraycpy(data->neighbors + 1, jranks, njranks);CHKERRQ(ierr); 36880a19bb7dSprj- ierr = PetscArraycpy(data->neighbors + njranks + 1, iranks, niranks);CHKERRQ(ierr); 36890a19bb7dSprj- n = njranks + niranks; 36900a19bb7dSprj- ierr = PetscSortRemoveDupsMPIInt(&n, data->neighbors + 1);CHKERRQ(ierr); 36910a19bb7dSprj- /* The following cast should never fail: can't have more neighbors than PETSC_MPI_INT_MAX */ 36920a19bb7dSprj- ierr = PetscMPIIntCast(n, data->neighbors);CHKERRQ(ierr); 36930a19bb7dSprj- } 36940a19bb7dSprj- if (nranks) *nranks = data->neighbors[0]; 36950a19bb7dSprj- if (ranks) { 36960a19bb7dSprj- if (data->neighbors[0]) *ranks = data->neighbors + 1; 36970a19bb7dSprj- else *ranks = NULL; 36980a19bb7dSprj- } 3699502a2867SDave May PetscFunctionReturn(0); 3700502a2867SDave May } 3701502a2867SDave May 37021eb70e55SToby Isaac PETSC_INTERN PetscErrorCode DMInterpolateSolution_Plex(DM, DM, Mat, Vec, Vec); 37031eb70e55SToby Isaac 370446fa42a0SMatthew G. Knepley static PetscErrorCode DMInitialize_Plex(DM dm) 3705552f7358SJed Brown { 3706713918a9SToby Isaac PetscErrorCode ierr; 3707713918a9SToby Isaac 3708552f7358SJed Brown PetscFunctionBegin; 3709552f7358SJed Brown dm->ops->view = DMView_Plex; 37102c40f234SMatthew G. Knepley dm->ops->load = DMLoad_Plex; 3711552f7358SJed Brown dm->ops->setfromoptions = DMSetFromOptions_Plex; 371238221697SMatthew G. Knepley dm->ops->clone = DMClone_Plex; 3713552f7358SJed Brown dm->ops->setup = DMSetUp_Plex; 37141bb6d2a8SBarry Smith dm->ops->createlocalsection = DMCreateLocalSection_Plex; 371566ad2231SToby Isaac dm->ops->createdefaultconstraints = DMCreateDefaultConstraints_Plex; 3716552f7358SJed Brown dm->ops->createglobalvector = DMCreateGlobalVector_Plex; 3717552f7358SJed Brown dm->ops->createlocalvector = DMCreateLocalVector_Plex; 3718184d77edSJed Brown dm->ops->getlocaltoglobalmapping = NULL; 37190298fd71SBarry Smith dm->ops->createfieldis = NULL; 3720552f7358SJed Brown dm->ops->createcoordinatedm = DMCreateCoordinateDM_Plex; 3721f19dbd58SToby Isaac dm->ops->createcoordinatefield = DMCreateCoordinateField_Plex; 37220a6ba040SMatthew G. Knepley dm->ops->getcoloring = NULL; 3723552f7358SJed Brown dm->ops->creatematrix = DMCreateMatrix_Plex; 3724bceba477SMatthew G. Knepley dm->ops->createinterpolation = DMCreateInterpolation_Plex; 3725bd041c0cSMatthew G. Knepley dm->ops->createmassmatrix = DMCreateMassMatrix_Plex; 3726b4937a87SMatthew G. Knepley dm->ops->createmassmatrixlumped = DMCreateMassMatrixLumped_Plex; 37275a84ad33SLisandro Dalcin dm->ops->createinjection = DMCreateInjection_Plex; 3728552f7358SJed Brown dm->ops->refine = DMRefine_Plex; 37290a6ba040SMatthew G. Knepley dm->ops->coarsen = DMCoarsen_Plex; 37300a6ba040SMatthew G. Knepley dm->ops->refinehierarchy = DMRefineHierarchy_Plex; 3731b653a561SMatthew G. Knepley dm->ops->coarsenhierarchy = DMCoarsenHierarchy_Plex; 3732d410b0cfSMatthew G. Knepley dm->ops->extrude = DMExtrude_Plex; 37330298fd71SBarry Smith dm->ops->globaltolocalbegin = NULL; 37340298fd71SBarry Smith dm->ops->globaltolocalend = NULL; 37350298fd71SBarry Smith dm->ops->localtoglobalbegin = NULL; 37360298fd71SBarry Smith dm->ops->localtoglobalend = NULL; 3737552f7358SJed Brown dm->ops->destroy = DMDestroy_Plex; 3738552f7358SJed Brown dm->ops->createsubdm = DMCreateSubDM_Plex; 37392adcc780SMatthew G. Knepley dm->ops->createsuperdm = DMCreateSuperDM_Plex; 3740793f3fe5SMatthew G. Knepley dm->ops->getdimpoints = DMGetDimPoints_Plex; 3741552f7358SJed Brown dm->ops->locatepoints = DMLocatePoints_Plex; 37420709b2feSToby Isaac dm->ops->projectfunctionlocal = DMProjectFunctionLocal_Plex; 37430709b2feSToby Isaac dm->ops->projectfunctionlabellocal = DMProjectFunctionLabelLocal_Plex; 3744bfc4295aSToby Isaac dm->ops->projectfieldlocal = DMProjectFieldLocal_Plex; 37458c6c5593SMatthew G. Knepley dm->ops->projectfieldlabellocal = DMProjectFieldLabelLocal_Plex; 3746ece3a9fcSMatthew G. Knepley dm->ops->projectbdfieldlabellocal = DMProjectBdFieldLabelLocal_Plex; 37470709b2feSToby Isaac dm->ops->computel2diff = DMComputeL2Diff_Plex; 3748b698f381SToby Isaac dm->ops->computel2gradientdiff = DMComputeL2GradientDiff_Plex; 37492a16baeaSToby Isaac dm->ops->computel2fielddiff = DMComputeL2FieldDiff_Plex; 375028d58a37SPierre Jolivet dm->ops->getneighbors = DMGetNeighbors_Plex; 3751f1d73a7aSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexInsertBoundaryValues_C",DMPlexInsertBoundaryValues_Plex);CHKERRQ(ierr); 375256cf3b9cSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexInsertTimeDerviativeBoundaryValues_C",DMPlexInsertTimeDerivativeBoundaryValues_Plex);CHKERRQ(ierr); 37538135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMSetUpGLVisViewer_C",DMSetUpGLVisViewer_Plex);CHKERRQ(ierr); 375428d58a37SPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)dm,"DMCreateNeumannOverlap_C",DMCreateNeumannOverlap_Plex);CHKERRQ(ierr); 3755cb54e036SVaclav Hapla ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexGetOverlap_C",DMPlexGetOverlap_Plex);CHKERRQ(ierr); 3756e600fa54SMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexDistributeGetDefault_C",DMPlexDistributeGetDefault_Plex);CHKERRQ(ierr); 3757e600fa54SMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexDistributeSetDefault_C",DMPlexDistributeSetDefault_Plex);CHKERRQ(ierr); 37581eb70e55SToby Isaac ierr = PetscObjectComposeFunction((PetscObject)dm,"DMInterpolateSolution_C",DMInterpolateSolution_Plex);CHKERRQ(ierr); 3759552f7358SJed Brown PetscFunctionReturn(0); 3760552f7358SJed Brown } 3761552f7358SJed Brown 376246fa42a0SMatthew G. Knepley PETSC_INTERN PetscErrorCode DMClone_Plex(DM dm, DM *newdm) 376363a16f15SMatthew G. Knepley { 376463a16f15SMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) dm->data; 376563a16f15SMatthew G. Knepley PetscErrorCode ierr; 376663a16f15SMatthew G. Knepley 376763a16f15SMatthew G. Knepley PetscFunctionBegin; 376863a16f15SMatthew G. Knepley mesh->refct++; 376963a16f15SMatthew G. Knepley (*newdm)->data = mesh; 377063a16f15SMatthew G. Knepley ierr = PetscObjectChangeTypeName((PetscObject) *newdm, DMPLEX);CHKERRQ(ierr); 377163a16f15SMatthew G. Knepley ierr = DMInitialize_Plex(*newdm);CHKERRQ(ierr); 377263a16f15SMatthew G. Knepley PetscFunctionReturn(0); 377363a16f15SMatthew G. Knepley } 377463a16f15SMatthew G. Knepley 37758818961aSMatthew G Knepley /*MC 37768818961aSMatthew G Knepley DMPLEX = "plex" - A DM object that encapsulates an unstructured mesh, or CW Complex, which can be expressed using a Hasse Diagram. 37778818961aSMatthew G Knepley In the local representation, Vecs contain all unknowns in the interior and shared boundary. This is 37788818961aSMatthew G Knepley specified by a PetscSection object. Ownership in the global representation is determined by 37798818961aSMatthew G Knepley ownership of the underlying DMPlex points. This is specified by another PetscSection object. 37808818961aSMatthew G Knepley 3781e5893cccSMatthew G. Knepley Options Database Keys: 3782250712c9SMatthew G. Knepley + -dm_refine_pre - Refine mesh before distribution 3783250712c9SMatthew G. Knepley + -dm_refine_uniform_pre - Choose uniform or generator-based refinement 3784250712c9SMatthew G. Knepley + -dm_refine_volume_limit_pre - Cell volume limit after pre-refinement using generator 3785250712c9SMatthew G. Knepley . -dm_distribute - Distribute mesh across processes 3786250712c9SMatthew G. Knepley . -dm_distribute_overlap - Number of cells to overlap for distribution 3787250712c9SMatthew G. Knepley . -dm_refine - Refine mesh after distribution 3788250712c9SMatthew G. Knepley . -dm_plex_hash_location - Use grid hashing for point location 3789ddce0771SMatthew G. Knepley . -dm_plex_hash_box_faces <n,m,p> - The number of divisions in each direction of the grid hash 3790f12cf164SMatthew G. Knepley . -dm_plex_partition_balance - Attempt to evenly divide points on partition boundary between processes 3791f12cf164SMatthew G. Knepley . -dm_plex_remesh_bd - Allow changes to the boundary on remeshing 3792f12cf164SMatthew G. Knepley . -dm_plex_max_projection_height - Maxmimum mesh point height used to project locally 3793f12cf164SMatthew G. Knepley . -dm_plex_regular_refinement - Use special nested projection algorithm for regular refinement 3794250712c9SMatthew G. Knepley . -dm_plex_check_all - Perform all shecks below 3795f12cf164SMatthew G. Knepley . -dm_plex_check_symmetry - Check that the adjacency information in the mesh is symmetric 3796f12cf164SMatthew G. Knepley . -dm_plex_check_skeleton <celltype> - Check that each cell has the correct number of vertices 3797f12cf164SMatthew 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 3798f12cf164SMatthew G. Knepley . -dm_plex_check_geometry - Check that cells have positive volume 3799f12cf164SMatthew G. Knepley . -dm_view :mesh.tex:ascii_latex - View the mesh in LaTeX/TikZ 3800e5893cccSMatthew G. Knepley . -dm_plex_view_scale <num> - Scale the TikZ 3801e5893cccSMatthew G. Knepley - -dm_plex_print_fem <num> - View FEM assembly information, such as element vectors and matrices 3802e5893cccSMatthew G. Knepley 38038818961aSMatthew G Knepley Level: intermediate 38048818961aSMatthew G Knepley 38058818961aSMatthew G Knepley .seealso: DMType, DMPlexCreate(), DMCreate(), DMSetType() 38068818961aSMatthew G Knepley M*/ 38078818961aSMatthew G Knepley 38088cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Plex(DM dm) 3809552f7358SJed Brown { 3810552f7358SJed Brown DM_Plex *mesh; 3811412e9a14SMatthew G. Knepley PetscInt unit; 3812552f7358SJed Brown PetscErrorCode ierr; 3813552f7358SJed Brown 3814552f7358SJed Brown PetscFunctionBegin; 3815552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3816b00a9115SJed Brown ierr = PetscNewLog(dm,&mesh);CHKERRQ(ierr); 3817552f7358SJed Brown dm->data = mesh; 3818552f7358SJed Brown 3819552f7358SJed Brown mesh->refct = 1; 382082f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &mesh->coneSection);CHKERRQ(ierr); 3821552f7358SJed Brown mesh->maxConeSize = 0; 38220298fd71SBarry Smith mesh->cones = NULL; 38230298fd71SBarry Smith mesh->coneOrientations = NULL; 382482f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &mesh->supportSection);CHKERRQ(ierr); 3825552f7358SJed Brown mesh->maxSupportSize = 0; 38260298fd71SBarry Smith mesh->supports = NULL; 3827552f7358SJed Brown mesh->refinementUniform = PETSC_TRUE; 3828552f7358SJed Brown mesh->refinementLimit = -1.0; 3829e600fa54SMatthew G. Knepley mesh->distDefault = PETSC_TRUE; 38307d0f5628SVaclav Hapla mesh->interpolated = DMPLEX_INTERPOLATED_INVALID; 38317d0f5628SVaclav Hapla mesh->interpolatedCollective = DMPLEX_INTERPOLATED_INVALID; 3832552f7358SJed Brown 38330298fd71SBarry Smith mesh->facesTmp = NULL; 3834552f7358SJed Brown 3835d9deefdfSMatthew G. Knepley mesh->tetgenOpts = NULL; 3836d9deefdfSMatthew G. Knepley mesh->triangleOpts = NULL; 383777623264SMatthew G. Knepley ierr = PetscPartitionerCreate(PetscObjectComm((PetscObject)dm), &mesh->partitioner);CHKERRQ(ierr); 38382e62ab5aSMatthew G. Knepley mesh->remeshBd = PETSC_FALSE; 3839d9deefdfSMatthew G. Knepley 38400298fd71SBarry Smith mesh->subpointMap = NULL; 3841552f7358SJed Brown 38428865f1eaSKarl Rupp for (unit = 0; unit < NUM_PETSC_UNITS; ++unit) mesh->scale[unit] = 1.0; 3843552f7358SJed Brown 38440aef6b92SMatthew G. Knepley mesh->regularRefinement = PETSC_FALSE; 3845df0420ecSMatthew G. Knepley mesh->depthState = -1; 3846ba2698f1SMatthew G. Knepley mesh->celltypeState = -1; 38470298fd71SBarry Smith mesh->globalVertexNumbers = NULL; 38480298fd71SBarry Smith mesh->globalCellNumbers = NULL; 3849a68b90caSToby Isaac mesh->anchorSection = NULL; 3850a68b90caSToby Isaac mesh->anchorIS = NULL; 385141e6d900SToby Isaac mesh->createanchors = NULL; 3852fa73a4e1SToby Isaac mesh->computeanchormatrix = NULL; 3853d961a43aSToby Isaac mesh->parentSection = NULL; 3854d961a43aSToby Isaac mesh->parents = NULL; 3855d961a43aSToby Isaac mesh->childIDs = NULL; 3856d961a43aSToby Isaac mesh->childSection = NULL; 3857d961a43aSToby Isaac mesh->children = NULL; 3858d6a7ad0dSToby Isaac mesh->referenceTree = NULL; 3859dcbd3bf7SToby Isaac mesh->getchildsymmetry = NULL; 3860552f7358SJed Brown mesh->vtkCellHeight = 0; 3861e228b242SToby Isaac mesh->useAnchors = PETSC_FALSE; 3862552f7358SJed Brown 3863b29cfa1cSToby Isaac mesh->maxProjectionHeight = 0; 3864b29cfa1cSToby Isaac 38650a19bb7dSprj- mesh->neighbors = NULL; 38660a19bb7dSprj- 3867552f7358SJed Brown mesh->printSetValues = PETSC_FALSE; 3868552f7358SJed Brown mesh->printFEM = 0; 38696113b454SMatthew G. Knepley mesh->printTol = 1.0e-10; 3870552f7358SJed Brown 3871552f7358SJed Brown ierr = DMInitialize_Plex(dm);CHKERRQ(ierr); 3872552f7358SJed Brown PetscFunctionReturn(0); 3873552f7358SJed Brown } 3874552f7358SJed Brown 3875552f7358SJed Brown /*@ 3876552f7358SJed Brown DMPlexCreate - Creates a DMPlex object, which encapsulates an unstructured mesh, or CW complex, which can be expressed using a Hasse Diagram. 3877552f7358SJed Brown 3878d083f849SBarry Smith Collective 3879552f7358SJed Brown 3880552f7358SJed Brown Input Parameter: 3881552f7358SJed Brown . comm - The communicator for the DMPlex object 3882552f7358SJed Brown 3883552f7358SJed Brown Output Parameter: 3884552f7358SJed Brown . mesh - The DMPlex object 3885552f7358SJed Brown 3886552f7358SJed Brown Level: beginner 3887552f7358SJed Brown 3888552f7358SJed Brown @*/ 3889552f7358SJed Brown PetscErrorCode DMPlexCreate(MPI_Comm comm, DM *mesh) 3890552f7358SJed Brown { 3891552f7358SJed Brown PetscErrorCode ierr; 3892552f7358SJed Brown 3893552f7358SJed Brown PetscFunctionBegin; 3894552f7358SJed Brown PetscValidPointer(mesh,2); 3895552f7358SJed Brown ierr = DMCreate(comm, mesh);CHKERRQ(ierr); 3896552f7358SJed Brown ierr = DMSetType(*mesh, DMPLEX);CHKERRQ(ierr); 3897552f7358SJed Brown PetscFunctionReturn(0); 3898552f7358SJed Brown } 3899552f7358SJed Brown 3900b09969d6SVaclav Hapla /*@C 3901b09969d6SVaclav Hapla DMPlexBuildFromCellListParallel - Build distributed DMPLEX topology from a list of vertices for each cell (common mesh generator output) 3902b09969d6SVaclav Hapla 3903b09969d6SVaclav Hapla Input Parameters: 3904b09969d6SVaclav Hapla + dm - The DM 3905b09969d6SVaclav Hapla . numCells - The number of cells owned by this process 3906325d53feSBarry Smith . numVertices - The number of vertices to be owned by this process, or PETSC_DECIDE 3907325d53feSBarry Smith . NVertices - The global number of vertices, or PETSC_DETERMINE 3908b09969d6SVaclav Hapla . numCorners - The number of vertices for each cell 39095e488331SVaclav Hapla - cells - An array of numCells*numCorners numbers, the global vertex numbers for each cell 3910b09969d6SVaclav Hapla 3911be8c289dSNicolas Barral Output Parameters: 3912be8c289dSNicolas Barral + vertexSF - (Optional) SF describing complete vertex ownership 3913be8c289dSNicolas Barral - verticesAdjSaved - (Optional) vertex adjacency array 3914b09969d6SVaclav Hapla 3915b09969d6SVaclav Hapla Notes: 3916b09969d6SVaclav Hapla Two triangles sharing a face 3917b09969d6SVaclav Hapla $ 3918b09969d6SVaclav Hapla $ 2 3919b09969d6SVaclav Hapla $ / | \ 3920b09969d6SVaclav Hapla $ / | \ 3921b09969d6SVaclav Hapla $ / | \ 3922b09969d6SVaclav Hapla $ 0 0 | 1 3 3923b09969d6SVaclav Hapla $ \ | / 3924b09969d6SVaclav Hapla $ \ | / 3925b09969d6SVaclav Hapla $ \ | / 3926b09969d6SVaclav Hapla $ 1 3927b09969d6SVaclav Hapla would have input 3928b09969d6SVaclav Hapla $ numCells = 2, numVertices = 4 3929b09969d6SVaclav Hapla $ cells = [0 1 2 1 3 2] 3930b09969d6SVaclav Hapla $ 3931b09969d6SVaclav Hapla which would result in the DMPlex 3932b09969d6SVaclav Hapla $ 3933b09969d6SVaclav Hapla $ 4 3934b09969d6SVaclav Hapla $ / | \ 3935b09969d6SVaclav Hapla $ / | \ 3936b09969d6SVaclav Hapla $ / | \ 3937b09969d6SVaclav Hapla $ 2 0 | 1 5 3938b09969d6SVaclav Hapla $ \ | / 3939b09969d6SVaclav Hapla $ \ | / 3940b09969d6SVaclav Hapla $ \ | / 3941b09969d6SVaclav Hapla $ 3 3942b09969d6SVaclav Hapla 394325b6865aSVaclav Hapla Vertices are implicitly numbered consecutively 0,...,NVertices. 394425b6865aSVaclav Hapla Each rank owns a chunk of numVertices consecutive vertices. 394525b6865aSVaclav Hapla If numVertices is PETSC_DECIDE, PETSc will distribute them as evenly as possible using PetscLayout. 3946325d53feSBarry Smith If NVertices is PETSC_DETERMINE and numVertices is PETSC_DECIDE, NVertices is computed by PETSc as the maximum vertex index in cells + 1. 3947325d53feSBarry Smith If only NVertices is PETSC_DETERMINE, it is computed as the sum of numVertices over all ranks. 394825b6865aSVaclav Hapla 3949b09969d6SVaclav Hapla The cell distribution is arbitrary non-overlapping, independent of the vertex distribution. 3950b09969d6SVaclav Hapla 3951b09969d6SVaclav Hapla Not currently supported in Fortran. 3952b09969d6SVaclav Hapla 3953b09969d6SVaclav Hapla Level: advanced 3954b09969d6SVaclav Hapla 3955b09969d6SVaclav Hapla .seealso: DMPlexBuildFromCellList(), DMPlexCreateFromCellListParallelPetsc(), DMPlexBuildCoordinatesFromCellListParallel() 3956b09969d6SVaclav Hapla @*/ 3957be8c289dSNicolas Barral PetscErrorCode DMPlexBuildFromCellListParallel(DM dm, PetscInt numCells, PetscInt numVertices, PetscInt NVertices, PetscInt numCorners, const PetscInt cells[], PetscSF *vertexSF, PetscInt **verticesAdjSaved) 3958a47d0d45SMatthew G. Knepley { 39592464107aSksagiyam PetscSF sfPoint; 39602464107aSksagiyam PetscLayout layout; 39612464107aSksagiyam PetscInt numVerticesAdj, *verticesAdj, *cones, c, p, dim; 39629852e123SBarry Smith PetscMPIInt rank, size; 3963a47d0d45SMatthew G. Knepley PetscErrorCode ierr; 3964a47d0d45SMatthew G. Knepley 3965a47d0d45SMatthew G. Knepley PetscFunctionBegin; 396625b6865aSVaclav Hapla PetscValidLogicalCollectiveInt(dm,NVertices,4); 3967b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 3968ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 3969ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRMPI(ierr); 39706cbf6523SVaclav Hapla ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 397125b6865aSVaclav Hapla /* Get/check global number of vertices */ 397225b6865aSVaclav Hapla { 397325b6865aSVaclav Hapla PetscInt NVerticesInCells, i; 397425b6865aSVaclav Hapla const PetscInt len = numCells * numCorners; 397525b6865aSVaclav Hapla 397625b6865aSVaclav Hapla /* NVerticesInCells = max(cells) + 1 */ 397725b6865aSVaclav Hapla NVerticesInCells = PETSC_MIN_INT; 397825b6865aSVaclav Hapla for (i=0; i<len; i++) if (cells[i] > NVerticesInCells) NVerticesInCells = cells[i]; 397925b6865aSVaclav Hapla ++NVerticesInCells; 3980ffc4695bSBarry Smith ierr = MPI_Allreduce(MPI_IN_PLACE, &NVerticesInCells, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 398125b6865aSVaclav Hapla 398225b6865aSVaclav Hapla if (numVertices == PETSC_DECIDE && NVertices == PETSC_DECIDE) NVertices = NVerticesInCells; 39832c71b3e2SJacob 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); 398425b6865aSVaclav Hapla } 39859079aca8SVaclav Hapla /* Count locally unique vertices */ 39869079aca8SVaclav Hapla { 39879079aca8SVaclav Hapla PetscHSetI vhash; 39889079aca8SVaclav Hapla PetscInt off = 0; 39899079aca8SVaclav Hapla 3990e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&vhash);CHKERRQ(ierr); 3991a47d0d45SMatthew G. Knepley for (c = 0; c < numCells; ++c) { 3992a47d0d45SMatthew G. Knepley for (p = 0; p < numCorners; ++p) { 3993e8f14785SLisandro Dalcin ierr = PetscHSetIAdd(vhash, cells[c*numCorners+p]);CHKERRQ(ierr); 3994a47d0d45SMatthew G. Knepley } 3995a47d0d45SMatthew G. Knepley } 3996e8f14785SLisandro Dalcin ierr = PetscHSetIGetSize(vhash, &numVerticesAdj);CHKERRQ(ierr); 3997be8c289dSNicolas Barral if (!verticesAdjSaved) { ierr = PetscMalloc1(numVerticesAdj, &verticesAdj);CHKERRQ(ierr); } 3998be8c289dSNicolas Barral else { verticesAdj = *verticesAdjSaved; } 3999e8f14785SLisandro Dalcin ierr = PetscHSetIGetElems(vhash, &off, verticesAdj);CHKERRQ(ierr); 4000e8f14785SLisandro Dalcin ierr = PetscHSetIDestroy(&vhash);CHKERRQ(ierr); 40012c71b3e2SJacob Faibussowitsch PetscCheckFalse(off != numVerticesAdj,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid number of local vertices %D should be %D", off, numVerticesAdj); 4002a47d0d45SMatthew G. Knepley } 40039079aca8SVaclav Hapla ierr = PetscSortInt(numVerticesAdj, verticesAdj);CHKERRQ(ierr); 4004a47d0d45SMatthew G. Knepley /* Create cones */ 4005a47d0d45SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVerticesAdj);CHKERRQ(ierr); 4006a47d0d45SMatthew G. Knepley for (c = 0; c < numCells; ++c) {ierr = DMPlexSetConeSize(dm, c, numCorners);CHKERRQ(ierr);} 4007a47d0d45SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); 4008961cfab0SVaclav Hapla ierr = DMPlexGetCones(dm,&cones);CHKERRQ(ierr); 4009a47d0d45SMatthew G. Knepley for (c = 0; c < numCells; ++c) { 4010a47d0d45SMatthew G. Knepley for (p = 0; p < numCorners; ++p) { 4011a47d0d45SMatthew G. Knepley const PetscInt gv = cells[c*numCorners+p]; 4012a47d0d45SMatthew G. Knepley PetscInt lv; 4013a47d0d45SMatthew G. Knepley 40149079aca8SVaclav Hapla /* Positions within verticesAdj form 0-based local vertex numbering; 40159079aca8SVaclav Hapla we need to shift it by numCells to get correct DAG points (cells go first) */ 4016a47d0d45SMatthew G. Knepley ierr = PetscFindInt(gv, numVerticesAdj, verticesAdj, &lv);CHKERRQ(ierr); 40172c71b3e2SJacob Faibussowitsch PetscCheckFalse(lv < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not find global vertex %D in local connectivity", gv); 4018961cfab0SVaclav Hapla cones[c*numCorners+p] = lv+numCells; 4019a47d0d45SMatthew G. Knepley } 4020a47d0d45SMatthew G. Knepley } 40212464107aSksagiyam /* Build point sf */ 40222464107aSksagiyam ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)dm), &layout);CHKERRQ(ierr); 40232464107aSksagiyam ierr = PetscLayoutSetSize(layout, NVertices);CHKERRQ(ierr); 40242464107aSksagiyam ierr = PetscLayoutSetLocalSize(layout, numVertices);CHKERRQ(ierr); 40252464107aSksagiyam ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr); 40262464107aSksagiyam ierr = PetscSFCreateByMatchingIndices(layout, numVerticesAdj, verticesAdj, NULL, numCells, numVerticesAdj, verticesAdj, NULL, numCells, vertexSF, &sfPoint);CHKERRQ(ierr); 40272464107aSksagiyam ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 4028be8c289dSNicolas Barral if (!verticesAdjSaved) { ierr = PetscFree(verticesAdj);CHKERRQ(ierr); } 4029a47d0d45SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) sfPoint, "point SF");CHKERRQ(ierr); 40302464107aSksagiyam if (dm->sf) { 40312464107aSksagiyam const char *prefix; 40322464107aSksagiyam 40332464107aSksagiyam ierr = PetscObjectGetOptionsPrefix((PetscObject)dm->sf, &prefix);CHKERRQ(ierr); 40342464107aSksagiyam ierr = PetscObjectSetOptionsPrefix((PetscObject)sfPoint, prefix);CHKERRQ(ierr); 40352464107aSksagiyam } 40362464107aSksagiyam ierr = DMSetPointSF(dm, sfPoint);CHKERRQ(ierr); 40372464107aSksagiyam ierr = PetscSFDestroy(&sfPoint);CHKERRQ(ierr); 40382464107aSksagiyam if (vertexSF) {ierr = PetscObjectSetName((PetscObject)(*vertexSF), "Vertex Ownership SF");CHKERRQ(ierr);} 4039a47d0d45SMatthew G. Knepley /* Fill in the rest of the topology structure */ 4040a47d0d45SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 4041a47d0d45SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 4042b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 4043a47d0d45SMatthew G. Knepley PetscFunctionReturn(0); 4044a47d0d45SMatthew G. Knepley } 4045a47d0d45SMatthew G. Knepley 4046b09969d6SVaclav Hapla /*@C 4047b09969d6SVaclav Hapla DMPlexBuildCoordinatesFromCellListParallel - Build DM coordinates from a list of coordinates for each owned vertex (common mesh generator output) 4048b09969d6SVaclav Hapla 4049b09969d6SVaclav Hapla Input Parameters: 4050b09969d6SVaclav Hapla + dm - The DM 4051b09969d6SVaclav Hapla . spaceDim - The spatial dimension used for coordinates 4052b09969d6SVaclav Hapla . sfVert - SF describing complete vertex ownership 4053b09969d6SVaclav Hapla - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 4054b09969d6SVaclav Hapla 4055b09969d6SVaclav Hapla Level: advanced 4056b09969d6SVaclav Hapla 4057b09969d6SVaclav Hapla Notes: 4058b09969d6SVaclav Hapla Not currently supported in Fortran. 4059b09969d6SVaclav Hapla 4060b09969d6SVaclav Hapla .seealso: DMPlexBuildCoordinatesFromCellList(), DMPlexCreateFromCellListParallelPetsc(), DMPlexBuildFromCellListParallel() 4061b09969d6SVaclav Hapla @*/ 40621edcf0b2SVaclav Hapla PetscErrorCode DMPlexBuildCoordinatesFromCellListParallel(DM dm, PetscInt spaceDim, PetscSF sfVert, const PetscReal vertexCoords[]) 4063a47d0d45SMatthew G. Knepley { 4064a47d0d45SMatthew G. Knepley PetscSection coordSection; 4065a47d0d45SMatthew G. Knepley Vec coordinates; 4066a47d0d45SMatthew G. Knepley PetscScalar *coords; 40671edcf0b2SVaclav Hapla PetscInt numVertices, numVerticesAdj, coordSize, v, vStart, vEnd; 4068a47d0d45SMatthew G. Knepley PetscErrorCode ierr; 4069a47d0d45SMatthew G. Knepley 4070a47d0d45SMatthew G. Knepley PetscFunctionBegin; 4071b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 40721edcf0b2SVaclav Hapla ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 40732c71b3e2SJacob Faibussowitsch PetscCheckFalse(vStart < 0 || vEnd < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "DM is not set up properly. DMPlexBuildFromCellList() should be called first."); 40749596c6baSMatthew G. Knepley ierr = DMSetCoordinateDim(dm, spaceDim);CHKERRQ(ierr); 4075a47d0d45SMatthew G. Knepley ierr = PetscSFGetGraph(sfVert, &numVertices, &numVerticesAdj, NULL, NULL);CHKERRQ(ierr); 40762c71b3e2SJacob 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); 4077a47d0d45SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 4078a47d0d45SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 4079a47d0d45SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, spaceDim);CHKERRQ(ierr); 40801edcf0b2SVaclav Hapla ierr = PetscSectionSetChart(coordSection, vStart, vEnd);CHKERRQ(ierr); 40811edcf0b2SVaclav Hapla for (v = vStart; v < vEnd; ++v) { 4082a47d0d45SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, spaceDim);CHKERRQ(ierr); 4083a47d0d45SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, spaceDim);CHKERRQ(ierr); 4084a47d0d45SMatthew G. Knepley } 4085a47d0d45SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 4086a47d0d45SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 4087a47d0d45SMatthew G. Knepley ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinates);CHKERRQ(ierr); 4088a47d0d45SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, spaceDim);CHKERRQ(ierr); 4089a47d0d45SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 4090a47d0d45SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 4091a47d0d45SMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 4092a47d0d45SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 4093a47d0d45SMatthew G. Knepley { 4094a47d0d45SMatthew G. Knepley MPI_Datatype coordtype; 4095a47d0d45SMatthew G. Knepley 4096a47d0d45SMatthew G. Knepley /* Need a temp buffer for coords if we have complex/single */ 4097ffc4695bSBarry Smith ierr = MPI_Type_contiguous(spaceDim, MPIU_SCALAR, &coordtype);CHKERRMPI(ierr); 4098ffc4695bSBarry Smith ierr = MPI_Type_commit(&coordtype);CHKERRMPI(ierr); 409921016a8bSBarry Smith #if defined(PETSC_USE_COMPLEX) 410021016a8bSBarry Smith { 410121016a8bSBarry Smith PetscScalar *svertexCoords; 410221016a8bSBarry Smith PetscInt i; 41033612f820SVaclav Hapla ierr = PetscMalloc1(numVertices*spaceDim,&svertexCoords);CHKERRQ(ierr); 41043612f820SVaclav Hapla for (i=0; i<numVertices*spaceDim; i++) svertexCoords[i] = vertexCoords[i]; 4105ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sfVert, coordtype, svertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 4106ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sfVert, coordtype, svertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 410721016a8bSBarry Smith ierr = PetscFree(svertexCoords);CHKERRQ(ierr); 410821016a8bSBarry Smith } 410921016a8bSBarry Smith #else 4110ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sfVert, coordtype, vertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 4111ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sfVert, coordtype, vertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 411221016a8bSBarry Smith #endif 4113ffc4695bSBarry Smith ierr = MPI_Type_free(&coordtype);CHKERRMPI(ierr); 4114a47d0d45SMatthew G. Knepley } 4115a47d0d45SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 4116a47d0d45SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 4117a47d0d45SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 4118b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 4119a47d0d45SMatthew G. Knepley PetscFunctionReturn(0); 4120a47d0d45SMatthew G. Knepley } 4121a47d0d45SMatthew G. Knepley 4122c3edce3dSSatish Balay /*@ 4123b09969d6SVaclav Hapla DMPlexCreateFromCellListParallelPetsc - Create distributed DMPLEX from a list of vertices for each cell (common mesh generator output) 4124a47d0d45SMatthew G. Knepley 4125a47d0d45SMatthew G. Knepley Input Parameters: 4126a47d0d45SMatthew G. Knepley + comm - The communicator 4127a47d0d45SMatthew G. Knepley . dim - The topological dimension of the mesh 4128a47d0d45SMatthew G. Knepley . numCells - The number of cells owned by this process 412925b6865aSVaclav Hapla . numVertices - The number of vertices owned by this process, or PETSC_DECIDE 413025b6865aSVaclav Hapla . NVertices - The global number of vertices, or PETSC_DECIDE 4131a47d0d45SMatthew G. Knepley . numCorners - The number of vertices for each cell 4132a47d0d45SMatthew G. Knepley . interpolate - Flag indicating that intermediate mesh entities (faces, edges) should be created automatically 4133a47d0d45SMatthew G. Knepley . cells - An array of numCells*numCorners numbers, the global vertex numbers for each cell 4134a47d0d45SMatthew G. Knepley . spaceDim - The spatial dimension used for coordinates 4135a47d0d45SMatthew G. Knepley - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 4136a47d0d45SMatthew G. Knepley 4137d8d19677SJose E. Roman Output Parameters: 413818d54ad4SMichael Lange + dm - The DM 4139be8c289dSNicolas Barral . vertexSF - (Optional) SF describing complete vertex ownership 4140be8c289dSNicolas Barral - verticesAdjSaved - (Optional) vertex adjacency array 4141a47d0d45SMatthew G. Knepley 4142b09969d6SVaclav Hapla Notes: 4143b09969d6SVaclav Hapla This function is just a convenient sequence of DMCreate(), DMSetType(), DMSetDimension(), 4144b09969d6SVaclav Hapla DMPlexBuildFromCellListParallel(), DMPlexInterpolate(), DMPlexBuildCoordinatesFromCellListParallel() 4145a47d0d45SMatthew G. Knepley 414625b6865aSVaclav Hapla See DMPlexBuildFromCellListParallel() for an example and details about the topology-related parameters. 414725b6865aSVaclav Hapla See DMPlexBuildCoordinatesFromCellListParallel() for details about the geometry-related parameters. 414825b6865aSVaclav Hapla 4149b09969d6SVaclav Hapla Level: intermediate 4150a47d0d45SMatthew G. Knepley 4151b09969d6SVaclav Hapla .seealso: DMPlexCreateFromCellListPetsc(), DMPlexBuildFromCellListParallel(), DMPlexBuildCoordinatesFromCellListParallel(), DMPlexCreateFromDAG(), DMPlexCreate() 4152a47d0d45SMatthew G. Knepley @*/ 4153be8c289dSNicolas 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) 4154a47d0d45SMatthew G. Knepley { 4155a47d0d45SMatthew G. Knepley PetscSF sfVert; 4156a47d0d45SMatthew G. Knepley PetscErrorCode ierr; 4157a47d0d45SMatthew G. Knepley 4158a47d0d45SMatthew G. Knepley PetscFunctionBegin; 4159a47d0d45SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 4160a47d0d45SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 4161a47d0d45SMatthew G. Knepley PetscValidLogicalCollectiveInt(*dm, dim, 2); 4162064a246eSJacob Faibussowitsch PetscValidLogicalCollectiveInt(*dm, spaceDim, 9); 4163a47d0d45SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 4164be8c289dSNicolas Barral ierr = DMPlexBuildFromCellListParallel(*dm, numCells, numVertices, NVertices, numCorners, cells, &sfVert, verticesAdj);CHKERRQ(ierr); 4165a47d0d45SMatthew G. Knepley if (interpolate) { 41665fd9971aSMatthew G. Knepley DM idm; 4167a47d0d45SMatthew G. Knepley 4168a47d0d45SMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 4169a47d0d45SMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 4170a47d0d45SMatthew G. Knepley *dm = idm; 4171a47d0d45SMatthew G. Knepley } 41721edcf0b2SVaclav Hapla ierr = DMPlexBuildCoordinatesFromCellListParallel(*dm, spaceDim, sfVert, vertexCoords);CHKERRQ(ierr); 417318d54ad4SMichael Lange if (vertexSF) *vertexSF = sfVert; 4174fba955ccSBarry Smith else {ierr = PetscSFDestroy(&sfVert);CHKERRQ(ierr);} 4175a47d0d45SMatthew G. Knepley PetscFunctionReturn(0); 4176a47d0d45SMatthew G. Knepley } 4177a47d0d45SMatthew G. Knepley 4178a4a685f2SJacob Faibussowitsch /*@ 4179a4a685f2SJacob Faibussowitsch DMPlexCreateFromCellListParallel - Deprecated, use DMPlexCreateFromCellListParallelPetsc() 4180a4a685f2SJacob Faibussowitsch 4181a4a685f2SJacob Faibussowitsch Level: deprecated 4182a4a685f2SJacob Faibussowitsch 4183a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromCellListParallelPetsc() 4184a4a685f2SJacob Faibussowitsch @*/ 4185a4a685f2SJacob 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) 4186a4a685f2SJacob Faibussowitsch { 4187a4a685f2SJacob Faibussowitsch PetscErrorCode ierr; 4188a4a685f2SJacob Faibussowitsch PetscInt i; 4189a4a685f2SJacob Faibussowitsch PetscInt *pintCells; 4190a4a685f2SJacob Faibussowitsch 4191a4a685f2SJacob Faibussowitsch PetscFunctionBegin; 41922c71b3e2SJacob 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)); 4193a4a685f2SJacob Faibussowitsch if (sizeof(int) == sizeof(PetscInt)) { 4194a4a685f2SJacob Faibussowitsch pintCells = (PetscInt *) cells; 4195a4a685f2SJacob Faibussowitsch } else { 4196a4a685f2SJacob Faibussowitsch ierr = PetscMalloc1(numCells*numCorners, &pintCells);CHKERRQ(ierr); 4197a4a685f2SJacob Faibussowitsch for (i = 0; i < numCells*numCorners; i++) { 4198a4a685f2SJacob Faibussowitsch pintCells[i] = (PetscInt) cells[i]; 4199a4a685f2SJacob Faibussowitsch } 4200a4a685f2SJacob Faibussowitsch } 4201be8c289dSNicolas Barral ierr = DMPlexCreateFromCellListParallelPetsc(comm, dim, numCells, numVertices, PETSC_DECIDE, numCorners, interpolate, pintCells, spaceDim, vertexCoords, vertexSF, NULL, dm);CHKERRQ(ierr); 4202a4a685f2SJacob Faibussowitsch if (sizeof(int) != sizeof(PetscInt)) { 4203a4a685f2SJacob Faibussowitsch ierr = PetscFree(pintCells);CHKERRQ(ierr); 4204a4a685f2SJacob Faibussowitsch } 4205a4a685f2SJacob Faibussowitsch PetscFunctionReturn(0); 4206a4a685f2SJacob Faibussowitsch } 4207a4a685f2SJacob Faibussowitsch 4208b09969d6SVaclav Hapla /*@C 4209b09969d6SVaclav Hapla DMPlexBuildFromCellList - Build DMPLEX topology from a list of vertices for each cell (common mesh generator output) 42109298eaa6SMatthew G Knepley 42119298eaa6SMatthew G Knepley Input Parameters: 4212b09969d6SVaclav Hapla + dm - The DM 4213b09969d6SVaclav Hapla . numCells - The number of cells owned by this process 4214325d53feSBarry Smith . numVertices - The number of vertices owned by this process, or PETSC_DETERMINE 42159298eaa6SMatthew G Knepley . numCorners - The number of vertices for each cell 42165e488331SVaclav Hapla - cells - An array of numCells*numCorners numbers, the global vertex numbers for each cell 42179298eaa6SMatthew G Knepley 4218b09969d6SVaclav Hapla Level: advanced 42199298eaa6SMatthew G Knepley 4220b09969d6SVaclav Hapla Notes: 4221b09969d6SVaclav Hapla Two triangles sharing a face 42229298eaa6SMatthew G Knepley $ 42239298eaa6SMatthew G Knepley $ 2 42249298eaa6SMatthew G Knepley $ / | \ 42259298eaa6SMatthew G Knepley $ / | \ 42269298eaa6SMatthew G Knepley $ / | \ 42279298eaa6SMatthew G Knepley $ 0 0 | 1 3 42289298eaa6SMatthew G Knepley $ \ | / 42299298eaa6SMatthew G Knepley $ \ | / 42309298eaa6SMatthew G Knepley $ \ | / 42319298eaa6SMatthew G Knepley $ 1 42329298eaa6SMatthew G Knepley would have input 42339298eaa6SMatthew G Knepley $ numCells = 2, numVertices = 4 42349298eaa6SMatthew G Knepley $ cells = [0 1 2 1 3 2] 42359298eaa6SMatthew G Knepley $ 42369298eaa6SMatthew G Knepley which would result in the DMPlex 42379298eaa6SMatthew G Knepley $ 42389298eaa6SMatthew G Knepley $ 4 42399298eaa6SMatthew G Knepley $ / | \ 42409298eaa6SMatthew G Knepley $ / | \ 42419298eaa6SMatthew G Knepley $ / | \ 42429298eaa6SMatthew G Knepley $ 2 0 | 1 5 42439298eaa6SMatthew G Knepley $ \ | / 42449298eaa6SMatthew G Knepley $ \ | / 42459298eaa6SMatthew G Knepley $ \ | / 42469298eaa6SMatthew G Knepley $ 3 42479298eaa6SMatthew G Knepley 4248325d53feSBarry Smith If numVertices is PETSC_DETERMINE, it is computed by PETSc as the maximum vertex index in cells + 1. 424925b6865aSVaclav Hapla 4250b09969d6SVaclav Hapla Not currently supported in Fortran. 42519298eaa6SMatthew G Knepley 4252b09969d6SVaclav Hapla .seealso: DMPlexBuildFromCellListParallel(), DMPlexBuildCoordinatesFromCellList(), DMPlexCreateFromCellListPetsc() 4253b09969d6SVaclav Hapla @*/ 42545e488331SVaclav Hapla PetscErrorCode DMPlexBuildFromCellList(DM dm, PetscInt numCells, PetscInt numVertices, PetscInt numCorners, const PetscInt cells[]) 4255b09969d6SVaclav Hapla { 4256961cfab0SVaclav Hapla PetscInt *cones, c, p, dim; 4257b09969d6SVaclav Hapla PetscErrorCode ierr; 4258b09969d6SVaclav Hapla 4259b09969d6SVaclav Hapla PetscFunctionBegin; 4260b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 4261b09969d6SVaclav Hapla ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 426225b6865aSVaclav Hapla /* Get/check global number of vertices */ 426325b6865aSVaclav Hapla { 426425b6865aSVaclav Hapla PetscInt NVerticesInCells, i; 426525b6865aSVaclav Hapla const PetscInt len = numCells * numCorners; 426625b6865aSVaclav Hapla 426725b6865aSVaclav Hapla /* NVerticesInCells = max(cells) + 1 */ 426825b6865aSVaclav Hapla NVerticesInCells = PETSC_MIN_INT; 426925b6865aSVaclav Hapla for (i=0; i<len; i++) if (cells[i] > NVerticesInCells) NVerticesInCells = cells[i]; 427025b6865aSVaclav Hapla ++NVerticesInCells; 427125b6865aSVaclav Hapla 427225b6865aSVaclav Hapla if (numVertices == PETSC_DECIDE) numVertices = NVerticesInCells; 42732c71b3e2SJacob 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); 427425b6865aSVaclav Hapla } 4275b09969d6SVaclav Hapla ierr = DMPlexSetChart(dm, 0, numCells+numVertices);CHKERRQ(ierr); 4276b09969d6SVaclav Hapla for (c = 0; c < numCells; ++c) { 4277b09969d6SVaclav Hapla ierr = DMPlexSetConeSize(dm, c, numCorners);CHKERRQ(ierr); 4278b09969d6SVaclav Hapla } 4279b09969d6SVaclav Hapla ierr = DMSetUp(dm);CHKERRQ(ierr); 4280961cfab0SVaclav Hapla ierr = DMPlexGetCones(dm,&cones);CHKERRQ(ierr); 4281b09969d6SVaclav Hapla for (c = 0; c < numCells; ++c) { 4282b09969d6SVaclav Hapla for (p = 0; p < numCorners; ++p) { 4283961cfab0SVaclav Hapla cones[c*numCorners+p] = cells[c*numCorners+p]+numCells; 4284b09969d6SVaclav Hapla } 4285b09969d6SVaclav Hapla } 4286b09969d6SVaclav Hapla ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 4287b09969d6SVaclav Hapla ierr = DMPlexStratify(dm);CHKERRQ(ierr); 4288b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 4289b09969d6SVaclav Hapla PetscFunctionReturn(0); 4290b09969d6SVaclav Hapla } 4291b09969d6SVaclav Hapla 4292b09969d6SVaclav Hapla /*@C 4293b09969d6SVaclav Hapla DMPlexBuildCoordinatesFromCellList - Build DM coordinates from a list of coordinates for each owned vertex (common mesh generator output) 4294b09969d6SVaclav Hapla 4295b09969d6SVaclav Hapla Input Parameters: 4296b09969d6SVaclav Hapla + dm - The DM 4297b09969d6SVaclav Hapla . spaceDim - The spatial dimension used for coordinates 4298b09969d6SVaclav Hapla - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 4299b09969d6SVaclav Hapla 4300b09969d6SVaclav Hapla Level: advanced 4301b09969d6SVaclav Hapla 4302b09969d6SVaclav Hapla Notes: 4303b09969d6SVaclav Hapla Not currently supported in Fortran. 4304b09969d6SVaclav Hapla 4305b09969d6SVaclav Hapla .seealso: DMPlexBuildCoordinatesFromCellListParallel(), DMPlexCreateFromCellListPetsc(), DMPlexBuildFromCellList() 4306b09969d6SVaclav Hapla @*/ 43071edcf0b2SVaclav Hapla PetscErrorCode DMPlexBuildCoordinatesFromCellList(DM dm, PetscInt spaceDim, const PetscReal vertexCoords[]) 4308b09969d6SVaclav Hapla { 4309b09969d6SVaclav Hapla PetscSection coordSection; 4310b09969d6SVaclav Hapla Vec coordinates; 4311b09969d6SVaclav Hapla DM cdm; 4312b09969d6SVaclav Hapla PetscScalar *coords; 43131edcf0b2SVaclav Hapla PetscInt v, vStart, vEnd, d; 4314b09969d6SVaclav Hapla PetscErrorCode ierr; 4315b09969d6SVaclav Hapla 4316b09969d6SVaclav Hapla PetscFunctionBegin; 4317b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 43181edcf0b2SVaclav Hapla ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 43192c71b3e2SJacob Faibussowitsch PetscCheckFalse(vStart < 0 || vEnd < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "DM is not set up properly. DMPlexBuildFromCellList() should be called first."); 4320b09969d6SVaclav Hapla ierr = DMSetCoordinateDim(dm, spaceDim);CHKERRQ(ierr); 4321b09969d6SVaclav Hapla ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 4322b09969d6SVaclav Hapla ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 4323b09969d6SVaclav Hapla ierr = PetscSectionSetFieldComponents(coordSection, 0, spaceDim);CHKERRQ(ierr); 43241edcf0b2SVaclav Hapla ierr = PetscSectionSetChart(coordSection, vStart, vEnd);CHKERRQ(ierr); 43251edcf0b2SVaclav Hapla for (v = vStart; v < vEnd; ++v) { 4326b09969d6SVaclav Hapla ierr = PetscSectionSetDof(coordSection, v, spaceDim);CHKERRQ(ierr); 4327b09969d6SVaclav Hapla ierr = PetscSectionSetFieldDof(coordSection, v, 0, spaceDim);CHKERRQ(ierr); 4328b09969d6SVaclav Hapla } 4329b09969d6SVaclav Hapla ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 4330b09969d6SVaclav Hapla 4331b09969d6SVaclav Hapla ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 4332b09969d6SVaclav Hapla ierr = DMCreateLocalVector(cdm, &coordinates);CHKERRQ(ierr); 4333b09969d6SVaclav Hapla ierr = VecSetBlockSize(coordinates, spaceDim);CHKERRQ(ierr); 4334b09969d6SVaclav Hapla ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 433599946890SBarry Smith ierr = VecGetArrayWrite(coordinates, &coords);CHKERRQ(ierr); 43361edcf0b2SVaclav Hapla for (v = 0; v < vEnd-vStart; ++v) { 4337b09969d6SVaclav Hapla for (d = 0; d < spaceDim; ++d) { 4338b09969d6SVaclav Hapla coords[v*spaceDim+d] = vertexCoords[v*spaceDim+d]; 4339b09969d6SVaclav Hapla } 4340b09969d6SVaclav Hapla } 434199946890SBarry Smith ierr = VecRestoreArrayWrite(coordinates, &coords);CHKERRQ(ierr); 4342b09969d6SVaclav Hapla ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 4343b09969d6SVaclav Hapla ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 4344b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 4345b09969d6SVaclav Hapla PetscFunctionReturn(0); 4346b09969d6SVaclav Hapla } 4347b09969d6SVaclav Hapla 4348b09969d6SVaclav Hapla /*@ 43493df08285SMatthew 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 43503df08285SMatthew G. Knepley 43513df08285SMatthew G. Knepley Collective on comm 4352b09969d6SVaclav Hapla 4353b09969d6SVaclav Hapla Input Parameters: 4354b09969d6SVaclav Hapla + comm - The communicator 4355b09969d6SVaclav Hapla . dim - The topological dimension of the mesh 43563df08285SMatthew G. Knepley . numCells - The number of cells, only on process 0 43573df08285SMatthew G. Knepley . numVertices - The number of vertices owned by this process, or PETSC_DECIDE, only on process 0 43583df08285SMatthew G. Knepley . numCorners - The number of vertices for each cell, only on process 0 4359b09969d6SVaclav Hapla . interpolate - Flag indicating that intermediate mesh entities (faces, edges) should be created automatically 43603df08285SMatthew G. Knepley . cells - An array of numCells*numCorners numbers, the vertices for each cell, only on process 0 4361b09969d6SVaclav Hapla . spaceDim - The spatial dimension used for coordinates 43623df08285SMatthew G. Knepley - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex, only on process 0 4363b09969d6SVaclav Hapla 4364b09969d6SVaclav Hapla Output Parameter: 43653df08285SMatthew G. Knepley . dm - The DM, which only has points on process 0 4366b09969d6SVaclav Hapla 4367b09969d6SVaclav Hapla Notes: 4368b09969d6SVaclav Hapla This function is just a convenient sequence of DMCreate(), DMSetType(), DMSetDimension(), DMPlexBuildFromCellList(), 4369b09969d6SVaclav Hapla DMPlexInterpolate(), DMPlexBuildCoordinatesFromCellList() 4370b09969d6SVaclav Hapla 437125b6865aSVaclav Hapla See DMPlexBuildFromCellList() for an example and details about the topology-related parameters. 437225b6865aSVaclav Hapla See DMPlexBuildCoordinatesFromCellList() for details about the geometry-related parameters. 43733df08285SMatthew G. Knepley See DMPlexCreateFromCellListParallelPetsc() for parallel input 437425b6865aSVaclav Hapla 4375b09969d6SVaclav Hapla Level: intermediate 4376b09969d6SVaclav Hapla 4377b09969d6SVaclav Hapla .seealso: DMPlexCreateFromCellListParallelPetsc(), DMPlexBuildFromCellList(), DMPlexBuildCoordinatesFromCellList(), DMPlexCreateFromDAG(), DMPlexCreate() 43789298eaa6SMatthew G Knepley @*/ 4379a4a685f2SJacob 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) 43809298eaa6SMatthew G Knepley { 43813df08285SMatthew G. Knepley PetscMPIInt rank; 43829298eaa6SMatthew G Knepley PetscErrorCode ierr; 43839298eaa6SMatthew G Knepley 43849298eaa6SMatthew G Knepley PetscFunctionBegin; 43852c71b3e2SJacob 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."); 43863df08285SMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 43879298eaa6SMatthew G Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 43889298eaa6SMatthew G Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 4389c73cfb54SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 43903df08285SMatthew G. Knepley if (!rank) {ierr = DMPlexBuildFromCellList(*dm, numCells, numVertices, numCorners, cells);CHKERRQ(ierr);} 43913df08285SMatthew G. Knepley else {ierr = DMPlexBuildFromCellList(*dm, 0, 0, 0, NULL);CHKERRQ(ierr);} 43929298eaa6SMatthew G Knepley if (interpolate) { 43935fd9971aSMatthew G. Knepley DM idm; 43949298eaa6SMatthew G Knepley 43959298eaa6SMatthew G Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 43969298eaa6SMatthew G Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 43979298eaa6SMatthew G Knepley *dm = idm; 43989298eaa6SMatthew G Knepley } 43993df08285SMatthew G. Knepley if (!rank) {ierr = DMPlexBuildCoordinatesFromCellList(*dm, spaceDim, vertexCoords);CHKERRQ(ierr);} 44003df08285SMatthew G. Knepley else {ierr = DMPlexBuildCoordinatesFromCellList(*dm, spaceDim, NULL);CHKERRQ(ierr);} 44019298eaa6SMatthew G Knepley PetscFunctionReturn(0); 44029298eaa6SMatthew G Knepley } 44039298eaa6SMatthew G Knepley 4404939f6067SMatthew G. Knepley /*@ 4405a4a685f2SJacob Faibussowitsch DMPlexCreateFromCellList - Deprecated, use DMPlexCreateFromCellListPetsc() 4406a4a685f2SJacob Faibussowitsch 4407a4a685f2SJacob Faibussowitsch Level: deprecated 4408a4a685f2SJacob Faibussowitsch 4409a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromCellListPetsc() 4410a4a685f2SJacob Faibussowitsch @*/ 4411a4a685f2SJacob 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) 4412a4a685f2SJacob Faibussowitsch { 4413a4a685f2SJacob Faibussowitsch PetscErrorCode ierr; 4414a4a685f2SJacob Faibussowitsch PetscInt i; 4415a4a685f2SJacob Faibussowitsch PetscInt *pintCells; 4416a4a685f2SJacob Faibussowitsch PetscReal *prealVC; 4417a4a685f2SJacob Faibussowitsch 4418a4a685f2SJacob Faibussowitsch PetscFunctionBegin; 44192c71b3e2SJacob 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)); 4420a4a685f2SJacob Faibussowitsch if (sizeof(int) == sizeof(PetscInt)) { 4421a4a685f2SJacob Faibussowitsch pintCells = (PetscInt *) cells; 4422a4a685f2SJacob Faibussowitsch } else { 4423a4a685f2SJacob Faibussowitsch ierr = PetscMalloc1(numCells*numCorners, &pintCells);CHKERRQ(ierr); 4424a4a685f2SJacob Faibussowitsch for (i = 0; i < numCells*numCorners; i++) { 4425a4a685f2SJacob Faibussowitsch pintCells[i] = (PetscInt) cells[i]; 4426a4a685f2SJacob Faibussowitsch } 4427a4a685f2SJacob Faibussowitsch } 44282c71b3e2SJacob 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)); 4429a4a685f2SJacob Faibussowitsch if (sizeof(double) == sizeof(PetscReal)) { 4430a4a685f2SJacob Faibussowitsch prealVC = (PetscReal *) vertexCoords; 4431a4a685f2SJacob Faibussowitsch } else { 4432a4a685f2SJacob Faibussowitsch ierr = PetscMalloc1(numVertices*spaceDim, &prealVC);CHKERRQ(ierr); 4433a4a685f2SJacob Faibussowitsch for (i = 0; i < numVertices*spaceDim; i++) { 4434a4a685f2SJacob Faibussowitsch prealVC[i] = (PetscReal) vertexCoords[i]; 4435a4a685f2SJacob Faibussowitsch } 4436a4a685f2SJacob Faibussowitsch } 4437a4a685f2SJacob Faibussowitsch ierr = DMPlexCreateFromCellListPetsc(comm, dim, numCells, numVertices, numCorners, interpolate, pintCells, spaceDim, prealVC, dm);CHKERRQ(ierr); 4438a4a685f2SJacob Faibussowitsch if (sizeof(int) != sizeof(PetscInt)) { 4439a4a685f2SJacob Faibussowitsch ierr = PetscFree(pintCells);CHKERRQ(ierr); 4440a4a685f2SJacob Faibussowitsch } 4441a4a685f2SJacob Faibussowitsch if (sizeof(double) != sizeof(PetscReal)) { 4442a4a685f2SJacob Faibussowitsch ierr = PetscFree(prealVC);CHKERRQ(ierr); 4443a4a685f2SJacob Faibussowitsch } 4444a4a685f2SJacob Faibussowitsch PetscFunctionReturn(0); 4445a4a685f2SJacob Faibussowitsch } 4446a4a685f2SJacob Faibussowitsch 4447a4a685f2SJacob Faibussowitsch /*@ 4448939f6067SMatthew 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 4449939f6067SMatthew G. Knepley 4450939f6067SMatthew G. Knepley Input Parameters: 4451c73cfb54SMatthew G. Knepley + dm - The empty DM object, usually from DMCreate() and DMSetDimension() 4452939f6067SMatthew G. Knepley . depth - The depth of the DAG 4453367003a6SStefano Zampini . numPoints - Array of size depth + 1 containing the number of points at each depth 4454939f6067SMatthew G. Knepley . coneSize - The cone size of each point 4455939f6067SMatthew G. Knepley . cones - The concatenation of the cone points for each point, the cone list must be oriented correctly for each point 4456939f6067SMatthew G. Knepley . coneOrientations - The orientation of each cone point 4457367003a6SStefano Zampini - vertexCoords - An array of numPoints[0]*spacedim numbers representing the coordinates of each vertex, with spacedim the value set via DMSetCoordinateDim() 4458939f6067SMatthew G. Knepley 4459939f6067SMatthew G. Knepley Output Parameter: 4460939f6067SMatthew G. Knepley . dm - The DM 4461939f6067SMatthew G. Knepley 4462939f6067SMatthew G. Knepley Note: Two triangles sharing a face would have input 4463939f6067SMatthew G. Knepley $ depth = 1, numPoints = [4 2], coneSize = [3 3 0 0 0 0] 4464939f6067SMatthew G. Knepley $ cones = [2 3 4 3 5 4], coneOrientations = [0 0 0 0 0 0] 4465939f6067SMatthew G. Knepley $ vertexCoords = [-1.0 0.0 0.0 -1.0 0.0 1.0 1.0 0.0] 4466939f6067SMatthew G. Knepley $ 4467939f6067SMatthew G. Knepley which would result in the DMPlex 4468939f6067SMatthew G. Knepley $ 4469939f6067SMatthew G. Knepley $ 4 4470939f6067SMatthew G. Knepley $ / | \ 4471939f6067SMatthew G. Knepley $ / | \ 4472939f6067SMatthew G. Knepley $ / | \ 4473939f6067SMatthew G. Knepley $ 2 0 | 1 5 4474939f6067SMatthew G. Knepley $ \ | / 4475939f6067SMatthew G. Knepley $ \ | / 4476939f6067SMatthew G. Knepley $ \ | / 4477939f6067SMatthew G. Knepley $ 3 4478939f6067SMatthew G. Knepley $ 4479a4a685f2SJacob Faibussowitsch $ Notice that all points are numbered consecutively, unlike DMPlexCreateFromCellListPetsc() 4480939f6067SMatthew G. Knepley 4481939f6067SMatthew G. Knepley Level: advanced 4482939f6067SMatthew G. Knepley 4483a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromCellListPetsc(), DMPlexCreate() 4484939f6067SMatthew G. Knepley @*/ 44859298eaa6SMatthew G Knepley PetscErrorCode DMPlexCreateFromDAG(DM dm, PetscInt depth, const PetscInt numPoints[], const PetscInt coneSize[], const PetscInt cones[], const PetscInt coneOrientations[], const PetscScalar vertexCoords[]) 44869298eaa6SMatthew G Knepley { 44879298eaa6SMatthew G Knepley Vec coordinates; 44889298eaa6SMatthew G Knepley PetscSection coordSection; 44899298eaa6SMatthew G Knepley PetscScalar *coords; 4490811e8653SToby Isaac PetscInt coordSize, firstVertex = -1, pStart = 0, pEnd = 0, p, v, dim, dimEmbed, d, off; 44919298eaa6SMatthew G Knepley PetscErrorCode ierr; 44929298eaa6SMatthew G Knepley 44939298eaa6SMatthew G Knepley PetscFunctionBegin; 4494c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 4495811e8653SToby Isaac ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr); 44962c71b3e2SJacob Faibussowitsch PetscCheckFalse(dimEmbed < dim,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Embedding dimension %D cannot be less than intrinsic dimension %d",dimEmbed,dim); 44979298eaa6SMatthew G Knepley for (d = 0; d <= depth; ++d) pEnd += numPoints[d]; 44989298eaa6SMatthew G Knepley ierr = DMPlexSetChart(dm, pStart, pEnd);CHKERRQ(ierr); 44999298eaa6SMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 45009298eaa6SMatthew G Knepley ierr = DMPlexSetConeSize(dm, p, coneSize[p-pStart]);CHKERRQ(ierr); 450197e052ccSToby Isaac if (firstVertex < 0 && !coneSize[p - pStart]) { 450297e052ccSToby Isaac firstVertex = p - pStart; 45039298eaa6SMatthew G Knepley } 450497e052ccSToby Isaac } 45052c71b3e2SJacob Faibussowitsch PetscCheckFalse(firstVertex < 0 && numPoints[0],PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Expected %D vertices but could not find any", numPoints[0]); 45069298eaa6SMatthew G Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 45079298eaa6SMatthew G Knepley for (p = pStart, off = 0; p < pEnd; off += coneSize[p-pStart], ++p) { 45089298eaa6SMatthew G Knepley ierr = DMPlexSetCone(dm, p, &cones[off]);CHKERRQ(ierr); 45099298eaa6SMatthew G Knepley ierr = DMPlexSetConeOrientation(dm, p, &coneOrientations[off]);CHKERRQ(ierr); 45109298eaa6SMatthew G Knepley } 45119298eaa6SMatthew G Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 45129298eaa6SMatthew G Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 45139298eaa6SMatthew G Knepley /* Build coordinates */ 4514c2166f76SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 45159298eaa6SMatthew G Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 4516811e8653SToby Isaac ierr = PetscSectionSetFieldComponents(coordSection, 0, dimEmbed);CHKERRQ(ierr); 45179298eaa6SMatthew G Knepley ierr = PetscSectionSetChart(coordSection, firstVertex, firstVertex+numPoints[0]);CHKERRQ(ierr); 45189298eaa6SMatthew G Knepley for (v = firstVertex; v < firstVertex+numPoints[0]; ++v) { 4519811e8653SToby Isaac ierr = PetscSectionSetDof(coordSection, v, dimEmbed);CHKERRQ(ierr); 4520811e8653SToby Isaac ierr = PetscSectionSetFieldDof(coordSection, v, 0, dimEmbed);CHKERRQ(ierr); 45219298eaa6SMatthew G Knepley } 45229298eaa6SMatthew G Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 45239298eaa6SMatthew G Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 45248b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 45256f8cbbeeSMatthew G Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 45269298eaa6SMatthew G Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 45278b9ced59SLisandro Dalcin ierr = VecSetBlockSize(coordinates, dimEmbed);CHKERRQ(ierr); 45282eb5907fSJed Brown ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 45299318fe57SMatthew G. Knepley if (vertexCoords) { 45309298eaa6SMatthew G Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 45319298eaa6SMatthew G Knepley for (v = 0; v < numPoints[0]; ++v) { 45329298eaa6SMatthew G Knepley PetscInt off; 45339298eaa6SMatthew G Knepley 45349298eaa6SMatthew G Knepley ierr = PetscSectionGetOffset(coordSection, v+firstVertex, &off);CHKERRQ(ierr); 4535811e8653SToby Isaac for (d = 0; d < dimEmbed; ++d) { 4536811e8653SToby Isaac coords[off+d] = vertexCoords[v*dimEmbed+d]; 45379298eaa6SMatthew G Knepley } 45389298eaa6SMatthew G Knepley } 45399318fe57SMatthew G. Knepley } 45409298eaa6SMatthew G Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 45419298eaa6SMatthew G Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 45429298eaa6SMatthew G Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 45439298eaa6SMatthew G Knepley PetscFunctionReturn(0); 45449298eaa6SMatthew G Knepley } 45458415267dSToby Isaac 4546ca522641SMatthew G. Knepley /*@C 45478ca92349SMatthew G. Knepley DMPlexCreateCellVertexFromFile - Create a DMPlex mesh from a simple cell-vertex file. 45488ca92349SMatthew G. Knepley 45498ca92349SMatthew G. Knepley + comm - The MPI communicator 45508ca92349SMatthew G. Knepley . filename - Name of the .dat file 45518ca92349SMatthew G. Knepley - interpolate - Create faces and edges in the mesh 45528ca92349SMatthew G. Knepley 45538ca92349SMatthew G. Knepley Output Parameter: 45548ca92349SMatthew G. Knepley . dm - The DM object representing the mesh 45558ca92349SMatthew G. Knepley 45568ca92349SMatthew G. Knepley Note: The format is the simplest possible: 45578ca92349SMatthew G. Knepley $ Ne 45588ca92349SMatthew G. Knepley $ v0 v1 ... vk 45598ca92349SMatthew G. Knepley $ Nv 45608ca92349SMatthew G. Knepley $ x y z marker 45618ca92349SMatthew G. Knepley 45628ca92349SMatthew G. Knepley Level: beginner 45638ca92349SMatthew G. Knepley 45648ca92349SMatthew G. Knepley .seealso: DMPlexCreateFromFile(), DMPlexCreateMedFromFile(), DMPlexCreateGmsh(), DMPlexCreate() 45658ca92349SMatthew G. Knepley @*/ 45668ca92349SMatthew G. Knepley PetscErrorCode DMPlexCreateCellVertexFromFile(MPI_Comm comm, const char filename[], PetscBool interpolate, DM *dm) 45678ca92349SMatthew G. Knepley { 45688ca92349SMatthew G. Knepley DMLabel marker; 45698ca92349SMatthew G. Knepley PetscViewer viewer; 45708ca92349SMatthew G. Knepley Vec coordinates; 45718ca92349SMatthew G. Knepley PetscSection coordSection; 45728ca92349SMatthew G. Knepley PetscScalar *coords; 45738ca92349SMatthew G. Knepley char line[PETSC_MAX_PATH_LEN]; 45748ca92349SMatthew G. Knepley PetscInt dim = 3, cdim = 3, coordSize, v, c, d; 45758ca92349SMatthew G. Knepley PetscMPIInt rank; 4576f8d5e320SMatthew G. Knepley int snum, Nv, Nc, Ncn, Nl; 45778ca92349SMatthew G. Knepley PetscErrorCode ierr; 45788ca92349SMatthew G. Knepley 45798ca92349SMatthew G. Knepley PetscFunctionBegin; 4580ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 45818ca92349SMatthew G. Knepley ierr = PetscViewerCreate(comm, &viewer);CHKERRQ(ierr); 45828ca92349SMatthew G. Knepley ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr); 45838ca92349SMatthew G. Knepley ierr = PetscViewerFileSetMode(viewer, FILE_MODE_READ);CHKERRQ(ierr); 45848ca92349SMatthew G. Knepley ierr = PetscViewerFileSetName(viewer, filename);CHKERRQ(ierr); 4585dd400576SPatrick Sanan if (rank == 0) { 4586f8d5e320SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 4, NULL, PETSC_STRING);CHKERRQ(ierr); 4587f8d5e320SMatthew G. Knepley snum = sscanf(line, "%d %d %d %d", &Nc, &Nv, &Ncn, &Nl); 45882c71b3e2SJacob Faibussowitsch PetscCheckFalse(snum != 4,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 458925ce1634SJed Brown } else { 4590f8d5e320SMatthew G. Knepley Nc = Nv = Ncn = Nl = 0; 45918ca92349SMatthew G. Knepley } 45928ca92349SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 45938ca92349SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 45948ca92349SMatthew G. Knepley ierr = DMPlexSetChart(*dm, 0, Nc+Nv);CHKERRQ(ierr); 45958ca92349SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 45968ca92349SMatthew G. Knepley ierr = DMSetCoordinateDim(*dm, cdim);CHKERRQ(ierr); 45978ca92349SMatthew G. Knepley /* Read topology */ 4598dd400576SPatrick Sanan if (rank == 0) { 4599f8d5e320SMatthew G. Knepley char format[PETSC_MAX_PATH_LEN]; 4600f8d5e320SMatthew G. Knepley PetscInt cone[8]; 46018ca92349SMatthew G. Knepley int vbuf[8], v; 46028ca92349SMatthew G. Knepley 4603f8d5e320SMatthew G. Knepley for (c = 0; c < Ncn; ++c) {format[c*3+0] = '%'; format[c*3+1] = 'd'; format[c*3+2] = ' ';} 4604f8d5e320SMatthew G. Knepley format[Ncn*3-1] = '\0'; 4605f8d5e320SMatthew G. Knepley for (c = 0; c < Nc; ++c) {ierr = DMPlexSetConeSize(*dm, c, Ncn);CHKERRQ(ierr);} 46068ca92349SMatthew G. Knepley ierr = DMSetUp(*dm);CHKERRQ(ierr); 46078ca92349SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 4608f8d5e320SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, Ncn, NULL, PETSC_STRING);CHKERRQ(ierr); 4609f8d5e320SMatthew G. Knepley switch (Ncn) { 4610f8d5e320SMatthew G. Knepley case 2: snum = sscanf(line, format, &vbuf[0], &vbuf[1]);break; 4611f8d5e320SMatthew G. Knepley case 3: snum = sscanf(line, format, &vbuf[0], &vbuf[1], &vbuf[2]);break; 4612f8d5e320SMatthew G. Knepley case 4: snum = sscanf(line, format, &vbuf[0], &vbuf[1], &vbuf[2], &vbuf[3]);break; 4613f8d5e320SMatthew G. Knepley case 6: snum = sscanf(line, format, &vbuf[0], &vbuf[1], &vbuf[2], &vbuf[3], &vbuf[4], &vbuf[5]);break; 4614f8d5e320SMatthew 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; 461598921bdaSJacob Faibussowitsch default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No cell shape with %D vertices", Ncn); 4616f8d5e320SMatthew G. Knepley } 46172c71b3e2SJacob Faibussowitsch PetscCheckFalse(snum != Ncn,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 4618f8d5e320SMatthew G. Knepley for (v = 0; v < Ncn; ++v) cone[v] = vbuf[v] + Nc; 46198ca92349SMatthew G. Knepley /* Hexahedra are inverted */ 4620f8d5e320SMatthew G. Knepley if (Ncn == 8) { 46218ca92349SMatthew G. Knepley PetscInt tmp = cone[1]; 46228ca92349SMatthew G. Knepley cone[1] = cone[3]; 46238ca92349SMatthew G. Knepley cone[3] = tmp; 46248ca92349SMatthew G. Knepley } 46258ca92349SMatthew G. Knepley ierr = DMPlexSetCone(*dm, c, cone);CHKERRQ(ierr); 46268ca92349SMatthew G. Knepley } 46278ca92349SMatthew G. Knepley } 46288ca92349SMatthew G. Knepley ierr = DMPlexSymmetrize(*dm);CHKERRQ(ierr); 46298ca92349SMatthew G. Knepley ierr = DMPlexStratify(*dm);CHKERRQ(ierr); 46308ca92349SMatthew G. Knepley /* Read coordinates */ 46318ca92349SMatthew G. Knepley ierr = DMGetCoordinateSection(*dm, &coordSection);CHKERRQ(ierr); 46328ca92349SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 46338ca92349SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, cdim);CHKERRQ(ierr); 46348ca92349SMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, Nc, Nc + Nv);CHKERRQ(ierr); 46358ca92349SMatthew G. Knepley for (v = Nc; v < Nc+Nv; ++v) { 46368ca92349SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, cdim);CHKERRQ(ierr); 46378ca92349SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, cdim);CHKERRQ(ierr); 46388ca92349SMatthew G. Knepley } 46398ca92349SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 46408ca92349SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 46418ca92349SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 46428ca92349SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 46438ca92349SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 46448ca92349SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, cdim);CHKERRQ(ierr); 46458ca92349SMatthew G. Knepley ierr = VecSetType(coordinates, VECSTANDARD);CHKERRQ(ierr); 46468ca92349SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 4647dd400576SPatrick Sanan if (rank == 0) { 4648f8d5e320SMatthew G. Knepley char format[PETSC_MAX_PATH_LEN]; 46498ca92349SMatthew G. Knepley double x[3]; 4650f8d5e320SMatthew G. Knepley int l, val[3]; 46518ca92349SMatthew G. Knepley 4652f8d5e320SMatthew G. Knepley if (Nl) { 4653f8d5e320SMatthew G. Knepley for (l = 0; l < Nl; ++l) {format[l*3+0] = '%'; format[l*3+1] = 'd'; format[l*3+2] = ' ';} 4654f8d5e320SMatthew G. Knepley format[Nl*3-1] = '\0'; 46558ca92349SMatthew G. Knepley ierr = DMCreateLabel(*dm, "marker");CHKERRQ(ierr); 46568ca92349SMatthew G. Knepley ierr = DMGetLabel(*dm, "marker", &marker);CHKERRQ(ierr); 4657f8d5e320SMatthew G. Knepley } 46588ca92349SMatthew G. Knepley for (v = 0; v < Nv; ++v) { 4659f8d5e320SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 3+Nl, NULL, PETSC_STRING);CHKERRQ(ierr); 4660f8d5e320SMatthew G. Knepley snum = sscanf(line, "%lg %lg %lg", &x[0], &x[1], &x[2]); 46612c71b3e2SJacob Faibussowitsch PetscCheckFalse(snum != 3,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 4662f8d5e320SMatthew G. Knepley switch (Nl) { 4663f8d5e320SMatthew G. Knepley case 0: snum = 0;break; 4664f8d5e320SMatthew G. Knepley case 1: snum = sscanf(line, format, &val[0]);break; 4665f8d5e320SMatthew G. Knepley case 2: snum = sscanf(line, format, &val[0], &val[1]);break; 4666f8d5e320SMatthew G. Knepley case 3: snum = sscanf(line, format, &val[0], &val[1], &val[2]);break; 466798921bdaSJacob Faibussowitsch default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Request support for %D labels", Nl); 4668f8d5e320SMatthew G. Knepley } 46692c71b3e2SJacob Faibussowitsch PetscCheckFalse(snum != Nl,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 46708ca92349SMatthew G. Knepley for (d = 0; d < cdim; ++d) coords[v*cdim+d] = x[d]; 4671f8d5e320SMatthew G. Knepley for (l = 0; l < Nl; ++l) {ierr = DMLabelSetValue(marker, v+Nc, val[l]);CHKERRQ(ierr);} 46728ca92349SMatthew G. Knepley } 46738ca92349SMatthew G. Knepley } 46748ca92349SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 46758ca92349SMatthew G. Knepley ierr = DMSetCoordinatesLocal(*dm, coordinates);CHKERRQ(ierr); 46768ca92349SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 46778ca92349SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 46788ca92349SMatthew G. Knepley if (interpolate) { 46798ca92349SMatthew G. Knepley DM idm; 46808ca92349SMatthew G. Knepley DMLabel bdlabel; 46818ca92349SMatthew G. Knepley 46828ca92349SMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 46838ca92349SMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 46848ca92349SMatthew G. Knepley *dm = idm; 46858ca92349SMatthew G. Knepley 4686f8d5e320SMatthew G. Knepley if (!Nl) { 4687f8d5e320SMatthew G. Knepley ierr = DMCreateLabel(*dm, "marker");CHKERRQ(ierr); 46888ca92349SMatthew G. Knepley ierr = DMGetLabel(*dm, "marker", &bdlabel);CHKERRQ(ierr); 46898ca92349SMatthew G. Knepley ierr = DMPlexMarkBoundaryFaces(*dm, PETSC_DETERMINE, bdlabel);CHKERRQ(ierr); 46908ca92349SMatthew G. Knepley ierr = DMPlexLabelComplete(*dm, bdlabel);CHKERRQ(ierr); 46918ca92349SMatthew G. Knepley } 4692f8d5e320SMatthew G. Knepley } 46938ca92349SMatthew G. Knepley PetscFunctionReturn(0); 46948ca92349SMatthew G. Knepley } 46958ca92349SMatthew G. Knepley 46968ca92349SMatthew G. Knepley /*@C 4697ca522641SMatthew G. Knepley DMPlexCreateFromFile - This takes a filename and produces a DM 4698ca522641SMatthew G. Knepley 4699ca522641SMatthew G. Knepley Input Parameters: 4700ca522641SMatthew G. Knepley + comm - The communicator 4701ca522641SMatthew G. Knepley . filename - A file name 4702cd7e8a5eSksagiyam . plexname - The object name of the resulting DM, also used for intra-datafile lookup by some formats 4703ca522641SMatthew G. Knepley - interpolate - Flag to create intermediate mesh pieces (edges, faces) 4704ca522641SMatthew G. Knepley 4705ca522641SMatthew G. Knepley Output Parameter: 4706ca522641SMatthew G. Knepley . dm - The DM 4707ca522641SMatthew G. Knepley 470802ef0d99SVaclav Hapla Options Database Keys: 470902ef0d99SVaclav Hapla . -dm_plex_create_from_hdf5_xdmf - use the PETSC_VIEWER_HDF5_XDMF format for reading HDF5 471002ef0d99SVaclav Hapla 4711bca97951SVaclav Hapla Use -dm_plex_create_ prefix to pass options to the internal PetscViewer, e.g. 4712bca97951SVaclav Hapla $ -dm_plex_create_viewer_hdf5_collective 4713bca97951SVaclav Hapla 4714cd7e8a5eSksagiyam Notes: 4715cd7e8a5eSksagiyam Using PETSCVIEWERHDF5 type with PETSC_VIEWER_HDF5_PETSC format, one can save multiple DMPlex 4716cd7e8a5eSksagiyam meshes in a single HDF5 file. This in turn requires one to name the DMPlex object with PetscObjectSetName() 4717cd7e8a5eSksagiyam before saving it with DMView() and before loading it with DMLoad() for identification of the mesh object. 4718cd7e8a5eSksagiyam The input parameter name is thus used to name the DMPlex object when DMPlexCreateFromFile() internally 4719cd7e8a5eSksagiyam calls DMLoad(). Currently, name is ignored for other viewer types and/or formats. 4720cd7e8a5eSksagiyam 4721ca522641SMatthew G. Knepley Level: beginner 4722ca522641SMatthew G. Knepley 4723cd7e8a5eSksagiyam .seealso: DMPlexCreateFromDAG(), DMPlexCreateFromCellListPetsc(), DMPlexCreate(), PetscObjectSetName(), DMView(), DMLoad() 4724ca522641SMatthew G. Knepley @*/ 4725cd7e8a5eSksagiyam PetscErrorCode DMPlexCreateFromFile(MPI_Comm comm, const char filename[], const char plexname[], PetscBool interpolate, DM *dm) 4726ca522641SMatthew G. Knepley { 4727ca522641SMatthew G. Knepley const char *extGmsh = ".msh"; 4728de78e4feSLisandro Dalcin const char *extGmsh2 = ".msh2"; 4729de78e4feSLisandro Dalcin const char *extGmsh4 = ".msh4"; 4730ca522641SMatthew G. Knepley const char *extCGNS = ".cgns"; 4731ca522641SMatthew G. Knepley const char *extExodus = ".exo"; 473286a0adb1SJed Brown const char *extExodus_e = ".e"; 473390c68965SMatthew G. Knepley const char *extGenesis = ".gen"; 47342f0bd6dcSMichael Lange const char *extFluent = ".cas"; 4735cc2f8f65SMatthew G. Knepley const char *extHDF5 = ".h5"; 4736707dd687SMichael Lange const char *extMed = ".med"; 4737f2801cd6SMatthew G. Knepley const char *extPLY = ".ply"; 4738c1cad2e7SMatthew G. Knepley const char *extEGADSLite = ".egadslite"; 4739c1cad2e7SMatthew G. Knepley const char *extEGADS = ".egads"; 4740c1cad2e7SMatthew G. Knepley const char *extIGES = ".igs"; 4741c1cad2e7SMatthew G. Knepley const char *extSTEP = ".stp"; 47428ca92349SMatthew G. Knepley const char *extCV = ".dat"; 4743ca522641SMatthew G. Knepley size_t len; 4744c1cad2e7SMatthew G. Knepley PetscBool isGmsh, isGmsh2, isGmsh4, isCGNS, isExodus, isGenesis, isFluent, isHDF5, isMed, isPLY, isEGADSLite, isEGADS, isIGES, isSTEP, isCV; 4745ca522641SMatthew G. Knepley PetscMPIInt rank; 4746ca522641SMatthew G. Knepley PetscErrorCode ierr; 4747ca522641SMatthew G. Knepley 4748ca522641SMatthew G. Knepley PetscFunctionBegin; 47495d80c0bfSVaclav Hapla PetscValidCharPointer(filename, 2); 47500d862eaeSPierre Jolivet if (plexname) PetscValidCharPointer(plexname, 3); 4751cd7e8a5eSksagiyam PetscValidPointer(dm, 5); 4752f1f45c63SVaclav Hapla ierr = DMInitializePackage();CHKERRQ(ierr); 4753f1f45c63SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_CreateFromFile,0,0,0,0);CHKERRQ(ierr); 4754ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 4755ca522641SMatthew G. Knepley ierr = PetscStrlen(filename, &len);CHKERRQ(ierr); 47562c71b3e2SJacob Faibussowitsch PetscCheckFalse(!len,comm, PETSC_ERR_ARG_WRONG, "Filename must be a valid path"); 4757ca522641SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extGmsh, 4, &isGmsh);CHKERRQ(ierr); 4758de78e4feSLisandro Dalcin ierr = PetscStrncmp(&filename[PetscMax(0,len-5)], extGmsh2, 5, &isGmsh2);CHKERRQ(ierr); 4759de78e4feSLisandro Dalcin ierr = PetscStrncmp(&filename[PetscMax(0,len-5)], extGmsh4, 5, &isGmsh4);CHKERRQ(ierr); 4760ca522641SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-5)], extCGNS, 5, &isCGNS);CHKERRQ(ierr); 4761ca522641SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extExodus, 4, &isExodus);CHKERRQ(ierr); 476286a0adb1SJed Brown if (!isExodus) { 476386a0adb1SJed Brown ierr = PetscStrncmp(&filename[PetscMax(0,len-2)], extExodus_e, 2, &isExodus);CHKERRQ(ierr); 476486a0adb1SJed Brown } 476590c68965SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extGenesis, 4, &isGenesis);CHKERRQ(ierr); 47662f0bd6dcSMichael Lange ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extFluent, 4, &isFluent);CHKERRQ(ierr); 4767cc2f8f65SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-3)], extHDF5, 3, &isHDF5);CHKERRQ(ierr); 4768707dd687SMichael Lange ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extMed, 4, &isMed);CHKERRQ(ierr); 4769f2801cd6SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extPLY, 4, &isPLY);CHKERRQ(ierr); 4770c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-10)], extEGADSLite, 10, &isEGADSLite);CHKERRQ(ierr); 4771c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-6)], extEGADS, 6, &isEGADS);CHKERRQ(ierr); 4772c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extIGES, 4, &isIGES);CHKERRQ(ierr); 4773c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extSTEP, 4, &isSTEP);CHKERRQ(ierr); 47748ca92349SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extCV, 4, &isCV);CHKERRQ(ierr); 4775de78e4feSLisandro Dalcin if (isGmsh || isGmsh2 || isGmsh4) { 47767d282ae0SMichael Lange ierr = DMPlexCreateGmshFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4777ca522641SMatthew G. Knepley } else if (isCGNS) { 4778ca522641SMatthew G. Knepley ierr = DMPlexCreateCGNSFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 477990c68965SMatthew G. Knepley } else if (isExodus || isGenesis) { 4780ca522641SMatthew G. Knepley ierr = DMPlexCreateExodusFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 47812f0bd6dcSMichael Lange } else if (isFluent) { 47822f0bd6dcSMichael Lange ierr = DMPlexCreateFluentFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4783cc2f8f65SMatthew G. Knepley } else if (isHDF5) { 47849c48423bSVaclav Hapla PetscBool load_hdf5_xdmf = PETSC_FALSE; 4785cc2f8f65SMatthew G. Knepley PetscViewer viewer; 4786cc2f8f65SMatthew G. Knepley 478743b242b4SVaclav 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 */ 478843b242b4SVaclav Hapla ierr = PetscStrncmp(&filename[PetscMax(0,len-8)], ".xdmf", 5, &load_hdf5_xdmf);CHKERRQ(ierr); 47899c48423bSVaclav Hapla ierr = PetscOptionsGetBool(NULL, NULL, "-dm_plex_create_from_hdf5_xdmf", &load_hdf5_xdmf, NULL);CHKERRQ(ierr); 4790cc2f8f65SMatthew G. Knepley ierr = PetscViewerCreate(comm, &viewer);CHKERRQ(ierr); 4791cc2f8f65SMatthew G. Knepley ierr = PetscViewerSetType(viewer, PETSCVIEWERHDF5);CHKERRQ(ierr); 4792bca97951SVaclav Hapla ierr = PetscViewerSetOptionsPrefix(viewer, "dm_plex_create_");CHKERRQ(ierr); 4793bca97951SVaclav Hapla ierr = PetscViewerSetFromOptions(viewer);CHKERRQ(ierr); 4794cc2f8f65SMatthew G. Knepley ierr = PetscViewerFileSetMode(viewer, FILE_MODE_READ);CHKERRQ(ierr); 4795cc2f8f65SMatthew G. Knepley ierr = PetscViewerFileSetName(viewer, filename);CHKERRQ(ierr); 4796cd7e8a5eSksagiyam 4797cc2f8f65SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 4798cd7e8a5eSksagiyam ierr = PetscObjectSetName((PetscObject)(*dm), plexname);CHKERRQ(ierr); 4799cc2f8f65SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 48009c48423bSVaclav Hapla if (load_hdf5_xdmf) {ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_HDF5_XDMF);CHKERRQ(ierr);} 4801cc2f8f65SMatthew G. Knepley ierr = DMLoad(*dm, viewer);CHKERRQ(ierr); 48029c48423bSVaclav Hapla if (load_hdf5_xdmf) {ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);} 4803cc2f8f65SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 48045fd9971aSMatthew G. Knepley 48055fd9971aSMatthew G. Knepley if (interpolate) { 48065fd9971aSMatthew G. Knepley DM idm; 48075fd9971aSMatthew G. Knepley 48085fd9971aSMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 48095fd9971aSMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 48105fd9971aSMatthew G. Knepley *dm = idm; 48115fd9971aSMatthew G. Knepley } 4812707dd687SMichael Lange } else if (isMed) { 4813707dd687SMichael Lange ierr = DMPlexCreateMedFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4814f2801cd6SMatthew G. Knepley } else if (isPLY) { 4815f2801cd6SMatthew G. Knepley ierr = DMPlexCreatePLYFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4816c1cad2e7SMatthew G. Knepley } else if (isEGADSLite || isEGADS || isIGES || isSTEP) { 4817c1cad2e7SMatthew G. Knepley if (isEGADSLite) {ierr = DMPlexCreateEGADSLiteFromFile(comm, filename, dm);CHKERRQ(ierr);} 4818c1cad2e7SMatthew G. Knepley else {ierr = DMPlexCreateEGADSFromFile(comm, filename, dm);CHKERRQ(ierr);} 48197bee2925SMatthew Knepley if (!interpolate) { 48207bee2925SMatthew Knepley DM udm; 48217bee2925SMatthew Knepley 48227bee2925SMatthew Knepley ierr = DMPlexUninterpolate(*dm, &udm);CHKERRQ(ierr); 48237bee2925SMatthew Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 48247bee2925SMatthew Knepley *dm = udm; 48257bee2925SMatthew Knepley } 48268ca92349SMatthew G. Knepley } else if (isCV) { 48278ca92349SMatthew G. Knepley ierr = DMPlexCreateCellVertexFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 482898921bdaSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot load file %s: unrecognized extension", filename); 4829ed5e4e85SVaclav Hapla ierr = PetscStrlen(plexname, &len);CHKERRQ(ierr); 4830ed5e4e85SVaclav Hapla if (len) {ierr = PetscObjectSetName((PetscObject)(*dm), plexname);CHKERRQ(ierr);} 4831f1f45c63SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_CreateFromFile,0,0,0,0);CHKERRQ(ierr); 4832ca522641SMatthew G. Knepley PetscFunctionReturn(0); 4833ca522641SMatthew G. Knepley } 4834