1552f7358SJed Brown #define PETSCDM_DLL 2af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 3e8f14785SLisandro Dalcin #include <petsc/private/hashseti.h> /*I "petscdmplex.h" I*/ 40c312b8eSJed Brown #include <petscsf.h> 5552f7358SJed Brown 6b09969d6SVaclav Hapla PetscLogEvent DMPLEX_CreateFromFile, DMPLEX_BuildFromCellList, DMPLEX_BuildCoordinatesFromCellList; 758cd63d5SVaclav Hapla 89318fe57SMatthew G. Knepley /* External function declarations here */ 99318fe57SMatthew G. Knepley static PetscErrorCode DMInitialize_Plex(DM dm); 109318fe57SMatthew G. Knepley 11*e600fa54SMatthew G. Knepley /* This copies internal things in the Plex structure that we generally want when making a new, related Plex */ 12*e600fa54SMatthew G. Knepley PetscErrorCode DMPlexCopy_Internal(DM dmin, PetscBool copyPeriodicity, DM dmout) 13*e600fa54SMatthew G. Knepley { 14*e600fa54SMatthew G. Knepley const DMBoundaryType *bd; 15*e600fa54SMatthew G. Knepley const PetscReal *maxCell, *L; 16*e600fa54SMatthew G. Knepley PetscBool isper, dist; 17*e600fa54SMatthew G. Knepley PetscErrorCode ierr; 18*e600fa54SMatthew G. Knepley 19*e600fa54SMatthew G. Knepley PetscFunctionBegin; 20*e600fa54SMatthew G. Knepley if (copyPeriodicity) { 21*e600fa54SMatthew G. Knepley ierr = DMGetPeriodicity(dmin, &isper, &maxCell, &L, &bd);CHKERRQ(ierr); 22*e600fa54SMatthew G. Knepley ierr = DMSetPeriodicity(dmout, isper, maxCell, L, bd);CHKERRQ(ierr); 23*e600fa54SMatthew G. Knepley } 24*e600fa54SMatthew G. Knepley ierr = DMPlexDistributeGetDefault(dmin, &dist);CHKERRQ(ierr); 25*e600fa54SMatthew G. Knepley ierr = DMPlexDistributeSetDefault(dmout, dist);CHKERRQ(ierr); 26*e600fa54SMatthew G. Knepley ((DM_Plex *) dmout->data)->useHashLocation = ((DM_Plex *) dmin->data)->useHashLocation; 27*e600fa54SMatthew G. Knepley PetscFunctionReturn(0); 28*e600fa54SMatthew G. Knepley } 29*e600fa54SMatthew G. Knepley 309318fe57SMatthew G. Knepley /* Replace dm with the contents of ndm, and then destroy ndm 319318fe57SMatthew G. Knepley - Share the DM_Plex structure 329318fe57SMatthew G. Knepley - Share the coordinates 339318fe57SMatthew G. Knepley - Share the SF 349318fe57SMatthew G. Knepley */ 359318fe57SMatthew G. Knepley static PetscErrorCode DMPlexReplace_Static(DM dm, DM *ndm) 369318fe57SMatthew G. Knepley { 379318fe57SMatthew G. Knepley PetscSF sf; 389318fe57SMatthew G. Knepley DM dmNew = *ndm, coordDM, coarseDM; 399318fe57SMatthew G. Knepley Vec coords; 409318fe57SMatthew G. Knepley PetscBool isper; 419318fe57SMatthew G. Knepley const PetscReal *maxCell, *L; 429318fe57SMatthew G. Knepley const DMBoundaryType *bd; 439318fe57SMatthew G. Knepley PetscInt dim, cdim; 449318fe57SMatthew G. Knepley PetscErrorCode ierr; 459318fe57SMatthew G. Knepley 469318fe57SMatthew G. Knepley PetscFunctionBegin; 479318fe57SMatthew G. Knepley if (dm == dmNew) { 489318fe57SMatthew G. Knepley ierr = DMDestroy(ndm);CHKERRQ(ierr); 499318fe57SMatthew G. Knepley PetscFunctionReturn(0); 509318fe57SMatthew G. Knepley } 519318fe57SMatthew G. Knepley dm->setupcalled = dmNew->setupcalled; 529318fe57SMatthew G. Knepley ierr = DMGetDimension(dmNew, &dim);CHKERRQ(ierr); 539318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 549318fe57SMatthew G. Knepley ierr = DMGetCoordinateDim(dmNew, &cdim);CHKERRQ(ierr); 559318fe57SMatthew G. Knepley ierr = DMSetCoordinateDim(dm, cdim);CHKERRQ(ierr); 569318fe57SMatthew G. Knepley ierr = DMGetPointSF(dmNew, &sf);CHKERRQ(ierr); 579318fe57SMatthew G. Knepley ierr = DMSetPointSF(dm, sf);CHKERRQ(ierr); 589318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dmNew, &coordDM);CHKERRQ(ierr); 599318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dmNew, &coords);CHKERRQ(ierr); 609318fe57SMatthew G. Knepley ierr = DMSetCoordinateDM(dm, coordDM);CHKERRQ(ierr); 619318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coords);CHKERRQ(ierr); 629318fe57SMatthew G. Knepley /* Do not want to create the coordinate field if it does not already exist, so do not call DMGetCoordinateField() */ 639318fe57SMatthew G. Knepley ierr = DMFieldDestroy(&dm->coordinateField);CHKERRQ(ierr); 649318fe57SMatthew G. Knepley dm->coordinateField = dmNew->coordinateField; 6561a622f3SMatthew G. Knepley ((DM_Plex *) dmNew->data)->coordFunc = ((DM_Plex *) dm->data)->coordFunc; 669318fe57SMatthew G. Knepley ierr = DMGetPeriodicity(dmNew, &isper, &maxCell, &L, &bd);CHKERRQ(ierr); 679318fe57SMatthew G. Knepley ierr = DMSetPeriodicity(dm, isper, maxCell, L, bd);CHKERRQ(ierr); 689318fe57SMatthew G. Knepley ierr = DMDestroy_Plex(dm);CHKERRQ(ierr); 699318fe57SMatthew G. Knepley ierr = DMInitialize_Plex(dm);CHKERRQ(ierr); 709318fe57SMatthew G. Knepley dm->data = dmNew->data; 719318fe57SMatthew G. Knepley ((DM_Plex *) dmNew->data)->refct++; 729318fe57SMatthew G. Knepley ierr = DMDestroyLabelLinkList_Internal(dm);CHKERRQ(ierr); 732cbb9b06SVaclav Hapla ierr = DMCopyLabels(dmNew, dm, PETSC_OWN_POINTER, PETSC_TRUE, DM_COPY_LABELS_FAIL);CHKERRQ(ierr); 749318fe57SMatthew G. Knepley ierr = DMGetCoarseDM(dmNew,&coarseDM);CHKERRQ(ierr); 759318fe57SMatthew G. Knepley ierr = DMSetCoarseDM(dm,coarseDM);CHKERRQ(ierr); 769318fe57SMatthew G. Knepley ierr = DMDestroy(ndm);CHKERRQ(ierr); 779318fe57SMatthew G. Knepley PetscFunctionReturn(0); 789318fe57SMatthew G. Knepley } 799318fe57SMatthew G. Knepley 809318fe57SMatthew G. Knepley /* Swap dm with the contents of dmNew 819318fe57SMatthew G. Knepley - Swap the DM_Plex structure 829318fe57SMatthew G. Knepley - Swap the coordinates 839318fe57SMatthew G. Knepley - Swap the point PetscSF 849318fe57SMatthew G. Knepley */ 859318fe57SMatthew G. Knepley static PetscErrorCode DMPlexSwap_Static(DM dmA, DM dmB) 869318fe57SMatthew G. Knepley { 879318fe57SMatthew G. Knepley DM coordDMA, coordDMB; 889318fe57SMatthew G. Knepley Vec coordsA, coordsB; 899318fe57SMatthew G. Knepley PetscSF sfA, sfB; 909318fe57SMatthew G. Knepley DMField fieldTmp; 919318fe57SMatthew G. Knepley void *tmp; 929318fe57SMatthew G. Knepley DMLabelLink listTmp; 939318fe57SMatthew G. Knepley DMLabel depthTmp; 949318fe57SMatthew G. Knepley PetscInt tmpI; 959318fe57SMatthew G. Knepley PetscErrorCode ierr; 969318fe57SMatthew G. Knepley 979318fe57SMatthew G. Knepley PetscFunctionBegin; 989318fe57SMatthew G. Knepley if (dmA == dmB) PetscFunctionReturn(0); 999318fe57SMatthew G. Knepley ierr = DMGetPointSF(dmA, &sfA);CHKERRQ(ierr); 1009318fe57SMatthew G. Knepley ierr = DMGetPointSF(dmB, &sfB);CHKERRQ(ierr); 1019318fe57SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) sfA);CHKERRQ(ierr); 1029318fe57SMatthew G. Knepley ierr = DMSetPointSF(dmA, sfB);CHKERRQ(ierr); 1039318fe57SMatthew G. Knepley ierr = DMSetPointSF(dmB, sfA);CHKERRQ(ierr); 1049318fe57SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) sfA);CHKERRQ(ierr); 1059318fe57SMatthew G. Knepley 1069318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dmA, &coordDMA);CHKERRQ(ierr); 1079318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dmB, &coordDMB);CHKERRQ(ierr); 1089318fe57SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) coordDMA);CHKERRQ(ierr); 1099318fe57SMatthew G. Knepley ierr = DMSetCoordinateDM(dmA, coordDMB);CHKERRQ(ierr); 1109318fe57SMatthew G. Knepley ierr = DMSetCoordinateDM(dmB, coordDMA);CHKERRQ(ierr); 1119318fe57SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) coordDMA);CHKERRQ(ierr); 1129318fe57SMatthew G. Knepley 1139318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dmA, &coordsA);CHKERRQ(ierr); 1149318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dmB, &coordsB);CHKERRQ(ierr); 1159318fe57SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) coordsA);CHKERRQ(ierr); 1169318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dmA, coordsB);CHKERRQ(ierr); 1179318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dmB, coordsA);CHKERRQ(ierr); 1189318fe57SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) coordsA);CHKERRQ(ierr); 1199318fe57SMatthew G. Knepley 1209318fe57SMatthew G. Knepley fieldTmp = dmA->coordinateField; 1219318fe57SMatthew G. Knepley dmA->coordinateField = dmB->coordinateField; 1229318fe57SMatthew G. Knepley dmB->coordinateField = fieldTmp; 1239318fe57SMatthew G. Knepley tmp = dmA->data; 1249318fe57SMatthew G. Knepley dmA->data = dmB->data; 1259318fe57SMatthew G. Knepley dmB->data = tmp; 1269318fe57SMatthew G. Knepley listTmp = dmA->labels; 1279318fe57SMatthew G. Knepley dmA->labels = dmB->labels; 1289318fe57SMatthew G. Knepley dmB->labels = listTmp; 1299318fe57SMatthew G. Knepley depthTmp = dmA->depthLabel; 1309318fe57SMatthew G. Knepley dmA->depthLabel = dmB->depthLabel; 1319318fe57SMatthew G. Knepley dmB->depthLabel = depthTmp; 1329318fe57SMatthew G. Knepley depthTmp = dmA->celltypeLabel; 1339318fe57SMatthew G. Knepley dmA->celltypeLabel = dmB->celltypeLabel; 1349318fe57SMatthew G. Knepley dmB->celltypeLabel = depthTmp; 1359318fe57SMatthew G. Knepley tmpI = dmA->levelup; 1369318fe57SMatthew G. Knepley dmA->levelup = dmB->levelup; 1379318fe57SMatthew G. Knepley dmB->levelup = tmpI; 1389318fe57SMatthew G. Knepley PetscFunctionReturn(0); 1399318fe57SMatthew G. Knepley } 1409318fe57SMatthew G. Knepley 1419318fe57SMatthew G. Knepley static PetscErrorCode DMPlexInterpolateInPlace_Internal(DM dm) 1429318fe57SMatthew G. Knepley { 1439318fe57SMatthew G. Knepley DM idm; 1449318fe57SMatthew G. Knepley PetscErrorCode ierr; 1459318fe57SMatthew G. Knepley 1469318fe57SMatthew G. Knepley PetscFunctionBegin; 1479318fe57SMatthew G. Knepley ierr = DMPlexInterpolate(dm, &idm);CHKERRQ(ierr); 1489318fe57SMatthew G. Knepley ierr = DMPlexCopyCoordinates(dm, idm);CHKERRQ(ierr); 1499318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &idm);CHKERRQ(ierr); 1509318fe57SMatthew G. Knepley PetscFunctionReturn(0); 1519318fe57SMatthew G. Knepley } 1529318fe57SMatthew G. Knepley 1539318fe57SMatthew G. Knepley /*@C 1549318fe57SMatthew G. Knepley DMPlexCreateCoordinateSpace - Creates a finite element space for the coordinates 1559318fe57SMatthew G. Knepley 1569318fe57SMatthew G. Knepley Collective 1579318fe57SMatthew G. Knepley 1589318fe57SMatthew G. Knepley Input Parameters: 1599318fe57SMatthew G. Knepley + DM - The DM 1609318fe57SMatthew G. Knepley . degree - The degree of the finite element 1619318fe57SMatthew G. Knepley - coordFunc - An optional function to map new points from refinement to the surface 1629318fe57SMatthew G. Knepley 1639318fe57SMatthew G. Knepley Level: advanced 1649318fe57SMatthew G. Knepley 1659318fe57SMatthew G. Knepley .seealso: PetscFECreateLagrange(), DMGetCoordinateDM() 1669318fe57SMatthew G. Knepley @*/ 1679318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateCoordinateSpace(DM dm, PetscInt degree, PetscPointFunc coordFunc) 1689318fe57SMatthew G. Knepley { 1699318fe57SMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) dm->data; 1709318fe57SMatthew G. Knepley DM cdm; 1719318fe57SMatthew G. Knepley PetscDS cds; 1729318fe57SMatthew G. Knepley PetscFE fe; 1739318fe57SMatthew G. Knepley PetscClassId id; 1749318fe57SMatthew G. Knepley PetscErrorCode ierr; 1759318fe57SMatthew G. Knepley 1769318fe57SMatthew G. Knepley PetscFunctionBegin; 1779318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 1789318fe57SMatthew G. Knepley ierr = DMGetDS(cdm, &cds);CHKERRQ(ierr); 1799318fe57SMatthew G. Knepley ierr = PetscDSGetDiscretization(cds, 0, (PetscObject *) &fe);CHKERRQ(ierr); 1809318fe57SMatthew G. Knepley ierr = PetscObjectGetClassId((PetscObject) fe, &id);CHKERRQ(ierr); 1819318fe57SMatthew G. Knepley if (id != PETSCFE_CLASSID) { 1829318fe57SMatthew G. Knepley PetscBool simplex; 1839318fe57SMatthew G. Knepley PetscInt dim, dE, qorder; 1849318fe57SMatthew G. Knepley 1859318fe57SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1869318fe57SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 1879318fe57SMatthew G. Knepley ierr = DMPlexIsSimplex(dm, &simplex);CHKERRQ(ierr); 1889318fe57SMatthew G. Knepley qorder = degree; 1899318fe57SMatthew G. Knepley ierr = PetscObjectOptionsBegin((PetscObject) cdm);CHKERRQ(ierr); 1909318fe57SMatthew 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); 1919318fe57SMatthew G. Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 1929318fe57SMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, dE, simplex, degree, qorder, &fe);CHKERRQ(ierr); 1939318fe57SMatthew G. Knepley ierr = DMSetField(cdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 1949318fe57SMatthew G. Knepley ierr = DMCreateDS(cdm);CHKERRQ(ierr); 1959318fe57SMatthew G. Knepley ierr = DMProjectCoordinates(dm, fe);CHKERRQ(ierr); 1969318fe57SMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 1979318fe57SMatthew G. Knepley } 1989318fe57SMatthew G. Knepley mesh->coordFunc = coordFunc; 1999318fe57SMatthew G. Knepley PetscFunctionReturn(0); 2009318fe57SMatthew G. Knepley } 2019318fe57SMatthew G. Knepley 2021df5d5c5SMatthew G. Knepley /*@ 2031df5d5c5SMatthew G. Knepley DMPlexCreateDoublet - Creates a mesh of two cells of the specified type, optionally with later refinement. 2041df5d5c5SMatthew G. Knepley 205d083f849SBarry Smith Collective 2061df5d5c5SMatthew G. Knepley 2071df5d5c5SMatthew G. Knepley Input Parameters: 2081df5d5c5SMatthew G. Knepley + comm - The communicator for the DM object 2091df5d5c5SMatthew G. Knepley . dim - The spatial dimension 2101df5d5c5SMatthew G. Knepley . simplex - Flag for simplicial cells, otherwise they are tensor product cells 2111df5d5c5SMatthew G. Knepley . interpolate - Flag to create intermediate mesh pieces (edges, faces) 2121df5d5c5SMatthew G. Knepley - refinementLimit - A nonzero number indicates the largest admissible volume for a refined cell 2131df5d5c5SMatthew G. Knepley 2141df5d5c5SMatthew G. Knepley Output Parameter: 2151df5d5c5SMatthew G. Knepley . dm - The DM object 2161df5d5c5SMatthew G. Knepley 2171df5d5c5SMatthew G. Knepley Level: beginner 2181df5d5c5SMatthew G. Knepley 2191df5d5c5SMatthew G. Knepley .seealso: DMSetType(), DMCreate() 2201df5d5c5SMatthew G. Knepley @*/ 2210fdc7489SMatthew Knepley PetscErrorCode DMPlexCreateDoublet(MPI_Comm comm, PetscInt dim, PetscBool simplex, PetscBool interpolate, PetscReal refinementLimit, DM *newdm) 2221df5d5c5SMatthew G. Knepley { 2231df5d5c5SMatthew G. Knepley DM dm; 2241df5d5c5SMatthew G. Knepley PetscMPIInt rank; 2251df5d5c5SMatthew G. Knepley PetscErrorCode ierr; 2261df5d5c5SMatthew G. Knepley 2271df5d5c5SMatthew G. Knepley PetscFunctionBegin; 2281df5d5c5SMatthew G. Knepley ierr = DMCreate(comm, &dm);CHKERRQ(ierr); 2291df5d5c5SMatthew G. Knepley ierr = DMSetType(dm, DMPLEX);CHKERRQ(ierr); 230c73cfb54SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 231ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 232ce78fa2fSMatthew G. Knepley switch (dim) { 233ce78fa2fSMatthew G. Knepley case 2: 234ce78fa2fSMatthew G. Knepley if (simplex) {ierr = PetscObjectSetName((PetscObject) dm, "triangular");CHKERRQ(ierr);} 235ce78fa2fSMatthew G. Knepley else {ierr = PetscObjectSetName((PetscObject) dm, "quadrilateral");CHKERRQ(ierr);} 236ce78fa2fSMatthew G. Knepley break; 237ce78fa2fSMatthew G. Knepley case 3: 238ce78fa2fSMatthew G. Knepley if (simplex) {ierr = PetscObjectSetName((PetscObject) dm, "tetrahedral");CHKERRQ(ierr);} 239ce78fa2fSMatthew G. Knepley else {ierr = PetscObjectSetName((PetscObject) dm, "hexahedral");CHKERRQ(ierr);} 240ce78fa2fSMatthew G. Knepley break; 241ce78fa2fSMatthew G. Knepley default: 24298921bdaSJacob Faibussowitsch SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make meshes for dimension %D", dim); 243ce78fa2fSMatthew G. Knepley } 2441df5d5c5SMatthew G. Knepley if (rank) { 2451df5d5c5SMatthew G. Knepley PetscInt numPoints[2] = {0, 0}; 2461df5d5c5SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm, 1, numPoints, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 2471df5d5c5SMatthew G. Knepley } else { 2481df5d5c5SMatthew G. Knepley switch (dim) { 2491df5d5c5SMatthew G. Knepley case 2: 2501df5d5c5SMatthew G. Knepley if (simplex) { 2511df5d5c5SMatthew G. Knepley PetscInt numPoints[2] = {4, 2}; 2521df5d5c5SMatthew G. Knepley PetscInt coneSize[6] = {3, 3, 0, 0, 0, 0}; 2531df5d5c5SMatthew G. Knepley PetscInt cones[6] = {2, 3, 4, 5, 4, 3}; 2541df5d5c5SMatthew G. Knepley PetscInt coneOrientations[6] = {0, 0, 0, 0, 0, 0}; 2551df5d5c5SMatthew G. Knepley PetscScalar vertexCoords[8] = {-0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 0.5, 0.5}; 2561df5d5c5SMatthew G. Knepley 2571df5d5c5SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 2581df5d5c5SMatthew G. Knepley } else { 2591df5d5c5SMatthew G. Knepley PetscInt numPoints[2] = {6, 2}; 2601df5d5c5SMatthew G. Knepley PetscInt coneSize[8] = {4, 4, 0, 0, 0, 0, 0, 0}; 2611df5d5c5SMatthew G. Knepley PetscInt cones[8] = {2, 3, 4, 5, 3, 6, 7, 4}; 2621df5d5c5SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 2631df5d5c5SMatthew 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}; 2641df5d5c5SMatthew G. Knepley 2651df5d5c5SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 2661df5d5c5SMatthew G. Knepley } 2671df5d5c5SMatthew G. Knepley break; 2681df5d5c5SMatthew G. Knepley case 3: 2691df5d5c5SMatthew G. Knepley if (simplex) { 2701df5d5c5SMatthew G. Knepley PetscInt numPoints[2] = {5, 2}; 2711df5d5c5SMatthew G. Knepley PetscInt coneSize[7] = {4, 4, 0, 0, 0, 0, 0}; 2721df5d5c5SMatthew G. Knepley PetscInt cones[8] = {4, 3, 5, 2, 5, 3, 4, 6}; 2731df5d5c5SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 2741df5d5c5SMatthew 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}; 2751df5d5c5SMatthew G. Knepley 2761df5d5c5SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 2771df5d5c5SMatthew G. Knepley } else { 2781df5d5c5SMatthew G. Knepley PetscInt numPoints[2] = {12, 2}; 2791df5d5c5SMatthew G. Knepley PetscInt coneSize[14] = {8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 2801df5d5c5SMatthew G. Knepley PetscInt cones[16] = {2, 3, 4, 5, 6, 7, 8, 9, 5, 4, 10, 11, 7, 12, 13, 8}; 2811df5d5c5SMatthew G. Knepley PetscInt coneOrientations[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 2821df5d5c5SMatthew 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, 2831df5d5c5SMatthew 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, 2841df5d5c5SMatthew 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}; 2851df5d5c5SMatthew G. Knepley 2861df5d5c5SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 2871df5d5c5SMatthew G. Knepley } 2881df5d5c5SMatthew G. Knepley break; 2891df5d5c5SMatthew G. Knepley default: 29098921bdaSJacob Faibussowitsch SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make meshes for dimension %D", dim); 2911df5d5c5SMatthew G. Knepley } 2921df5d5c5SMatthew G. Knepley } 2931df5d5c5SMatthew G. Knepley *newdm = dm; 2941df5d5c5SMatthew G. Knepley if (refinementLimit > 0.0) { 2951df5d5c5SMatthew G. Knepley DM rdm; 2961df5d5c5SMatthew G. Knepley const char *name; 2971df5d5c5SMatthew G. Knepley 2981df5d5c5SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*newdm, PETSC_FALSE);CHKERRQ(ierr); 2991df5d5c5SMatthew G. Knepley ierr = DMPlexSetRefinementLimit(*newdm, refinementLimit);CHKERRQ(ierr); 3001df5d5c5SMatthew G. Knepley ierr = DMRefine(*newdm, comm, &rdm);CHKERRQ(ierr); 3011df5d5c5SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) *newdm, &name);CHKERRQ(ierr); 3021df5d5c5SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) rdm, name);CHKERRQ(ierr); 3031df5d5c5SMatthew G. Knepley ierr = DMDestroy(newdm);CHKERRQ(ierr); 3041df5d5c5SMatthew G. Knepley *newdm = rdm; 3051df5d5c5SMatthew G. Knepley } 3061df5d5c5SMatthew G. Knepley if (interpolate) { 3075fd9971aSMatthew G. Knepley DM idm; 3081df5d5c5SMatthew G. Knepley 3091df5d5c5SMatthew G. Knepley ierr = DMPlexInterpolate(*newdm, &idm);CHKERRQ(ierr); 3101df5d5c5SMatthew G. Knepley ierr = DMDestroy(newdm);CHKERRQ(ierr); 3111df5d5c5SMatthew G. Knepley *newdm = idm; 3121df5d5c5SMatthew G. Knepley } 3131df5d5c5SMatthew G. Knepley PetscFunctionReturn(0); 3141df5d5c5SMatthew G. Knepley } 3151df5d5c5SMatthew G. Knepley 3169318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxSurfaceMesh_Tensor_1D_Internal(DM dm, const PetscReal lower[], const PetscReal upper[], const PetscInt edges[]) 3179318fe57SMatthew G. Knepley { 3189318fe57SMatthew G. Knepley const PetscInt numVertices = 2; 3199318fe57SMatthew G. Knepley PetscInt markerRight = 1; 3209318fe57SMatthew G. Knepley PetscInt markerLeft = 1; 3219318fe57SMatthew G. Knepley PetscBool markerSeparate = PETSC_FALSE; 3229318fe57SMatthew G. Knepley Vec coordinates; 3239318fe57SMatthew G. Knepley PetscSection coordSection; 3249318fe57SMatthew G. Knepley PetscScalar *coords; 3259318fe57SMatthew G. Knepley PetscInt coordSize; 3269318fe57SMatthew G. Knepley PetscMPIInt rank; 3279318fe57SMatthew G. Knepley PetscInt cdim = 1, v; 3289318fe57SMatthew G. Knepley PetscErrorCode ierr; 329552f7358SJed Brown 3309318fe57SMatthew G. Knepley PetscFunctionBegin; 3319318fe57SMatthew G. Knepley ierr = PetscOptionsGetBool(((PetscObject) dm)->options,((PetscObject) dm)->prefix, "-dm_plex_separate_marker", &markerSeparate, NULL);CHKERRQ(ierr); 3329318fe57SMatthew G. Knepley if (markerSeparate) { 3339318fe57SMatthew G. Knepley markerRight = 2; 3349318fe57SMatthew G. Knepley markerLeft = 1; 3359318fe57SMatthew G. Knepley } 3369318fe57SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 3379318fe57SMatthew G. Knepley if (!rank) { 3389318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numVertices);CHKERRQ(ierr); 3399318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 3409318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", 0, markerLeft);CHKERRQ(ierr); 3419318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", 1, markerRight);CHKERRQ(ierr); 3429318fe57SMatthew G. Knepley } 3439318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 3449318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 3459318fe57SMatthew G. Knepley /* Build coordinates */ 3469318fe57SMatthew G. Knepley ierr = DMSetCoordinateDim(dm, cdim);CHKERRQ(ierr); 3479318fe57SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 3489318fe57SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 3499318fe57SMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, 0, numVertices);CHKERRQ(ierr); 3509318fe57SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, cdim);CHKERRQ(ierr); 3519318fe57SMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 3529318fe57SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, cdim);CHKERRQ(ierr); 3539318fe57SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, cdim);CHKERRQ(ierr); 3549318fe57SMatthew G. Knepley } 3559318fe57SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 3569318fe57SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 3579318fe57SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 3589318fe57SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 3599318fe57SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 3609318fe57SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, cdim);CHKERRQ(ierr); 3619318fe57SMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 3629318fe57SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 3639318fe57SMatthew G. Knepley coords[0] = lower[0]; 3649318fe57SMatthew G. Knepley coords[1] = upper[0]; 3659318fe57SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 3669318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 3679318fe57SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 3689318fe57SMatthew G. Knepley PetscFunctionReturn(0); 3699318fe57SMatthew G. Knepley } 37026492d91SMatthew G. Knepley 3719318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxSurfaceMesh_Tensor_2D_Internal(DM dm, const PetscReal lower[], const PetscReal upper[], const PetscInt edges[]) 372552f7358SJed Brown { 3731df21d24SMatthew G. Knepley const PetscInt numVertices = (edges[0]+1)*(edges[1]+1); 3741df21d24SMatthew G. Knepley const PetscInt numEdges = edges[0]*(edges[1]+1) + (edges[0]+1)*edges[1]; 375552f7358SJed Brown PetscInt markerTop = 1; 376552f7358SJed Brown PetscInt markerBottom = 1; 377552f7358SJed Brown PetscInt markerRight = 1; 378552f7358SJed Brown PetscInt markerLeft = 1; 379552f7358SJed Brown PetscBool markerSeparate = PETSC_FALSE; 380552f7358SJed Brown Vec coordinates; 381552f7358SJed Brown PetscSection coordSection; 382552f7358SJed Brown PetscScalar *coords; 383552f7358SJed Brown PetscInt coordSize; 384552f7358SJed Brown PetscMPIInt rank; 385552f7358SJed Brown PetscInt v, vx, vy; 386552f7358SJed Brown PetscErrorCode ierr; 387552f7358SJed Brown 388552f7358SJed Brown PetscFunctionBegin; 389c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject) dm)->options,((PetscObject) dm)->prefix, "-dm_plex_separate_marker", &markerSeparate, NULL);CHKERRQ(ierr); 390552f7358SJed Brown if (markerSeparate) { 3911df21d24SMatthew G. Knepley markerTop = 3; 3921df21d24SMatthew G. Knepley markerBottom = 1; 3931df21d24SMatthew G. Knepley markerRight = 2; 3941df21d24SMatthew G. Knepley markerLeft = 4; 395552f7358SJed Brown } 396ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 397dd400576SPatrick Sanan if (rank == 0) { 398552f7358SJed Brown PetscInt e, ex, ey; 399552f7358SJed Brown 400552f7358SJed Brown ierr = DMPlexSetChart(dm, 0, numEdges+numVertices);CHKERRQ(ierr); 401552f7358SJed Brown for (e = 0; e < numEdges; ++e) { 402552f7358SJed Brown ierr = DMPlexSetConeSize(dm, e, 2);CHKERRQ(ierr); 403552f7358SJed Brown } 404552f7358SJed Brown ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 405552f7358SJed Brown for (vx = 0; vx <= edges[0]; vx++) { 406552f7358SJed Brown for (ey = 0; ey < edges[1]; ey++) { 407552f7358SJed Brown PetscInt edge = vx*edges[1] + ey + edges[0]*(edges[1]+1); 408552f7358SJed Brown PetscInt vertex = ey*(edges[0]+1) + vx + numEdges; 409da80777bSKarl Rupp PetscInt cone[2]; 410552f7358SJed Brown 411da80777bSKarl Rupp cone[0] = vertex; cone[1] = vertex+edges[0]+1; 412552f7358SJed Brown ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); 413552f7358SJed Brown if (vx == edges[0]) { 414c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerRight);CHKERRQ(ierr); 415c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerRight);CHKERRQ(ierr); 416552f7358SJed Brown if (ey == edges[1]-1) { 417c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerRight);CHKERRQ(ierr); 418c668006fSMatthew G. Knepley ierr = DMSetLabelValue(dm, "Face Sets", cone[1], markerRight);CHKERRQ(ierr); 419552f7358SJed Brown } 420552f7358SJed Brown } else if (vx == 0) { 421c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerLeft);CHKERRQ(ierr); 422c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerLeft);CHKERRQ(ierr); 423552f7358SJed Brown if (ey == edges[1]-1) { 424c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerLeft);CHKERRQ(ierr); 425c668006fSMatthew G. Knepley ierr = DMSetLabelValue(dm, "Face Sets", cone[1], markerLeft);CHKERRQ(ierr); 426552f7358SJed Brown } 427552f7358SJed Brown } 428552f7358SJed Brown } 429552f7358SJed Brown } 430552f7358SJed Brown for (vy = 0; vy <= edges[1]; vy++) { 431552f7358SJed Brown for (ex = 0; ex < edges[0]; ex++) { 432552f7358SJed Brown PetscInt edge = vy*edges[0] + ex; 433552f7358SJed Brown PetscInt vertex = vy*(edges[0]+1) + ex + numEdges; 434da80777bSKarl Rupp PetscInt cone[2]; 435552f7358SJed Brown 436da80777bSKarl Rupp cone[0] = vertex; cone[1] = vertex+1; 437552f7358SJed Brown ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); 438552f7358SJed Brown if (vy == edges[1]) { 439c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerTop);CHKERRQ(ierr); 440c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerTop);CHKERRQ(ierr); 441552f7358SJed Brown if (ex == edges[0]-1) { 442c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerTop);CHKERRQ(ierr); 443c668006fSMatthew G. Knepley ierr = DMSetLabelValue(dm, "Face Sets", cone[1], markerTop);CHKERRQ(ierr); 444552f7358SJed Brown } 445552f7358SJed Brown } else if (vy == 0) { 446c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBottom);CHKERRQ(ierr); 447c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerBottom);CHKERRQ(ierr); 448552f7358SJed Brown if (ex == edges[0]-1) { 449c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerBottom);CHKERRQ(ierr); 450c668006fSMatthew G. Knepley ierr = DMSetLabelValue(dm, "Face Sets", cone[1], markerBottom);CHKERRQ(ierr); 451552f7358SJed Brown } 452552f7358SJed Brown } 453552f7358SJed Brown } 454552f7358SJed Brown } 455552f7358SJed Brown } 456552f7358SJed Brown ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 457552f7358SJed Brown ierr = DMPlexStratify(dm);CHKERRQ(ierr); 458552f7358SJed Brown /* Build coordinates */ 4599596c6baSMatthew G. Knepley ierr = DMSetCoordinateDim(dm, 2);CHKERRQ(ierr); 460c2166f76SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 461972bc18aSToby Isaac ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 462552f7358SJed Brown ierr = PetscSectionSetChart(coordSection, numEdges, numEdges + numVertices);CHKERRQ(ierr); 463972bc18aSToby Isaac ierr = PetscSectionSetFieldComponents(coordSection, 0, 2);CHKERRQ(ierr); 464552f7358SJed Brown for (v = numEdges; v < numEdges+numVertices; ++v) { 465552f7358SJed Brown ierr = PetscSectionSetDof(coordSection, v, 2);CHKERRQ(ierr); 466972bc18aSToby Isaac ierr = PetscSectionSetFieldDof(coordSection, v, 0, 2);CHKERRQ(ierr); 467552f7358SJed Brown } 468552f7358SJed Brown ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 469552f7358SJed Brown ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 4708b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 471da16285aSMichael Lange ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 472552f7358SJed Brown ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 4738b9ced59SLisandro Dalcin ierr = VecSetBlockSize(coordinates, 2);CHKERRQ(ierr); 4742eb5907fSJed Brown ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 475552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 476552f7358SJed Brown for (vy = 0; vy <= edges[1]; ++vy) { 477552f7358SJed Brown for (vx = 0; vx <= edges[0]; ++vx) { 478552f7358SJed Brown coords[(vy*(edges[0]+1)+vx)*2+0] = lower[0] + ((upper[0] - lower[0])/edges[0])*vx; 479552f7358SJed Brown coords[(vy*(edges[0]+1)+vx)*2+1] = lower[1] + ((upper[1] - lower[1])/edges[1])*vy; 480552f7358SJed Brown } 481552f7358SJed Brown } 482552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 483552f7358SJed Brown ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 484552f7358SJed Brown ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 485552f7358SJed Brown PetscFunctionReturn(0); 486552f7358SJed Brown } 487552f7358SJed Brown 4889318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxSurfaceMesh_Tensor_3D_Internal(DM dm, const PetscReal lower[], const PetscReal upper[], const PetscInt faces[]) 489552f7358SJed Brown { 4909e8abbc3SMichael Lange PetscInt vertices[3], numVertices; 4917b59f5a9SMichael Lange PetscInt numFaces = 2*faces[0]*faces[1] + 2*faces[1]*faces[2] + 2*faces[0]*faces[2]; 492552f7358SJed Brown Vec coordinates; 493552f7358SJed Brown PetscSection coordSection; 494552f7358SJed Brown PetscScalar *coords; 495552f7358SJed Brown PetscInt coordSize; 496552f7358SJed Brown PetscMPIInt rank; 497552f7358SJed Brown PetscInt v, vx, vy, vz; 4987b59f5a9SMichael Lange PetscInt voffset, iface=0, cone[4]; 499552f7358SJed Brown PetscErrorCode ierr; 500552f7358SJed Brown 501552f7358SJed Brown PetscFunctionBegin; 5022c71b3e2SJacob 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"); 503ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 5049e8abbc3SMichael Lange vertices[0] = faces[0]+1; vertices[1] = faces[1]+1; vertices[2] = faces[2]+1; 5059e8abbc3SMichael Lange numVertices = vertices[0]*vertices[1]*vertices[2]; 506dd400576SPatrick Sanan if (rank == 0) { 507552f7358SJed Brown PetscInt f; 508552f7358SJed Brown 509552f7358SJed Brown ierr = DMPlexSetChart(dm, 0, numFaces+numVertices);CHKERRQ(ierr); 510552f7358SJed Brown for (f = 0; f < numFaces; ++f) { 511552f7358SJed Brown ierr = DMPlexSetConeSize(dm, f, 4);CHKERRQ(ierr); 512552f7358SJed Brown } 513552f7358SJed Brown ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 5147b59f5a9SMichael Lange 5157b59f5a9SMichael Lange /* Side 0 (Top) */ 5167b59f5a9SMichael Lange for (vy = 0; vy < faces[1]; vy++) { 5177b59f5a9SMichael Lange for (vx = 0; vx < faces[0]; vx++) { 5187b59f5a9SMichael Lange voffset = numFaces + vertices[0]*vertices[1]*(vertices[2]-1) + vy*vertices[0] + vx; 5197b59f5a9SMichael Lange cone[0] = voffset; cone[1] = voffset+1; cone[2] = voffset+vertices[0]+1; cone[3] = voffset+vertices[0]; 5207b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 521c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 522c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 523c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+1, 1);CHKERRQ(ierr); 524c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+0, 1);CHKERRQ(ierr); 525c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+1, 1);CHKERRQ(ierr); 5267b59f5a9SMichael Lange iface++; 527552f7358SJed Brown } 528552f7358SJed Brown } 5297b59f5a9SMichael Lange 5307b59f5a9SMichael Lange /* Side 1 (Bottom) */ 5317b59f5a9SMichael Lange for (vy = 0; vy < faces[1]; vy++) { 5327b59f5a9SMichael Lange for (vx = 0; vx < faces[0]; vx++) { 5337b59f5a9SMichael Lange voffset = numFaces + vy*(faces[0]+1) + vx; 5347b59f5a9SMichael Lange cone[0] = voffset+1; cone[1] = voffset; cone[2] = voffset+vertices[0]; cone[3] = voffset+vertices[0]+1; 5357b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 536c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 537c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 538c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+1, 1);CHKERRQ(ierr); 539c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+0, 1);CHKERRQ(ierr); 540c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+1, 1);CHKERRQ(ierr); 5417b59f5a9SMichael Lange iface++; 542552f7358SJed Brown } 543552f7358SJed Brown } 5447b59f5a9SMichael Lange 5457b59f5a9SMichael Lange /* Side 2 (Front) */ 5467b59f5a9SMichael Lange for (vz = 0; vz < faces[2]; vz++) { 5477b59f5a9SMichael Lange for (vx = 0; vx < faces[0]; vx++) { 5487b59f5a9SMichael Lange voffset = numFaces + vz*vertices[0]*vertices[1] + vx; 5497b59f5a9SMichael Lange cone[0] = voffset; cone[1] = voffset+1; cone[2] = voffset+vertices[0]*vertices[1]+1; cone[3] = voffset+vertices[0]*vertices[1]; 5507b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 551c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 552c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 553c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+1, 1);CHKERRQ(ierr); 554c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+0, 1);CHKERRQ(ierr); 555c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+1, 1);CHKERRQ(ierr); 5567b59f5a9SMichael Lange iface++; 557552f7358SJed Brown } 5587b59f5a9SMichael Lange } 5597b59f5a9SMichael Lange 5607b59f5a9SMichael Lange /* Side 3 (Back) */ 5617b59f5a9SMichael Lange for (vz = 0; vz < faces[2]; vz++) { 5627b59f5a9SMichael Lange for (vx = 0; vx < faces[0]; vx++) { 5637b59f5a9SMichael Lange voffset = numFaces + vz*vertices[0]*vertices[1] + vertices[0]*(vertices[1]-1) + vx; 5647b59f5a9SMichael Lange cone[0] = voffset+vertices[0]*vertices[1]; cone[1] = voffset+vertices[0]*vertices[1]+1; 5657b59f5a9SMichael Lange cone[2] = voffset+1; cone[3] = voffset; 5667b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 567c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 568c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 569c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+1, 1);CHKERRQ(ierr); 570c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+0, 1);CHKERRQ(ierr); 571c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+1, 1);CHKERRQ(ierr); 5727b59f5a9SMichael Lange iface++; 5737b59f5a9SMichael Lange } 5747b59f5a9SMichael Lange } 5757b59f5a9SMichael Lange 5767b59f5a9SMichael Lange /* Side 4 (Left) */ 5777b59f5a9SMichael Lange for (vz = 0; vz < faces[2]; vz++) { 5787b59f5a9SMichael Lange for (vy = 0; vy < faces[1]; vy++) { 5797b59f5a9SMichael Lange voffset = numFaces + vz*vertices[0]*vertices[1] + vy*vertices[0]; 5807b59f5a9SMichael Lange cone[0] = voffset; cone[1] = voffset+vertices[0]*vertices[1]; 5817b59f5a9SMichael Lange cone[2] = voffset+vertices[0]*vertices[1]+vertices[0]; cone[3] = voffset+vertices[0]; 5827b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 583c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 584c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 585c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+0, 1);CHKERRQ(ierr); 586c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[1]+0, 1);CHKERRQ(ierr); 587c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+vertices[0], 1);CHKERRQ(ierr); 5887b59f5a9SMichael Lange iface++; 5897b59f5a9SMichael Lange } 5907b59f5a9SMichael Lange } 5917b59f5a9SMichael Lange 5927b59f5a9SMichael Lange /* Side 5 (Right) */ 5937b59f5a9SMichael Lange for (vz = 0; vz < faces[2]; vz++) { 5947b59f5a9SMichael Lange for (vy = 0; vy < faces[1]; vy++) { 595aab5bcd8SJed Brown voffset = numFaces + vz*vertices[0]*vertices[1] + vy*vertices[0] + faces[0]; 5967b59f5a9SMichael Lange cone[0] = voffset+vertices[0]*vertices[1]; cone[1] = voffset; 5977b59f5a9SMichael Lange cone[2] = voffset+vertices[0]; cone[3] = voffset+vertices[0]*vertices[1]+vertices[0]; 5987b59f5a9SMichael Lange ierr = DMPlexSetCone(dm, iface, cone);CHKERRQ(ierr); 599c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", iface, 1);CHKERRQ(ierr); 600c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+0, 1);CHKERRQ(ierr); 601c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]+0, 1);CHKERRQ(ierr); 602c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+0, 1);CHKERRQ(ierr); 603c9360375SMatthew G. Knepley ierr = DMSetLabelValue(dm, "marker", voffset+vertices[0]*vertices[1]+vertices[0], 1);CHKERRQ(ierr); 6047b59f5a9SMichael Lange iface++; 6057b59f5a9SMichael Lange } 606552f7358SJed Brown } 607552f7358SJed Brown } 608552f7358SJed Brown ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 609552f7358SJed Brown ierr = DMPlexStratify(dm);CHKERRQ(ierr); 610552f7358SJed Brown /* Build coordinates */ 6119596c6baSMatthew G. Knepley ierr = DMSetCoordinateDim(dm, 3);CHKERRQ(ierr); 612c2166f76SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 6139318fe57SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 614552f7358SJed Brown ierr = PetscSectionSetChart(coordSection, numFaces, numFaces + numVertices);CHKERRQ(ierr); 6159318fe57SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, 3);CHKERRQ(ierr); 616552f7358SJed Brown for (v = numFaces; v < numFaces+numVertices; ++v) { 617552f7358SJed Brown ierr = PetscSectionSetDof(coordSection, v, 3);CHKERRQ(ierr); 6189318fe57SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, 3);CHKERRQ(ierr); 619552f7358SJed Brown } 620552f7358SJed Brown ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 621552f7358SJed Brown ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 6228b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 623552f7358SJed Brown ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 624552f7358SJed Brown ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 6258b9ced59SLisandro Dalcin ierr = VecSetBlockSize(coordinates, 3);CHKERRQ(ierr); 6262eb5907fSJed Brown ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 627552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 628552f7358SJed Brown for (vz = 0; vz <= faces[2]; ++vz) { 629552f7358SJed Brown for (vy = 0; vy <= faces[1]; ++vy) { 630552f7358SJed Brown for (vx = 0; vx <= faces[0]; ++vx) { 631552f7358SJed Brown coords[((vz*(faces[1]+1)+vy)*(faces[0]+1)+vx)*3+0] = lower[0] + ((upper[0] - lower[0])/faces[0])*vx; 632552f7358SJed Brown coords[((vz*(faces[1]+1)+vy)*(faces[0]+1)+vx)*3+1] = lower[1] + ((upper[1] - lower[1])/faces[1])*vy; 633552f7358SJed Brown coords[((vz*(faces[1]+1)+vy)*(faces[0]+1)+vx)*3+2] = lower[2] + ((upper[2] - lower[2])/faces[2])*vz; 634552f7358SJed Brown } 635552f7358SJed Brown } 636552f7358SJed Brown } 637552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 638552f7358SJed Brown ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 639552f7358SJed Brown ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 640552f7358SJed Brown PetscFunctionReturn(0); 641552f7358SJed Brown } 642552f7358SJed Brown 6439318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxSurfaceMesh_Internal(DM dm, PetscInt dim, const PetscInt faces[], const PetscReal lower[], const PetscReal upper[], PetscBool interpolate) 6449318fe57SMatthew G. Knepley { 6459318fe57SMatthew G. Knepley PetscErrorCode ierr; 6469318fe57SMatthew G. Knepley 6479318fe57SMatthew G. Knepley PetscFunctionBegin; 6489318fe57SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 6499318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim-1);CHKERRQ(ierr); 6509318fe57SMatthew G. Knepley ierr = DMSetCoordinateDim(dm, dim);CHKERRQ(ierr); 6519318fe57SMatthew G. Knepley switch (dim) { 6529318fe57SMatthew G. Knepley case 1: ierr = DMPlexCreateBoxSurfaceMesh_Tensor_1D_Internal(dm, lower, upper, faces);CHKERRQ(ierr);break; 6539318fe57SMatthew G. Knepley case 2: ierr = DMPlexCreateBoxSurfaceMesh_Tensor_2D_Internal(dm, lower, upper, faces);CHKERRQ(ierr);break; 6549318fe57SMatthew G. Knepley case 3: ierr = DMPlexCreateBoxSurfaceMesh_Tensor_3D_Internal(dm, lower, upper, faces);CHKERRQ(ierr);break; 65598921bdaSJacob Faibussowitsch default: SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Dimension not supported: %D", dim); 6569318fe57SMatthew G. Knepley } 6579318fe57SMatthew G. Knepley if (interpolate) {ierr = DMPlexInterpolateInPlace_Internal(dm);CHKERRQ(ierr);} 6589318fe57SMatthew G. Knepley PetscFunctionReturn(0); 6599318fe57SMatthew G. Knepley } 6609318fe57SMatthew G. Knepley 6619318fe57SMatthew G. Knepley /*@C 6629318fe57SMatthew G. Knepley DMPlexCreateBoxSurfaceMesh - Creates a mesh on the surface of the tensor product of unit intervals (box) using tensor cells (hexahedra). 6639318fe57SMatthew G. Knepley 6649318fe57SMatthew G. Knepley Collective 6659318fe57SMatthew G. Knepley 6669318fe57SMatthew G. Knepley Input Parameters: 6679318fe57SMatthew G. Knepley + comm - The communicator for the DM object 6689318fe57SMatthew G. Knepley . dim - The spatial dimension of the box, so the resulting mesh is has dimension dim-1 6699318fe57SMatthew 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 6709318fe57SMatthew G. Knepley . lower - The lower left corner, or NULL for (0, 0, 0) 6719318fe57SMatthew G. Knepley . upper - The upper right corner, or NULL for (1, 1, 1) 6729318fe57SMatthew G. Knepley - interpolate - Flag to create intermediate mesh pieces (edges, faces) 6739318fe57SMatthew G. Knepley 6749318fe57SMatthew G. Knepley Output Parameter: 6759318fe57SMatthew G. Knepley . dm - The DM object 6769318fe57SMatthew G. Knepley 6779318fe57SMatthew G. Knepley Level: beginner 6789318fe57SMatthew G. Knepley 6799318fe57SMatthew G. Knepley .seealso: DMSetFromOptions(), DMPlexCreateBoxMesh(), DMPlexCreateFromFile(), DMSetType(), DMCreate() 6809318fe57SMatthew G. Knepley @*/ 6819318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateBoxSurfaceMesh(MPI_Comm comm, PetscInt dim, const PetscInt faces[], const PetscReal lower[], const PetscReal upper[], PetscBool interpolate, DM *dm) 6829318fe57SMatthew G. Knepley { 6839318fe57SMatthew G. Knepley PetscInt fac[3] = {1, 1, 1}; 6849318fe57SMatthew G. Knepley PetscReal low[3] = {0, 0, 0}; 6859318fe57SMatthew G. Knepley PetscReal upp[3] = {1, 1, 1}; 6869318fe57SMatthew G. Knepley PetscErrorCode ierr; 6879318fe57SMatthew G. Knepley 6889318fe57SMatthew G. Knepley PetscFunctionBegin; 6899318fe57SMatthew G. Knepley ierr = DMCreate(comm,dm);CHKERRQ(ierr); 6909318fe57SMatthew G. Knepley ierr = DMSetType(*dm,DMPLEX);CHKERRQ(ierr); 6919318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxSurfaceMesh_Internal(*dm, dim, faces ? faces : fac, lower ? lower : low, upper ? upper : upp, interpolate);CHKERRQ(ierr); 6929318fe57SMatthew G. Knepley PetscFunctionReturn(0); 6939318fe57SMatthew G. Knepley } 6949318fe57SMatthew G. Knepley 6959318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateLineMesh_Internal(DM dm,PetscInt segments,PetscReal lower,PetscReal upper,DMBoundaryType bd) 696fdbf62faSLisandro Dalcin { 697fdbf62faSLisandro Dalcin PetscInt i,fStart,fEnd,numCells = 0,numVerts = 0; 698fdbf62faSLisandro Dalcin PetscInt numPoints[2],*coneSize,*cones,*coneOrientations; 699fdbf62faSLisandro Dalcin PetscScalar *vertexCoords; 700fdbf62faSLisandro Dalcin PetscReal L,maxCell; 701fdbf62faSLisandro Dalcin PetscBool markerSeparate = PETSC_FALSE; 702fdbf62faSLisandro Dalcin PetscInt markerLeft = 1, faceMarkerLeft = 1; 703fdbf62faSLisandro Dalcin PetscInt markerRight = 1, faceMarkerRight = 2; 704fdbf62faSLisandro Dalcin PetscBool wrap = (bd == DM_BOUNDARY_PERIODIC || bd == DM_BOUNDARY_TWIST) ? PETSC_TRUE : PETSC_FALSE; 705fdbf62faSLisandro Dalcin PetscMPIInt rank; 706fdbf62faSLisandro Dalcin PetscErrorCode ierr; 707fdbf62faSLisandro Dalcin 708fdbf62faSLisandro Dalcin PetscFunctionBegin; 7099318fe57SMatthew G. Knepley PetscValidPointer(dm,1); 710fdbf62faSLisandro Dalcin 7119318fe57SMatthew G. Knepley ierr = DMSetDimension(dm,1);CHKERRQ(ierr); 7129318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm,"marker");CHKERRQ(ierr); 7139318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm,"Face Sets");CHKERRQ(ierr); 714fdbf62faSLisandro Dalcin 7159318fe57SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm),&rank);CHKERRMPI(ierr); 716dd400576SPatrick Sanan if (rank == 0) numCells = segments; 717dd400576SPatrick Sanan if (rank == 0) numVerts = segments + (wrap ? 0 : 1); 718fdbf62faSLisandro Dalcin 719fdbf62faSLisandro Dalcin numPoints[0] = numVerts ; numPoints[1] = numCells; 720fdbf62faSLisandro Dalcin ierr = PetscMalloc4(numCells+numVerts,&coneSize,numCells*2,&cones,numCells+numVerts,&coneOrientations,numVerts,&vertexCoords);CHKERRQ(ierr); 721580bdb30SBarry Smith ierr = PetscArrayzero(coneOrientations,numCells+numVerts);CHKERRQ(ierr); 722fdbf62faSLisandro Dalcin for (i = 0; i < numCells; ++i) { coneSize[i] = 2; } 723fdbf62faSLisandro Dalcin for (i = 0; i < numVerts; ++i) { coneSize[numCells+i] = 0; } 724fdbf62faSLisandro Dalcin for (i = 0; i < numCells; ++i) { cones[2*i] = numCells + i%numVerts; cones[2*i+1] = numCells + (i+1)%numVerts; } 725fdbf62faSLisandro Dalcin for (i = 0; i < numVerts; ++i) { vertexCoords[i] = lower + (upper-lower)*((PetscReal)i/(PetscReal)numCells); } 7269318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(dm,1,numPoints,coneSize,cones,coneOrientations,vertexCoords);CHKERRQ(ierr); 727fdbf62faSLisandro Dalcin ierr = PetscFree4(coneSize,cones,coneOrientations,vertexCoords);CHKERRQ(ierr); 728fdbf62faSLisandro Dalcin 7299318fe57SMatthew G. Knepley ierr = PetscOptionsGetBool(((PetscObject)dm)->options,((PetscObject)dm)->prefix,"-dm_plex_separate_marker",&markerSeparate,NULL);CHKERRQ(ierr); 730fdbf62faSLisandro Dalcin if (markerSeparate) { markerLeft = faceMarkerLeft; markerRight = faceMarkerRight;} 731dd400576SPatrick Sanan if (!wrap && rank == 0) { 7329318fe57SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm,1,&fStart,&fEnd);CHKERRQ(ierr); 7339318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm,"marker",fStart,markerLeft);CHKERRQ(ierr); 7349318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm,"marker",fEnd-1,markerRight);CHKERRQ(ierr); 7359318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm,"Face Sets",fStart,faceMarkerLeft);CHKERRQ(ierr); 7369318fe57SMatthew G. Knepley ierr = DMSetLabelValue(dm,"Face Sets",fEnd-1,faceMarkerRight);CHKERRQ(ierr); 737fdbf62faSLisandro Dalcin } 738fdbf62faSLisandro Dalcin if (wrap) { 739fdbf62faSLisandro Dalcin L = upper - lower; 740fdbf62faSLisandro Dalcin maxCell = (PetscReal)1.1*(L/(PetscReal)PetscMax(1,segments)); 7419318fe57SMatthew G. Knepley ierr = DMSetPeriodicity(dm,PETSC_TRUE,&maxCell,&L,&bd);CHKERRQ(ierr); 742fdbf62faSLisandro Dalcin } 7439318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr); 744fdbf62faSLisandro Dalcin PetscFunctionReturn(0); 745fdbf62faSLisandro Dalcin } 746fdbf62faSLisandro Dalcin 7479318fe57SMatthew 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) 748d6218766SMatthew G. Knepley { 7499318fe57SMatthew G. Knepley DM boundary, vol; 750768d5fceSMatthew G. Knepley PetscInt i; 751d6218766SMatthew G. Knepley PetscErrorCode ierr; 752d6218766SMatthew G. Knepley 753d6218766SMatthew G. Knepley PetscFunctionBegin; 7549318fe57SMatthew G. Knepley PetscValidPointer(dm, 1); 7552c71b3e2SJacob 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"); 7569318fe57SMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject) dm), &boundary);CHKERRQ(ierr); 757d6218766SMatthew G. Knepley ierr = DMSetType(boundary, DMPLEX);CHKERRQ(ierr); 7589318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxSurfaceMesh_Internal(boundary, dim, faces, lower, upper, PETSC_FALSE);CHKERRQ(ierr); 7599318fe57SMatthew G. Knepley ierr = DMPlexGenerate(boundary, NULL, interpolate, &vol);CHKERRQ(ierr); 760*e600fa54SMatthew G. Knepley ierr = DMPlexCopy_Internal(dm, PETSC_TRUE, vol);CHKERRQ(ierr); 7619318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &vol);CHKERRQ(ierr); 762d6218766SMatthew G. Knepley ierr = DMDestroy(&boundary);CHKERRQ(ierr); 763d6218766SMatthew G. Knepley PetscFunctionReturn(0); 764d6218766SMatthew G. Knepley } 765d6218766SMatthew G. Knepley 7663dfda0b1SToby Isaac static PetscErrorCode DMPlexCreateCubeMesh_Internal(DM dm, const PetscReal lower[], const PetscReal upper[], const PetscInt edges[], DMBoundaryType bdX, DMBoundaryType bdY, DMBoundaryType bdZ) 7673dfda0b1SToby Isaac { 768ed0e4b50SMatthew G. Knepley DMLabel cutLabel = NULL; 769f4eb4c5dSMatthew G. Knepley PetscInt markerTop = 1, faceMarkerTop = 1; 770f4eb4c5dSMatthew G. Knepley PetscInt markerBottom = 1, faceMarkerBottom = 1; 771f4eb4c5dSMatthew G. Knepley PetscInt markerFront = 1, faceMarkerFront = 1; 772f4eb4c5dSMatthew G. Knepley PetscInt markerBack = 1, faceMarkerBack = 1; 773f4eb4c5dSMatthew G. Knepley PetscInt markerRight = 1, faceMarkerRight = 1; 774f4eb4c5dSMatthew G. Knepley PetscInt markerLeft = 1, faceMarkerLeft = 1; 7753dfda0b1SToby Isaac PetscInt dim; 776d8211ee3SMatthew G. Knepley PetscBool markerSeparate = PETSC_FALSE, cutMarker = PETSC_FALSE; 7773dfda0b1SToby Isaac PetscMPIInt rank; 7783dfda0b1SToby Isaac PetscErrorCode ierr; 7793dfda0b1SToby Isaac 7803dfda0b1SToby Isaac PetscFunctionBegin; 781f0226e14SMatthew G. Knepley ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 782ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 78350ae33c3SToby Isaac ierr = DMCreateLabel(dm,"marker");CHKERRQ(ierr); 78450ae33c3SToby Isaac ierr = DMCreateLabel(dm,"Face Sets");CHKERRQ(ierr); 7854c67ea77SStefano Zampini ierr = PetscOptionsGetBool(((PetscObject) dm)->options,((PetscObject) dm)->prefix, "-dm_plex_periodic_cut", &cutMarker, NULL);CHKERRQ(ierr); 786d8211ee3SMatthew G. Knepley if (bdX == DM_BOUNDARY_PERIODIC || bdX == DM_BOUNDARY_TWIST || 787d8211ee3SMatthew G. Knepley bdY == DM_BOUNDARY_PERIODIC || bdY == DM_BOUNDARY_TWIST || 788d8211ee3SMatthew G. Knepley bdZ == DM_BOUNDARY_PERIODIC || bdZ == DM_BOUNDARY_TWIST) { 7894c67ea77SStefano Zampini 790d1c88043SMatthew G. Knepley if (cutMarker) {ierr = DMCreateLabel(dm, "periodic_cut");CHKERRQ(ierr); ierr = DMGetLabel(dm, "periodic_cut", &cutLabel);CHKERRQ(ierr);} 791d8211ee3SMatthew G. Knepley } 7923dfda0b1SToby Isaac switch (dim) { 7933dfda0b1SToby Isaac case 2: 794f4eb4c5dSMatthew G. Knepley faceMarkerTop = 3; 795f4eb4c5dSMatthew G. Knepley faceMarkerBottom = 1; 796f4eb4c5dSMatthew G. Knepley faceMarkerRight = 2; 797f4eb4c5dSMatthew G. Knepley faceMarkerLeft = 4; 7983dfda0b1SToby Isaac break; 7993dfda0b1SToby Isaac case 3: 800f4eb4c5dSMatthew G. Knepley faceMarkerBottom = 1; 801f4eb4c5dSMatthew G. Knepley faceMarkerTop = 2; 802f4eb4c5dSMatthew G. Knepley faceMarkerFront = 3; 803f4eb4c5dSMatthew G. Knepley faceMarkerBack = 4; 804f4eb4c5dSMatthew G. Knepley faceMarkerRight = 5; 805f4eb4c5dSMatthew G. Knepley faceMarkerLeft = 6; 8063dfda0b1SToby Isaac break; 8073dfda0b1SToby Isaac default: 80898921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Dimension %D not supported",dim); 8093dfda0b1SToby Isaac } 810c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject) dm)->options,((PetscObject) dm)->prefix, "-dm_plex_separate_marker", &markerSeparate, NULL);CHKERRQ(ierr); 811f4eb4c5dSMatthew G. Knepley if (markerSeparate) { 812f4eb4c5dSMatthew G. Knepley markerBottom = faceMarkerBottom; 813f4eb4c5dSMatthew G. Knepley markerTop = faceMarkerTop; 814f4eb4c5dSMatthew G. Knepley markerFront = faceMarkerFront; 815f4eb4c5dSMatthew G. Knepley markerBack = faceMarkerBack; 816f4eb4c5dSMatthew G. Knepley markerRight = faceMarkerRight; 817f4eb4c5dSMatthew G. Knepley markerLeft = faceMarkerLeft; 8183dfda0b1SToby Isaac } 8193dfda0b1SToby Isaac { 820dd400576SPatrick Sanan const PetscInt numXEdges = rank == 0 ? edges[0] : 0; 821dd400576SPatrick Sanan const PetscInt numYEdges = rank == 0 ? edges[1] : 0; 822dd400576SPatrick Sanan const PetscInt numZEdges = rank == 0 ? edges[2] : 0; 823dd400576SPatrick Sanan const PetscInt numXVertices = rank == 0 ? (bdX == DM_BOUNDARY_PERIODIC || bdX == DM_BOUNDARY_TWIST ? edges[0] : edges[0]+1) : 0; 824dd400576SPatrick Sanan const PetscInt numYVertices = rank == 0 ? (bdY == DM_BOUNDARY_PERIODIC || bdY == DM_BOUNDARY_TWIST ? edges[1] : edges[1]+1) : 0; 825dd400576SPatrick Sanan const PetscInt numZVertices = rank == 0 ? (bdZ == DM_BOUNDARY_PERIODIC || bdZ == DM_BOUNDARY_TWIST ? edges[2] : edges[2]+1) : 0; 8263dfda0b1SToby Isaac const PetscInt numCells = numXEdges*numYEdges*numZEdges; 8273dfda0b1SToby Isaac const PetscInt numXFaces = numYEdges*numZEdges; 8283dfda0b1SToby Isaac const PetscInt numYFaces = numXEdges*numZEdges; 8293dfda0b1SToby Isaac const PetscInt numZFaces = numXEdges*numYEdges; 8303dfda0b1SToby Isaac const PetscInt numTotXFaces = numXVertices*numXFaces; 8313dfda0b1SToby Isaac const PetscInt numTotYFaces = numYVertices*numYFaces; 8323dfda0b1SToby Isaac const PetscInt numTotZFaces = numZVertices*numZFaces; 8333dfda0b1SToby Isaac const PetscInt numFaces = numTotXFaces + numTotYFaces + numTotZFaces; 8343dfda0b1SToby Isaac const PetscInt numTotXEdges = numXEdges*numYVertices*numZVertices; 8353dfda0b1SToby Isaac const PetscInt numTotYEdges = numYEdges*numXVertices*numZVertices; 8363dfda0b1SToby Isaac const PetscInt numTotZEdges = numZEdges*numXVertices*numYVertices; 8373dfda0b1SToby Isaac const PetscInt numVertices = numXVertices*numYVertices*numZVertices; 8383dfda0b1SToby Isaac const PetscInt numEdges = numTotXEdges + numTotYEdges + numTotZEdges; 8393dfda0b1SToby Isaac const PetscInt firstVertex = (dim == 2) ? numFaces : numCells; 8403dfda0b1SToby Isaac const PetscInt firstXFace = (dim == 2) ? 0 : numCells + numVertices; 8413dfda0b1SToby Isaac const PetscInt firstYFace = firstXFace + numTotXFaces; 8423dfda0b1SToby Isaac const PetscInt firstZFace = firstYFace + numTotYFaces; 8433dfda0b1SToby Isaac const PetscInt firstXEdge = numCells + numFaces + numVertices; 8443dfda0b1SToby Isaac const PetscInt firstYEdge = firstXEdge + numTotXEdges; 8453dfda0b1SToby Isaac const PetscInt firstZEdge = firstYEdge + numTotYEdges; 8463dfda0b1SToby Isaac Vec coordinates; 8473dfda0b1SToby Isaac PetscSection coordSection; 8483dfda0b1SToby Isaac PetscScalar *coords; 8493dfda0b1SToby Isaac PetscInt coordSize; 8503dfda0b1SToby Isaac PetscInt v, vx, vy, vz; 8513dfda0b1SToby Isaac PetscInt c, f, fx, fy, fz, e, ex, ey, ez; 8523dfda0b1SToby Isaac 8533dfda0b1SToby Isaac ierr = DMPlexSetChart(dm, 0, numCells+numFaces+numEdges+numVertices);CHKERRQ(ierr); 8543dfda0b1SToby Isaac for (c = 0; c < numCells; c++) { 8553dfda0b1SToby Isaac ierr = DMPlexSetConeSize(dm, c, 6);CHKERRQ(ierr); 8563dfda0b1SToby Isaac } 8573dfda0b1SToby Isaac for (f = firstXFace; f < firstXFace+numFaces; ++f) { 8583dfda0b1SToby Isaac ierr = DMPlexSetConeSize(dm, f, 4);CHKERRQ(ierr); 8593dfda0b1SToby Isaac } 8603dfda0b1SToby Isaac for (e = firstXEdge; e < firstXEdge+numEdges; ++e) { 8613dfda0b1SToby Isaac ierr = DMPlexSetConeSize(dm, e, 2);CHKERRQ(ierr); 8623dfda0b1SToby Isaac } 8633dfda0b1SToby Isaac ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 8643dfda0b1SToby Isaac /* Build cells */ 8653dfda0b1SToby Isaac for (fz = 0; fz < numZEdges; ++fz) { 8663dfda0b1SToby Isaac for (fy = 0; fy < numYEdges; ++fy) { 8673dfda0b1SToby Isaac for (fx = 0; fx < numXEdges; ++fx) { 8683dfda0b1SToby Isaac PetscInt cell = (fz*numYEdges + fy)*numXEdges + fx; 8693dfda0b1SToby Isaac PetscInt faceB = firstZFace + (fy*numXEdges+fx)*numZVertices + fz; 8703dfda0b1SToby Isaac PetscInt faceT = firstZFace + (fy*numXEdges+fx)*numZVertices + ((fz+1)%numZVertices); 8713dfda0b1SToby Isaac PetscInt faceF = firstYFace + (fz*numXEdges+fx)*numYVertices + fy; 8723dfda0b1SToby Isaac PetscInt faceK = firstYFace + (fz*numXEdges+fx)*numYVertices + ((fy+1)%numYVertices); 8733dfda0b1SToby Isaac PetscInt faceL = firstXFace + (fz*numYEdges+fy)*numXVertices + fx; 8743dfda0b1SToby Isaac PetscInt faceR = firstXFace + (fz*numYEdges+fy)*numXVertices + ((fx+1)%numXVertices); 8753dfda0b1SToby Isaac /* B, T, F, K, R, L */ 876b5a892a1SMatthew G. Knepley PetscInt ornt[6] = {-2, 0, 0, -3, 0, -2}; /* ??? */ 87742206facSLisandro Dalcin PetscInt cone[6]; 8783dfda0b1SToby Isaac 8793dfda0b1SToby Isaac /* no boundary twisting in 3D */ 8803dfda0b1SToby Isaac cone[0] = faceB; cone[1] = faceT; cone[2] = faceF; cone[3] = faceK; cone[4] = faceR; cone[5] = faceL; 8813dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, cell, cone);CHKERRQ(ierr); 8823dfda0b1SToby Isaac ierr = DMPlexSetConeOrientation(dm, cell, ornt);CHKERRQ(ierr); 8838a5b437dSMatthew G. Knepley if (bdX != DM_BOUNDARY_NONE && fx == numXEdges-1 && cutLabel) {ierr = DMLabelSetValue(cutLabel, cell, 2);CHKERRQ(ierr);} 8848a5b437dSMatthew G. Knepley if (bdY != DM_BOUNDARY_NONE && fy == numYEdges-1 && cutLabel) {ierr = DMLabelSetValue(cutLabel, cell, 2);CHKERRQ(ierr);} 8858a5b437dSMatthew G. Knepley if (bdZ != DM_BOUNDARY_NONE && fz == numZEdges-1 && cutLabel) {ierr = DMLabelSetValue(cutLabel, cell, 2);CHKERRQ(ierr);} 8863dfda0b1SToby Isaac } 8873dfda0b1SToby Isaac } 8883dfda0b1SToby Isaac } 8893dfda0b1SToby Isaac /* Build x faces */ 8903dfda0b1SToby Isaac for (fz = 0; fz < numZEdges; ++fz) { 8913dfda0b1SToby Isaac for (fy = 0; fy < numYEdges; ++fy) { 8923dfda0b1SToby Isaac for (fx = 0; fx < numXVertices; ++fx) { 8933dfda0b1SToby Isaac PetscInt face = firstXFace + (fz*numYEdges+fy) *numXVertices+fx; 8943dfda0b1SToby Isaac PetscInt edgeL = firstZEdge + (fy *numXVertices+fx)*numZEdges + fz; 8953dfda0b1SToby Isaac PetscInt edgeR = firstZEdge + (((fy+1)%numYVertices)*numXVertices+fx)*numZEdges + fz; 8963dfda0b1SToby Isaac PetscInt edgeB = firstYEdge + (fz *numXVertices+fx)*numYEdges + fy; 8973dfda0b1SToby Isaac PetscInt edgeT = firstYEdge + (((fz+1)%numZVertices)*numXVertices+fx)*numYEdges + fy; 898b5a892a1SMatthew G. Knepley PetscInt ornt[4] = {0, 0, -1, -1}; 8993dfda0b1SToby Isaac PetscInt cone[4]; 9003dfda0b1SToby Isaac 9013dfda0b1SToby Isaac if (dim == 3) { 9023dfda0b1SToby Isaac /* markers */ 9033dfda0b1SToby Isaac if (bdX != DM_BOUNDARY_PERIODIC) { 9043dfda0b1SToby Isaac if (fx == numXVertices-1) { 905c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerRight);CHKERRQ(ierr); 906c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerRight);CHKERRQ(ierr); 9073dfda0b1SToby Isaac } 9083dfda0b1SToby Isaac else if (fx == 0) { 909c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerLeft);CHKERRQ(ierr); 910c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerLeft);CHKERRQ(ierr); 9113dfda0b1SToby Isaac } 9123dfda0b1SToby Isaac } 9133dfda0b1SToby Isaac } 9143dfda0b1SToby Isaac cone[0] = edgeB; cone[1] = edgeR; cone[2] = edgeT; cone[3] = edgeL; 9153dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, face, cone);CHKERRQ(ierr); 9163dfda0b1SToby Isaac ierr = DMPlexSetConeOrientation(dm, face, ornt);CHKERRQ(ierr); 9173dfda0b1SToby Isaac } 9183dfda0b1SToby Isaac } 9193dfda0b1SToby Isaac } 9203dfda0b1SToby Isaac /* Build y faces */ 9213dfda0b1SToby Isaac for (fz = 0; fz < numZEdges; ++fz) { 92242206facSLisandro Dalcin for (fx = 0; fx < numXEdges; ++fx) { 9233dfda0b1SToby Isaac for (fy = 0; fy < numYVertices; ++fy) { 9243dfda0b1SToby Isaac PetscInt face = firstYFace + (fz*numXEdges+fx)*numYVertices + fy; 9253dfda0b1SToby Isaac PetscInt edgeL = firstZEdge + (fy*numXVertices+ fx)*numZEdges + fz; 9263dfda0b1SToby Isaac PetscInt edgeR = firstZEdge + (fy*numXVertices+((fx+1)%numXVertices))*numZEdges + fz; 9273dfda0b1SToby Isaac PetscInt edgeB = firstXEdge + (fz *numYVertices+fy)*numXEdges + fx; 9283dfda0b1SToby Isaac PetscInt edgeT = firstXEdge + (((fz+1)%numZVertices)*numYVertices+fy)*numXEdges + fx; 929b5a892a1SMatthew G. Knepley PetscInt ornt[4] = {0, 0, -1, -1}; 9303dfda0b1SToby Isaac PetscInt cone[4]; 9313dfda0b1SToby Isaac 9323dfda0b1SToby Isaac if (dim == 3) { 9333dfda0b1SToby Isaac /* markers */ 9343dfda0b1SToby Isaac if (bdY != DM_BOUNDARY_PERIODIC) { 9353dfda0b1SToby Isaac if (fy == numYVertices-1) { 936c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerBack);CHKERRQ(ierr); 937c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerBack);CHKERRQ(ierr); 9383dfda0b1SToby Isaac } 9393dfda0b1SToby Isaac else if (fy == 0) { 940c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerFront);CHKERRQ(ierr); 941c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerFront);CHKERRQ(ierr); 9423dfda0b1SToby Isaac } 9433dfda0b1SToby Isaac } 9443dfda0b1SToby Isaac } 9453dfda0b1SToby Isaac cone[0] = edgeB; cone[1] = edgeR; cone[2] = edgeT; cone[3] = edgeL; 9463dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, face, cone);CHKERRQ(ierr); 9473dfda0b1SToby Isaac ierr = DMPlexSetConeOrientation(dm, face, ornt);CHKERRQ(ierr); 9483dfda0b1SToby Isaac } 9493dfda0b1SToby Isaac } 9503dfda0b1SToby Isaac } 9513dfda0b1SToby Isaac /* Build z faces */ 9523dfda0b1SToby Isaac for (fy = 0; fy < numYEdges; ++fy) { 9533dfda0b1SToby Isaac for (fx = 0; fx < numXEdges; ++fx) { 9543dfda0b1SToby Isaac for (fz = 0; fz < numZVertices; fz++) { 9553dfda0b1SToby Isaac PetscInt face = firstZFace + (fy*numXEdges+fx)*numZVertices + fz; 9563dfda0b1SToby Isaac PetscInt edgeL = firstYEdge + (fz*numXVertices+ fx)*numYEdges + fy; 9573dfda0b1SToby Isaac PetscInt edgeR = firstYEdge + (fz*numXVertices+((fx+1)%numXVertices))*numYEdges + fy; 9583dfda0b1SToby Isaac PetscInt edgeB = firstXEdge + (fz*numYVertices+ fy)*numXEdges + fx; 9593dfda0b1SToby Isaac PetscInt edgeT = firstXEdge + (fz*numYVertices+((fy+1)%numYVertices))*numXEdges + fx; 960b5a892a1SMatthew G. Knepley PetscInt ornt[4] = {0, 0, -1, -1}; 9613dfda0b1SToby Isaac PetscInt cone[4]; 9623dfda0b1SToby Isaac 9633dfda0b1SToby Isaac if (dim == 2) { 964b5a892a1SMatthew G. Knepley if (bdX == DM_BOUNDARY_TWIST && fx == numXEdges-1) {edgeR += numYEdges-1-2*fy; ornt[1] = -1;} 9653dfda0b1SToby Isaac if (bdY == DM_BOUNDARY_TWIST && fy == numYEdges-1) {edgeT += numXEdges-1-2*fx; ornt[2] = 0;} 9668a5b437dSMatthew G. Knepley if (bdX != DM_BOUNDARY_NONE && fx == numXEdges-1 && cutLabel) {ierr = DMLabelSetValue(cutLabel, face, 2);CHKERRQ(ierr);} 9678a5b437dSMatthew G. Knepley if (bdY != DM_BOUNDARY_NONE && fy == numYEdges-1 && cutLabel) {ierr = DMLabelSetValue(cutLabel, face, 2);CHKERRQ(ierr);} 968d1c88043SMatthew G. Knepley } else { 9693dfda0b1SToby Isaac /* markers */ 9703dfda0b1SToby Isaac if (bdZ != DM_BOUNDARY_PERIODIC) { 9713dfda0b1SToby Isaac if (fz == numZVertices-1) { 972c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerTop);CHKERRQ(ierr); 973c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerTop);CHKERRQ(ierr); 9743dfda0b1SToby Isaac } 9753dfda0b1SToby Isaac else if (fz == 0) { 976c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", face, faceMarkerBottom);CHKERRQ(ierr); 977c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", face, markerBottom);CHKERRQ(ierr); 9783dfda0b1SToby Isaac } 9793dfda0b1SToby Isaac } 9803dfda0b1SToby Isaac } 9813dfda0b1SToby Isaac cone[0] = edgeB; cone[1] = edgeR; cone[2] = edgeT; cone[3] = edgeL; 9823dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, face, cone);CHKERRQ(ierr); 9833dfda0b1SToby Isaac ierr = DMPlexSetConeOrientation(dm, face, ornt);CHKERRQ(ierr); 9843dfda0b1SToby Isaac } 9853dfda0b1SToby Isaac } 9863dfda0b1SToby Isaac } 9873dfda0b1SToby Isaac /* Build Z edges*/ 9883dfda0b1SToby Isaac for (vy = 0; vy < numYVertices; vy++) { 9893dfda0b1SToby Isaac for (vx = 0; vx < numXVertices; vx++) { 9903dfda0b1SToby Isaac for (ez = 0; ez < numZEdges; ez++) { 9913dfda0b1SToby Isaac const PetscInt edge = firstZEdge + (vy*numXVertices+vx)*numZEdges + ez; 9923dfda0b1SToby Isaac const PetscInt vertexB = firstVertex + (ez *numYVertices+vy)*numXVertices + vx; 9933dfda0b1SToby Isaac const PetscInt vertexT = firstVertex + (((ez+1)%numZVertices)*numYVertices+vy)*numXVertices + vx; 9943dfda0b1SToby Isaac PetscInt cone[2]; 9953dfda0b1SToby Isaac 9963dfda0b1SToby Isaac if (dim == 3) { 9973dfda0b1SToby Isaac if (bdX != DM_BOUNDARY_PERIODIC) { 9983dfda0b1SToby Isaac if (vx == numXVertices-1) { 999c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerRight);CHKERRQ(ierr); 10003dfda0b1SToby Isaac } 10013dfda0b1SToby Isaac else if (vx == 0) { 1002c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerLeft);CHKERRQ(ierr); 10033dfda0b1SToby Isaac } 10043dfda0b1SToby Isaac } 10053dfda0b1SToby Isaac if (bdY != DM_BOUNDARY_PERIODIC) { 10063dfda0b1SToby Isaac if (vy == numYVertices-1) { 1007c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBack);CHKERRQ(ierr); 10083dfda0b1SToby Isaac } 10093dfda0b1SToby Isaac else if (vy == 0) { 1010c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerFront);CHKERRQ(ierr); 10113dfda0b1SToby Isaac } 10123dfda0b1SToby Isaac } 10133dfda0b1SToby Isaac } 10143dfda0b1SToby Isaac cone[0] = vertexB; cone[1] = vertexT; 10153dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); 10163dfda0b1SToby Isaac } 10173dfda0b1SToby Isaac } 10183dfda0b1SToby Isaac } 10193dfda0b1SToby Isaac /* Build Y edges*/ 10203dfda0b1SToby Isaac for (vz = 0; vz < numZVertices; vz++) { 10213dfda0b1SToby Isaac for (vx = 0; vx < numXVertices; vx++) { 10223dfda0b1SToby Isaac for (ey = 0; ey < numYEdges; ey++) { 10233dfda0b1SToby Isaac const PetscInt nextv = (dim == 2 && bdY == DM_BOUNDARY_TWIST && ey == numYEdges-1) ? (numXVertices-vx-1) : (vz*numYVertices+((ey+1)%numYVertices))*numXVertices + vx; 10243dfda0b1SToby Isaac const PetscInt edge = firstYEdge + (vz*numXVertices+vx)*numYEdges + ey; 10253dfda0b1SToby Isaac const PetscInt vertexF = firstVertex + (vz*numYVertices+ey)*numXVertices + vx; 10263dfda0b1SToby Isaac const PetscInt vertexK = firstVertex + nextv; 10273dfda0b1SToby Isaac PetscInt cone[2]; 10283dfda0b1SToby Isaac 10293dfda0b1SToby Isaac cone[0] = vertexF; cone[1] = vertexK; 10303dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); 10313dfda0b1SToby Isaac if (dim == 2) { 10323dfda0b1SToby Isaac if ((bdX != DM_BOUNDARY_PERIODIC) && (bdX != DM_BOUNDARY_TWIST)) { 10333dfda0b1SToby Isaac if (vx == numXVertices-1) { 1034c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", edge, faceMarkerRight);CHKERRQ(ierr); 1035c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerRight);CHKERRQ(ierr); 1036c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerRight);CHKERRQ(ierr); 10373dfda0b1SToby Isaac if (ey == numYEdges-1) { 1038c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerRight);CHKERRQ(ierr); 10393dfda0b1SToby Isaac } 1040d8211ee3SMatthew G. Knepley } else if (vx == 0) { 1041c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", edge, faceMarkerLeft);CHKERRQ(ierr); 1042c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerLeft);CHKERRQ(ierr); 1043c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerLeft);CHKERRQ(ierr); 10443dfda0b1SToby Isaac if (ey == numYEdges-1) { 1045c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerLeft);CHKERRQ(ierr); 10463dfda0b1SToby Isaac } 10473dfda0b1SToby Isaac } 1048d8211ee3SMatthew G. Knepley } else { 10494c67ea77SStefano Zampini if (vx == 0 && cutLabel) { 1050d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, edge, 1);CHKERRQ(ierr); 1051d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, cone[0], 1);CHKERRQ(ierr); 1052d8211ee3SMatthew G. Knepley if (ey == numYEdges-1) { 1053d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, cone[1], 1);CHKERRQ(ierr); 10543dfda0b1SToby Isaac } 10553dfda0b1SToby Isaac } 1056d8211ee3SMatthew G. Knepley } 1057d8211ee3SMatthew G. Knepley } else { 10583dfda0b1SToby Isaac if (bdX != DM_BOUNDARY_PERIODIC) { 10593dfda0b1SToby Isaac if (vx == numXVertices-1) { 1060c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerRight);CHKERRQ(ierr); 1061d8211ee3SMatthew G. Knepley } else if (vx == 0) { 1062c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerLeft);CHKERRQ(ierr); 10633dfda0b1SToby Isaac } 10643dfda0b1SToby Isaac } 10653dfda0b1SToby Isaac if (bdZ != DM_BOUNDARY_PERIODIC) { 10663dfda0b1SToby Isaac if (vz == numZVertices-1) { 1067c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerTop);CHKERRQ(ierr); 1068d8211ee3SMatthew G. Knepley } else if (vz == 0) { 1069c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBottom);CHKERRQ(ierr); 10703dfda0b1SToby Isaac } 10713dfda0b1SToby Isaac } 10723dfda0b1SToby Isaac } 10733dfda0b1SToby Isaac } 10743dfda0b1SToby Isaac } 10753dfda0b1SToby Isaac } 10763dfda0b1SToby Isaac /* Build X edges*/ 10773dfda0b1SToby Isaac for (vz = 0; vz < numZVertices; vz++) { 10783dfda0b1SToby Isaac for (vy = 0; vy < numYVertices; vy++) { 10793dfda0b1SToby Isaac for (ex = 0; ex < numXEdges; ex++) { 10803dfda0b1SToby Isaac const PetscInt nextv = (dim == 2 && bdX == DM_BOUNDARY_TWIST && ex == numXEdges-1) ? (numYVertices-vy-1)*numXVertices : (vz*numYVertices+vy)*numXVertices + (ex+1)%numXVertices; 10813dfda0b1SToby Isaac const PetscInt edge = firstXEdge + (vz*numYVertices+vy)*numXEdges + ex; 10823dfda0b1SToby Isaac const PetscInt vertexL = firstVertex + (vz*numYVertices+vy)*numXVertices + ex; 10833dfda0b1SToby Isaac const PetscInt vertexR = firstVertex + nextv; 10843dfda0b1SToby Isaac PetscInt cone[2]; 10853dfda0b1SToby Isaac 10863dfda0b1SToby Isaac cone[0] = vertexL; cone[1] = vertexR; 10873dfda0b1SToby Isaac ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); 10883dfda0b1SToby Isaac if (dim == 2) { 10893dfda0b1SToby Isaac if ((bdY != DM_BOUNDARY_PERIODIC) && (bdY != DM_BOUNDARY_TWIST)) { 10903dfda0b1SToby Isaac if (vy == numYVertices-1) { 1091c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", edge, faceMarkerTop);CHKERRQ(ierr); 1092c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerTop);CHKERRQ(ierr); 1093c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerTop);CHKERRQ(ierr); 10943dfda0b1SToby Isaac if (ex == numXEdges-1) { 1095c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerTop);CHKERRQ(ierr); 10963dfda0b1SToby Isaac } 1097d8211ee3SMatthew G. Knepley } else if (vy == 0) { 1098c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "Face Sets", edge, faceMarkerBottom);CHKERRQ(ierr); 1099c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBottom);CHKERRQ(ierr); 1100c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[0], markerBottom);CHKERRQ(ierr); 11013dfda0b1SToby Isaac if (ex == numXEdges-1) { 1102c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", cone[1], markerBottom);CHKERRQ(ierr); 11033dfda0b1SToby Isaac } 11043dfda0b1SToby Isaac } 1105d8211ee3SMatthew G. Knepley } else { 11064c67ea77SStefano Zampini if (vy == 0 && cutLabel) { 1107d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, edge, 1);CHKERRQ(ierr); 1108d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, cone[0], 1);CHKERRQ(ierr); 1109d8211ee3SMatthew G. Knepley if (ex == numXEdges-1) { 1110d1c88043SMatthew G. Knepley ierr = DMLabelSetValue(cutLabel, cone[1], 1);CHKERRQ(ierr); 11113dfda0b1SToby Isaac } 11123dfda0b1SToby Isaac } 1113d8211ee3SMatthew G. Knepley } 1114d8211ee3SMatthew G. Knepley } else { 11153dfda0b1SToby Isaac if (bdY != DM_BOUNDARY_PERIODIC) { 11163dfda0b1SToby Isaac if (vy == numYVertices-1) { 1117c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBack);CHKERRQ(ierr); 11183dfda0b1SToby Isaac } 11193dfda0b1SToby Isaac else if (vy == 0) { 1120c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerFront);CHKERRQ(ierr); 11213dfda0b1SToby Isaac } 11223dfda0b1SToby Isaac } 11233dfda0b1SToby Isaac if (bdZ != DM_BOUNDARY_PERIODIC) { 11243dfda0b1SToby Isaac if (vz == numZVertices-1) { 1125c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerTop);CHKERRQ(ierr); 11263dfda0b1SToby Isaac } 11273dfda0b1SToby Isaac else if (vz == 0) { 1128c58f1c22SToby Isaac ierr = DMSetLabelValue(dm, "marker", edge, markerBottom);CHKERRQ(ierr); 11293dfda0b1SToby Isaac } 11303dfda0b1SToby Isaac } 11313dfda0b1SToby Isaac } 11323dfda0b1SToby Isaac } 11333dfda0b1SToby Isaac } 11343dfda0b1SToby Isaac } 11353dfda0b1SToby Isaac ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 11363dfda0b1SToby Isaac ierr = DMPlexStratify(dm);CHKERRQ(ierr); 11373dfda0b1SToby Isaac /* Build coordinates */ 11383dfda0b1SToby Isaac ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 11393dfda0b1SToby Isaac ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 11403dfda0b1SToby Isaac ierr = PetscSectionSetFieldComponents(coordSection, 0, dim);CHKERRQ(ierr); 11413dfda0b1SToby Isaac ierr = PetscSectionSetChart(coordSection, firstVertex, firstVertex+numVertices);CHKERRQ(ierr); 11423dfda0b1SToby Isaac for (v = firstVertex; v < firstVertex+numVertices; ++v) { 11433dfda0b1SToby Isaac ierr = PetscSectionSetDof(coordSection, v, dim);CHKERRQ(ierr); 11443dfda0b1SToby Isaac ierr = PetscSectionSetFieldDof(coordSection, v, 0, dim);CHKERRQ(ierr); 11453dfda0b1SToby Isaac } 11463dfda0b1SToby Isaac ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 11473dfda0b1SToby Isaac ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 11488b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 1149da16285aSMichael Lange ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 11503dfda0b1SToby Isaac ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 11518b9ced59SLisandro Dalcin ierr = VecSetBlockSize(coordinates, dim);CHKERRQ(ierr); 11523dfda0b1SToby Isaac ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 11533dfda0b1SToby Isaac ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 11543dfda0b1SToby Isaac for (vz = 0; vz < numZVertices; ++vz) { 11553dfda0b1SToby Isaac for (vy = 0; vy < numYVertices; ++vy) { 11563dfda0b1SToby Isaac for (vx = 0; vx < numXVertices; ++vx) { 11573dfda0b1SToby Isaac coords[((vz*numYVertices+vy)*numXVertices+vx)*dim+0] = lower[0] + ((upper[0] - lower[0])/numXEdges)*vx; 11583dfda0b1SToby Isaac coords[((vz*numYVertices+vy)*numXVertices+vx)*dim+1] = lower[1] + ((upper[1] - lower[1])/numYEdges)*vy; 11593dfda0b1SToby Isaac if (dim == 3) { 11603dfda0b1SToby Isaac coords[((vz*numYVertices+vy)*numXVertices+vx)*dim+2] = lower[2] + ((upper[2] - lower[2])/numZEdges)*vz; 11613dfda0b1SToby Isaac } 11623dfda0b1SToby Isaac } 11633dfda0b1SToby Isaac } 11643dfda0b1SToby Isaac } 11653dfda0b1SToby Isaac ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 11663dfda0b1SToby Isaac ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 11673dfda0b1SToby Isaac ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 11683dfda0b1SToby Isaac } 11693dfda0b1SToby Isaac PetscFunctionReturn(0); 11703dfda0b1SToby Isaac } 11713dfda0b1SToby Isaac 11729318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoxMesh_Tensor_Internal(DM dm, PetscInt dim, const PetscInt faces[], const PetscReal lower[], const PetscReal upper[], const DMBoundaryType periodicity[]) 1173a6dfd86eSKarl Rupp { 11749318fe57SMatthew G. Knepley DMBoundaryType bdt[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE}; 11759318fe57SMatthew G. Knepley PetscInt fac[3] = {0, 0, 0}, d; 1176552f7358SJed Brown PetscErrorCode ierr; 1177552f7358SJed Brown 1178552f7358SJed Brown PetscFunctionBegin; 11799318fe57SMatthew G. Knepley PetscValidPointer(dm, 1); 11809318fe57SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 11819318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 11829318fe57SMatthew G. Knepley for (d = 0; d < dim; ++d) {fac[d] = faces[d]; bdt[d] = periodicity[d];} 11839318fe57SMatthew G. Knepley ierr = DMPlexCreateCubeMesh_Internal(dm, lower, upper, fac, bdt[0], bdt[1], bdt[2]);CHKERRQ(ierr); 1184768d5fceSMatthew G. Knepley if (periodicity[0] == DM_BOUNDARY_PERIODIC || periodicity[0] == DM_BOUNDARY_TWIST || 1185768d5fceSMatthew G. Knepley periodicity[1] == DM_BOUNDARY_PERIODIC || periodicity[1] == DM_BOUNDARY_TWIST || 1186768d5fceSMatthew G. Knepley (dim > 2 && (periodicity[2] == DM_BOUNDARY_PERIODIC || periodicity[2] == DM_BOUNDARY_TWIST))) { 1187768d5fceSMatthew G. Knepley PetscReal L[3]; 1188768d5fceSMatthew G. Knepley PetscReal maxCell[3]; 1189552f7358SJed Brown 11909318fe57SMatthew G. Knepley for (d = 0; d < dim; ++d) { 11919318fe57SMatthew G. Knepley L[d] = upper[d] - lower[d]; 11929318fe57SMatthew G. Knepley maxCell[d] = 1.1 * (L[d] / PetscMax(1, faces[d])); 1193768d5fceSMatthew G. Knepley } 11949318fe57SMatthew G. Knepley ierr = DMSetPeriodicity(dm, PETSC_TRUE, maxCell, L, periodicity);CHKERRQ(ierr); 1195768d5fceSMatthew G. Knepley } 11969318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr); 11979318fe57SMatthew G. Knepley PetscFunctionReturn(0); 11989318fe57SMatthew G. Knepley } 11999318fe57SMatthew G. Knepley 12009318fe57SMatthew 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) 12019318fe57SMatthew G. Knepley { 12029318fe57SMatthew G. Knepley PetscErrorCode ierr; 12039318fe57SMatthew G. Knepley 12049318fe57SMatthew G. Knepley PetscFunctionBegin; 12059318fe57SMatthew G. Knepley if (dim == 1) {ierr = DMPlexCreateLineMesh_Internal(dm, faces[0], lower[0], upper[0], periodicity[0]);CHKERRQ(ierr);} 12069318fe57SMatthew G. Knepley else if (simplex) {ierr = DMPlexCreateBoxMesh_Simplex_Internal(dm, dim, faces, lower, upper, periodicity, interpolate);CHKERRQ(ierr);} 12079318fe57SMatthew G. Knepley else {ierr = DMPlexCreateBoxMesh_Tensor_Internal(dm, dim, faces, lower, upper, periodicity);CHKERRQ(ierr);} 12089318fe57SMatthew G. Knepley if (!interpolate && dim > 1 && !simplex) { 1209768d5fceSMatthew G. Knepley DM udm; 1210768d5fceSMatthew G. Knepley 12119318fe57SMatthew G. Knepley ierr = DMPlexUninterpolate(dm, &udm);CHKERRQ(ierr); 12129318fe57SMatthew G. Knepley ierr = DMPlexCopyCoordinates(dm, udm);CHKERRQ(ierr); 12139318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &udm);CHKERRQ(ierr); 1214768d5fceSMatthew G. Knepley } 1215768d5fceSMatthew G. Knepley PetscFunctionReturn(0); 1216c8c68bd8SToby Isaac } 1217c8c68bd8SToby Isaac 1218768d5fceSMatthew G. Knepley /*@C 1219768d5fceSMatthew G. Knepley DMPlexCreateBoxMesh - Creates a mesh on the tensor product of unit intervals (box) using simplices or tensor cells (hexahedra). 1220768d5fceSMatthew G. Knepley 1221d083f849SBarry Smith Collective 1222768d5fceSMatthew G. Knepley 1223768d5fceSMatthew G. Knepley Input Parameters: 1224768d5fceSMatthew G. Knepley + comm - The communicator for the DM object 1225768d5fceSMatthew G. Knepley . dim - The spatial dimension 1226768d5fceSMatthew G. Knepley . simplex - PETSC_TRUE for simplices, PETSC_FALSE for tensor cells 1227fdbf62faSLisandro Dalcin . faces - Number of faces per dimension, or NULL for (1,) in 1D and (2, 2) in 2D and (1, 1, 1) in 3D 1228768d5fceSMatthew G. Knepley . lower - The lower left corner, or NULL for (0, 0, 0) 1229768d5fceSMatthew G. Knepley . upper - The upper right corner, or NULL for (1, 1, 1) 1230fdbf62faSLisandro Dalcin . periodicity - The boundary type for the X,Y,Z direction, or NULL for DM_BOUNDARY_NONE 1231768d5fceSMatthew G. Knepley - interpolate - Flag to create intermediate mesh pieces (edges, faces) 1232768d5fceSMatthew G. Knepley 1233768d5fceSMatthew G. Knepley Output Parameter: 1234768d5fceSMatthew G. Knepley . dm - The DM object 1235768d5fceSMatthew G. Knepley 12369318fe57SMatthew G. Knepley Note: If you want to customize this mesh using options, you just need to 12379318fe57SMatthew G. Knepley $ DMCreate(comm, &dm); 12389318fe57SMatthew G. Knepley $ DMSetType(dm, DMPLEX); 12399318fe57SMatthew G. Knepley $ DMSetFromOptions(dm); 12409318fe57SMatthew G. Knepley and use the options on the DMSetFromOptions() page. 12411367e252SJed Brown 12421367e252SJed Brown Here is the numbering returned for 2 faces in each direction for tensor cells: 1243768d5fceSMatthew G. Knepley $ 10---17---11---18----12 1244768d5fceSMatthew G. Knepley $ | | | 1245768d5fceSMatthew G. Knepley $ | | | 1246768d5fceSMatthew G. Knepley $ 20 2 22 3 24 1247768d5fceSMatthew G. Knepley $ | | | 1248768d5fceSMatthew G. Knepley $ | | | 1249768d5fceSMatthew G. Knepley $ 7---15----8---16----9 1250768d5fceSMatthew G. Knepley $ | | | 1251768d5fceSMatthew G. Knepley $ | | | 1252768d5fceSMatthew G. Knepley $ 19 0 21 1 23 1253768d5fceSMatthew G. Knepley $ | | | 1254768d5fceSMatthew G. Knepley $ | | | 1255768d5fceSMatthew G. Knepley $ 4---13----5---14----6 1256768d5fceSMatthew G. Knepley 1257768d5fceSMatthew G. Knepley and for simplicial cells 1258768d5fceSMatthew G. Knepley 1259768d5fceSMatthew G. Knepley $ 14----8---15----9----16 1260768d5fceSMatthew G. Knepley $ |\ 5 |\ 7 | 1261768d5fceSMatthew G. Knepley $ | \ | \ | 1262768d5fceSMatthew G. Knepley $ 13 2 14 3 15 1263768d5fceSMatthew G. Knepley $ | 4 \ | 6 \ | 1264768d5fceSMatthew G. Knepley $ | \ | \ | 1265768d5fceSMatthew G. Knepley $ 11----6---12----7----13 1266768d5fceSMatthew G. Knepley $ |\ |\ | 1267768d5fceSMatthew G. Knepley $ | \ 1 | \ 3 | 1268768d5fceSMatthew G. Knepley $ 10 0 11 1 12 1269768d5fceSMatthew G. Knepley $ | 0 \ | 2 \ | 1270768d5fceSMatthew G. Knepley $ | \ | \ | 1271768d5fceSMatthew G. Knepley $ 8----4----9----5----10 1272768d5fceSMatthew G. Knepley 1273768d5fceSMatthew G. Knepley Level: beginner 1274768d5fceSMatthew G. Knepley 12759318fe57SMatthew G. Knepley .seealso: DMSetFromOptions(), DMPlexCreateFromFile(), DMPlexCreateHexCylinderMesh(), DMSetType(), DMCreate() 1276768d5fceSMatthew G. Knepley @*/ 1277768d5fceSMatthew 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) 1278552f7358SJed Brown { 12799318fe57SMatthew G. Knepley PetscInt fac[3] = {1, 1, 1}; 1280fdbf62faSLisandro Dalcin PetscReal low[3] = {0, 0, 0}; 1281fdbf62faSLisandro Dalcin PetscReal upp[3] = {1, 1, 1}; 1282fdbf62faSLisandro Dalcin DMBoundaryType bdt[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE}; 1283768d5fceSMatthew G. Knepley PetscErrorCode ierr; 1284552f7358SJed Brown 1285768d5fceSMatthew G. Knepley PetscFunctionBegin; 12869318fe57SMatthew G. Knepley ierr = DMCreate(comm,dm);CHKERRQ(ierr); 12879318fe57SMatthew G. Knepley ierr = DMSetType(*dm,DMPLEX);CHKERRQ(ierr); 12889318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxMesh_Internal(*dm, dim, simplex, faces ? faces : fac, lower ? lower : low, upper ? upper : upp, periodicity ? periodicity : bdt, interpolate);CHKERRQ(ierr); 12899318fe57SMatthew G. Knepley PetscFunctionReturn(0); 12909318fe57SMatthew G. Knepley } 1291fdbf62faSLisandro Dalcin 1292d410b0cfSMatthew G. Knepley static PetscErrorCode DMPlexCreateWedgeBoxMesh_Internal(DM dm, const PetscInt faces[], const PetscReal lower[], const PetscReal upper[], const DMBoundaryType periodicity[]) 12939318fe57SMatthew G. Knepley { 12949318fe57SMatthew G. Knepley DM bdm, vol; 12959318fe57SMatthew G. Knepley PetscInt i; 12969318fe57SMatthew G. Knepley PetscErrorCode ierr; 12979318fe57SMatthew G. Knepley 12989318fe57SMatthew G. Knepley PetscFunctionBegin; 12992c71b3e2SJacob Faibussowitsch for (i = 0; i < 3; ++i) PetscCheckFalse(periodicity[i] != DM_BOUNDARY_NONE,PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Periodicity not yet supported"); 13009318fe57SMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject) dm), &bdm);CHKERRQ(ierr); 13019318fe57SMatthew G. Knepley ierr = DMSetType(bdm, DMPLEX);CHKERRQ(ierr); 13029318fe57SMatthew G. Knepley ierr = DMSetDimension(bdm, 2);CHKERRQ(ierr); 1303d410b0cfSMatthew G. Knepley ierr = DMPlexCreateBoxMesh_Simplex_Internal(bdm, 2, faces, lower, upper, periodicity, PETSC_TRUE);CHKERRQ(ierr); 1304d410b0cfSMatthew G. Knepley ierr = DMPlexExtrude(bdm, faces[2], upper[2] - lower[2], PETSC_TRUE, PETSC_FALSE, NULL, NULL, &vol);CHKERRQ(ierr); 13059318fe57SMatthew G. Knepley ierr = DMDestroy(&bdm);CHKERRQ(ierr); 13069318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &vol);CHKERRQ(ierr); 13079318fe57SMatthew G. Knepley if (lower[2] != 0.0) { 13089318fe57SMatthew G. Knepley Vec v; 13099318fe57SMatthew G. Knepley PetscScalar *x; 13109318fe57SMatthew G. Knepley PetscInt cDim, n; 13119318fe57SMatthew G. Knepley 13129318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &v);CHKERRQ(ierr); 13139318fe57SMatthew G. Knepley ierr = VecGetBlockSize(v, &cDim);CHKERRQ(ierr); 13149318fe57SMatthew G. Knepley ierr = VecGetLocalSize(v, &n);CHKERRQ(ierr); 13159318fe57SMatthew G. Knepley ierr = VecGetArray(v, &x);CHKERRQ(ierr); 13169318fe57SMatthew G. Knepley x += cDim; 13179318fe57SMatthew G. Knepley for (i = 0; i < n; i += cDim) x[i] += lower[2]; 13189318fe57SMatthew G. Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 13199318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, v);CHKERRQ(ierr); 13209318fe57SMatthew G. Knepley } 1321552f7358SJed Brown PetscFunctionReturn(0); 1322552f7358SJed Brown } 1323552f7358SJed Brown 132400dabe28SStefano Zampini /*@ 132500dabe28SStefano Zampini DMPlexCreateWedgeBoxMesh - Creates a 3-D mesh tesselating the (x,y) plane and extruding in the third direction using wedge cells. 132600dabe28SStefano Zampini 1327d083f849SBarry Smith Collective 132800dabe28SStefano Zampini 132900dabe28SStefano Zampini Input Parameters: 133000dabe28SStefano Zampini + comm - The communicator for the DM object 133100dabe28SStefano Zampini . faces - Number of faces per dimension, or NULL for (1, 1, 1) 133200dabe28SStefano Zampini . lower - The lower left corner, or NULL for (0, 0, 0) 133300dabe28SStefano Zampini . upper - The upper right corner, or NULL for (1, 1, 1) 133400dabe28SStefano Zampini . periodicity - The boundary type for the X,Y,Z direction, or NULL for DM_BOUNDARY_NONE 1335d0fcb9c2SMatthew G. Knepley . orderHeight - If PETSC_TRUE, orders the extruded cells in the height first. Otherwise, orders the cell on the layers first 133600dabe28SStefano Zampini - interpolate - Flag to create intermediate mesh pieces (edges, faces) 133700dabe28SStefano Zampini 133800dabe28SStefano Zampini Output Parameter: 133900dabe28SStefano Zampini . dm - The DM object 134000dabe28SStefano Zampini 134100dabe28SStefano Zampini Level: beginner 134200dabe28SStefano Zampini 1343d410b0cfSMatthew G. Knepley .seealso: DMPlexCreateHexCylinderMesh(), DMPlexCreateWedgeCylinderMesh(), DMExtrude(), DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 134400dabe28SStefano Zampini @*/ 1345d0fcb9c2SMatthew 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) 134600dabe28SStefano Zampini { 13479318fe57SMatthew G. Knepley PetscInt fac[3] = {1, 1, 1}; 134800dabe28SStefano Zampini PetscReal low[3] = {0, 0, 0}; 134900dabe28SStefano Zampini PetscReal upp[3] = {1, 1, 1}; 135000dabe28SStefano Zampini DMBoundaryType bdt[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE}; 135100dabe28SStefano Zampini PetscErrorCode ierr; 135200dabe28SStefano Zampini 135300dabe28SStefano Zampini PetscFunctionBegin; 13549318fe57SMatthew G. Knepley ierr = DMCreate(comm,dm);CHKERRQ(ierr); 13559318fe57SMatthew G. Knepley ierr = DMSetType(*dm,DMPLEX);CHKERRQ(ierr); 1356d410b0cfSMatthew G. Knepley ierr = DMPlexCreateWedgeBoxMesh_Internal(*dm, faces ? faces : fac, lower ? lower : low, upper ? upper : upp, periodicity ? periodicity : bdt);CHKERRQ(ierr); 1357d410b0cfSMatthew G. Knepley if (!interpolate) { 1358d410b0cfSMatthew G. Knepley DM udm; 135900dabe28SStefano Zampini 1360d410b0cfSMatthew G. Knepley ierr = DMPlexUninterpolate(*dm, &udm);CHKERRQ(ierr); 1361d410b0cfSMatthew G. Knepley ierr = DMPlexReplace_Static(*dm, &udm);CHKERRQ(ierr); 136200dabe28SStefano Zampini } 136300dabe28SStefano Zampini PetscFunctionReturn(0); 136400dabe28SStefano Zampini } 136500dabe28SStefano Zampini 1366a9074c1eSMatthew G. Knepley /*@C 1367a9074c1eSMatthew G. Knepley DMPlexSetOptionsPrefix - Sets the prefix used for searching for all DM options in the database. 1368a9074c1eSMatthew G. Knepley 1369d083f849SBarry Smith Logically Collective on dm 1370a9074c1eSMatthew G. Knepley 1371a9074c1eSMatthew G. Knepley Input Parameters: 1372a9074c1eSMatthew G. Knepley + dm - the DM context 1373a9074c1eSMatthew G. Knepley - prefix - the prefix to prepend to all option names 1374a9074c1eSMatthew G. Knepley 1375a9074c1eSMatthew G. Knepley Notes: 1376a9074c1eSMatthew G. Knepley A hyphen (-) must NOT be given at the beginning of the prefix name. 1377a9074c1eSMatthew G. Knepley The first character of all runtime options is AUTOMATICALLY the hyphen. 1378a9074c1eSMatthew G. Knepley 1379a9074c1eSMatthew G. Knepley Level: advanced 1380a9074c1eSMatthew G. Knepley 1381a9074c1eSMatthew G. Knepley .seealso: SNESSetFromOptions() 1382a9074c1eSMatthew G. Knepley @*/ 1383a9074c1eSMatthew G. Knepley PetscErrorCode DMPlexSetOptionsPrefix(DM dm, const char prefix[]) 1384a9074c1eSMatthew G. Knepley { 1385a9074c1eSMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) dm->data; 1386a9074c1eSMatthew G. Knepley PetscErrorCode ierr; 1387a9074c1eSMatthew G. Knepley 1388a9074c1eSMatthew G. Knepley PetscFunctionBegin; 1389a9074c1eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1390a9074c1eSMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) dm, prefix);CHKERRQ(ierr); 1391a9074c1eSMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) mesh->partitioner, prefix);CHKERRQ(ierr); 1392a9074c1eSMatthew G. Knepley PetscFunctionReturn(0); 1393a9074c1eSMatthew G. Knepley } 1394a9074c1eSMatthew G. Knepley 13959318fe57SMatthew G. Knepley /* Remap geometry to cylinder 139661a622f3SMatthew G. Knepley TODO: This only works for a single refinement, then it is broken 139761a622f3SMatthew G. Knepley 13989318fe57SMatthew G. Knepley Interior square: Linear interpolation is correct 13999318fe57SMatthew G. Knepley The other cells all have vertices on rays from the origin. We want to uniformly expand the spacing 14009318fe57SMatthew G. Knepley such that the last vertex is on the unit circle. So the closest and farthest vertices are at distance 14010510c589SMatthew G. Knepley 14029318fe57SMatthew G. Knepley phi = arctan(y/x) 14039318fe57SMatthew G. Knepley d_close = sqrt(1/8 + 1/4 sin^2(phi)) 14049318fe57SMatthew G. Knepley d_far = sqrt(1/2 + sin^2(phi)) 14050510c589SMatthew G. Knepley 14069318fe57SMatthew G. Knepley so we remap them using 14070510c589SMatthew G. Knepley 14089318fe57SMatthew G. Knepley x_new = x_close + (x - x_close) (1 - d_close) / (d_far - d_close) 14099318fe57SMatthew G. Knepley y_new = y_close + (y - y_close) (1 - d_close) / (d_far - d_close) 14100510c589SMatthew G. Knepley 14119318fe57SMatthew G. Knepley If pi/4 < phi < 3pi/4 or -3pi/4 < phi < -pi/4, then we switch x and y. 14129318fe57SMatthew G. Knepley */ 14139318fe57SMatthew G. Knepley static void snapToCylinder(PetscInt dim, PetscInt Nf, PetscInt NfAux, 14149318fe57SMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 14159318fe57SMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 14169318fe57SMatthew G. Knepley PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 14179318fe57SMatthew G. Knepley { 14189318fe57SMatthew G. Knepley const PetscReal dis = 1.0/PetscSqrtReal(2.0); 14199318fe57SMatthew G. Knepley const PetscReal ds2 = 0.5*dis; 142022cc497dSMatthew G. Knepley 14219318fe57SMatthew G. Knepley if ((PetscAbsScalar(u[0]) <= ds2) && (PetscAbsScalar(u[1]) <= ds2)) { 14229318fe57SMatthew G. Knepley f0[0] = u[0]; 14239318fe57SMatthew G. Knepley f0[1] = u[1]; 14249318fe57SMatthew G. Knepley } else { 14259318fe57SMatthew G. Knepley PetscReal phi, sinp, cosp, dc, df, x, y, xc, yc; 14260510c589SMatthew G. Knepley 14279318fe57SMatthew G. Knepley x = PetscRealPart(u[0]); 14289318fe57SMatthew G. Knepley y = PetscRealPart(u[1]); 14299318fe57SMatthew G. Knepley phi = PetscAtan2Real(y, x); 14309318fe57SMatthew G. Knepley sinp = PetscSinReal(phi); 14319318fe57SMatthew G. Knepley cosp = PetscCosReal(phi); 14329318fe57SMatthew G. Knepley if ((PetscAbsReal(phi) > PETSC_PI/4.0) && (PetscAbsReal(phi) < 3.0*PETSC_PI/4.0)) { 14339318fe57SMatthew G. Knepley dc = PetscAbsReal(ds2/sinp); 14349318fe57SMatthew G. Knepley df = PetscAbsReal(dis/sinp); 14359318fe57SMatthew G. Knepley xc = ds2*x/PetscAbsReal(y); 14369318fe57SMatthew G. Knepley yc = ds2*PetscSignReal(y); 14379318fe57SMatthew G. Knepley } else { 14389318fe57SMatthew G. Knepley dc = PetscAbsReal(ds2/cosp); 14399318fe57SMatthew G. Knepley df = PetscAbsReal(dis/cosp); 14409318fe57SMatthew G. Knepley xc = ds2*PetscSignReal(x); 14419318fe57SMatthew G. Knepley yc = ds2*y/PetscAbsReal(x); 14429318fe57SMatthew G. Knepley } 14439318fe57SMatthew G. Knepley f0[0] = xc + (u[0] - xc)*(1.0 - dc)/(df - dc); 14449318fe57SMatthew G. Knepley f0[1] = yc + (u[1] - yc)*(1.0 - dc)/(df - dc); 14459318fe57SMatthew G. Knepley } 14469318fe57SMatthew G. Knepley f0[2] = u[2]; 14479318fe57SMatthew G. Knepley } 14480510c589SMatthew G. Knepley 14499318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateHexCylinderMesh_Internal(DM dm, DMBoundaryType periodicZ) 14500510c589SMatthew G. Knepley { 14510510c589SMatthew G. Knepley const PetscInt dim = 3; 14529318fe57SMatthew G. Knepley PetscInt numCells, numVertices; 1453d8c47e87SMatthew G. Knepley PetscMPIInt rank; 14540510c589SMatthew G. Knepley PetscErrorCode ierr; 14550510c589SMatthew G. Knepley 14560510c589SMatthew G. Knepley PetscFunctionBegin; 14579318fe57SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 14589318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 14590510c589SMatthew G. Knepley /* Create topology */ 14600510c589SMatthew G. Knepley { 14610510c589SMatthew G. Knepley PetscInt cone[8], c; 14620510c589SMatthew G. Knepley 1463dd400576SPatrick Sanan numCells = rank == 0 ? 5 : 0; 1464dd400576SPatrick Sanan numVertices = rank == 0 ? 16 : 0; 1465006a8963SMatthew G. Knepley if (periodicZ == DM_BOUNDARY_PERIODIC) { 1466ae8bcbbbSMatthew G. Knepley numCells *= 3; 1467dd400576SPatrick Sanan numVertices = rank == 0 ? 24 : 0; 1468006a8963SMatthew G. Knepley } 14699318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVertices);CHKERRQ(ierr); 14709318fe57SMatthew G. Knepley for (c = 0; c < numCells; c++) {ierr = DMPlexSetConeSize(dm, c, 8);CHKERRQ(ierr);} 14719318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); 1472dd400576SPatrick Sanan if (rank == 0) { 1473006a8963SMatthew G. Knepley if (periodicZ == DM_BOUNDARY_PERIODIC) { 1474ae8bcbbbSMatthew G. Knepley cone[0] = 15; cone[1] = 18; cone[2] = 17; cone[3] = 16; 1475ae8bcbbbSMatthew G. Knepley cone[4] = 31; cone[5] = 32; cone[6] = 33; cone[7] = 34; 14769318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 0, cone);CHKERRQ(ierr); 1477ae8bcbbbSMatthew G. Knepley cone[0] = 16; cone[1] = 17; cone[2] = 24; cone[3] = 23; 1478ae8bcbbbSMatthew G. Knepley cone[4] = 32; cone[5] = 36; cone[6] = 37; cone[7] = 33; /* 22 25 26 21 */ 14799318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 1, cone);CHKERRQ(ierr); 1480ae8bcbbbSMatthew G. Knepley cone[0] = 18; cone[1] = 27; cone[2] = 24; cone[3] = 17; 1481ae8bcbbbSMatthew G. Knepley cone[4] = 34; cone[5] = 33; cone[6] = 37; cone[7] = 38; 14829318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 2, cone);CHKERRQ(ierr); 1483ae8bcbbbSMatthew G. Knepley cone[0] = 29; cone[1] = 27; cone[2] = 18; cone[3] = 15; 1484ae8bcbbbSMatthew G. Knepley cone[4] = 35; cone[5] = 31; cone[6] = 34; cone[7] = 38; 14859318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 3, cone);CHKERRQ(ierr); 1486ae8bcbbbSMatthew G. Knepley cone[0] = 29; cone[1] = 15; cone[2] = 16; cone[3] = 23; 1487ae8bcbbbSMatthew G. Knepley cone[4] = 35; cone[5] = 36; cone[6] = 32; cone[7] = 31; 14889318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 4, cone);CHKERRQ(ierr); 1489006a8963SMatthew G. Knepley 1490ae8bcbbbSMatthew G. Knepley cone[0] = 31; cone[1] = 34; cone[2] = 33; cone[3] = 32; 1491ae8bcbbbSMatthew G. Knepley cone[4] = 19; cone[5] = 22; cone[6] = 21; cone[7] = 20; 14929318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 5, cone);CHKERRQ(ierr); 1493ae8bcbbbSMatthew G. Knepley cone[0] = 32; cone[1] = 33; cone[2] = 37; cone[3] = 36; 1494ae8bcbbbSMatthew G. Knepley cone[4] = 22; cone[5] = 25; cone[6] = 26; cone[7] = 21; 14959318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 6, cone);CHKERRQ(ierr); 1496ae8bcbbbSMatthew G. Knepley cone[0] = 34; cone[1] = 38; cone[2] = 37; cone[3] = 33; 1497ae8bcbbbSMatthew G. Knepley cone[4] = 20; cone[5] = 21; cone[6] = 26; cone[7] = 28; 14989318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 7, cone);CHKERRQ(ierr); 1499ae8bcbbbSMatthew G. Knepley cone[0] = 35; cone[1] = 38; cone[2] = 34; cone[3] = 31; 1500ae8bcbbbSMatthew G. Knepley cone[4] = 30; cone[5] = 19; cone[6] = 20; cone[7] = 28; 15019318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 8, cone);CHKERRQ(ierr); 1502ae8bcbbbSMatthew G. Knepley cone[0] = 35; cone[1] = 31; cone[2] = 32; cone[3] = 36; 1503ae8bcbbbSMatthew G. Knepley cone[4] = 30; cone[5] = 25; cone[6] = 22; cone[7] = 19; 15049318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 9, cone);CHKERRQ(ierr); 1505ae8bcbbbSMatthew G. Knepley 1506ae8bcbbbSMatthew G. Knepley cone[0] = 19; cone[1] = 20; cone[2] = 21; cone[3] = 22; 1507ae8bcbbbSMatthew G. Knepley cone[4] = 15; cone[5] = 16; cone[6] = 17; cone[7] = 18; 15089318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 10, cone);CHKERRQ(ierr); 1509ae8bcbbbSMatthew G. Knepley cone[0] = 22; cone[1] = 21; cone[2] = 26; cone[3] = 25; 1510ae8bcbbbSMatthew G. Knepley cone[4] = 16; cone[5] = 23; cone[6] = 24; cone[7] = 17; 15119318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 11, cone);CHKERRQ(ierr); 1512ae8bcbbbSMatthew G. Knepley cone[0] = 20; cone[1] = 28; cone[2] = 26; cone[3] = 21; 1513ae8bcbbbSMatthew G. Knepley cone[4] = 18; cone[5] = 17; cone[6] = 24; cone[7] = 27; 15149318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 12, cone);CHKERRQ(ierr); 1515ae8bcbbbSMatthew G. Knepley cone[0] = 30; cone[1] = 28; cone[2] = 20; cone[3] = 19; 1516ae8bcbbbSMatthew G. Knepley cone[4] = 29; cone[5] = 15; cone[6] = 18; cone[7] = 27; 15179318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 13, cone);CHKERRQ(ierr); 1518ae8bcbbbSMatthew G. Knepley cone[0] = 30; cone[1] = 19; cone[2] = 22; cone[3] = 25; 1519ae8bcbbbSMatthew G. Knepley cone[4] = 29; cone[5] = 23; cone[6] = 16; cone[7] = 15; 15209318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 14, cone);CHKERRQ(ierr); 1521006a8963SMatthew G. Knepley } else { 152210c6f908SMatthew G. Knepley cone[0] = 5; cone[1] = 8; cone[2] = 7; cone[3] = 6; 152310c6f908SMatthew G. Knepley cone[4] = 9; cone[5] = 12; cone[6] = 11; cone[7] = 10; 15249318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 0, cone);CHKERRQ(ierr); 152510c6f908SMatthew G. Knepley cone[0] = 6; cone[1] = 7; cone[2] = 14; cone[3] = 13; 152610c6f908SMatthew G. Knepley cone[4] = 12; cone[5] = 15; cone[6] = 16; cone[7] = 11; 15279318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 1, cone);CHKERRQ(ierr); 152810c6f908SMatthew G. Knepley cone[0] = 8; cone[1] = 17; cone[2] = 14; cone[3] = 7; 152910c6f908SMatthew G. Knepley cone[4] = 10; cone[5] = 11; cone[6] = 16; cone[7] = 18; 15309318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 2, cone);CHKERRQ(ierr); 153110c6f908SMatthew G. Knepley cone[0] = 19; cone[1] = 17; cone[2] = 8; cone[3] = 5; 153210c6f908SMatthew G. Knepley cone[4] = 20; cone[5] = 9; cone[6] = 10; cone[7] = 18; 15339318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 3, cone);CHKERRQ(ierr); 153410c6f908SMatthew G. Knepley cone[0] = 19; cone[1] = 5; cone[2] = 6; cone[3] = 13; 153510c6f908SMatthew G. Knepley cone[4] = 20; cone[5] = 15; cone[6] = 12; cone[7] = 9; 15369318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 4, cone);CHKERRQ(ierr); 1537006a8963SMatthew G. Knepley } 1538d8c47e87SMatthew G. Knepley } 15399318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 15409318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 15410510c589SMatthew G. Knepley } 1542dbc1dc17SMatthew G. Knepley /* Create cube geometry */ 15430510c589SMatthew G. Knepley { 15440510c589SMatthew G. Knepley Vec coordinates; 15450510c589SMatthew G. Knepley PetscSection coordSection; 15460510c589SMatthew G. Knepley PetscScalar *coords; 15470510c589SMatthew G. Knepley PetscInt coordSize, v; 15480510c589SMatthew G. Knepley const PetscReal dis = 1.0/PetscSqrtReal(2.0); 15490510c589SMatthew G. Knepley const PetscReal ds2 = dis/2.0; 15500510c589SMatthew G. Knepley 15510510c589SMatthew G. Knepley /* Build coordinates */ 15529318fe57SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 15530510c589SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 15540510c589SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, dim);CHKERRQ(ierr); 15550510c589SMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, numCells, numCells+numVertices);CHKERRQ(ierr); 15560510c589SMatthew G. Knepley for (v = numCells; v < numCells+numVertices; ++v) { 15570510c589SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, dim);CHKERRQ(ierr); 15580510c589SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, dim);CHKERRQ(ierr); 15590510c589SMatthew G. Knepley } 15600510c589SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 15610510c589SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 15620510c589SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 15630510c589SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 15640510c589SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 15650510c589SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, dim);CHKERRQ(ierr); 15660510c589SMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 15670510c589SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 1568dd400576SPatrick Sanan if (rank == 0) { 15690510c589SMatthew G. Knepley coords[0*dim+0] = -ds2; coords[0*dim+1] = -ds2; coords[0*dim+2] = 0.0; 15700510c589SMatthew G. Knepley coords[1*dim+0] = ds2; coords[1*dim+1] = -ds2; coords[1*dim+2] = 0.0; 15710510c589SMatthew G. Knepley coords[2*dim+0] = ds2; coords[2*dim+1] = ds2; coords[2*dim+2] = 0.0; 15720510c589SMatthew G. Knepley coords[3*dim+0] = -ds2; coords[3*dim+1] = ds2; coords[3*dim+2] = 0.0; 15730510c589SMatthew G. Knepley coords[4*dim+0] = -ds2; coords[4*dim+1] = -ds2; coords[4*dim+2] = 1.0; 15740510c589SMatthew G. Knepley coords[5*dim+0] = -ds2; coords[5*dim+1] = ds2; coords[5*dim+2] = 1.0; 15750510c589SMatthew G. Knepley coords[6*dim+0] = ds2; coords[6*dim+1] = ds2; coords[6*dim+2] = 1.0; 15760510c589SMatthew G. Knepley coords[7*dim+0] = ds2; coords[7*dim+1] = -ds2; coords[7*dim+2] = 1.0; 15770510c589SMatthew G. Knepley coords[ 8*dim+0] = dis; coords[ 8*dim+1] = -dis; coords[ 8*dim+2] = 0.0; 15780510c589SMatthew G. Knepley coords[ 9*dim+0] = dis; coords[ 9*dim+1] = dis; coords[ 9*dim+2] = 0.0; 15790510c589SMatthew G. Knepley coords[10*dim+0] = dis; coords[10*dim+1] = -dis; coords[10*dim+2] = 1.0; 15800510c589SMatthew G. Knepley coords[11*dim+0] = dis; coords[11*dim+1] = dis; coords[11*dim+2] = 1.0; 15810510c589SMatthew G. Knepley coords[12*dim+0] = -dis; coords[12*dim+1] = dis; coords[12*dim+2] = 0.0; 15820510c589SMatthew G. Knepley coords[13*dim+0] = -dis; coords[13*dim+1] = dis; coords[13*dim+2] = 1.0; 15830510c589SMatthew G. Knepley coords[14*dim+0] = -dis; coords[14*dim+1] = -dis; coords[14*dim+2] = 0.0; 15840510c589SMatthew G. Knepley coords[15*dim+0] = -dis; coords[15*dim+1] = -dis; coords[15*dim+2] = 1.0; 1585ae8bcbbbSMatthew G. Knepley if (periodicZ == DM_BOUNDARY_PERIODIC) { 1586ae8bcbbbSMatthew G. Knepley /* 15 31 19 */ coords[16*dim+0] = -ds2; coords[16*dim+1] = -ds2; coords[16*dim+2] = 0.5; 1587ae8bcbbbSMatthew G. Knepley /* 16 32 22 */ coords[17*dim+0] = ds2; coords[17*dim+1] = -ds2; coords[17*dim+2] = 0.5; 1588ae8bcbbbSMatthew G. Knepley /* 17 33 21 */ coords[18*dim+0] = ds2; coords[18*dim+1] = ds2; coords[18*dim+2] = 0.5; 1589ae8bcbbbSMatthew G. Knepley /* 18 34 20 */ coords[19*dim+0] = -ds2; coords[19*dim+1] = ds2; coords[19*dim+2] = 0.5; 1590ae8bcbbbSMatthew G. Knepley /* 29 35 30 */ coords[20*dim+0] = -dis; coords[20*dim+1] = -dis; coords[20*dim+2] = 0.5; 1591ae8bcbbbSMatthew G. Knepley /* 23 36 25 */ coords[21*dim+0] = dis; coords[21*dim+1] = -dis; coords[21*dim+2] = 0.5; 1592ae8bcbbbSMatthew G. Knepley /* 24 37 26 */ coords[22*dim+0] = dis; coords[22*dim+1] = dis; coords[22*dim+2] = 0.5; 1593ae8bcbbbSMatthew G. Knepley /* 27 38 28 */ coords[23*dim+0] = -dis; coords[23*dim+1] = dis; coords[23*dim+2] = 0.5; 1594ae8bcbbbSMatthew G. Knepley } 1595d8c47e87SMatthew G. Knepley } 15960510c589SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 15979318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 15980510c589SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 15990510c589SMatthew G. Knepley } 1600006a8963SMatthew G. Knepley /* Create periodicity */ 1601006a8963SMatthew G. Knepley if (periodicZ == DM_BOUNDARY_PERIODIC || periodicZ == DM_BOUNDARY_TWIST) { 1602006a8963SMatthew G. Knepley PetscReal L[3]; 1603006a8963SMatthew G. Knepley PetscReal maxCell[3]; 1604006a8963SMatthew G. Knepley DMBoundaryType bdType[3]; 1605006a8963SMatthew G. Knepley PetscReal lower[3] = {0.0, 0.0, 0.0}; 1606ae8bcbbbSMatthew G. Knepley PetscReal upper[3] = {1.0, 1.0, 1.5}; 1607ae8bcbbbSMatthew G. Knepley PetscInt i, numZCells = 3; 1608006a8963SMatthew G. Knepley 1609006a8963SMatthew G. Knepley bdType[0] = DM_BOUNDARY_NONE; 1610006a8963SMatthew G. Knepley bdType[1] = DM_BOUNDARY_NONE; 1611006a8963SMatthew G. Knepley bdType[2] = periodicZ; 1612006a8963SMatthew G. Knepley for (i = 0; i < dim; i++) { 1613006a8963SMatthew G. Knepley L[i] = upper[i] - lower[i]; 1614006a8963SMatthew G. Knepley maxCell[i] = 1.1 * (L[i] / numZCells); 1615006a8963SMatthew G. Knepley } 16169318fe57SMatthew G. Knepley ierr = DMSetPeriodicity(dm, PETSC_TRUE, maxCell, L, bdType);CHKERRQ(ierr); 1617006a8963SMatthew G. Knepley } 1618dbc1dc17SMatthew G. Knepley { 16199318fe57SMatthew G. Knepley DM cdm; 16209318fe57SMatthew G. Knepley PetscDS cds; 16219318fe57SMatthew G. Knepley PetscScalar c[2] = {1.0, 1.0}; 1622dbc1dc17SMatthew G. Knepley 16239318fe57SMatthew G. Knepley ierr = DMPlexCreateCoordinateSpace(dm, 1, snapToCylinder);CHKERRQ(ierr); 16249318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 16259318fe57SMatthew G. Knepley ierr = DMGetDS(cdm, &cds);CHKERRQ(ierr); 16269318fe57SMatthew G. Knepley ierr = PetscDSSetConstants(cds, 2, c);CHKERRQ(ierr); 1627dbc1dc17SMatthew G. Knepley } 16289318fe57SMatthew G. Knepley /* Wait for coordinate creation before doing in-place modification */ 16299318fe57SMatthew G. Knepley ierr = DMPlexInterpolateInPlace_Internal(dm);CHKERRQ(ierr); 16300510c589SMatthew G. Knepley PetscFunctionReturn(0); 16310510c589SMatthew G. Knepley } 16320510c589SMatthew G. Knepley 163324119c2aSMatthew G. Knepley /*@ 16349318fe57SMatthew G. Knepley DMPlexCreateHexCylinderMesh - Creates a mesh on the tensor product of the unit interval with the circle (cylinder) using hexahedra. 163524119c2aSMatthew G. Knepley 1636d083f849SBarry Smith Collective 163724119c2aSMatthew G. Knepley 163824119c2aSMatthew G. Knepley Input Parameters: 163924119c2aSMatthew G. Knepley + comm - The communicator for the DM object 16409318fe57SMatthew G. Knepley - periodicZ - The boundary type for the Z direction 164124119c2aSMatthew G. Knepley 164224119c2aSMatthew G. Knepley Output Parameter: 164324119c2aSMatthew G. Knepley . dm - The DM object 164424119c2aSMatthew G. Knepley 16459318fe57SMatthew G. Knepley Note: 16469318fe57SMatthew G. Knepley Here is the output numbering looking from the bottom of the cylinder: 16479318fe57SMatthew G. Knepley $ 17-----14 16489318fe57SMatthew G. Knepley $ | | 16499318fe57SMatthew G. Knepley $ | 2 | 16509318fe57SMatthew G. Knepley $ | | 16519318fe57SMatthew G. Knepley $ 17-----8-----7-----14 16529318fe57SMatthew G. Knepley $ | | | | 16539318fe57SMatthew G. Knepley $ | 3 | 0 | 1 | 16549318fe57SMatthew G. Knepley $ | | | | 16559318fe57SMatthew G. Knepley $ 19-----5-----6-----13 16569318fe57SMatthew G. Knepley $ | | 16579318fe57SMatthew G. Knepley $ | 4 | 16589318fe57SMatthew G. Knepley $ | | 16599318fe57SMatthew G. Knepley $ 19-----13 16609318fe57SMatthew G. Knepley $ 16619318fe57SMatthew G. Knepley $ and up through the top 16629318fe57SMatthew G. Knepley $ 16639318fe57SMatthew G. Knepley $ 18-----16 16649318fe57SMatthew G. Knepley $ | | 16659318fe57SMatthew G. Knepley $ | 2 | 16669318fe57SMatthew G. Knepley $ | | 16679318fe57SMatthew G. Knepley $ 18----10----11-----16 16689318fe57SMatthew G. Knepley $ | | | | 16699318fe57SMatthew G. Knepley $ | 3 | 0 | 1 | 16709318fe57SMatthew G. Knepley $ | | | | 16719318fe57SMatthew G. Knepley $ 20-----9----12-----15 16729318fe57SMatthew G. Knepley $ | | 16739318fe57SMatthew G. Knepley $ | 4 | 16749318fe57SMatthew G. Knepley $ | | 16759318fe57SMatthew G. Knepley $ 20-----15 16769318fe57SMatthew G. Knepley 167724119c2aSMatthew G. Knepley Level: beginner 167824119c2aSMatthew G. Knepley 16799318fe57SMatthew G. Knepley .seealso: DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 168024119c2aSMatthew G. Knepley @*/ 16819318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateHexCylinderMesh(MPI_Comm comm, DMBoundaryType periodicZ, DM *dm) 16829318fe57SMatthew G. Knepley { 16839318fe57SMatthew G. Knepley PetscErrorCode ierr; 16849318fe57SMatthew G. Knepley 16859318fe57SMatthew G. Knepley PetscFunctionBegin; 16869318fe57SMatthew G. Knepley PetscValidPointer(dm, 3); 16879318fe57SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 16889318fe57SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 16899318fe57SMatthew G. Knepley ierr = DMPlexCreateHexCylinderMesh_Internal(*dm, periodicZ);CHKERRQ(ierr); 16909318fe57SMatthew G. Knepley PetscFunctionReturn(0); 16919318fe57SMatthew G. Knepley } 16929318fe57SMatthew G. Knepley 16939318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateWedgeCylinderMesh_Internal(DM dm, PetscInt n, PetscBool interpolate) 169424119c2aSMatthew G. Knepley { 169524119c2aSMatthew G. Knepley const PetscInt dim = 3; 1696412e9a14SMatthew G. Knepley PetscInt numCells, numVertices, v; 16979fe9f049SMatthew G. Knepley PetscMPIInt rank; 169824119c2aSMatthew G. Knepley PetscErrorCode ierr; 169924119c2aSMatthew G. Knepley 170024119c2aSMatthew G. Knepley PetscFunctionBegin; 17012c71b3e2SJacob Faibussowitsch PetscCheckFalse(n < 0,PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Number of wedges %D cannot be negative", n); 17029318fe57SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 17039318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 1704412e9a14SMatthew G. Knepley /* Must create the celltype label here so that we do not automatically try to compute the types */ 17059318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm, "celltype");CHKERRQ(ierr); 170624119c2aSMatthew G. Knepley /* Create topology */ 170724119c2aSMatthew G. Knepley { 170824119c2aSMatthew G. Knepley PetscInt cone[6], c; 170924119c2aSMatthew G. Knepley 1710dd400576SPatrick Sanan numCells = rank == 0 ? n : 0; 1711dd400576SPatrick Sanan numVertices = rank == 0 ? 2*(n+1) : 0; 17129318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVertices);CHKERRQ(ierr); 17139318fe57SMatthew G. Knepley for (c = 0; c < numCells; c++) {ierr = DMPlexSetConeSize(dm, c, 6);CHKERRQ(ierr);} 17149318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); 171524119c2aSMatthew G. Knepley for (c = 0; c < numCells; c++) { 171624119c2aSMatthew G. Knepley cone[0] = c+n*1; cone[1] = (c+1)%n+n*1; cone[2] = 0+3*n; 171724119c2aSMatthew G. Knepley cone[3] = c+n*2; cone[4] = (c+1)%n+n*2; cone[5] = 1+3*n; 17189318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, c, cone);CHKERRQ(ierr); 17199318fe57SMatthew G. Knepley ierr = DMPlexSetCellType(dm, c, DM_POLYTOPE_TRI_PRISM_TENSOR);CHKERRQ(ierr); 172024119c2aSMatthew G. Knepley } 17219318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 17229318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 172324119c2aSMatthew G. Knepley } 1724412e9a14SMatthew G. Knepley for (v = numCells; v < numCells+numVertices; ++v) { 17259318fe57SMatthew G. Knepley ierr = DMPlexSetCellType(dm, v, DM_POLYTOPE_POINT);CHKERRQ(ierr); 172624119c2aSMatthew G. Knepley } 172724119c2aSMatthew G. Knepley /* Create cylinder geometry */ 172824119c2aSMatthew G. Knepley { 172924119c2aSMatthew G. Knepley Vec coordinates; 173024119c2aSMatthew G. Knepley PetscSection coordSection; 173124119c2aSMatthew G. Knepley PetscScalar *coords; 1732412e9a14SMatthew G. Knepley PetscInt coordSize, c; 173324119c2aSMatthew G. Knepley 173424119c2aSMatthew G. Knepley /* Build coordinates */ 17359318fe57SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 173624119c2aSMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 173724119c2aSMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, dim);CHKERRQ(ierr); 173824119c2aSMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, numCells, numCells+numVertices);CHKERRQ(ierr); 173924119c2aSMatthew G. Knepley for (v = numCells; v < numCells+numVertices; ++v) { 174024119c2aSMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, dim);CHKERRQ(ierr); 174124119c2aSMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, dim);CHKERRQ(ierr); 174224119c2aSMatthew G. Knepley } 174324119c2aSMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 174424119c2aSMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 174524119c2aSMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 174624119c2aSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 174724119c2aSMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 174824119c2aSMatthew G. Knepley ierr = VecSetBlockSize(coordinates, dim);CHKERRQ(ierr); 174924119c2aSMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 175024119c2aSMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 175124119c2aSMatthew G. Knepley for (c = 0; c < numCells; c++) { 175224119c2aSMatthew 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; 175324119c2aSMatthew 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; 175424119c2aSMatthew G. Knepley } 1755dd400576SPatrick Sanan if (rank == 0) { 175624119c2aSMatthew 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; 175724119c2aSMatthew 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; 17589fe9f049SMatthew G. Knepley } 175924119c2aSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 17609318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 176124119c2aSMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 176224119c2aSMatthew G. Knepley } 17639318fe57SMatthew G. Knepley /* Interpolate */ 17649318fe57SMatthew G. Knepley if (interpolate) {ierr = DMPlexInterpolateInPlace_Internal(dm);CHKERRQ(ierr);} 17659318fe57SMatthew G. Knepley PetscFunctionReturn(0); 17669318fe57SMatthew G. Knepley } 17679318fe57SMatthew G. Knepley 17689318fe57SMatthew G. Knepley /*@ 17699318fe57SMatthew G. Knepley DMPlexCreateWedgeCylinderMesh - Creates a mesh on the tensor product of the unit interval with the circle (cylinder) using wedges. 17709318fe57SMatthew G. Knepley 17719318fe57SMatthew G. Knepley Collective 17729318fe57SMatthew G. Knepley 17739318fe57SMatthew G. Knepley Input Parameters: 17749318fe57SMatthew G. Knepley + comm - The communicator for the DM object 17759318fe57SMatthew G. Knepley . n - The number of wedges around the origin 17769318fe57SMatthew G. Knepley - interpolate - Create edges and faces 17779318fe57SMatthew G. Knepley 17789318fe57SMatthew G. Knepley Output Parameter: 17799318fe57SMatthew G. Knepley . dm - The DM object 17809318fe57SMatthew G. Knepley 17819318fe57SMatthew G. Knepley Level: beginner 17829318fe57SMatthew G. Knepley 17839318fe57SMatthew G. Knepley .seealso: DMPlexCreateHexCylinderMesh(), DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 17849318fe57SMatthew G. Knepley @*/ 17859318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateWedgeCylinderMesh(MPI_Comm comm, PetscInt n, PetscBool interpolate, DM *dm) 17869318fe57SMatthew G. Knepley { 17879318fe57SMatthew G. Knepley PetscErrorCode ierr; 17889318fe57SMatthew G. Knepley 17899318fe57SMatthew G. Knepley PetscFunctionBegin; 17909318fe57SMatthew G. Knepley PetscValidPointer(dm, 4); 17919318fe57SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 17929318fe57SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 17939318fe57SMatthew G. Knepley ierr = DMPlexCreateWedgeCylinderMesh_Internal(*dm, n, interpolate);CHKERRQ(ierr); 179424119c2aSMatthew G. Knepley PetscFunctionReturn(0); 179524119c2aSMatthew G. Knepley } 179624119c2aSMatthew G. Knepley 17979fbee547SJacob Faibussowitsch static inline PetscReal DiffNormReal(PetscInt dim, const PetscReal x[], const PetscReal y[]) 179865a81367SMatthew G. Knepley { 179965a81367SMatthew G. Knepley PetscReal prod = 0.0; 180065a81367SMatthew G. Knepley PetscInt i; 180165a81367SMatthew G. Knepley for (i = 0; i < dim; ++i) prod += PetscSqr(x[i] - y[i]); 180265a81367SMatthew G. Knepley return PetscSqrtReal(prod); 180365a81367SMatthew G. Knepley } 18049fbee547SJacob Faibussowitsch static inline PetscReal DotReal(PetscInt dim, const PetscReal x[], const PetscReal y[]) 180565a81367SMatthew G. Knepley { 180665a81367SMatthew G. Knepley PetscReal prod = 0.0; 180765a81367SMatthew G. Knepley PetscInt i; 180865a81367SMatthew G. Knepley for (i = 0; i < dim; ++i) prod += x[i]*y[i]; 180965a81367SMatthew G. Knepley return prod; 181065a81367SMatthew G. Knepley } 181165a81367SMatthew G. Knepley 181251a74b61SMatthew G. Knepley /* The first constant is the sphere radius */ 181351a74b61SMatthew G. Knepley static void snapToSphere(PetscInt dim, PetscInt Nf, PetscInt NfAux, 181451a74b61SMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 181551a74b61SMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 181651a74b61SMatthew G. Knepley PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 181751a74b61SMatthew G. Knepley { 181851a74b61SMatthew G. Knepley PetscReal r = PetscRealPart(constants[0]); 181951a74b61SMatthew G. Knepley PetscReal norm2 = 0.0, fac; 182051a74b61SMatthew G. Knepley PetscInt n = uOff[1] - uOff[0], d; 182151a74b61SMatthew G. Knepley 182251a74b61SMatthew G. Knepley for (d = 0; d < n; ++d) norm2 += PetscSqr(PetscRealPart(u[d])); 182351a74b61SMatthew G. Knepley fac = r/PetscSqrtReal(norm2); 182451a74b61SMatthew G. Knepley for (d = 0; d < n; ++d) f0[d] = u[d]*fac; 182551a74b61SMatthew G. Knepley } 182651a74b61SMatthew G. Knepley 18279318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateSphereMesh_Internal(DM dm, PetscInt dim, PetscBool simplex, PetscReal R) 18282829fed8SMatthew G. Knepley { 182965a81367SMatthew G. Knepley const PetscInt embedDim = dim+1; 183065a81367SMatthew G. Knepley PetscSection coordSection; 183165a81367SMatthew G. Knepley Vec coordinates; 183265a81367SMatthew G. Knepley PetscScalar *coords; 183365a81367SMatthew G. Knepley PetscReal *coordsIn; 183465a81367SMatthew G. Knepley PetscInt numCells, numEdges, numVerts, firstVertex, v, firstEdge, coordSize, d, c, e; 183565a81367SMatthew G. Knepley PetscMPIInt rank; 183665a81367SMatthew G. Knepley PetscErrorCode ierr; 183765a81367SMatthew G. Knepley 183865a81367SMatthew G. Knepley PetscFunctionBegin; 18399318fe57SMatthew G. Knepley PetscValidLogicalCollectiveBool(dm, simplex, 3); 18409318fe57SMatthew G. Knepley ierr = DMSetDimension(dm, dim);CHKERRQ(ierr); 18419318fe57SMatthew G. Knepley ierr = DMSetCoordinateDim(dm, dim+1);CHKERRQ(ierr); 18429318fe57SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 184365a81367SMatthew G. Knepley switch (dim) { 184465a81367SMatthew G. Knepley case 2: 184565a81367SMatthew G. Knepley if (simplex) { 184651a74b61SMatthew G. Knepley const PetscReal radius = PetscSqrtReal(1 + PETSC_PHI*PETSC_PHI)/(1.0 + PETSC_PHI); 184751a74b61SMatthew G. Knepley const PetscReal edgeLen = 2.0/(1.0 + PETSC_PHI) * (R/radius); 184865a81367SMatthew G. Knepley const PetscInt degree = 5; 184951a74b61SMatthew G. Knepley PetscReal vertex[3] = {0.0, 1.0/(1.0 + PETSC_PHI), PETSC_PHI/(1.0 + PETSC_PHI)}; 185065a81367SMatthew G. Knepley PetscInt s[3] = {1, 1, 1}; 185165a81367SMatthew G. Knepley PetscInt cone[3]; 185265a81367SMatthew G. Knepley PetscInt *graph, p, i, j, k; 185365a81367SMatthew G. Knepley 185451a74b61SMatthew G. Knepley vertex[0] *= R/radius; vertex[1] *= R/radius; vertex[2] *= R/radius; 1855dd400576SPatrick Sanan numCells = rank == 0 ? 20 : 0; 1856dd400576SPatrick Sanan numVerts = rank == 0 ? 12 : 0; 185765a81367SMatthew G. Knepley firstVertex = numCells; 185851a74b61SMatthew G. Knepley /* Use icosahedron, which for a R-sphere has coordinates which are all cyclic permutations of 185965a81367SMatthew G. Knepley 186065a81367SMatthew G. Knepley (0, \pm 1/\phi+1, \pm \phi/\phi+1) 186165a81367SMatthew G. Knepley 186265a81367SMatthew G. Knepley where \phi^2 - \phi - 1 = 0, meaning \phi is the golden ratio \frac{1 + \sqrt{5}}{2}. The edge 186351a74b61SMatthew G. Knepley length is then given by 2/(1+\phi) = 2 * 0.38197 = 0.76393. 186465a81367SMatthew G. Knepley */ 186565a81367SMatthew G. Knepley /* Construct vertices */ 186665a81367SMatthew G. Knepley ierr = PetscCalloc1(numVerts * embedDim, &coordsIn);CHKERRQ(ierr); 1867dd400576SPatrick Sanan if (rank == 0) { 186865a81367SMatthew G. Knepley for (p = 0, i = 0; p < embedDim; ++p) { 186965a81367SMatthew G. Knepley for (s[1] = -1; s[1] < 2; s[1] += 2) { 187065a81367SMatthew G. Knepley for (s[2] = -1; s[2] < 2; s[2] += 2) { 187165a81367SMatthew G. Knepley for (d = 0; d < embedDim; ++d) coordsIn[i*embedDim+d] = s[(d+p)%embedDim]*vertex[(d+p)%embedDim]; 187265a81367SMatthew G. Knepley ++i; 187365a81367SMatthew G. Knepley } 187465a81367SMatthew G. Knepley } 187565a81367SMatthew G. Knepley } 187645da822fSValeria Barra } 187765a81367SMatthew G. Knepley /* Construct graph */ 187865a81367SMatthew G. Knepley ierr = PetscCalloc1(numVerts * numVerts, &graph);CHKERRQ(ierr); 187965a81367SMatthew G. Knepley for (i = 0; i < numVerts; ++i) { 188065a81367SMatthew G. Knepley for (j = 0, k = 0; j < numVerts; ++j) { 188165a81367SMatthew G. Knepley if (PetscAbsReal(DiffNormReal(embedDim, &coordsIn[i*embedDim], &coordsIn[j*embedDim]) - edgeLen) < PETSC_SMALL) {graph[i*numVerts+j] = 1; ++k;} 188265a81367SMatthew G. Knepley } 18832c71b3e2SJacob Faibussowitsch PetscCheckFalse(k != degree,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid icosahedron, vertex %D degree %D != %D", i, k, degree); 188465a81367SMatthew G. Knepley } 188565a81367SMatthew G. Knepley /* Build Topology */ 18869318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVerts);CHKERRQ(ierr); 188765a81367SMatthew G. Knepley for (c = 0; c < numCells; c++) { 18889318fe57SMatthew G. Knepley ierr = DMPlexSetConeSize(dm, c, embedDim);CHKERRQ(ierr); 188965a81367SMatthew G. Knepley } 18909318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 189165a81367SMatthew G. Knepley /* Cells */ 189265a81367SMatthew G. Knepley for (i = 0, c = 0; i < numVerts; ++i) { 189365a81367SMatthew G. Knepley for (j = 0; j < i; ++j) { 189465a81367SMatthew G. Knepley for (k = 0; k < j; ++k) { 189565a81367SMatthew G. Knepley if (graph[i*numVerts+j] && graph[j*numVerts+k] && graph[k*numVerts+i]) { 189665a81367SMatthew G. Knepley cone[0] = firstVertex+i; cone[1] = firstVertex+j; cone[2] = firstVertex+k; 189765a81367SMatthew G. Knepley /* Check orientation */ 189865a81367SMatthew G. Knepley { 189965a81367SMatthew 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}}}; 190065a81367SMatthew G. Knepley PetscReal normal[3]; 190165a81367SMatthew G. Knepley PetscInt e, f; 190265a81367SMatthew G. Knepley 190365a81367SMatthew G. Knepley for (d = 0; d < embedDim; ++d) { 190465a81367SMatthew G. Knepley normal[d] = 0.0; 190565a81367SMatthew G. Knepley for (e = 0; e < embedDim; ++e) { 190665a81367SMatthew G. Knepley for (f = 0; f < embedDim; ++f) { 190765a81367SMatthew G. Knepley normal[d] += epsilon[d][e][f]*(coordsIn[j*embedDim+e] - coordsIn[i*embedDim+e])*(coordsIn[k*embedDim+f] - coordsIn[i*embedDim+f]); 190865a81367SMatthew G. Knepley } 190965a81367SMatthew G. Knepley } 191065a81367SMatthew G. Knepley } 191165a81367SMatthew G. Knepley if (DotReal(embedDim, normal, &coordsIn[i*embedDim]) < 0) {PetscInt tmp = cone[1]; cone[1] = cone[2]; cone[2] = tmp;} 191265a81367SMatthew G. Knepley } 19139318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, c++, cone);CHKERRQ(ierr); 191465a81367SMatthew G. Knepley } 191565a81367SMatthew G. Knepley } 191665a81367SMatthew G. Knepley } 191765a81367SMatthew G. Knepley } 19189318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 19199318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 192065a81367SMatthew G. Knepley ierr = PetscFree(graph);CHKERRQ(ierr); 192165a81367SMatthew G. Knepley } else { 19222829fed8SMatthew G. Knepley /* 19232829fed8SMatthew G. Knepley 12-21--13 19242829fed8SMatthew G. Knepley | | 19252829fed8SMatthew G. Knepley 25 4 24 19262829fed8SMatthew G. Knepley | | 19272829fed8SMatthew G. Knepley 12-25--9-16--8-24--13 19282829fed8SMatthew G. Knepley | | | | 19292829fed8SMatthew G. Knepley 23 5 17 0 15 3 22 19302829fed8SMatthew G. Knepley | | | | 19312829fed8SMatthew G. Knepley 10-20--6-14--7-19--11 19322829fed8SMatthew G. Knepley | | 19332829fed8SMatthew G. Knepley 20 1 19 19342829fed8SMatthew G. Knepley | | 19352829fed8SMatthew G. Knepley 10-18--11 19362829fed8SMatthew G. Knepley | | 19372829fed8SMatthew G. Knepley 23 2 22 19382829fed8SMatthew G. Knepley | | 19392829fed8SMatthew G. Knepley 12-21--13 19402829fed8SMatthew G. Knepley */ 19412829fed8SMatthew G. Knepley PetscInt cone[4], ornt[4]; 19422829fed8SMatthew G. Knepley 1943dd400576SPatrick Sanan numCells = rank == 0 ? 6 : 0; 1944dd400576SPatrick Sanan numEdges = rank == 0 ? 12 : 0; 1945dd400576SPatrick Sanan numVerts = rank == 0 ? 8 : 0; 194665a81367SMatthew G. Knepley firstVertex = numCells; 194765a81367SMatthew G. Knepley firstEdge = numCells + numVerts; 19482829fed8SMatthew G. Knepley /* Build Topology */ 19499318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numEdges+numVerts);CHKERRQ(ierr); 19502829fed8SMatthew G. Knepley for (c = 0; c < numCells; c++) { 19519318fe57SMatthew G. Knepley ierr = DMPlexSetConeSize(dm, c, 4);CHKERRQ(ierr); 19522829fed8SMatthew G. Knepley } 19532829fed8SMatthew G. Knepley for (e = firstEdge; e < firstEdge+numEdges; ++e) { 19549318fe57SMatthew G. Knepley ierr = DMPlexSetConeSize(dm, e, 2);CHKERRQ(ierr); 19552829fed8SMatthew G. Knepley } 19569318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 1957dd400576SPatrick Sanan if (rank == 0) { 19582829fed8SMatthew G. Knepley /* Cell 0 */ 19592829fed8SMatthew G. Knepley cone[0] = 14; cone[1] = 15; cone[2] = 16; cone[3] = 17; 19609318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 0, cone);CHKERRQ(ierr); 19612829fed8SMatthew G. Knepley ornt[0] = 0; ornt[1] = 0; ornt[2] = 0; ornt[3] = 0; 19629318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 0, ornt);CHKERRQ(ierr); 19632829fed8SMatthew G. Knepley /* Cell 1 */ 19642829fed8SMatthew G. Knepley cone[0] = 18; cone[1] = 19; cone[2] = 14; cone[3] = 20; 19659318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 1, cone);CHKERRQ(ierr); 1966b5a892a1SMatthew G. Knepley ornt[0] = 0; ornt[1] = 0; ornt[2] = -1; ornt[3] = 0; 19679318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 1, ornt);CHKERRQ(ierr); 19682829fed8SMatthew G. Knepley /* Cell 2 */ 19692829fed8SMatthew G. Knepley cone[0] = 21; cone[1] = 22; cone[2] = 18; cone[3] = 23; 19709318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 2, cone);CHKERRQ(ierr); 1971b5a892a1SMatthew G. Knepley ornt[0] = 0; ornt[1] = 0; ornt[2] = -1; ornt[3] = 0; 19729318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 2, ornt);CHKERRQ(ierr); 19732829fed8SMatthew G. Knepley /* Cell 3 */ 19742829fed8SMatthew G. Knepley cone[0] = 19; cone[1] = 22; cone[2] = 24; cone[3] = 15; 19759318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 3, cone);CHKERRQ(ierr); 1976b5a892a1SMatthew G. Knepley ornt[0] = -1; ornt[1] = -1; ornt[2] = 0; ornt[3] = -1; 19779318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 3, ornt);CHKERRQ(ierr); 19782829fed8SMatthew G. Knepley /* Cell 4 */ 19792829fed8SMatthew G. Knepley cone[0] = 16; cone[1] = 24; cone[2] = 21; cone[3] = 25; 19809318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 4, cone);CHKERRQ(ierr); 1981b5a892a1SMatthew G. Knepley ornt[0] = -1; ornt[1] = -1; ornt[2] = -1; ornt[3] = 0; 19829318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 4, ornt);CHKERRQ(ierr); 19832829fed8SMatthew G. Knepley /* Cell 5 */ 19842829fed8SMatthew G. Knepley cone[0] = 20; cone[1] = 17; cone[2] = 25; cone[3] = 23; 19859318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 5, cone);CHKERRQ(ierr); 1986b5a892a1SMatthew G. Knepley ornt[0] = -1; ornt[1] = -1; ornt[2] = -1; ornt[3] = -1; 19879318fe57SMatthew G. Knepley ierr = DMPlexSetConeOrientation(dm, 5, ornt);CHKERRQ(ierr); 19882829fed8SMatthew G. Knepley /* Edges */ 19892829fed8SMatthew G. Knepley cone[0] = 6; cone[1] = 7; 19909318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 14, cone);CHKERRQ(ierr); 19912829fed8SMatthew G. Knepley cone[0] = 7; cone[1] = 8; 19929318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 15, cone);CHKERRQ(ierr); 19932829fed8SMatthew G. Knepley cone[0] = 8; cone[1] = 9; 19949318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 16, cone);CHKERRQ(ierr); 19952829fed8SMatthew G. Knepley cone[0] = 9; cone[1] = 6; 19969318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 17, cone);CHKERRQ(ierr); 19972829fed8SMatthew G. Knepley cone[0] = 10; cone[1] = 11; 19989318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 18, cone);CHKERRQ(ierr); 19992829fed8SMatthew G. Knepley cone[0] = 11; cone[1] = 7; 20009318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 19, cone);CHKERRQ(ierr); 20012829fed8SMatthew G. Knepley cone[0] = 6; cone[1] = 10; 20029318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 20, cone);CHKERRQ(ierr); 20032829fed8SMatthew G. Knepley cone[0] = 12; cone[1] = 13; 20049318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 21, cone);CHKERRQ(ierr); 20052829fed8SMatthew G. Knepley cone[0] = 13; cone[1] = 11; 20069318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 22, cone);CHKERRQ(ierr); 20072829fed8SMatthew G. Knepley cone[0] = 10; cone[1] = 12; 20089318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 23, cone);CHKERRQ(ierr); 20092829fed8SMatthew G. Knepley cone[0] = 13; cone[1] = 8; 20109318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 24, cone);CHKERRQ(ierr); 20112829fed8SMatthew G. Knepley cone[0] = 12; cone[1] = 9; 20129318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, 25, cone);CHKERRQ(ierr); 201345da822fSValeria Barra } 20149318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 20159318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 20162829fed8SMatthew G. Knepley /* Build coordinates */ 201765a81367SMatthew G. Knepley ierr = PetscCalloc1(numVerts * embedDim, &coordsIn);CHKERRQ(ierr); 2018dd400576SPatrick Sanan if (rank == 0) { 201951a74b61SMatthew G. Knepley coordsIn[0*embedDim+0] = -R; coordsIn[0*embedDim+1] = R; coordsIn[0*embedDim+2] = -R; 202051a74b61SMatthew G. Knepley coordsIn[1*embedDim+0] = R; coordsIn[1*embedDim+1] = R; coordsIn[1*embedDim+2] = -R; 202151a74b61SMatthew G. Knepley coordsIn[2*embedDim+0] = R; coordsIn[2*embedDim+1] = -R; coordsIn[2*embedDim+2] = -R; 202251a74b61SMatthew G. Knepley coordsIn[3*embedDim+0] = -R; coordsIn[3*embedDim+1] = -R; coordsIn[3*embedDim+2] = -R; 202351a74b61SMatthew G. Knepley coordsIn[4*embedDim+0] = -R; coordsIn[4*embedDim+1] = R; coordsIn[4*embedDim+2] = R; 202451a74b61SMatthew G. Knepley coordsIn[5*embedDim+0] = R; coordsIn[5*embedDim+1] = R; coordsIn[5*embedDim+2] = R; 202551a74b61SMatthew G. Knepley coordsIn[6*embedDim+0] = -R; coordsIn[6*embedDim+1] = -R; coordsIn[6*embedDim+2] = R; 202651a74b61SMatthew G. Knepley coordsIn[7*embedDim+0] = R; coordsIn[7*embedDim+1] = -R; coordsIn[7*embedDim+2] = R; 202765a81367SMatthew G. Knepley } 202845da822fSValeria Barra } 202965a81367SMatthew G. Knepley break; 203065a81367SMatthew G. Knepley case 3: 2031116ded15SMatthew G. Knepley if (simplex) { 2032116ded15SMatthew G. Knepley const PetscReal edgeLen = 1.0/PETSC_PHI; 203351a74b61SMatthew G. Knepley PetscReal vertexA[4] = {0.5, 0.5, 0.5, 0.5}; 203451a74b61SMatthew G. Knepley PetscReal vertexB[4] = {1.0, 0.0, 0.0, 0.0}; 203551a74b61SMatthew G. Knepley PetscReal vertexC[4] = {0.5, 0.5*PETSC_PHI, 0.5/PETSC_PHI, 0.0}; 2036116ded15SMatthew G. Knepley const PetscInt degree = 12; 2037116ded15SMatthew G. Knepley PetscInt s[4] = {1, 1, 1}; 2038116ded15SMatthew 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}, 2039116ded15SMatthew 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}}; 2040116ded15SMatthew G. Knepley PetscInt cone[4]; 2041116ded15SMatthew G. Knepley PetscInt *graph, p, i, j, k, l; 2042116ded15SMatthew G. Knepley 204351a74b61SMatthew G. Knepley vertexA[0] *= R; vertexA[1] *= R; vertexA[2] *= R; vertexA[3] *= R; 204451a74b61SMatthew G. Knepley vertexB[0] *= R; vertexB[1] *= R; vertexB[2] *= R; vertexB[3] *= R; 204551a74b61SMatthew G. Knepley vertexC[0] *= R; vertexC[1] *= R; vertexC[2] *= R; vertexC[3] *= R; 2046dd400576SPatrick Sanan numCells = rank == 0 ? 600 : 0; 2047dd400576SPatrick Sanan numVerts = rank == 0 ? 120 : 0; 2048116ded15SMatthew G. Knepley firstVertex = numCells; 2049116ded15SMatthew G. Knepley /* Use the 600-cell, which for a unit sphere has coordinates which are 2050116ded15SMatthew G. Knepley 2051116ded15SMatthew G. Knepley 1/2 (\pm 1, \pm 1, \pm 1, \pm 1) 16 2052116ded15SMatthew G. Knepley (\pm 1, 0, 0, 0) all cyclic permutations 8 2053116ded15SMatthew G. Knepley 1/2 (\pm 1, \pm phi, \pm 1/phi, 0) all even permutations 96 2054116ded15SMatthew G. Knepley 2055116ded15SMatthew G. Knepley where \phi^2 - \phi - 1 = 0, meaning \phi is the golden ratio \frac{1 + \sqrt{5}}{2}. The edge 20566333ae4fSvaleriabarra length is then given by 1/\phi = 0.61803. 2057116ded15SMatthew G. Knepley 2058116ded15SMatthew G. Knepley http://buzzard.pugetsound.edu/sage-practice/ch03s03.html 2059116ded15SMatthew G. Knepley http://mathworld.wolfram.com/600-Cell.html 2060116ded15SMatthew G. Knepley */ 2061116ded15SMatthew G. Knepley /* Construct vertices */ 2062116ded15SMatthew G. Knepley ierr = PetscCalloc1(numVerts * embedDim, &coordsIn);CHKERRQ(ierr); 2063116ded15SMatthew G. Knepley i = 0; 2064dd400576SPatrick Sanan if (rank == 0) { 2065116ded15SMatthew G. Knepley for (s[0] = -1; s[0] < 2; s[0] += 2) { 2066116ded15SMatthew G. Knepley for (s[1] = -1; s[1] < 2; s[1] += 2) { 2067116ded15SMatthew G. Knepley for (s[2] = -1; s[2] < 2; s[2] += 2) { 2068116ded15SMatthew G. Knepley for (s[3] = -1; s[3] < 2; s[3] += 2) { 2069116ded15SMatthew G. Knepley for (d = 0; d < embedDim; ++d) coordsIn[i*embedDim+d] = s[d]*vertexA[d]; 2070116ded15SMatthew G. Knepley ++i; 2071116ded15SMatthew G. Knepley } 2072116ded15SMatthew G. Knepley } 2073116ded15SMatthew G. Knepley } 2074116ded15SMatthew G. Knepley } 2075116ded15SMatthew G. Knepley for (p = 0; p < embedDim; ++p) { 2076116ded15SMatthew G. Knepley s[1] = s[2] = s[3] = 1; 2077116ded15SMatthew G. Knepley for (s[0] = -1; s[0] < 2; s[0] += 2) { 2078116ded15SMatthew G. Knepley for (d = 0; d < embedDim; ++d) coordsIn[i*embedDim+d] = s[(d+p)%embedDim]*vertexB[(d+p)%embedDim]; 2079116ded15SMatthew G. Knepley ++i; 2080116ded15SMatthew G. Knepley } 2081116ded15SMatthew G. Knepley } 2082116ded15SMatthew G. Knepley for (p = 0; p < 12; ++p) { 2083116ded15SMatthew G. Knepley s[3] = 1; 2084116ded15SMatthew G. Knepley for (s[0] = -1; s[0] < 2; s[0] += 2) { 2085116ded15SMatthew G. Knepley for (s[1] = -1; s[1] < 2; s[1] += 2) { 2086116ded15SMatthew G. Knepley for (s[2] = -1; s[2] < 2; s[2] += 2) { 2087116ded15SMatthew G. Knepley for (d = 0; d < embedDim; ++d) coordsIn[i*embedDim+d] = s[evenPerm[p][d]]*vertexC[evenPerm[p][d]]; 2088116ded15SMatthew G. Knepley ++i; 2089116ded15SMatthew G. Knepley } 2090116ded15SMatthew G. Knepley } 2091116ded15SMatthew G. Knepley } 2092116ded15SMatthew G. Knepley } 209345da822fSValeria Barra } 20942c71b3e2SJacob Faibussowitsch PetscCheckFalse(i != numVerts,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid 600-cell, vertices %D != %D", i, numVerts); 2095116ded15SMatthew G. Knepley /* Construct graph */ 2096116ded15SMatthew G. Knepley ierr = PetscCalloc1(numVerts * numVerts, &graph);CHKERRQ(ierr); 2097116ded15SMatthew G. Knepley for (i = 0; i < numVerts; ++i) { 2098116ded15SMatthew G. Knepley for (j = 0, k = 0; j < numVerts; ++j) { 2099116ded15SMatthew G. Knepley if (PetscAbsReal(DiffNormReal(embedDim, &coordsIn[i*embedDim], &coordsIn[j*embedDim]) - edgeLen) < PETSC_SMALL) {graph[i*numVerts+j] = 1; ++k;} 2100116ded15SMatthew G. Knepley } 21012c71b3e2SJacob Faibussowitsch PetscCheckFalse(k != degree,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid 600-cell, vertex %D degree %D != %D", i, k, degree); 2102116ded15SMatthew G. Knepley } 2103116ded15SMatthew G. Knepley /* Build Topology */ 21049318fe57SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVerts);CHKERRQ(ierr); 2105116ded15SMatthew G. Knepley for (c = 0; c < numCells; c++) { 21069318fe57SMatthew G. Knepley ierr = DMPlexSetConeSize(dm, c, embedDim);CHKERRQ(ierr); 2107116ded15SMatthew G. Knepley } 21089318fe57SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 2109116ded15SMatthew G. Knepley /* Cells */ 2110dd400576SPatrick Sanan if (rank == 0) { 2111116ded15SMatthew G. Knepley for (i = 0, c = 0; i < numVerts; ++i) { 2112116ded15SMatthew G. Knepley for (j = 0; j < i; ++j) { 2113116ded15SMatthew G. Knepley for (k = 0; k < j; ++k) { 2114116ded15SMatthew G. Knepley for (l = 0; l < k; ++l) { 2115116ded15SMatthew G. Knepley if (graph[i*numVerts+j] && graph[j*numVerts+k] && graph[k*numVerts+i] && 2116116ded15SMatthew G. Knepley graph[l*numVerts+i] && graph[l*numVerts+j] && graph[l*numVerts+k]) { 2117116ded15SMatthew G. Knepley cone[0] = firstVertex+i; cone[1] = firstVertex+j; cone[2] = firstVertex+k; cone[3] = firstVertex+l; 2118116ded15SMatthew G. Knepley /* Check orientation: https://ef.gy/linear-algebra:normal-vectors-in-higher-dimensional-spaces */ 2119116ded15SMatthew G. Knepley { 2120116ded15SMatthew 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}}, 2121116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 1}, { 0, 0, -1, 0}}, 2122116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 0, -1}, { 0, 0, 0, 0}, { 0, 1, 0, 0}}, 2123116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 1, 0}, { 0, -1, 0, 0}, { 0, 0, 0, 0}}}, 2124116ded15SMatthew G. Knepley 2125116ded15SMatthew G. Knepley {{{0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, -1}, { 0, 0, 1, 0}}, 2126116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}}, 2127116ded15SMatthew G. Knepley {{0, 0, 0, 1}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, {-1, 0, 0, 0}}, 2128116ded15SMatthew G. Knepley {{0, 0, -1, 0}, { 0, 0, 0, 0}, { 1, 0, 0, 0}, { 0, 0, 0, 0}}}, 2129116ded15SMatthew G. Knepley 2130116ded15SMatthew G. Knepley {{{0, 0, 0, 0}, { 0, 0, 0, 1}, { 0, 0, 0, 0}, { 0, -1, 0, 0}}, 2131116ded15SMatthew G. Knepley {{0, 0, 0, -1}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 1, 0, 0, 0}}, 2132116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}}, 2133116ded15SMatthew G. Knepley {{0, 1, 0, 0}, {-1, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}}}, 2134116ded15SMatthew G. Knepley 2135116ded15SMatthew G. Knepley {{{0, 0, 0, 0}, { 0, 0, -1, 0}, { 0, 1, 0, 0}, { 0, 0, 0, 0}}, 2136116ded15SMatthew G. Knepley {{0, 0, 1, 0}, { 0, 0, 0, 0}, {-1, 0, 0, 0}, { 0, 0, 0, 0}}, 2137116ded15SMatthew G. Knepley {{0, -1, 0, 0}, { 1, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}}, 2138116ded15SMatthew G. Knepley {{0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}}}}; 2139116ded15SMatthew G. Knepley PetscReal normal[4]; 2140116ded15SMatthew G. Knepley PetscInt e, f, g; 2141116ded15SMatthew G. Knepley 2142116ded15SMatthew G. Knepley for (d = 0; d < embedDim; ++d) { 2143116ded15SMatthew G. Knepley normal[d] = 0.0; 2144116ded15SMatthew G. Knepley for (e = 0; e < embedDim; ++e) { 2145116ded15SMatthew G. Knepley for (f = 0; f < embedDim; ++f) { 2146116ded15SMatthew G. Knepley for (g = 0; g < embedDim; ++g) { 2147116ded15SMatthew 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]); 2148116ded15SMatthew G. Knepley } 2149116ded15SMatthew G. Knepley } 2150116ded15SMatthew G. Knepley } 2151116ded15SMatthew G. Knepley } 2152116ded15SMatthew G. Knepley if (DotReal(embedDim, normal, &coordsIn[i*embedDim]) < 0) {PetscInt tmp = cone[1]; cone[1] = cone[2]; cone[2] = tmp;} 2153116ded15SMatthew G. Knepley } 21549318fe57SMatthew G. Knepley ierr = DMPlexSetCone(dm, c++, cone);CHKERRQ(ierr); 2155116ded15SMatthew G. Knepley } 2156116ded15SMatthew G. Knepley } 2157116ded15SMatthew G. Knepley } 2158116ded15SMatthew G. Knepley } 2159116ded15SMatthew G. Knepley } 216045da822fSValeria Barra } 21619318fe57SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 21629318fe57SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 2163116ded15SMatthew G. Knepley ierr = PetscFree(graph);CHKERRQ(ierr); 2164116ded15SMatthew G. Knepley break; 2165116ded15SMatthew G. Knepley } 216698921bdaSJacob Faibussowitsch default: SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Unsupported dimension for sphere: %D", dim); 216765a81367SMatthew G. Knepley } 216865a81367SMatthew G. Knepley /* Create coordinates */ 21699318fe57SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 21702829fed8SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 21712829fed8SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, embedDim);CHKERRQ(ierr); 21722829fed8SMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, firstVertex, firstVertex+numVerts);CHKERRQ(ierr); 21732829fed8SMatthew G. Knepley for (v = firstVertex; v < firstVertex+numVerts; ++v) { 21742829fed8SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, embedDim);CHKERRQ(ierr); 21752829fed8SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, embedDim);CHKERRQ(ierr); 21762829fed8SMatthew G. Knepley } 21772829fed8SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 21782829fed8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 21792829fed8SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 21802829fed8SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, embedDim);CHKERRQ(ierr); 21812829fed8SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 21822829fed8SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 21832829fed8SMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 21842829fed8SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 218565a81367SMatthew G. Knepley for (v = 0; v < numVerts; ++v) for (d = 0; d < embedDim; ++d) {coords[v*embedDim+d] = coordsIn[v*embedDim+d];} 21862829fed8SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 21879318fe57SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 21882829fed8SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 218965a81367SMatthew G. Knepley ierr = PetscFree(coordsIn);CHKERRQ(ierr); 219051a74b61SMatthew G. Knepley { 219151a74b61SMatthew G. Knepley DM cdm; 219251a74b61SMatthew G. Knepley PetscDS cds; 21939318fe57SMatthew G. Knepley PetscScalar c = R; 219451a74b61SMatthew G. Knepley 21959318fe57SMatthew G. Knepley ierr = DMPlexCreateCoordinateSpace(dm, 1, snapToSphere);CHKERRQ(ierr); 21969318fe57SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 219751a74b61SMatthew G. Knepley ierr = DMGetDS(cdm, &cds);CHKERRQ(ierr); 21989318fe57SMatthew G. Knepley ierr = PetscDSSetConstants(cds, 1, &c);CHKERRQ(ierr); 219951a74b61SMatthew G. Knepley } 22009318fe57SMatthew G. Knepley /* Wait for coordinate creation before doing in-place modification */ 22019318fe57SMatthew G. Knepley if (simplex) {ierr = DMPlexInterpolateInPlace_Internal(dm);CHKERRQ(ierr);} 22029318fe57SMatthew G. Knepley PetscFunctionReturn(0); 22039318fe57SMatthew G. Knepley } 22049318fe57SMatthew G. Knepley 22059318fe57SMatthew G. Knepley /*@ 22069318fe57SMatthew G. Knepley DMPlexCreateSphereMesh - Creates a mesh on the d-dimensional sphere, S^d. 22079318fe57SMatthew G. Knepley 22089318fe57SMatthew G. Knepley Collective 22099318fe57SMatthew G. Knepley 22109318fe57SMatthew G. Knepley Input Parameters: 22119318fe57SMatthew G. Knepley + comm - The communicator for the DM object 22129318fe57SMatthew G. Knepley . dim - The dimension 22139318fe57SMatthew G. Knepley . simplex - Use simplices, or tensor product cells 22149318fe57SMatthew G. Knepley - R - The radius 22159318fe57SMatthew G. Knepley 22169318fe57SMatthew G. Knepley Output Parameter: 22179318fe57SMatthew G. Knepley . dm - The DM object 22189318fe57SMatthew G. Knepley 22199318fe57SMatthew G. Knepley Level: beginner 22209318fe57SMatthew G. Knepley 22219318fe57SMatthew G. Knepley .seealso: DMPlexCreateBallMesh(), DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 22229318fe57SMatthew G. Knepley @*/ 22239318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateSphereMesh(MPI_Comm comm, PetscInt dim, PetscBool simplex, PetscReal R, DM *dm) 22249318fe57SMatthew G. Knepley { 22259318fe57SMatthew G. Knepley PetscErrorCode ierr; 22269318fe57SMatthew G. Knepley 22279318fe57SMatthew G. Knepley PetscFunctionBegin; 22289318fe57SMatthew G. Knepley PetscValidPointer(dm, 5); 22299318fe57SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 22309318fe57SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 22319318fe57SMatthew G. Knepley ierr = DMPlexCreateSphereMesh_Internal(*dm, dim, simplex, R);CHKERRQ(ierr); 22329318fe57SMatthew G. Knepley PetscFunctionReturn(0); 22339318fe57SMatthew G. Knepley } 22349318fe57SMatthew G. Knepley 22359318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBallMesh_Internal(DM dm, PetscInt dim, PetscReal R) 22369318fe57SMatthew G. Knepley { 22379318fe57SMatthew G. Knepley DM sdm, vol; 22389318fe57SMatthew G. Knepley DMLabel bdlabel; 22399318fe57SMatthew G. Knepley PetscErrorCode ierr; 22409318fe57SMatthew G. Knepley 22419318fe57SMatthew G. Knepley PetscFunctionBegin; 22429318fe57SMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject) dm), &sdm);CHKERRQ(ierr); 22439318fe57SMatthew G. Knepley ierr = DMSetType(sdm, DMPLEX);CHKERRQ(ierr); 22449318fe57SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) sdm, "bd_");CHKERRQ(ierr); 22459318fe57SMatthew G. Knepley ierr = DMPlexCreateSphereMesh_Internal(sdm, dim-1, PETSC_TRUE, R);CHKERRQ(ierr); 22469318fe57SMatthew G. Knepley ierr = DMSetFromOptions(sdm);CHKERRQ(ierr); 22479318fe57SMatthew G. Knepley ierr = DMViewFromOptions(sdm, NULL, "-dm_view");CHKERRQ(ierr); 22489318fe57SMatthew G. Knepley ierr = DMPlexGenerate(sdm, NULL, PETSC_TRUE, &vol);CHKERRQ(ierr); 22499318fe57SMatthew G. Knepley ierr = DMDestroy(&sdm);CHKERRQ(ierr); 22509318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &vol);CHKERRQ(ierr); 22519318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm, "marker");CHKERRQ(ierr); 22529318fe57SMatthew G. Knepley ierr = DMGetLabel(dm, "marker", &bdlabel);CHKERRQ(ierr); 22539318fe57SMatthew G. Knepley ierr = DMPlexMarkBoundaryFaces(dm, PETSC_DETERMINE, bdlabel);CHKERRQ(ierr); 22549318fe57SMatthew G. Knepley ierr = DMPlexLabelComplete(dm, bdlabel);CHKERRQ(ierr); 225551a74b61SMatthew G. Knepley PetscFunctionReturn(0); 225651a74b61SMatthew G. Knepley } 225751a74b61SMatthew G. Knepley 225851a74b61SMatthew G. Knepley /*@ 225951a74b61SMatthew G. Knepley DMPlexCreateBallMesh - Creates a simplex mesh on the d-dimensional ball, B^d. 226051a74b61SMatthew G. Knepley 226151a74b61SMatthew G. Knepley Collective 226251a74b61SMatthew G. Knepley 226351a74b61SMatthew G. Knepley Input Parameters: 226451a74b61SMatthew G. Knepley + comm - The communicator for the DM object 226551a74b61SMatthew G. Knepley . dim - The dimension 226651a74b61SMatthew G. Knepley - R - The radius 226751a74b61SMatthew G. Knepley 226851a74b61SMatthew G. Knepley Output Parameter: 226951a74b61SMatthew G. Knepley . dm - The DM object 227051a74b61SMatthew G. Knepley 227151a74b61SMatthew G. Knepley Options Database Keys: 227251a74b61SMatthew G. Knepley - bd_dm_refine - This will refine the surface mesh preserving the sphere geometry 227351a74b61SMatthew G. Knepley 227451a74b61SMatthew G. Knepley Level: beginner 227551a74b61SMatthew G. Knepley 227651a74b61SMatthew G. Knepley .seealso: DMPlexCreateSphereMesh(), DMPlexCreateBoxMesh(), DMSetType(), DMCreate() 227751a74b61SMatthew G. Knepley @*/ 227851a74b61SMatthew G. Knepley PetscErrorCode DMPlexCreateBallMesh(MPI_Comm comm, PetscInt dim, PetscReal R, DM *dm) 227951a74b61SMatthew G. Knepley { 228051a74b61SMatthew G. Knepley PetscErrorCode ierr; 228151a74b61SMatthew G. Knepley 228251a74b61SMatthew G. Knepley PetscFunctionBegin; 22839318fe57SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 22849318fe57SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 22859318fe57SMatthew G. Knepley ierr = DMPlexCreateBallMesh_Internal(*dm, dim, R);CHKERRQ(ierr); 22862829fed8SMatthew G. Knepley PetscFunctionReturn(0); 22872829fed8SMatthew G. Knepley } 22882829fed8SMatthew G. Knepley 22899318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateReferenceCell_Internal(DM rdm, DMPolytopeType ct) 22900a6ba040SMatthew G. Knepley { 22910a6ba040SMatthew G. Knepley PetscErrorCode ierr; 22920a6ba040SMatthew G. Knepley 22930a6ba040SMatthew G. Knepley PetscFunctionBegin; 22949318fe57SMatthew G. Knepley switch (ct) { 22959318fe57SMatthew G. Knepley case DM_POLYTOPE_POINT: 22969318fe57SMatthew G. Knepley { 22979318fe57SMatthew G. Knepley PetscInt numPoints[1] = {1}; 22989318fe57SMatthew G. Knepley PetscInt coneSize[1] = {0}; 22999318fe57SMatthew G. Knepley PetscInt cones[1] = {0}; 23009318fe57SMatthew G. Knepley PetscInt coneOrientations[1] = {0}; 23019318fe57SMatthew G. Knepley PetscScalar vertexCoords[1] = {0.0}; 23029318fe57SMatthew G. Knepley 23039318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 0);CHKERRQ(ierr); 23049318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 0, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 23059318fe57SMatthew G. Knepley } 23069318fe57SMatthew G. Knepley break; 23079318fe57SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 23089318fe57SMatthew G. Knepley { 23099318fe57SMatthew G. Knepley PetscInt numPoints[2] = {2, 1}; 23109318fe57SMatthew G. Knepley PetscInt coneSize[3] = {2, 0, 0}; 23119318fe57SMatthew G. Knepley PetscInt cones[2] = {1, 2}; 23129318fe57SMatthew G. Knepley PetscInt coneOrientations[2] = {0, 0}; 23139318fe57SMatthew G. Knepley PetscScalar vertexCoords[2] = {-1.0, 1.0}; 23149318fe57SMatthew G. Knepley 23159318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 1);CHKERRQ(ierr); 23169318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 23179318fe57SMatthew G. Knepley } 23189318fe57SMatthew G. Knepley break; 2319b5a892a1SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 2320b5a892a1SMatthew G. Knepley { 2321b5a892a1SMatthew G. Knepley PetscInt numPoints[2] = {2, 1}; 2322b5a892a1SMatthew G. Knepley PetscInt coneSize[3] = {2, 0, 0}; 2323b5a892a1SMatthew G. Knepley PetscInt cones[2] = {1, 2}; 2324b5a892a1SMatthew G. Knepley PetscInt coneOrientations[2] = {0, 0}; 2325b5a892a1SMatthew G. Knepley PetscScalar vertexCoords[2] = {-1.0, 1.0}; 2326b5a892a1SMatthew G. Knepley 2327b5a892a1SMatthew G. Knepley ierr = DMSetDimension(rdm, 1);CHKERRQ(ierr); 2328b5a892a1SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 2329b5a892a1SMatthew G. Knepley } 2330b5a892a1SMatthew G. Knepley break; 23319318fe57SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 23329318fe57SMatthew G. Knepley { 23339318fe57SMatthew G. Knepley PetscInt numPoints[2] = {3, 1}; 23349318fe57SMatthew G. Knepley PetscInt coneSize[4] = {3, 0, 0, 0}; 23359318fe57SMatthew G. Knepley PetscInt cones[3] = {1, 2, 3}; 23369318fe57SMatthew G. Knepley PetscInt coneOrientations[3] = {0, 0, 0}; 23379318fe57SMatthew G. Knepley PetscScalar vertexCoords[6] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0}; 23389318fe57SMatthew G. Knepley 23399318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 2);CHKERRQ(ierr); 23409318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 23419318fe57SMatthew G. Knepley } 23429318fe57SMatthew G. Knepley break; 23439318fe57SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 23449318fe57SMatthew G. Knepley { 23459318fe57SMatthew G. Knepley PetscInt numPoints[2] = {4, 1}; 23469318fe57SMatthew G. Knepley PetscInt coneSize[5] = {4, 0, 0, 0, 0}; 23479318fe57SMatthew G. Knepley PetscInt cones[4] = {1, 2, 3, 4}; 23489318fe57SMatthew G. Knepley PetscInt coneOrientations[4] = {0, 0, 0, 0}; 23499318fe57SMatthew G. Knepley PetscScalar vertexCoords[8] = {-1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0}; 23509318fe57SMatthew G. Knepley 23519318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 2);CHKERRQ(ierr); 23529318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 23539318fe57SMatthew G. Knepley } 23549318fe57SMatthew G. Knepley break; 23559318fe57SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 23569318fe57SMatthew G. Knepley { 23579318fe57SMatthew G. Knepley PetscInt numPoints[2] = {4, 1}; 23589318fe57SMatthew G. Knepley PetscInt coneSize[5] = {4, 0, 0, 0, 0}; 23599318fe57SMatthew G. Knepley PetscInt cones[4] = {1, 2, 3, 4}; 23609318fe57SMatthew G. Knepley PetscInt coneOrientations[4] = {0, 0, 0, 0}; 23619318fe57SMatthew G. Knepley PetscScalar vertexCoords[8] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0}; 23629318fe57SMatthew G. Knepley 23639318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 2);CHKERRQ(ierr); 23649318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 23659318fe57SMatthew G. Knepley } 23669318fe57SMatthew G. Knepley break; 23679318fe57SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 23689318fe57SMatthew G. Knepley { 23699318fe57SMatthew G. Knepley PetscInt numPoints[2] = {4, 1}; 23709318fe57SMatthew G. Knepley PetscInt coneSize[5] = {4, 0, 0, 0, 0}; 2371f0edb160SMatthew G. Knepley PetscInt cones[4] = {1, 2, 3, 4}; 23729318fe57SMatthew G. Knepley PetscInt coneOrientations[4] = {0, 0, 0, 0}; 2373f0edb160SMatthew 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}; 23749318fe57SMatthew G. Knepley 23759318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 23769318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 23779318fe57SMatthew G. Knepley } 23789318fe57SMatthew G. Knepley break; 23799318fe57SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 23809318fe57SMatthew G. Knepley { 23819318fe57SMatthew G. Knepley PetscInt numPoints[2] = {8, 1}; 23829318fe57SMatthew G. Knepley PetscInt coneSize[9] = {8, 0, 0, 0, 0, 0, 0, 0, 0}; 2383f0edb160SMatthew G. Knepley PetscInt cones[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 23849318fe57SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 2385f0edb160SMatthew 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, 23869318fe57SMatthew 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}; 23879318fe57SMatthew G. Knepley 23889318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 23899318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 23909318fe57SMatthew G. Knepley } 23919318fe57SMatthew G. Knepley break; 23929318fe57SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 23939318fe57SMatthew G. Knepley { 23949318fe57SMatthew G. Knepley PetscInt numPoints[2] = {6, 1}; 23959318fe57SMatthew G. Knepley PetscInt coneSize[7] = {6, 0, 0, 0, 0, 0, 0}; 2396f0edb160SMatthew G. Knepley PetscInt cones[6] = {1, 2, 3, 4, 5, 6}; 23979318fe57SMatthew G. Knepley PetscInt coneOrientations[6] = {0, 0, 0, 0, 0, 0}; 2398f0edb160SMatthew G. Knepley PetscScalar vertexCoords[18] = {-1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 23999318fe57SMatthew G. Knepley -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0}; 24009318fe57SMatthew G. Knepley 24019318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 24029318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 24039318fe57SMatthew G. Knepley } 24049318fe57SMatthew G. Knepley break; 24059318fe57SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 24069318fe57SMatthew G. Knepley { 24079318fe57SMatthew G. Knepley PetscInt numPoints[2] = {6, 1}; 24089318fe57SMatthew G. Knepley PetscInt coneSize[7] = {6, 0, 0, 0, 0, 0, 0}; 24099318fe57SMatthew G. Knepley PetscInt cones[6] = {1, 2, 3, 4, 5, 6}; 24109318fe57SMatthew G. Knepley PetscInt coneOrientations[6] = {0, 0, 0, 0, 0, 0}; 24119318fe57SMatthew G. Knepley PetscScalar vertexCoords[18] = {-1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 24129318fe57SMatthew G. Knepley -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0}; 24139318fe57SMatthew G. Knepley 24149318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 24159318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 24169318fe57SMatthew G. Knepley } 24179318fe57SMatthew G. Knepley break; 24189318fe57SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 24199318fe57SMatthew G. Knepley { 24209318fe57SMatthew G. Knepley PetscInt numPoints[2] = {8, 1}; 24219318fe57SMatthew G. Knepley PetscInt coneSize[9] = {8, 0, 0, 0, 0, 0, 0, 0, 0}; 24229318fe57SMatthew G. Knepley PetscInt cones[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 24239318fe57SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 24249318fe57SMatthew 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, 24259318fe57SMatthew 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}; 24269318fe57SMatthew G. Knepley 24279318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 24289318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 24299318fe57SMatthew G. Knepley } 24309318fe57SMatthew G. Knepley break; 24319318fe57SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 24329318fe57SMatthew G. Knepley { 24339318fe57SMatthew G. Knepley PetscInt numPoints[2] = {5, 1}; 24349318fe57SMatthew G. Knepley PetscInt coneSize[6] = {5, 0, 0, 0, 0, 0}; 2435f0edb160SMatthew G. Knepley PetscInt cones[5] = {1, 2, 3, 4, 5}; 24369318fe57SMatthew G. Knepley PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 2437f0edb160SMatthew 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, 24389318fe57SMatthew G. Knepley 0.0, 0.0, 1.0}; 24399318fe57SMatthew G. Knepley 24409318fe57SMatthew G. Knepley ierr = DMSetDimension(rdm, 3);CHKERRQ(ierr); 24419318fe57SMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 24429318fe57SMatthew G. Knepley } 24439318fe57SMatthew G. Knepley break; 244498921bdaSJacob Faibussowitsch default: SETERRQ(PetscObjectComm((PetscObject) rdm), PETSC_ERR_ARG_WRONG, "Cannot create reference cell for cell type %s", DMPolytopeTypes[ct]); 24459318fe57SMatthew G. Knepley } 24469318fe57SMatthew G. Knepley { 24479318fe57SMatthew G. Knepley PetscInt Nv, v; 24489318fe57SMatthew G. Knepley 24499318fe57SMatthew G. Knepley /* Must create the celltype label here so that we do not automatically try to compute the types */ 24509318fe57SMatthew G. Knepley ierr = DMCreateLabel(rdm, "celltype");CHKERRQ(ierr); 24519318fe57SMatthew G. Knepley ierr = DMPlexSetCellType(rdm, 0, ct);CHKERRQ(ierr); 24529318fe57SMatthew G. Knepley ierr = DMPlexGetChart(rdm, NULL, &Nv);CHKERRQ(ierr); 24539318fe57SMatthew G. Knepley for (v = 1; v < Nv; ++v) {ierr = DMPlexSetCellType(rdm, v, DM_POLYTOPE_POINT);CHKERRQ(ierr);} 24549318fe57SMatthew G. Knepley } 24559318fe57SMatthew G. Knepley ierr = DMPlexInterpolateInPlace_Internal(rdm);CHKERRQ(ierr); 2456b7f6ffafSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) rdm, DMPolytopeTypes[ct]);CHKERRQ(ierr); 24570a6ba040SMatthew G. Knepley PetscFunctionReturn(0); 24580a6ba040SMatthew G. Knepley } 24590a6ba040SMatthew G. Knepley 24609318fe57SMatthew G. Knepley /*@ 24619318fe57SMatthew G. Knepley DMPlexCreateReferenceCell - Create a DMPLEX with the appropriate FEM reference cell 24629318fe57SMatthew G. Knepley 24639318fe57SMatthew G. Knepley Collective 24649318fe57SMatthew G. Knepley 24659318fe57SMatthew G. Knepley Input Parameters: 24669318fe57SMatthew G. Knepley + comm - The communicator 24679318fe57SMatthew G. Knepley - ct - The cell type of the reference cell 24689318fe57SMatthew G. Knepley 24699318fe57SMatthew G. Knepley Output Parameter: 24709318fe57SMatthew G. Knepley . refdm - The reference cell 24719318fe57SMatthew G. Knepley 24729318fe57SMatthew G. Knepley Level: intermediate 24739318fe57SMatthew G. Knepley 24749318fe57SMatthew G. Knepley .seealso: DMPlexCreateReferenceCell(), DMPlexCreateBoxMesh() 24759318fe57SMatthew G. Knepley @*/ 24769318fe57SMatthew G. Knepley PetscErrorCode DMPlexCreateReferenceCell(MPI_Comm comm, DMPolytopeType ct, DM *refdm) 24770a6ba040SMatthew G. Knepley { 24780a6ba040SMatthew G. Knepley PetscErrorCode ierr; 24790a6ba040SMatthew G. Knepley 24800a6ba040SMatthew G. Knepley PetscFunctionBegin; 24819318fe57SMatthew G. Knepley ierr = DMCreate(comm, refdm);CHKERRQ(ierr); 24829318fe57SMatthew G. Knepley ierr = DMSetType(*refdm, DMPLEX);CHKERRQ(ierr); 24839318fe57SMatthew G. Knepley ierr = DMPlexCreateReferenceCell_Internal(*refdm, ct);CHKERRQ(ierr); 24849318fe57SMatthew G. Knepley PetscFunctionReturn(0); 24859318fe57SMatthew G. Knepley } 248679a015ccSMatthew G. Knepley 24879318fe57SMatthew G. Knepley static PetscErrorCode DMPlexCreateBoundaryLabel_Private(DM dm, const char name[]) 24889318fe57SMatthew G. Knepley { 24899318fe57SMatthew G. Knepley DM plex; 24909318fe57SMatthew G. Knepley DMLabel label; 24919318fe57SMatthew G. Knepley PetscBool hasLabel; 24929318fe57SMatthew G. Knepley PetscErrorCode ierr; 24930a6ba040SMatthew G. Knepley 24949318fe57SMatthew G. Knepley PetscFunctionBeginUser; 24959318fe57SMatthew G. Knepley ierr = DMHasLabel(dm, name, &hasLabel);CHKERRQ(ierr); 24969318fe57SMatthew G. Knepley if (hasLabel) PetscFunctionReturn(0); 24979318fe57SMatthew G. Knepley ierr = DMCreateLabel(dm, name);CHKERRQ(ierr); 24989318fe57SMatthew G. Knepley ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 24999318fe57SMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 25009318fe57SMatthew G. Knepley ierr = DMPlexMarkBoundaryFaces(plex, 1, label);CHKERRQ(ierr); 25019318fe57SMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 25029318fe57SMatthew G. Knepley PetscFunctionReturn(0); 25039318fe57SMatthew G. Knepley } 2504acdc6f61SToby Isaac 25059318fe57SMatthew G. Knepley const char * const DMPlexShapes[] = {"box", "box_surface", "ball", "sphere", "cylinder", "unknown", "DMPlexShape", "DM_SHAPE_", NULL}; 25069318fe57SMatthew G. Knepley 250761a622f3SMatthew G. Knepley static PetscErrorCode DMPlexCreateFromOptions_Internal(PetscOptionItems *PetscOptionsObject, PetscBool *useCoordSpace, DM dm) 25089318fe57SMatthew G. Knepley { 25099318fe57SMatthew G. Knepley DMPlexShape shape = DM_SHAPE_BOX; 25109318fe57SMatthew G. Knepley DMPolytopeType cell = DM_POLYTOPE_TRIANGLE; 25119318fe57SMatthew G. Knepley PetscInt dim = 2; 25129318fe57SMatthew G. Knepley PetscBool simplex = PETSC_TRUE, interpolate = PETSC_TRUE, adjCone = PETSC_FALSE, adjClosure = PETSC_TRUE, refDomain = PETSC_FALSE; 2513cd7e8a5eSksagiyam PetscBool flg, flg2, fflg, bdfflg, nameflg; 25149318fe57SMatthew G. Knepley MPI_Comm comm; 2515ed5e4e85SVaclav Hapla char filename[PETSC_MAX_PATH_LEN] = "<unspecified>"; 2516ed5e4e85SVaclav Hapla char bdFilename[PETSC_MAX_PATH_LEN] = "<unspecified>"; 2517ed5e4e85SVaclav Hapla char plexname[PETSC_MAX_PATH_LEN] = ""; 25189318fe57SMatthew G. Knepley PetscErrorCode ierr; 25199318fe57SMatthew G. Knepley 25209318fe57SMatthew G. Knepley PetscFunctionBegin; 25219318fe57SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 25229318fe57SMatthew G. Knepley /* TODO Turn this into a registration interface */ 25239318fe57SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_filename", "File containing a mesh", "DMPlexCreateFromFile", filename, filename, sizeof(filename), &fflg);CHKERRQ(ierr); 25249318fe57SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_boundary_filename", "File containing a mesh boundary", "DMPlexCreateFromFile", bdFilename, bdFilename, sizeof(bdFilename), &bdfflg);CHKERRQ(ierr); 2525cd7e8a5eSksagiyam ierr = PetscOptionsString("-dm_plex_name", "Name of the mesh in the file", "DMPlexCreateFromFile", plexname, plexname, sizeof(plexname), &nameflg);CHKERRQ(ierr); 25269318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_cell", "Cell shape", "", DMPolytopeTypes, (PetscEnum) cell, (PetscEnum *) &cell, NULL);CHKERRQ(ierr); 25279318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_reference_cell_domain", "Use a reference cell domain", "", refDomain, &refDomain, NULL);CHKERRQ(ierr); 25289318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_shape", "Shape for built-in mesh", "", DMPlexShapes, (PetscEnum) shape, (PetscEnum *) &shape, &flg);CHKERRQ(ierr); 25299318fe57SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_plex_dim", "Topological dimension of the mesh", "DMGetDimension", dim, &dim, &flg, 0);CHKERRQ(ierr); 25302c71b3e2SJacob Faibussowitsch PetscCheckFalse((dim < 0) || (dim > 3),comm, PETSC_ERR_ARG_OUTOFRANGE, "Dimension %D should be in [1, 3]", dim); 25319318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_simplex", "Mesh cell shape", "", simplex, &simplex, &flg);CHKERRQ(ierr); 25329318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_interpolate", "Flag to create edges and faces automatically", "", interpolate, &interpolate, &flg);CHKERRQ(ierr); 25339318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_adj_cone", "Set adjacency direction", "DMSetBasicAdjacency", adjCone, &adjCone, &flg);CHKERRQ(ierr); 25349318fe57SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_adj_closure", "Set adjacency size", "DMSetBasicAdjacency", adjClosure, &adjClosure, &flg2);CHKERRQ(ierr); 25359318fe57SMatthew G. Knepley if (flg || flg2) {ierr = DMSetBasicAdjacency(dm, adjCone, adjClosure);CHKERRQ(ierr);} 25369318fe57SMatthew G. Knepley 253761a622f3SMatthew G. Knepley switch (cell) { 253861a622f3SMatthew G. Knepley case DM_POLYTOPE_POINT: 253961a622f3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 254061a622f3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 254161a622f3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 254261a622f3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 254361a622f3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 254461a622f3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 254561a622f3SMatthew G. Knepley *useCoordSpace = PETSC_TRUE;break; 254661a622f3SMatthew G. Knepley default: *useCoordSpace = PETSC_FALSE;break; 254761a622f3SMatthew G. Knepley } 254861a622f3SMatthew G. Knepley 25499318fe57SMatthew G. Knepley if (fflg) { 25509318fe57SMatthew G. Knepley DM dmnew; 25519318fe57SMatthew G. Knepley 2552cd7e8a5eSksagiyam ierr = DMPlexCreateFromFile(PetscObjectComm((PetscObject) dm), filename, plexname, interpolate, &dmnew);CHKERRQ(ierr); 2553*e600fa54SMatthew G. Knepley ierr = DMPlexCopy_Internal(dm, PETSC_FALSE, dmnew);CHKERRQ(ierr); 25549318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &dmnew);CHKERRQ(ierr); 25559318fe57SMatthew G. Knepley } else if (refDomain) { 25569318fe57SMatthew G. Knepley ierr = DMPlexCreateReferenceCell_Internal(dm, cell);CHKERRQ(ierr); 25579318fe57SMatthew G. Knepley } else if (bdfflg) { 25589318fe57SMatthew G. Knepley DM bdm, dmnew; 25599318fe57SMatthew G. Knepley 2560cd7e8a5eSksagiyam ierr = DMPlexCreateFromFile(PetscObjectComm((PetscObject) dm), bdFilename, plexname, interpolate, &bdm);CHKERRQ(ierr); 25619318fe57SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) bdm, "bd_");CHKERRQ(ierr); 25629318fe57SMatthew G. Knepley ierr = DMSetFromOptions(bdm);CHKERRQ(ierr); 25639318fe57SMatthew G. Knepley ierr = DMPlexGenerate(bdm, NULL, interpolate, &dmnew);CHKERRQ(ierr); 25649318fe57SMatthew G. Knepley ierr = DMDestroy(&bdm);CHKERRQ(ierr); 2565*e600fa54SMatthew G. Knepley ierr = DMPlexCopy_Internal(dm, PETSC_FALSE, dmnew);CHKERRQ(ierr); 25669318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &dmnew);CHKERRQ(ierr); 25679318fe57SMatthew G. Knepley } else { 25689318fe57SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) dm, DMPlexShapes[shape]);CHKERRQ(ierr); 25699318fe57SMatthew G. Knepley switch (shape) { 25709318fe57SMatthew G. Knepley case DM_SHAPE_BOX: 25719318fe57SMatthew G. Knepley { 25729318fe57SMatthew G. Knepley PetscInt faces[3] = {0, 0, 0}; 25739318fe57SMatthew G. Knepley PetscReal lower[3] = {0, 0, 0}; 25749318fe57SMatthew G. Knepley PetscReal upper[3] = {1, 1, 1}; 25759318fe57SMatthew G. Knepley DMBoundaryType bdt[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE}; 25769318fe57SMatthew G. Knepley PetscInt i, n; 25779318fe57SMatthew G. Knepley 25789318fe57SMatthew G. Knepley n = dim; 25799318fe57SMatthew G. Knepley for (i = 0; i < dim; ++i) faces[i] = (dim == 1 ? 1 : 4-dim); 25809318fe57SMatthew G. Knepley ierr = PetscOptionsIntArray("-dm_plex_box_faces", "Number of faces along each dimension", "", faces, &n, &flg);CHKERRQ(ierr); 25819318fe57SMatthew G. Knepley n = 3; 25829318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_lower", "Lower left corner of box", "", lower, &n, &flg);CHKERRQ(ierr); 25832c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && (n != dim),comm, PETSC_ERR_ARG_SIZ, "Lower box point had %D values, should have been %D", n, dim); 25849318fe57SMatthew G. Knepley n = 3; 25859318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_upper", "Upper right corner of box", "", upper, &n, &flg);CHKERRQ(ierr); 25862c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && (n != dim),comm, PETSC_ERR_ARG_SIZ, "Upper box point had %D values, should have been %D", n, dim); 25879318fe57SMatthew G. Knepley n = 3; 25889318fe57SMatthew G. Knepley ierr = PetscOptionsEnumArray("-dm_plex_box_bd", "Boundary type for each dimension", "", DMBoundaryTypes, (PetscEnum *) bdt, &n, &flg);CHKERRQ(ierr); 25892c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && (n != dim),comm, PETSC_ERR_ARG_SIZ, "Box boundary types had %D values, should have been %D", n, dim); 25909318fe57SMatthew G. Knepley switch (cell) { 259161a622f3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 2592d410b0cfSMatthew G. Knepley ierr = DMPlexCreateWedgeBoxMesh_Internal(dm, faces, lower, upper, bdt);CHKERRQ(ierr); 2593d410b0cfSMatthew G. Knepley if (!interpolate) { 2594d410b0cfSMatthew G. Knepley DM udm; 2595d410b0cfSMatthew G. Knepley 2596d410b0cfSMatthew G. Knepley ierr = DMPlexUninterpolate(dm, &udm);CHKERRQ(ierr); 2597d410b0cfSMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &udm);CHKERRQ(ierr); 2598d410b0cfSMatthew G. Knepley } 25999318fe57SMatthew G. Knepley break; 26009318fe57SMatthew G. Knepley default: 26019318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxMesh_Internal(dm, dim, simplex, faces, lower, upper, bdt, interpolate);CHKERRQ(ierr); 26029318fe57SMatthew G. Knepley break; 26039318fe57SMatthew G. Knepley } 26049318fe57SMatthew G. Knepley } 26059318fe57SMatthew G. Knepley break; 26069318fe57SMatthew G. Knepley case DM_SHAPE_BOX_SURFACE: 26079318fe57SMatthew G. Knepley { 26089318fe57SMatthew G. Knepley PetscInt faces[3] = {0, 0, 0}; 26099318fe57SMatthew G. Knepley PetscReal lower[3] = {0, 0, 0}; 26109318fe57SMatthew G. Knepley PetscReal upper[3] = {1, 1, 1}; 26119318fe57SMatthew G. Knepley PetscInt i, n; 26129318fe57SMatthew G. Knepley 26139318fe57SMatthew G. Knepley n = dim+1; 26149318fe57SMatthew G. Knepley for (i = 0; i < dim+1; ++i) faces[i] = (dim+1 == 1 ? 1 : 4-(dim+1)); 26159318fe57SMatthew G. Knepley ierr = PetscOptionsIntArray("-dm_plex_box_faces", "Number of faces along each dimension", "", faces, &n, &flg);CHKERRQ(ierr); 26169318fe57SMatthew G. Knepley n = 3; 26179318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_lower", "Lower left corner of box", "", lower, &n, &flg);CHKERRQ(ierr); 26182c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && (n != dim+1),comm, PETSC_ERR_ARG_SIZ, "Lower box point had %D values, should have been %D", n, dim+1); 26199318fe57SMatthew G. Knepley n = 3; 26209318fe57SMatthew G. Knepley ierr = PetscOptionsRealArray("-dm_plex_box_upper", "Upper right corner of box", "", upper, &n, &flg);CHKERRQ(ierr); 26212c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && (n != dim+1),comm, PETSC_ERR_ARG_SIZ, "Upper box point had %D values, should have been %D", n, dim+1); 26229318fe57SMatthew G. Knepley ierr = DMPlexCreateBoxSurfaceMesh_Internal(dm, dim+1, faces, lower, upper, interpolate);CHKERRQ(ierr); 26239318fe57SMatthew G. Knepley } 26249318fe57SMatthew G. Knepley break; 26259318fe57SMatthew G. Knepley case DM_SHAPE_SPHERE: 26269318fe57SMatthew G. Knepley { 26279318fe57SMatthew G. Knepley PetscReal R = 1.0; 26289318fe57SMatthew G. Knepley 26299318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_sphere_radius", "Radius of the sphere", "", R, &R, &flg);CHKERRQ(ierr); 26309318fe57SMatthew G. Knepley ierr = DMPlexCreateSphereMesh_Internal(dm, dim, simplex, R);CHKERRQ(ierr); 26319318fe57SMatthew G. Knepley } 26329318fe57SMatthew G. Knepley break; 26339318fe57SMatthew G. Knepley case DM_SHAPE_BALL: 26349318fe57SMatthew G. Knepley { 26359318fe57SMatthew G. Knepley PetscReal R = 1.0; 26369318fe57SMatthew G. Knepley 26379318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_ball_radius", "Radius of the ball", "", R, &R, &flg);CHKERRQ(ierr); 26389318fe57SMatthew G. Knepley ierr = DMPlexCreateBallMesh_Internal(dm, dim, R);CHKERRQ(ierr); 26399318fe57SMatthew G. Knepley } 26409318fe57SMatthew G. Knepley break; 26419318fe57SMatthew G. Knepley case DM_SHAPE_CYLINDER: 26429318fe57SMatthew G. Knepley { 26439318fe57SMatthew G. Knepley DMBoundaryType bdt = DM_BOUNDARY_NONE; 26449318fe57SMatthew G. Knepley PetscInt Nw = 6; 26459318fe57SMatthew G. Knepley 26469318fe57SMatthew G. Knepley ierr = PetscOptionsEnum("-dm_plex_cylinder_bd", "Boundary type in the z direction", "", DMBoundaryTypes, (PetscEnum) bdt, (PetscEnum *) &bdt, NULL);CHKERRQ(ierr); 264761a622f3SMatthew G. Knepley ierr = PetscOptionsInt("-dm_plex_cylinder_num_wedges", "Number of wedges around the cylinder", "", Nw, &Nw, NULL);CHKERRQ(ierr); 26489318fe57SMatthew G. Knepley switch (cell) { 264961a622f3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 26509318fe57SMatthew G. Knepley ierr = DMPlexCreateWedgeCylinderMesh_Internal(dm, Nw, interpolate);CHKERRQ(ierr); 26519318fe57SMatthew G. Knepley break; 26529318fe57SMatthew G. Knepley default: 26539318fe57SMatthew G. Knepley ierr = DMPlexCreateHexCylinderMesh_Internal(dm, bdt);CHKERRQ(ierr); 26549318fe57SMatthew G. Knepley break; 26559318fe57SMatthew G. Knepley } 26569318fe57SMatthew G. Knepley } 26579318fe57SMatthew G. Knepley break; 265898921bdaSJacob Faibussowitsch default: SETERRQ(comm, PETSC_ERR_SUP, "Domain shape %s is unsupported", DMPlexShapes[shape]); 26599318fe57SMatthew G. Knepley } 26609318fe57SMatthew G. Knepley } 26619318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr); 2662ed5e4e85SVaclav Hapla if (!((PetscObject)dm)->name && nameflg) { 2663ed5e4e85SVaclav Hapla ierr = PetscObjectSetName((PetscObject)dm, plexname);CHKERRQ(ierr); 2664ed5e4e85SVaclav Hapla } 26650a6ba040SMatthew G. Knepley PetscFunctionReturn(0); 26660a6ba040SMatthew G. Knepley } 26670a6ba040SMatthew G. Knepley 266847920aaeSMatthew G. Knepley PetscErrorCode DMSetFromOptions_NonRefinement_Plex(PetscOptionItems *PetscOptionsObject, DM dm) 26690a6ba040SMatthew G. Knepley { 26700a6ba040SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 2671c0f0dcc3SMatthew G. Knepley PetscBool flg; 26729318fe57SMatthew G. Knepley char bdLabel[PETSC_MAX_PATH_LEN]; 26730a6ba040SMatthew G. Knepley PetscErrorCode ierr; 26740a6ba040SMatthew G. Knepley 26750a6ba040SMatthew G. Knepley PetscFunctionBegin; 26760a6ba040SMatthew G. Knepley /* Handle viewing */ 26770c77aedcSMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_print_set_values", "Output all set values info", "DMPlexMatSetClosure", PETSC_FALSE, &mesh->printSetValues, NULL);CHKERRQ(ierr); 26785a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_plex_print_fem", "Debug output level all fem computations", "DMPlexSNESComputeResidualFEM", 0, &mesh->printFEM, NULL,0);CHKERRQ(ierr); 26790c77aedcSMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_print_tol", "Tolerance for FEM output", "DMPlexSNESComputeResidualFEM", mesh->printTol, &mesh->printTol, NULL);CHKERRQ(ierr); 26805a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_plex_print_l2", "Debug output level all L2 diff computations", "DMComputeL2Diff", 0, &mesh->printL2, NULL,0);CHKERRQ(ierr); 2681c0f0dcc3SMatthew G. Knepley ierr = DMMonitorSetFromOptions(dm, "-dm_plex_monitor_throughput", "Monitor the simulation throughput", "DMPlexMonitorThroughput", DMPlexMonitorThroughput, NULL, &flg);CHKERRQ(ierr); 2682c0f0dcc3SMatthew G. Knepley if (flg) {ierr = PetscLogDefaultBegin();CHKERRQ(ierr);} 26839318fe57SMatthew G. Knepley /* Labeling */ 26849318fe57SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_boundary_label", "Label to mark the mesh boundary", "", bdLabel, bdLabel, sizeof(bdLabel), &flg);CHKERRQ(ierr); 26859318fe57SMatthew G. Knepley if (flg) {ierr = DMPlexCreateBoundaryLabel_Private(dm, bdLabel);CHKERRQ(ierr);} 2686953fc75cSMatthew G. Knepley /* Point Location */ 26870c77aedcSMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_hash_location", "Use grid hashing for point location", "DMInterpolate", PETSC_FALSE, &mesh->useHashLocation, NULL);CHKERRQ(ierr); 26880848f4b5SMatthew G. Knepley /* Partitioning and distribution */ 268998ba2d7fSLawrence 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); 26902e62ab5aSMatthew G. Knepley /* Generation and remeshing */ 26910c77aedcSMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_remesh_bd", "Allow changes to the boundary on remeshing", "DMAdapt", PETSC_FALSE, &mesh->remeshBd, NULL);CHKERRQ(ierr); 2692b29cfa1cSToby Isaac /* Projection behavior */ 26935a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_plex_max_projection_height", "Maxmimum mesh point height used to project locally", "DMPlexSetMaxProjectionHeight", 0, &mesh->maxProjectionHeight, NULL,0);CHKERRQ(ierr); 269464141f95SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_regular_refinement", "Use special nested projection algorithm for regular refinement", "DMPlexSetRegularRefinement", mesh->regularRefinement, &mesh->regularRefinement, NULL);CHKERRQ(ierr); 2695f12cf164SMatthew G. Knepley /* Checking structure */ 2696f12cf164SMatthew G. Knepley { 2697e902f1eaSVaclav Hapla PetscBool flg = PETSC_FALSE, flg2 = PETSC_FALSE, all = PETSC_FALSE; 2698f12cf164SMatthew G. Knepley 2699e902f1eaSVaclav Hapla ierr = PetscOptionsBool("-dm_plex_check_all", "Perform all checks", NULL, PETSC_FALSE, &all, &flg2);CHKERRQ(ierr); 2700f12cf164SMatthew 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); 2701e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckSymmetry(dm);CHKERRQ(ierr);} 270225c50c26SVaclav 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); 2703e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckSkeleton(dm, 0);CHKERRQ(ierr);} 270425c50c26SVaclav 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); 2705e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckFaces(dm, 0);CHKERRQ(ierr);} 2706f12cf164SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_check_geometry", "Check that cells have positive volume", "DMPlexCheckGeometry", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 2707e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckGeometry(dm);CHKERRQ(ierr);} 270875ebff7aSVaclav Hapla ierr = PetscOptionsBool("-dm_plex_check_pointsf", "Check some necessary conditions for PointSF", "DMPlexCheckPointSF", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 2709e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckPointSF(dm);CHKERRQ(ierr);} 271075ebff7aSVaclav 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); 2711e902f1eaSVaclav Hapla if (all || (flg && flg2)) {ierr = DMPlexCheckInterfaceCones(dm);CHKERRQ(ierr);} 2712412e9a14SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_check_cell_shape", "Check cell shape", "DMPlexCheckCellShape", PETSC_FALSE, &flg, &flg2);CHKERRQ(ierr); 2713412e9a14SMatthew G. Knepley if (flg && flg2) {ierr = DMPlexCheckCellShape(dm, PETSC_TRUE, PETSC_DETERMINE);CHKERRQ(ierr);} 2714f12cf164SMatthew G. Knepley } 27159318fe57SMatthew G. Knepley { 27169318fe57SMatthew G. Knepley PetscReal scale = 1.0; 27174f3833eaSMatthew G. Knepley 27189318fe57SMatthew G. Knepley ierr = PetscOptionsReal("-dm_plex_scale", "Scale factor for mesh coordinates", "DMPlexScale", scale, &scale, &flg);CHKERRQ(ierr); 27199318fe57SMatthew G. Knepley if (flg) { 27209318fe57SMatthew G. Knepley Vec coordinates, coordinatesLocal; 27219318fe57SMatthew G. Knepley 27229318fe57SMatthew G. Knepley ierr = DMGetCoordinates(dm, &coordinates);CHKERRQ(ierr); 27239318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinatesLocal);CHKERRQ(ierr); 27249318fe57SMatthew G. Knepley ierr = VecScale(coordinates, scale);CHKERRQ(ierr); 27259318fe57SMatthew G. Knepley ierr = VecScale(coordinatesLocal, scale);CHKERRQ(ierr); 27269318fe57SMatthew G. Knepley } 27279318fe57SMatthew G. Knepley } 27284f3833eaSMatthew G. Knepley ierr = PetscPartitionerSetFromOptions(mesh->partitioner);CHKERRQ(ierr); 272968d4fef7SMatthew G. Knepley PetscFunctionReturn(0); 273068d4fef7SMatthew G. Knepley } 273168d4fef7SMatthew G. Knepley 273246fa42a0SMatthew G. Knepley static PetscErrorCode DMSetFromOptions_Plex(PetscOptionItems *PetscOptionsObject,DM dm) 273368d4fef7SMatthew G. Knepley { 2734bdf63967SMatthew G. Knepley PetscFunctionList ordlist; 2735bdf63967SMatthew G. Knepley char oname[256]; 2736d410b0cfSMatthew G. Knepley PetscReal volume = -1.0; 27379318fe57SMatthew G. Knepley PetscInt prerefine = 0, refine = 0, r, coarsen = 0, overlap = 0, extLayers = 0, dim; 2738*e600fa54SMatthew 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; 273968d4fef7SMatthew G. Knepley PetscErrorCode ierr; 274068d4fef7SMatthew G. Knepley 274168d4fef7SMatthew G. Knepley PetscFunctionBegin; 2742064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 27431a1499c8SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"DMPlex Options");CHKERRQ(ierr); 27449318fe57SMatthew G. Knepley /* Handle automatic creation */ 27459318fe57SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 274661a622f3SMatthew G. Knepley if (dim < 0) {ierr = DMPlexCreateFromOptions_Internal(PetscOptionsObject, &coordSpace, dm);CHKERRQ(ierr);created = PETSC_TRUE;} 2747d89e6e46SMatthew G. Knepley /* Handle interpolation before distribution */ 2748d89e6e46SMatthew G. Knepley ierr = PetscOptionsBool("-dm_plex_interpolate_pre", "Flag to interpolate mesh before distribution", "", interpolate, &interpolate, &flg);CHKERRQ(ierr); 2749d89e6e46SMatthew G. Knepley if (flg) { 2750d89e6e46SMatthew G. Knepley DMPlexInterpolatedFlag interpolated; 2751d89e6e46SMatthew G. Knepley 2752d89e6e46SMatthew G. Knepley ierr = DMPlexIsInterpolated(dm, &interpolated);CHKERRQ(ierr); 2753d89e6e46SMatthew G. Knepley if (interpolated == DMPLEX_INTERPOLATED_FULL && !interpolate) { 2754d89e6e46SMatthew G. Knepley DM udm; 2755d89e6e46SMatthew G. Knepley 2756d89e6e46SMatthew G. Knepley ierr = DMPlexUninterpolate(dm, &udm);CHKERRQ(ierr); 2757d89e6e46SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &udm);CHKERRQ(ierr); 2758d89e6e46SMatthew G. Knepley } else if (interpolated != DMPLEX_INTERPOLATED_FULL && interpolate) { 2759d89e6e46SMatthew G. Knepley DM idm; 2760d89e6e46SMatthew G. Knepley 2761d89e6e46SMatthew G. Knepley ierr = DMPlexInterpolate(dm, &idm);CHKERRQ(ierr); 2762d89e6e46SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &idm);CHKERRQ(ierr); 2763d89e6e46SMatthew G. Knepley } 2764d89e6e46SMatthew G. Knepley } 27659b44eab4SMatthew G. Knepley /* Handle DMPlex refinement before distribution */ 2766c1cad2e7SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_ignore_model", "Flag to ignore the geometry model when refining", "DMCreate", ignoreModel, &ignoreModel, &flg);CHKERRQ(ierr); 2767c1cad2e7SMatthew G. Knepley if (flg) {((DM_Plex *) dm->data)->ignoreModel = ignoreModel;} 2768250712c9SMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &uniformOrig);CHKERRQ(ierr); 27699318fe57SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_refine_pre", "The number of refinements before distribution", "DMCreate", prerefine, &prerefine, NULL,0);CHKERRQ(ierr); 277061a622f3SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_remap_pre", "Flag to control coordinate remapping", "DMCreate", remap, &remap, NULL);CHKERRQ(ierr); 2771250712c9SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_uniform_pre", "Flag for uniform refinement before distribution", "DMCreate", uniform, &uniform, &flg);CHKERRQ(ierr); 2772250712c9SMatthew G. Knepley if (flg) {ierr = DMPlexSetRefinementUniform(dm, uniform);CHKERRQ(ierr);} 2773250712c9SMatthew G. Knepley ierr = PetscOptionsReal("-dm_refine_volume_limit_pre", "The maximum cell volume after refinement before distribution", "DMCreate", volume, &volume, &flg);CHKERRQ(ierr); 27749318fe57SMatthew G. Knepley if (flg) { 27759318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, PETSC_FALSE);CHKERRQ(ierr); 27769318fe57SMatthew G. Knepley ierr = DMPlexSetRefinementLimit(dm, volume);CHKERRQ(ierr); 27779318fe57SMatthew G. Knepley prerefine = PetscMax(prerefine, 1); 27789318fe57SMatthew G. Knepley } 27799b44eab4SMatthew G. Knepley for (r = 0; r < prerefine; ++r) { 27809b44eab4SMatthew G. Knepley DM rdm; 27819b44eab4SMatthew G. Knepley PetscPointFunc coordFunc = ((DM_Plex*) dm->data)->coordFunc; 27829b44eab4SMatthew G. Knepley 27839b44eab4SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 27849b44eab4SMatthew G. Knepley ierr = DMRefine(dm, PetscObjectComm((PetscObject) dm), &rdm);CHKERRQ(ierr); 27859318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &rdm);CHKERRQ(ierr); 27869b44eab4SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 278761a622f3SMatthew G. Knepley if (coordFunc && remap) { 27889b44eab4SMatthew G. Knepley ierr = DMPlexRemapGeometry(dm, 0.0, coordFunc);CHKERRQ(ierr); 27899b44eab4SMatthew G. Knepley ((DM_Plex*) dm->data)->coordFunc = coordFunc; 27909b44eab4SMatthew G. Knepley } 27919b44eab4SMatthew G. Knepley } 2792250712c9SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(dm, uniformOrig);CHKERRQ(ierr); 27939318fe57SMatthew G. Knepley /* Handle DMPlex extrusion before distribution */ 2794d410b0cfSMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_extrude", "The number of layers to extrude", "", extLayers, &extLayers, NULL, 0);CHKERRQ(ierr); 27959318fe57SMatthew G. Knepley if (extLayers) { 27969318fe57SMatthew G. Knepley DM edm; 27979318fe57SMatthew G. Knepley 2798d410b0cfSMatthew G. Knepley ierr = DMExtrude(dm, extLayers, &edm);CHKERRQ(ierr); 27999318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &edm);CHKERRQ(ierr); 280048d16a33SMatthew G. Knepley ((DM_Plex *) dm->data)->coordFunc = NULL; 2801d410b0cfSMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 2802d410b0cfSMatthew G. Knepley extLayers = 0; 28039318fe57SMatthew G. Knepley } 2804bdf63967SMatthew G. Knepley /* Handle DMPlex reordering before distribution */ 2805bdf63967SMatthew G. Knepley ierr = MatGetOrderingList(&ordlist);CHKERRQ(ierr); 2806bdf63967SMatthew G. Knepley ierr = PetscOptionsFList("-dm_plex_reorder", "Set mesh reordering type", "DMPlexGetOrdering", ordlist, MATORDERINGNATURAL, oname, sizeof(oname), &flg);CHKERRQ(ierr); 2807bdf63967SMatthew G. Knepley if (flg) { 2808bdf63967SMatthew G. Knepley DM pdm; 2809bdf63967SMatthew G. Knepley IS perm; 2810bdf63967SMatthew G. Knepley 2811bdf63967SMatthew G. Knepley ierr = DMPlexGetOrdering(dm, oname, NULL, &perm);CHKERRQ(ierr); 2812bdf63967SMatthew G. Knepley ierr = DMPlexPermute(dm, perm, &pdm);CHKERRQ(ierr); 2813bdf63967SMatthew G. Knepley ierr = ISDestroy(&perm);CHKERRQ(ierr); 2814bdf63967SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &pdm);CHKERRQ(ierr); 2815bdf63967SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 2816bdf63967SMatthew G. Knepley } 28179b44eab4SMatthew G. Knepley /* Handle DMPlex distribution */ 2818*e600fa54SMatthew G. Knepley ierr = DMPlexDistributeGetDefault(dm, &distribute);CHKERRQ(ierr); 28199b44eab4SMatthew G. Knepley ierr = PetscOptionsBool("-dm_distribute", "Flag to redistribute a mesh among processes", "DMCreate", distribute, &distribute, NULL);CHKERRQ(ierr); 28209b44eab4SMatthew G. Knepley ierr = PetscOptionsBoundedInt("-dm_distribute_overlap", "The size of the overlap halo", "DMCreate", overlap, &overlap, NULL, 0);CHKERRQ(ierr); 28219b44eab4SMatthew G. Knepley if (distribute) { 28229b44eab4SMatthew G. Knepley DM pdm = NULL; 28239b44eab4SMatthew G. Knepley PetscPartitioner part; 28249b44eab4SMatthew G. Knepley 28259b44eab4SMatthew G. Knepley ierr = DMPlexGetPartitioner(dm, &part);CHKERRQ(ierr); 28269b44eab4SMatthew G. Knepley ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); 28279b44eab4SMatthew G. Knepley ierr = DMPlexDistribute(dm, overlap, NULL, &pdm);CHKERRQ(ierr); 28289b44eab4SMatthew G. Knepley if (pdm) { 28299318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &pdm);CHKERRQ(ierr); 28309b44eab4SMatthew G. Knepley } 28319b44eab4SMatthew G. Knepley } 28329318fe57SMatthew G. Knepley /* Create coordinate space */ 28339318fe57SMatthew G. Knepley if (created) { 283461a622f3SMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) dm->data; 28359318fe57SMatthew G. Knepley PetscInt degree = 1; 283661a622f3SMatthew G. Knepley PetscBool periodic, flg; 28379318fe57SMatthew G. Knepley 283861a622f3SMatthew G. Knepley ierr = PetscOptionsBool("-dm_coord_space", "Use an FEM space for coordinates", "", coordSpace, &coordSpace, &flg);CHKERRQ(ierr); 28399318fe57SMatthew G. Knepley ierr = PetscOptionsInt("-dm_coord_petscspace_degree", "FEM degree for coordinate space", "", degree, °ree, NULL);CHKERRQ(ierr); 284061a622f3SMatthew G. Knepley if (coordSpace) {ierr = DMPlexCreateCoordinateSpace(dm, degree, mesh->coordFunc);CHKERRQ(ierr);} 284161a622f3SMatthew G. Knepley if (flg && !coordSpace) { 284261a622f3SMatthew G. Knepley DM cdm; 284361a622f3SMatthew G. Knepley PetscDS cds; 284461a622f3SMatthew G. Knepley PetscObject obj; 284561a622f3SMatthew G. Knepley PetscClassId id; 284661a622f3SMatthew G. Knepley 284761a622f3SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 284861a622f3SMatthew G. Knepley ierr = DMGetDS(cdm, &cds);CHKERRQ(ierr); 284961a622f3SMatthew G. Knepley ierr = PetscDSGetDiscretization(cds, 0, &obj);CHKERRQ(ierr); 285061a622f3SMatthew G. Knepley ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 285161a622f3SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 285261a622f3SMatthew G. Knepley PetscContainer dummy; 285361a622f3SMatthew G. Knepley 285461a622f3SMatthew G. Knepley ierr = PetscContainerCreate(PETSC_COMM_SELF, &dummy);CHKERRQ(ierr); 285561a622f3SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) dummy, "coordinates");CHKERRQ(ierr); 285661a622f3SMatthew G. Knepley ierr = DMSetField(cdm, 0, NULL, (PetscObject) dummy);CHKERRQ(ierr); 285761a622f3SMatthew G. Knepley ierr = PetscContainerDestroy(&dummy);CHKERRQ(ierr); 285861a622f3SMatthew G. Knepley ierr = DMClearDS(cdm);CHKERRQ(ierr); 285961a622f3SMatthew G. Knepley } 286061a622f3SMatthew G. Knepley mesh->coordFunc = NULL; 286161a622f3SMatthew G. Knepley } 28629318fe57SMatthew G. Knepley ierr = DMLocalizeCoordinates(dm);CHKERRQ(ierr); 286361a622f3SMatthew G. Knepley ierr = DMGetPeriodicity(dm, &periodic, NULL, NULL, NULL);CHKERRQ(ierr); 286461a622f3SMatthew G. Knepley if (periodic) {ierr = DMSetPeriodicity(dm, PETSC_TRUE, NULL, NULL, NULL);CHKERRQ(ierr);} 28659318fe57SMatthew G. Knepley } 286668d4fef7SMatthew G. Knepley /* Handle DMPlex refinement */ 286761a622f3SMatthew G. Knepley remap = PETSC_TRUE; 28685a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_refine", "The number of uniform refinements", "DMCreate", refine, &refine, NULL,0);CHKERRQ(ierr); 286961a622f3SMatthew G. Knepley ierr = PetscOptionsBool("-dm_refine_remap", "Flag to control coordinate remapping", "DMCreate", remap, &remap, NULL);CHKERRQ(ierr); 28705a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_refine_hierarchy", "The number of uniform refinements", "DMCreate", refine, &refine, &isHierarchy,0);CHKERRQ(ierr); 2871b6a0289aSMatthew G. Knepley if (refine) {ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE);CHKERRQ(ierr);} 287268d4fef7SMatthew G. Knepley if (refine && isHierarchy) { 2873acdc6f61SToby Isaac DM *dms, coarseDM; 287468d4fef7SMatthew G. Knepley 2875acdc6f61SToby Isaac ierr = DMGetCoarseDM(dm, &coarseDM);CHKERRQ(ierr); 2876acdc6f61SToby Isaac ierr = PetscObjectReference((PetscObject)coarseDM);CHKERRQ(ierr); 287768d4fef7SMatthew G. Knepley ierr = PetscMalloc1(refine,&dms);CHKERRQ(ierr); 287868d4fef7SMatthew G. Knepley ierr = DMRefineHierarchy(dm, refine, dms);CHKERRQ(ierr); 287968d4fef7SMatthew G. Knepley /* Total hack since we do not pass in a pointer */ 288068d4fef7SMatthew G. Knepley ierr = DMPlexSwap_Static(dm, dms[refine-1]);CHKERRQ(ierr); 288168d4fef7SMatthew G. Knepley if (refine == 1) { 2882a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dm, dms[0]);CHKERRQ(ierr); 28830aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dm, PETSC_TRUE);CHKERRQ(ierr); 288468d4fef7SMatthew G. Knepley } else { 2885a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dm, dms[refine-2]);CHKERRQ(ierr); 28860aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dm, PETSC_TRUE);CHKERRQ(ierr); 2887a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dms[0], dms[refine-1]);CHKERRQ(ierr); 28880aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dms[0], PETSC_TRUE);CHKERRQ(ierr); 288968d4fef7SMatthew G. Knepley } 2890acdc6f61SToby Isaac ierr = DMSetCoarseDM(dms[refine-1], coarseDM);CHKERRQ(ierr); 2891acdc6f61SToby Isaac ierr = PetscObjectDereference((PetscObject)coarseDM);CHKERRQ(ierr); 289268d4fef7SMatthew G. Knepley /* Free DMs */ 289368d4fef7SMatthew G. Knepley for (r = 0; r < refine; ++r) { 2894547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dms[r]);CHKERRQ(ierr); 289568d4fef7SMatthew G. Knepley ierr = DMDestroy(&dms[r]);CHKERRQ(ierr); 289668d4fef7SMatthew G. Knepley } 289768d4fef7SMatthew G. Knepley ierr = PetscFree(dms);CHKERRQ(ierr); 289868d4fef7SMatthew G. Knepley } else { 289968d4fef7SMatthew G. Knepley for (r = 0; r < refine; ++r) { 29009318fe57SMatthew G. Knepley DM rdm; 290151a74b61SMatthew G. Knepley PetscPointFunc coordFunc = ((DM_Plex*) dm->data)->coordFunc; 290268d4fef7SMatthew G. Knepley 29031a1499c8SBarry Smith ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 29049318fe57SMatthew G. Knepley ierr = DMRefine(dm, PetscObjectComm((PetscObject) dm), &rdm);CHKERRQ(ierr); 290568d4fef7SMatthew G. Knepley /* Total hack since we do not pass in a pointer */ 29069318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &rdm);CHKERRQ(ierr); 2907547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 290861a622f3SMatthew G. Knepley if (coordFunc && remap) { 290951a74b61SMatthew G. Knepley ierr = DMPlexRemapGeometry(dm, 0.0, coordFunc);CHKERRQ(ierr); 291051a74b61SMatthew G. Knepley ((DM_Plex*) dm->data)->coordFunc = coordFunc; 291151a74b61SMatthew G. Knepley } 291268d4fef7SMatthew G. Knepley } 291368d4fef7SMatthew G. Knepley } 29143cf6fe12SMatthew G. Knepley /* Handle DMPlex coarsening */ 29155a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_coarsen", "Coarsen the mesh", "DMCreate", coarsen, &coarsen, NULL,0);CHKERRQ(ierr); 29165a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_coarsen_hierarchy", "The number of coarsenings", "DMCreate", coarsen, &coarsen, &isHierarchy,0);CHKERRQ(ierr); 2917b653a561SMatthew G. Knepley if (coarsen && isHierarchy) { 2918b653a561SMatthew G. Knepley DM *dms; 2919b653a561SMatthew G. Knepley 2920b653a561SMatthew G. Knepley ierr = PetscMalloc1(coarsen, &dms);CHKERRQ(ierr); 2921b653a561SMatthew G. Knepley ierr = DMCoarsenHierarchy(dm, coarsen, dms);CHKERRQ(ierr); 2922b653a561SMatthew G. Knepley /* Free DMs */ 2923b653a561SMatthew G. Knepley for (r = 0; r < coarsen; ++r) { 2924547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dms[r]);CHKERRQ(ierr); 2925b653a561SMatthew G. Knepley ierr = DMDestroy(&dms[r]);CHKERRQ(ierr); 2926b653a561SMatthew G. Knepley } 2927b653a561SMatthew G. Knepley ierr = PetscFree(dms);CHKERRQ(ierr); 2928b653a561SMatthew G. Knepley } else { 2929b653a561SMatthew G. Knepley for (r = 0; r < coarsen; ++r) { 29309318fe57SMatthew G. Knepley DM cdm; 29319318fe57SMatthew G. Knepley PetscPointFunc coordFunc = ((DM_Plex*) dm->data)->coordFunc; 29323cf6fe12SMatthew G. Knepley 29333cf6fe12SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 29349318fe57SMatthew G. Knepley ierr = DMCoarsen(dm, PetscObjectComm((PetscObject) dm), &cdm);CHKERRQ(ierr); 29353cf6fe12SMatthew G. Knepley /* Total hack since we do not pass in a pointer */ 29369318fe57SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &cdm);CHKERRQ(ierr); 2937547f7119SMatthew G. Knepley ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 29389318fe57SMatthew G. Knepley if (coordFunc) { 29399318fe57SMatthew G. Knepley ierr = DMPlexRemapGeometry(dm, 0.0, coordFunc);CHKERRQ(ierr); 29409318fe57SMatthew G. Knepley ((DM_Plex*) dm->data)->coordFunc = coordFunc; 29419318fe57SMatthew G. Knepley } 29423cf6fe12SMatthew G. Knepley } 2943b653a561SMatthew G. Knepley } 2944909dfd52SMatthew G. Knepley /* Handle ghost cells */ 2945909dfd52SMatthew 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); 2946909dfd52SMatthew G. Knepley if (ghostCells) { 2947909dfd52SMatthew G. Knepley DM gdm; 2948909dfd52SMatthew G. Knepley char lname[PETSC_MAX_PATH_LEN]; 2949909dfd52SMatthew G. Knepley 2950909dfd52SMatthew G. Knepley lname[0] = '\0'; 2951909dfd52SMatthew G. Knepley ierr = PetscOptionsString("-dm_plex_fv_ghost_cells_label", "Label name for ghost cells boundary", "DMCreate", lname, lname, sizeof(lname), &flg);CHKERRQ(ierr); 2952909dfd52SMatthew G. Knepley ierr = DMPlexConstructGhostCells(dm, flg ? lname : NULL, NULL, &gdm);CHKERRQ(ierr); 2953909dfd52SMatthew G. Knepley ierr = DMPlexReplace_Static(dm, &gdm);CHKERRQ(ierr); 2954909dfd52SMatthew G. Knepley } 29553cf6fe12SMatthew G. Knepley /* Handle */ 29561a1499c8SBarry Smith ierr = DMSetFromOptions_NonRefinement_Plex(PetscOptionsObject, dm);CHKERRQ(ierr); 29570a6ba040SMatthew G. Knepley ierr = PetscOptionsTail();CHKERRQ(ierr); 29580a6ba040SMatthew G. Knepley PetscFunctionReturn(0); 29590a6ba040SMatthew G. Knepley } 29600a6ba040SMatthew G. Knepley 2961552f7358SJed Brown static PetscErrorCode DMCreateGlobalVector_Plex(DM dm,Vec *vec) 2962552f7358SJed Brown { 2963552f7358SJed Brown PetscErrorCode ierr; 2964552f7358SJed Brown 2965552f7358SJed Brown PetscFunctionBegin; 2966552f7358SJed Brown ierr = DMCreateGlobalVector_Section_Private(dm,vec);CHKERRQ(ierr); 2967552f7358SJed Brown /* ierr = VecSetOperation(*vec, VECOP_DUPLICATE, (void(*)(void)) VecDuplicate_MPI_DM);CHKERRQ(ierr); */ 2968552f7358SJed Brown ierr = VecSetOperation(*vec, VECOP_VIEW, (void (*)(void)) VecView_Plex);CHKERRQ(ierr); 2969d930f514SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_VIEWNATIVE, (void (*)(void)) VecView_Plex_Native);CHKERRQ(ierr); 29702c40f234SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_LOAD, (void (*)(void)) VecLoad_Plex);CHKERRQ(ierr); 2971d930f514SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_LOADNATIVE, (void (*)(void)) VecLoad_Plex_Native);CHKERRQ(ierr); 2972552f7358SJed Brown PetscFunctionReturn(0); 2973552f7358SJed Brown } 2974552f7358SJed Brown 2975552f7358SJed Brown static PetscErrorCode DMCreateLocalVector_Plex(DM dm,Vec *vec) 2976552f7358SJed Brown { 2977552f7358SJed Brown PetscErrorCode ierr; 2978552f7358SJed Brown 2979552f7358SJed Brown PetscFunctionBegin; 2980552f7358SJed Brown ierr = DMCreateLocalVector_Section_Private(dm,vec);CHKERRQ(ierr); 2981552f7358SJed Brown ierr = VecSetOperation(*vec, VECOP_VIEW, (void (*)(void)) VecView_Plex_Local);CHKERRQ(ierr); 29822c40f234SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_LOAD, (void (*)(void)) VecLoad_Plex_Local);CHKERRQ(ierr); 2983552f7358SJed Brown PetscFunctionReturn(0); 2984552f7358SJed Brown } 2985552f7358SJed Brown 2986793f3fe5SMatthew G. Knepley static PetscErrorCode DMGetDimPoints_Plex(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 2987793f3fe5SMatthew G. Knepley { 2988793f3fe5SMatthew G. Knepley PetscInt depth, d; 2989793f3fe5SMatthew G. Knepley PetscErrorCode ierr; 2990793f3fe5SMatthew G. Knepley 2991793f3fe5SMatthew G. Knepley PetscFunctionBegin; 2992793f3fe5SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 2993793f3fe5SMatthew G. Knepley if (depth == 1) { 2994793f3fe5SMatthew G. Knepley ierr = DMGetDimension(dm, &d);CHKERRQ(ierr); 2995793f3fe5SMatthew G. Knepley if (dim == 0) {ierr = DMPlexGetDepthStratum(dm, dim, pStart, pEnd);CHKERRQ(ierr);} 2996793f3fe5SMatthew G. Knepley else if (dim == d) {ierr = DMPlexGetDepthStratum(dm, 1, pStart, pEnd);CHKERRQ(ierr);} 2997793f3fe5SMatthew G. Knepley else {*pStart = 0; *pEnd = 0;} 2998793f3fe5SMatthew G. Knepley } else { 2999793f3fe5SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, dim, pStart, pEnd);CHKERRQ(ierr); 3000793f3fe5SMatthew G. Knepley } 3001793f3fe5SMatthew G. Knepley PetscFunctionReturn(0); 3002793f3fe5SMatthew G. Knepley } 3003793f3fe5SMatthew G. Knepley 300428d58a37SPierre Jolivet static PetscErrorCode DMGetNeighbors_Plex(DM dm, PetscInt *nranks, const PetscMPIInt *ranks[]) 3005502a2867SDave May { 3006502a2867SDave May PetscSF sf; 30070a19bb7dSprj- PetscInt niranks, njranks, n; 30080a19bb7dSprj- const PetscMPIInt *iranks, *jranks; 30090a19bb7dSprj- DM_Plex *data = (DM_Plex*) dm->data; 30102f356facSMatthew G. Knepley PetscErrorCode ierr; 3011502a2867SDave May 30122f356facSMatthew G. Knepley PetscFunctionBegin; 3013502a2867SDave May ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 30140a19bb7dSprj- if (!data->neighbors) { 301507a779feSPierre Jolivet ierr = PetscSFSetUp(sf);CHKERRQ(ierr); 30160a19bb7dSprj- ierr = PetscSFGetRootRanks(sf, &njranks, &jranks, NULL, NULL, NULL);CHKERRQ(ierr); 30170a19bb7dSprj- ierr = PetscSFGetLeafRanks(sf, &niranks, &iranks, NULL, NULL);CHKERRQ(ierr); 30180a19bb7dSprj- ierr = PetscMalloc1(njranks + niranks + 1, &data->neighbors);CHKERRQ(ierr); 30190a19bb7dSprj- ierr = PetscArraycpy(data->neighbors + 1, jranks, njranks);CHKERRQ(ierr); 30200a19bb7dSprj- ierr = PetscArraycpy(data->neighbors + njranks + 1, iranks, niranks);CHKERRQ(ierr); 30210a19bb7dSprj- n = njranks + niranks; 30220a19bb7dSprj- ierr = PetscSortRemoveDupsMPIInt(&n, data->neighbors + 1);CHKERRQ(ierr); 30230a19bb7dSprj- /* The following cast should never fail: can't have more neighbors than PETSC_MPI_INT_MAX */ 30240a19bb7dSprj- ierr = PetscMPIIntCast(n, data->neighbors);CHKERRQ(ierr); 30250a19bb7dSprj- } 30260a19bb7dSprj- if (nranks) *nranks = data->neighbors[0]; 30270a19bb7dSprj- if (ranks) { 30280a19bb7dSprj- if (data->neighbors[0]) *ranks = data->neighbors + 1; 30290a19bb7dSprj- else *ranks = NULL; 30300a19bb7dSprj- } 3031502a2867SDave May PetscFunctionReturn(0); 3032502a2867SDave May } 3033502a2867SDave May 30341eb70e55SToby Isaac PETSC_INTERN PetscErrorCode DMInterpolateSolution_Plex(DM, DM, Mat, Vec, Vec); 30351eb70e55SToby Isaac 303646fa42a0SMatthew G. Knepley static PetscErrorCode DMInitialize_Plex(DM dm) 3037552f7358SJed Brown { 3038713918a9SToby Isaac PetscErrorCode ierr; 3039713918a9SToby Isaac 3040552f7358SJed Brown PetscFunctionBegin; 3041552f7358SJed Brown dm->ops->view = DMView_Plex; 30422c40f234SMatthew G. Knepley dm->ops->load = DMLoad_Plex; 3043552f7358SJed Brown dm->ops->setfromoptions = DMSetFromOptions_Plex; 304438221697SMatthew G. Knepley dm->ops->clone = DMClone_Plex; 3045552f7358SJed Brown dm->ops->setup = DMSetUp_Plex; 30461bb6d2a8SBarry Smith dm->ops->createlocalsection = DMCreateLocalSection_Plex; 304766ad2231SToby Isaac dm->ops->createdefaultconstraints = DMCreateDefaultConstraints_Plex; 3048552f7358SJed Brown dm->ops->createglobalvector = DMCreateGlobalVector_Plex; 3049552f7358SJed Brown dm->ops->createlocalvector = DMCreateLocalVector_Plex; 3050184d77edSJed Brown dm->ops->getlocaltoglobalmapping = NULL; 30510298fd71SBarry Smith dm->ops->createfieldis = NULL; 3052552f7358SJed Brown dm->ops->createcoordinatedm = DMCreateCoordinateDM_Plex; 3053f19dbd58SToby Isaac dm->ops->createcoordinatefield = DMCreateCoordinateField_Plex; 30540a6ba040SMatthew G. Knepley dm->ops->getcoloring = NULL; 3055552f7358SJed Brown dm->ops->creatematrix = DMCreateMatrix_Plex; 3056bceba477SMatthew G. Knepley dm->ops->createinterpolation = DMCreateInterpolation_Plex; 3057bd041c0cSMatthew G. Knepley dm->ops->createmassmatrix = DMCreateMassMatrix_Plex; 3058b4937a87SMatthew G. Knepley dm->ops->createmassmatrixlumped = DMCreateMassMatrixLumped_Plex; 30595a84ad33SLisandro Dalcin dm->ops->createinjection = DMCreateInjection_Plex; 3060552f7358SJed Brown dm->ops->refine = DMRefine_Plex; 30610a6ba040SMatthew G. Knepley dm->ops->coarsen = DMCoarsen_Plex; 30620a6ba040SMatthew G. Knepley dm->ops->refinehierarchy = DMRefineHierarchy_Plex; 3063b653a561SMatthew G. Knepley dm->ops->coarsenhierarchy = DMCoarsenHierarchy_Plex; 3064d410b0cfSMatthew G. Knepley dm->ops->extrude = DMExtrude_Plex; 30650298fd71SBarry Smith dm->ops->globaltolocalbegin = NULL; 30660298fd71SBarry Smith dm->ops->globaltolocalend = NULL; 30670298fd71SBarry Smith dm->ops->localtoglobalbegin = NULL; 30680298fd71SBarry Smith dm->ops->localtoglobalend = NULL; 3069552f7358SJed Brown dm->ops->destroy = DMDestroy_Plex; 3070552f7358SJed Brown dm->ops->createsubdm = DMCreateSubDM_Plex; 30712adcc780SMatthew G. Knepley dm->ops->createsuperdm = DMCreateSuperDM_Plex; 3072793f3fe5SMatthew G. Knepley dm->ops->getdimpoints = DMGetDimPoints_Plex; 3073552f7358SJed Brown dm->ops->locatepoints = DMLocatePoints_Plex; 30740709b2feSToby Isaac dm->ops->projectfunctionlocal = DMProjectFunctionLocal_Plex; 30750709b2feSToby Isaac dm->ops->projectfunctionlabellocal = DMProjectFunctionLabelLocal_Plex; 3076bfc4295aSToby Isaac dm->ops->projectfieldlocal = DMProjectFieldLocal_Plex; 30778c6c5593SMatthew G. Knepley dm->ops->projectfieldlabellocal = DMProjectFieldLabelLocal_Plex; 3078ece3a9fcSMatthew G. Knepley dm->ops->projectbdfieldlabellocal = DMProjectBdFieldLabelLocal_Plex; 30790709b2feSToby Isaac dm->ops->computel2diff = DMComputeL2Diff_Plex; 3080b698f381SToby Isaac dm->ops->computel2gradientdiff = DMComputeL2GradientDiff_Plex; 30812a16baeaSToby Isaac dm->ops->computel2fielddiff = DMComputeL2FieldDiff_Plex; 308228d58a37SPierre Jolivet dm->ops->getneighbors = DMGetNeighbors_Plex; 3083f1d73a7aSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexInsertBoundaryValues_C",DMPlexInsertBoundaryValues_Plex);CHKERRQ(ierr); 308456cf3b9cSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexInsertTimeDerviativeBoundaryValues_C",DMPlexInsertTimeDerivativeBoundaryValues_Plex);CHKERRQ(ierr); 30858135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMSetUpGLVisViewer_C",DMSetUpGLVisViewer_Plex);CHKERRQ(ierr); 308628d58a37SPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)dm,"DMCreateNeumannOverlap_C",DMCreateNeumannOverlap_Plex);CHKERRQ(ierr); 3087cb54e036SVaclav Hapla ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexGetOverlap_C",DMPlexGetOverlap_Plex);CHKERRQ(ierr); 3088*e600fa54SMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexDistributeGetDefault_C",DMPlexDistributeGetDefault_Plex);CHKERRQ(ierr); 3089*e600fa54SMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexDistributeSetDefault_C",DMPlexDistributeSetDefault_Plex);CHKERRQ(ierr); 30901eb70e55SToby Isaac ierr = PetscObjectComposeFunction((PetscObject)dm,"DMInterpolateSolution_C",DMInterpolateSolution_Plex);CHKERRQ(ierr); 3091552f7358SJed Brown PetscFunctionReturn(0); 3092552f7358SJed Brown } 3093552f7358SJed Brown 309446fa42a0SMatthew G. Knepley PETSC_INTERN PetscErrorCode DMClone_Plex(DM dm, DM *newdm) 309563a16f15SMatthew G. Knepley { 309663a16f15SMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) dm->data; 309763a16f15SMatthew G. Knepley PetscErrorCode ierr; 309863a16f15SMatthew G. Knepley 309963a16f15SMatthew G. Knepley PetscFunctionBegin; 310063a16f15SMatthew G. Knepley mesh->refct++; 310163a16f15SMatthew G. Knepley (*newdm)->data = mesh; 310263a16f15SMatthew G. Knepley ierr = PetscObjectChangeTypeName((PetscObject) *newdm, DMPLEX);CHKERRQ(ierr); 310363a16f15SMatthew G. Knepley ierr = DMInitialize_Plex(*newdm);CHKERRQ(ierr); 310463a16f15SMatthew G. Knepley PetscFunctionReturn(0); 310563a16f15SMatthew G. Knepley } 310663a16f15SMatthew G. Knepley 31078818961aSMatthew G Knepley /*MC 31088818961aSMatthew G Knepley DMPLEX = "plex" - A DM object that encapsulates an unstructured mesh, or CW Complex, which can be expressed using a Hasse Diagram. 31098818961aSMatthew G Knepley In the local representation, Vecs contain all unknowns in the interior and shared boundary. This is 31108818961aSMatthew G Knepley specified by a PetscSection object. Ownership in the global representation is determined by 31118818961aSMatthew G Knepley ownership of the underlying DMPlex points. This is specified by another PetscSection object. 31128818961aSMatthew G Knepley 3113e5893cccSMatthew G. Knepley Options Database Keys: 3114250712c9SMatthew G. Knepley + -dm_refine_pre - Refine mesh before distribution 3115250712c9SMatthew G. Knepley + -dm_refine_uniform_pre - Choose uniform or generator-based refinement 3116250712c9SMatthew G. Knepley + -dm_refine_volume_limit_pre - Cell volume limit after pre-refinement using generator 3117250712c9SMatthew G. Knepley . -dm_distribute - Distribute mesh across processes 3118250712c9SMatthew G. Knepley . -dm_distribute_overlap - Number of cells to overlap for distribution 3119250712c9SMatthew G. Knepley . -dm_refine - Refine mesh after distribution 3120250712c9SMatthew G. Knepley . -dm_plex_hash_location - Use grid hashing for point location 3121ddce0771SMatthew G. Knepley . -dm_plex_hash_box_faces <n,m,p> - The number of divisions in each direction of the grid hash 3122f12cf164SMatthew G. Knepley . -dm_plex_partition_balance - Attempt to evenly divide points on partition boundary between processes 3123f12cf164SMatthew G. Knepley . -dm_plex_remesh_bd - Allow changes to the boundary on remeshing 3124f12cf164SMatthew G. Knepley . -dm_plex_max_projection_height - Maxmimum mesh point height used to project locally 3125f12cf164SMatthew G. Knepley . -dm_plex_regular_refinement - Use special nested projection algorithm for regular refinement 3126250712c9SMatthew G. Knepley . -dm_plex_check_all - Perform all shecks below 3127f12cf164SMatthew G. Knepley . -dm_plex_check_symmetry - Check that the adjacency information in the mesh is symmetric 3128f12cf164SMatthew G. Knepley . -dm_plex_check_skeleton <celltype> - Check that each cell has the correct number of vertices 3129f12cf164SMatthew 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 3130f12cf164SMatthew G. Knepley . -dm_plex_check_geometry - Check that cells have positive volume 3131f12cf164SMatthew G. Knepley . -dm_view :mesh.tex:ascii_latex - View the mesh in LaTeX/TikZ 3132e5893cccSMatthew G. Knepley . -dm_plex_view_scale <num> - Scale the TikZ 3133e5893cccSMatthew G. Knepley - -dm_plex_print_fem <num> - View FEM assembly information, such as element vectors and matrices 3134e5893cccSMatthew G. Knepley 31358818961aSMatthew G Knepley Level: intermediate 31368818961aSMatthew G Knepley 31378818961aSMatthew G Knepley .seealso: DMType, DMPlexCreate(), DMCreate(), DMSetType() 31388818961aSMatthew G Knepley M*/ 31398818961aSMatthew G Knepley 31408cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Plex(DM dm) 3141552f7358SJed Brown { 3142552f7358SJed Brown DM_Plex *mesh; 3143412e9a14SMatthew G. Knepley PetscInt unit; 3144552f7358SJed Brown PetscErrorCode ierr; 3145552f7358SJed Brown 3146552f7358SJed Brown PetscFunctionBegin; 3147552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3148b00a9115SJed Brown ierr = PetscNewLog(dm,&mesh);CHKERRQ(ierr); 3149552f7358SJed Brown dm->data = mesh; 3150552f7358SJed Brown 3151552f7358SJed Brown mesh->refct = 1; 315282f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &mesh->coneSection);CHKERRQ(ierr); 3153552f7358SJed Brown mesh->maxConeSize = 0; 31540298fd71SBarry Smith mesh->cones = NULL; 31550298fd71SBarry Smith mesh->coneOrientations = NULL; 315682f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &mesh->supportSection);CHKERRQ(ierr); 3157552f7358SJed Brown mesh->maxSupportSize = 0; 31580298fd71SBarry Smith mesh->supports = NULL; 3159552f7358SJed Brown mesh->refinementUniform = PETSC_TRUE; 3160552f7358SJed Brown mesh->refinementLimit = -1.0; 3161*e600fa54SMatthew G. Knepley mesh->distDefault = PETSC_TRUE; 31627d0f5628SVaclav Hapla mesh->interpolated = DMPLEX_INTERPOLATED_INVALID; 31637d0f5628SVaclav Hapla mesh->interpolatedCollective = DMPLEX_INTERPOLATED_INVALID; 3164552f7358SJed Brown 31650298fd71SBarry Smith mesh->facesTmp = NULL; 3166552f7358SJed Brown 3167d9deefdfSMatthew G. Knepley mesh->tetgenOpts = NULL; 3168d9deefdfSMatthew G. Knepley mesh->triangleOpts = NULL; 316977623264SMatthew G. Knepley ierr = PetscPartitionerCreate(PetscObjectComm((PetscObject)dm), &mesh->partitioner);CHKERRQ(ierr); 31702e62ab5aSMatthew G. Knepley mesh->remeshBd = PETSC_FALSE; 3171d9deefdfSMatthew G. Knepley 31720298fd71SBarry Smith mesh->subpointMap = NULL; 3173552f7358SJed Brown 31748865f1eaSKarl Rupp for (unit = 0; unit < NUM_PETSC_UNITS; ++unit) mesh->scale[unit] = 1.0; 3175552f7358SJed Brown 31760aef6b92SMatthew G. Knepley mesh->regularRefinement = PETSC_FALSE; 3177df0420ecSMatthew G. Knepley mesh->depthState = -1; 3178ba2698f1SMatthew G. Knepley mesh->celltypeState = -1; 31790298fd71SBarry Smith mesh->globalVertexNumbers = NULL; 31800298fd71SBarry Smith mesh->globalCellNumbers = NULL; 3181a68b90caSToby Isaac mesh->anchorSection = NULL; 3182a68b90caSToby Isaac mesh->anchorIS = NULL; 318341e6d900SToby Isaac mesh->createanchors = NULL; 3184fa73a4e1SToby Isaac mesh->computeanchormatrix = NULL; 3185d961a43aSToby Isaac mesh->parentSection = NULL; 3186d961a43aSToby Isaac mesh->parents = NULL; 3187d961a43aSToby Isaac mesh->childIDs = NULL; 3188d961a43aSToby Isaac mesh->childSection = NULL; 3189d961a43aSToby Isaac mesh->children = NULL; 3190d6a7ad0dSToby Isaac mesh->referenceTree = NULL; 3191dcbd3bf7SToby Isaac mesh->getchildsymmetry = NULL; 3192552f7358SJed Brown mesh->vtkCellHeight = 0; 3193e228b242SToby Isaac mesh->useAnchors = PETSC_FALSE; 3194552f7358SJed Brown 3195b29cfa1cSToby Isaac mesh->maxProjectionHeight = 0; 3196b29cfa1cSToby Isaac 31970a19bb7dSprj- mesh->neighbors = NULL; 31980a19bb7dSprj- 3199552f7358SJed Brown mesh->printSetValues = PETSC_FALSE; 3200552f7358SJed Brown mesh->printFEM = 0; 32016113b454SMatthew G. Knepley mesh->printTol = 1.0e-10; 3202552f7358SJed Brown 3203552f7358SJed Brown ierr = DMInitialize_Plex(dm);CHKERRQ(ierr); 3204552f7358SJed Brown PetscFunctionReturn(0); 3205552f7358SJed Brown } 3206552f7358SJed Brown 3207552f7358SJed Brown /*@ 3208552f7358SJed Brown DMPlexCreate - Creates a DMPlex object, which encapsulates an unstructured mesh, or CW complex, which can be expressed using a Hasse Diagram. 3209552f7358SJed Brown 3210d083f849SBarry Smith Collective 3211552f7358SJed Brown 3212552f7358SJed Brown Input Parameter: 3213552f7358SJed Brown . comm - The communicator for the DMPlex object 3214552f7358SJed Brown 3215552f7358SJed Brown Output Parameter: 3216552f7358SJed Brown . mesh - The DMPlex object 3217552f7358SJed Brown 3218552f7358SJed Brown Level: beginner 3219552f7358SJed Brown 3220552f7358SJed Brown @*/ 3221552f7358SJed Brown PetscErrorCode DMPlexCreate(MPI_Comm comm, DM *mesh) 3222552f7358SJed Brown { 3223552f7358SJed Brown PetscErrorCode ierr; 3224552f7358SJed Brown 3225552f7358SJed Brown PetscFunctionBegin; 3226552f7358SJed Brown PetscValidPointer(mesh,2); 3227552f7358SJed Brown ierr = DMCreate(comm, mesh);CHKERRQ(ierr); 3228552f7358SJed Brown ierr = DMSetType(*mesh, DMPLEX);CHKERRQ(ierr); 3229552f7358SJed Brown PetscFunctionReturn(0); 3230552f7358SJed Brown } 3231552f7358SJed Brown 3232b09969d6SVaclav Hapla /*@C 3233b09969d6SVaclav Hapla DMPlexBuildFromCellListParallel - Build distributed DMPLEX topology from a list of vertices for each cell (common mesh generator output) 3234b09969d6SVaclav Hapla 3235b09969d6SVaclav Hapla Input Parameters: 3236b09969d6SVaclav Hapla + dm - The DM 3237b09969d6SVaclav Hapla . numCells - The number of cells owned by this process 323825b6865aSVaclav Hapla . numVertices - The number of vertices owned by this process, or PETSC_DECIDE 323925b6865aSVaclav Hapla . NVertices - The global number of vertices, or PETSC_DECIDE 3240b09969d6SVaclav Hapla . numCorners - The number of vertices for each cell 32415e488331SVaclav Hapla - cells - An array of numCells*numCorners numbers, the global vertex numbers for each cell 3242b09969d6SVaclav Hapla 3243be8c289dSNicolas Barral Output Parameters: 3244be8c289dSNicolas Barral + vertexSF - (Optional) SF describing complete vertex ownership 3245be8c289dSNicolas Barral - verticesAdjSaved - (Optional) vertex adjacency array 3246b09969d6SVaclav Hapla 3247b09969d6SVaclav Hapla Notes: 3248b09969d6SVaclav Hapla Two triangles sharing a face 3249b09969d6SVaclav Hapla $ 3250b09969d6SVaclav Hapla $ 2 3251b09969d6SVaclav Hapla $ / | \ 3252b09969d6SVaclav Hapla $ / | \ 3253b09969d6SVaclav Hapla $ / | \ 3254b09969d6SVaclav Hapla $ 0 0 | 1 3 3255b09969d6SVaclav Hapla $ \ | / 3256b09969d6SVaclav Hapla $ \ | / 3257b09969d6SVaclav Hapla $ \ | / 3258b09969d6SVaclav Hapla $ 1 3259b09969d6SVaclav Hapla would have input 3260b09969d6SVaclav Hapla $ numCells = 2, numVertices = 4 3261b09969d6SVaclav Hapla $ cells = [0 1 2 1 3 2] 3262b09969d6SVaclav Hapla $ 3263b09969d6SVaclav Hapla which would result in the DMPlex 3264b09969d6SVaclav Hapla $ 3265b09969d6SVaclav Hapla $ 4 3266b09969d6SVaclav Hapla $ / | \ 3267b09969d6SVaclav Hapla $ / | \ 3268b09969d6SVaclav Hapla $ / | \ 3269b09969d6SVaclav Hapla $ 2 0 | 1 5 3270b09969d6SVaclav Hapla $ \ | / 3271b09969d6SVaclav Hapla $ \ | / 3272b09969d6SVaclav Hapla $ \ | / 3273b09969d6SVaclav Hapla $ 3 3274b09969d6SVaclav Hapla 327525b6865aSVaclav Hapla Vertices are implicitly numbered consecutively 0,...,NVertices. 327625b6865aSVaclav Hapla Each rank owns a chunk of numVertices consecutive vertices. 327725b6865aSVaclav Hapla If numVertices is PETSC_DECIDE, PETSc will distribute them as evenly as possible using PetscLayout. 327825b6865aSVaclav Hapla If both NVertices and numVertices are PETSC_DECIDE, NVertices is computed by PETSc as the maximum vertex index in cells + 1. 327925b6865aSVaclav Hapla If only NVertices is PETSC_DECIDE, it is computed as the sum of numVertices over all ranks. 328025b6865aSVaclav Hapla 3281b09969d6SVaclav Hapla The cell distribution is arbitrary non-overlapping, independent of the vertex distribution. 3282b09969d6SVaclav Hapla 3283b09969d6SVaclav Hapla Not currently supported in Fortran. 3284b09969d6SVaclav Hapla 3285b09969d6SVaclav Hapla Level: advanced 3286b09969d6SVaclav Hapla 3287b09969d6SVaclav Hapla .seealso: DMPlexBuildFromCellList(), DMPlexCreateFromCellListParallelPetsc(), DMPlexBuildCoordinatesFromCellListParallel() 3288b09969d6SVaclav Hapla @*/ 3289be8c289dSNicolas Barral PetscErrorCode DMPlexBuildFromCellListParallel(DM dm, PetscInt numCells, PetscInt numVertices, PetscInt NVertices, PetscInt numCorners, const PetscInt cells[], PetscSF *vertexSF, PetscInt **verticesAdjSaved) 3290a47d0d45SMatthew G. Knepley { 32912464107aSksagiyam PetscSF sfPoint; 32922464107aSksagiyam PetscLayout layout; 32932464107aSksagiyam PetscInt numVerticesAdj, *verticesAdj, *cones, c, p, dim; 32949852e123SBarry Smith PetscMPIInt rank, size; 3295a47d0d45SMatthew G. Knepley PetscErrorCode ierr; 3296a47d0d45SMatthew G. Knepley 3297a47d0d45SMatthew G. Knepley PetscFunctionBegin; 329825b6865aSVaclav Hapla PetscValidLogicalCollectiveInt(dm,NVertices,4); 3299b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 3300ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 3301ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRMPI(ierr); 33026cbf6523SVaclav Hapla ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 330325b6865aSVaclav Hapla /* Get/check global number of vertices */ 330425b6865aSVaclav Hapla { 330525b6865aSVaclav Hapla PetscInt NVerticesInCells, i; 330625b6865aSVaclav Hapla const PetscInt len = numCells * numCorners; 330725b6865aSVaclav Hapla 330825b6865aSVaclav Hapla /* NVerticesInCells = max(cells) + 1 */ 330925b6865aSVaclav Hapla NVerticesInCells = PETSC_MIN_INT; 331025b6865aSVaclav Hapla for (i=0; i<len; i++) if (cells[i] > NVerticesInCells) NVerticesInCells = cells[i]; 331125b6865aSVaclav Hapla ++NVerticesInCells; 3312ffc4695bSBarry Smith ierr = MPI_Allreduce(MPI_IN_PLACE, &NVerticesInCells, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 331325b6865aSVaclav Hapla 331425b6865aSVaclav Hapla if (numVertices == PETSC_DECIDE && NVertices == PETSC_DECIDE) NVertices = NVerticesInCells; 33152c71b3e2SJacob 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); 331625b6865aSVaclav Hapla } 33179079aca8SVaclav Hapla /* Count locally unique vertices */ 33189079aca8SVaclav Hapla { 33199079aca8SVaclav Hapla PetscHSetI vhash; 33209079aca8SVaclav Hapla PetscInt off = 0; 33219079aca8SVaclav Hapla 3322e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&vhash);CHKERRQ(ierr); 3323a47d0d45SMatthew G. Knepley for (c = 0; c < numCells; ++c) { 3324a47d0d45SMatthew G. Knepley for (p = 0; p < numCorners; ++p) { 3325e8f14785SLisandro Dalcin ierr = PetscHSetIAdd(vhash, cells[c*numCorners+p]);CHKERRQ(ierr); 3326a47d0d45SMatthew G. Knepley } 3327a47d0d45SMatthew G. Knepley } 3328e8f14785SLisandro Dalcin ierr = PetscHSetIGetSize(vhash, &numVerticesAdj);CHKERRQ(ierr); 3329be8c289dSNicolas Barral if (!verticesAdjSaved) { ierr = PetscMalloc1(numVerticesAdj, &verticesAdj);CHKERRQ(ierr); } 3330be8c289dSNicolas Barral else { verticesAdj = *verticesAdjSaved; } 3331e8f14785SLisandro Dalcin ierr = PetscHSetIGetElems(vhash, &off, verticesAdj);CHKERRQ(ierr); 3332e8f14785SLisandro Dalcin ierr = PetscHSetIDestroy(&vhash);CHKERRQ(ierr); 33332c71b3e2SJacob Faibussowitsch PetscCheckFalse(off != numVerticesAdj,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid number of local vertices %D should be %D", off, numVerticesAdj); 3334a47d0d45SMatthew G. Knepley } 33359079aca8SVaclav Hapla ierr = PetscSortInt(numVerticesAdj, verticesAdj);CHKERRQ(ierr); 3336a47d0d45SMatthew G. Knepley /* Create cones */ 3337a47d0d45SMatthew G. Knepley ierr = DMPlexSetChart(dm, 0, numCells+numVerticesAdj);CHKERRQ(ierr); 3338a47d0d45SMatthew G. Knepley for (c = 0; c < numCells; ++c) {ierr = DMPlexSetConeSize(dm, c, numCorners);CHKERRQ(ierr);} 3339a47d0d45SMatthew G. Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); 3340961cfab0SVaclav Hapla ierr = DMPlexGetCones(dm,&cones);CHKERRQ(ierr); 3341a47d0d45SMatthew G. Knepley for (c = 0; c < numCells; ++c) { 3342a47d0d45SMatthew G. Knepley for (p = 0; p < numCorners; ++p) { 3343a47d0d45SMatthew G. Knepley const PetscInt gv = cells[c*numCorners+p]; 3344a47d0d45SMatthew G. Knepley PetscInt lv; 3345a47d0d45SMatthew G. Knepley 33469079aca8SVaclav Hapla /* Positions within verticesAdj form 0-based local vertex numbering; 33479079aca8SVaclav Hapla we need to shift it by numCells to get correct DAG points (cells go first) */ 3348a47d0d45SMatthew G. Knepley ierr = PetscFindInt(gv, numVerticesAdj, verticesAdj, &lv);CHKERRQ(ierr); 33492c71b3e2SJacob Faibussowitsch PetscCheckFalse(lv < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not find global vertex %D in local connectivity", gv); 3350961cfab0SVaclav Hapla cones[c*numCorners+p] = lv+numCells; 3351a47d0d45SMatthew G. Knepley } 3352a47d0d45SMatthew G. Knepley } 33532464107aSksagiyam /* Build point sf */ 33542464107aSksagiyam ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)dm), &layout);CHKERRQ(ierr); 33552464107aSksagiyam ierr = PetscLayoutSetSize(layout, NVertices);CHKERRQ(ierr); 33562464107aSksagiyam ierr = PetscLayoutSetLocalSize(layout, numVertices);CHKERRQ(ierr); 33572464107aSksagiyam ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr); 33582464107aSksagiyam ierr = PetscSFCreateByMatchingIndices(layout, numVerticesAdj, verticesAdj, NULL, numCells, numVerticesAdj, verticesAdj, NULL, numCells, vertexSF, &sfPoint);CHKERRQ(ierr); 33592464107aSksagiyam ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 3360be8c289dSNicolas Barral if (!verticesAdjSaved) { ierr = PetscFree(verticesAdj);CHKERRQ(ierr); } 3361a47d0d45SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) sfPoint, "point SF");CHKERRQ(ierr); 33622464107aSksagiyam if (dm->sf) { 33632464107aSksagiyam const char *prefix; 33642464107aSksagiyam 33652464107aSksagiyam ierr = PetscObjectGetOptionsPrefix((PetscObject)dm->sf, &prefix);CHKERRQ(ierr); 33662464107aSksagiyam ierr = PetscObjectSetOptionsPrefix((PetscObject)sfPoint, prefix);CHKERRQ(ierr); 33672464107aSksagiyam } 33682464107aSksagiyam ierr = DMSetPointSF(dm, sfPoint);CHKERRQ(ierr); 33692464107aSksagiyam ierr = PetscSFDestroy(&sfPoint);CHKERRQ(ierr); 33702464107aSksagiyam if (vertexSF) {ierr = PetscObjectSetName((PetscObject)(*vertexSF), "Vertex Ownership SF");CHKERRQ(ierr);} 3371a47d0d45SMatthew G. Knepley /* Fill in the rest of the topology structure */ 3372a47d0d45SMatthew G. Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 3373a47d0d45SMatthew G. Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 3374b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 3375a47d0d45SMatthew G. Knepley PetscFunctionReturn(0); 3376a47d0d45SMatthew G. Knepley } 3377a47d0d45SMatthew G. Knepley 3378b09969d6SVaclav Hapla /*@C 3379b09969d6SVaclav Hapla DMPlexBuildCoordinatesFromCellListParallel - Build DM coordinates from a list of coordinates for each owned vertex (common mesh generator output) 3380b09969d6SVaclav Hapla 3381b09969d6SVaclav Hapla Input Parameters: 3382b09969d6SVaclav Hapla + dm - The DM 3383b09969d6SVaclav Hapla . spaceDim - The spatial dimension used for coordinates 3384b09969d6SVaclav Hapla . sfVert - SF describing complete vertex ownership 3385b09969d6SVaclav Hapla - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 3386b09969d6SVaclav Hapla 3387b09969d6SVaclav Hapla Level: advanced 3388b09969d6SVaclav Hapla 3389b09969d6SVaclav Hapla Notes: 3390b09969d6SVaclav Hapla Not currently supported in Fortran. 3391b09969d6SVaclav Hapla 3392b09969d6SVaclav Hapla .seealso: DMPlexBuildCoordinatesFromCellList(), DMPlexCreateFromCellListParallelPetsc(), DMPlexBuildFromCellListParallel() 3393b09969d6SVaclav Hapla @*/ 33941edcf0b2SVaclav Hapla PetscErrorCode DMPlexBuildCoordinatesFromCellListParallel(DM dm, PetscInt spaceDim, PetscSF sfVert, const PetscReal vertexCoords[]) 3395a47d0d45SMatthew G. Knepley { 3396a47d0d45SMatthew G. Knepley PetscSection coordSection; 3397a47d0d45SMatthew G. Knepley Vec coordinates; 3398a47d0d45SMatthew G. Knepley PetscScalar *coords; 33991edcf0b2SVaclav Hapla PetscInt numVertices, numVerticesAdj, coordSize, v, vStart, vEnd; 3400a47d0d45SMatthew G. Knepley PetscErrorCode ierr; 3401a47d0d45SMatthew G. Knepley 3402a47d0d45SMatthew G. Knepley PetscFunctionBegin; 3403b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 34041edcf0b2SVaclav Hapla ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 34052c71b3e2SJacob Faibussowitsch PetscCheckFalse(vStart < 0 || vEnd < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "DM is not set up properly. DMPlexBuildFromCellList() should be called first."); 34069596c6baSMatthew G. Knepley ierr = DMSetCoordinateDim(dm, spaceDim);CHKERRQ(ierr); 3407a47d0d45SMatthew G. Knepley ierr = PetscSFGetGraph(sfVert, &numVertices, &numVerticesAdj, NULL, NULL);CHKERRQ(ierr); 34082c71b3e2SJacob 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); 3409a47d0d45SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 3410a47d0d45SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 3411a47d0d45SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, spaceDim);CHKERRQ(ierr); 34121edcf0b2SVaclav Hapla ierr = PetscSectionSetChart(coordSection, vStart, vEnd);CHKERRQ(ierr); 34131edcf0b2SVaclav Hapla for (v = vStart; v < vEnd; ++v) { 3414a47d0d45SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, spaceDim);CHKERRQ(ierr); 3415a47d0d45SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, spaceDim);CHKERRQ(ierr); 3416a47d0d45SMatthew G. Knepley } 3417a47d0d45SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 3418a47d0d45SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 3419a47d0d45SMatthew G. Knepley ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinates);CHKERRQ(ierr); 3420a47d0d45SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, spaceDim);CHKERRQ(ierr); 3421a47d0d45SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 3422a47d0d45SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 3423a47d0d45SMatthew G. Knepley ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 3424a47d0d45SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 3425a47d0d45SMatthew G. Knepley { 3426a47d0d45SMatthew G. Knepley MPI_Datatype coordtype; 3427a47d0d45SMatthew G. Knepley 3428a47d0d45SMatthew G. Knepley /* Need a temp buffer for coords if we have complex/single */ 3429ffc4695bSBarry Smith ierr = MPI_Type_contiguous(spaceDim, MPIU_SCALAR, &coordtype);CHKERRMPI(ierr); 3430ffc4695bSBarry Smith ierr = MPI_Type_commit(&coordtype);CHKERRMPI(ierr); 343121016a8bSBarry Smith #if defined(PETSC_USE_COMPLEX) 343221016a8bSBarry Smith { 343321016a8bSBarry Smith PetscScalar *svertexCoords; 343421016a8bSBarry Smith PetscInt i; 34353612f820SVaclav Hapla ierr = PetscMalloc1(numVertices*spaceDim,&svertexCoords);CHKERRQ(ierr); 34363612f820SVaclav Hapla for (i=0; i<numVertices*spaceDim; i++) svertexCoords[i] = vertexCoords[i]; 3437ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sfVert, coordtype, svertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 3438ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sfVert, coordtype, svertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 343921016a8bSBarry Smith ierr = PetscFree(svertexCoords);CHKERRQ(ierr); 344021016a8bSBarry Smith } 344121016a8bSBarry Smith #else 3442ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sfVert, coordtype, vertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 3443ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sfVert, coordtype, vertexCoords, coords,MPI_REPLACE);CHKERRQ(ierr); 344421016a8bSBarry Smith #endif 3445ffc4695bSBarry Smith ierr = MPI_Type_free(&coordtype);CHKERRMPI(ierr); 3446a47d0d45SMatthew G. Knepley } 3447a47d0d45SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 3448a47d0d45SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 3449a47d0d45SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 3450b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 3451a47d0d45SMatthew G. Knepley PetscFunctionReturn(0); 3452a47d0d45SMatthew G. Knepley } 3453a47d0d45SMatthew G. Knepley 3454c3edce3dSSatish Balay /*@ 3455b09969d6SVaclav Hapla DMPlexCreateFromCellListParallelPetsc - Create distributed DMPLEX from a list of vertices for each cell (common mesh generator output) 3456a47d0d45SMatthew G. Knepley 3457a47d0d45SMatthew G. Knepley Input Parameters: 3458a47d0d45SMatthew G. Knepley + comm - The communicator 3459a47d0d45SMatthew G. Knepley . dim - The topological dimension of the mesh 3460a47d0d45SMatthew G. Knepley . numCells - The number of cells owned by this process 346125b6865aSVaclav Hapla . numVertices - The number of vertices owned by this process, or PETSC_DECIDE 346225b6865aSVaclav Hapla . NVertices - The global number of vertices, or PETSC_DECIDE 3463a47d0d45SMatthew G. Knepley . numCorners - The number of vertices for each cell 3464a47d0d45SMatthew G. Knepley . interpolate - Flag indicating that intermediate mesh entities (faces, edges) should be created automatically 3465a47d0d45SMatthew G. Knepley . cells - An array of numCells*numCorners numbers, the global vertex numbers for each cell 3466a47d0d45SMatthew G. Knepley . spaceDim - The spatial dimension used for coordinates 3467a47d0d45SMatthew G. Knepley - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 3468a47d0d45SMatthew G. Knepley 3469d8d19677SJose E. Roman Output Parameters: 347018d54ad4SMichael Lange + dm - The DM 3471be8c289dSNicolas Barral . vertexSF - (Optional) SF describing complete vertex ownership 3472be8c289dSNicolas Barral - verticesAdjSaved - (Optional) vertex adjacency array 3473a47d0d45SMatthew G. Knepley 3474b09969d6SVaclav Hapla Notes: 3475b09969d6SVaclav Hapla This function is just a convenient sequence of DMCreate(), DMSetType(), DMSetDimension(), 3476b09969d6SVaclav Hapla DMPlexBuildFromCellListParallel(), DMPlexInterpolate(), DMPlexBuildCoordinatesFromCellListParallel() 3477a47d0d45SMatthew G. Knepley 347825b6865aSVaclav Hapla See DMPlexBuildFromCellListParallel() for an example and details about the topology-related parameters. 347925b6865aSVaclav Hapla See DMPlexBuildCoordinatesFromCellListParallel() for details about the geometry-related parameters. 348025b6865aSVaclav Hapla 3481b09969d6SVaclav Hapla Level: intermediate 3482a47d0d45SMatthew G. Knepley 3483b09969d6SVaclav Hapla .seealso: DMPlexCreateFromCellListPetsc(), DMPlexBuildFromCellListParallel(), DMPlexBuildCoordinatesFromCellListParallel(), DMPlexCreateFromDAG(), DMPlexCreate() 3484a47d0d45SMatthew G. Knepley @*/ 3485be8c289dSNicolas 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) 3486a47d0d45SMatthew G. Knepley { 3487a47d0d45SMatthew G. Knepley PetscSF sfVert; 3488a47d0d45SMatthew G. Knepley PetscErrorCode ierr; 3489a47d0d45SMatthew G. Knepley 3490a47d0d45SMatthew G. Knepley PetscFunctionBegin; 3491a47d0d45SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 3492a47d0d45SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 3493a47d0d45SMatthew G. Knepley PetscValidLogicalCollectiveInt(*dm, dim, 2); 3494064a246eSJacob Faibussowitsch PetscValidLogicalCollectiveInt(*dm, spaceDim, 9); 3495a47d0d45SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 3496be8c289dSNicolas Barral ierr = DMPlexBuildFromCellListParallel(*dm, numCells, numVertices, NVertices, numCorners, cells, &sfVert, verticesAdj);CHKERRQ(ierr); 3497a47d0d45SMatthew G. Knepley if (interpolate) { 34985fd9971aSMatthew G. Knepley DM idm; 3499a47d0d45SMatthew G. Knepley 3500a47d0d45SMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 3501a47d0d45SMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 3502a47d0d45SMatthew G. Knepley *dm = idm; 3503a47d0d45SMatthew G. Knepley } 35041edcf0b2SVaclav Hapla ierr = DMPlexBuildCoordinatesFromCellListParallel(*dm, spaceDim, sfVert, vertexCoords);CHKERRQ(ierr); 350518d54ad4SMichael Lange if (vertexSF) *vertexSF = sfVert; 3506fba955ccSBarry Smith else {ierr = PetscSFDestroy(&sfVert);CHKERRQ(ierr);} 3507a47d0d45SMatthew G. Knepley PetscFunctionReturn(0); 3508a47d0d45SMatthew G. Knepley } 3509a47d0d45SMatthew G. Knepley 3510a4a685f2SJacob Faibussowitsch /*@ 3511a4a685f2SJacob Faibussowitsch DMPlexCreateFromCellListParallel - Deprecated, use DMPlexCreateFromCellListParallelPetsc() 3512a4a685f2SJacob Faibussowitsch 3513a4a685f2SJacob Faibussowitsch Level: deprecated 3514a4a685f2SJacob Faibussowitsch 3515a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromCellListParallelPetsc() 3516a4a685f2SJacob Faibussowitsch @*/ 3517a4a685f2SJacob 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) 3518a4a685f2SJacob Faibussowitsch { 3519a4a685f2SJacob Faibussowitsch PetscErrorCode ierr; 3520a4a685f2SJacob Faibussowitsch PetscInt i; 3521a4a685f2SJacob Faibussowitsch PetscInt *pintCells; 3522a4a685f2SJacob Faibussowitsch 3523a4a685f2SJacob Faibussowitsch PetscFunctionBegin; 35242c71b3e2SJacob 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)); 3525a4a685f2SJacob Faibussowitsch if (sizeof(int) == sizeof(PetscInt)) { 3526a4a685f2SJacob Faibussowitsch pintCells = (PetscInt *) cells; 3527a4a685f2SJacob Faibussowitsch } else { 3528a4a685f2SJacob Faibussowitsch ierr = PetscMalloc1(numCells*numCorners, &pintCells);CHKERRQ(ierr); 3529a4a685f2SJacob Faibussowitsch for (i = 0; i < numCells*numCorners; i++) { 3530a4a685f2SJacob Faibussowitsch pintCells[i] = (PetscInt) cells[i]; 3531a4a685f2SJacob Faibussowitsch } 3532a4a685f2SJacob Faibussowitsch } 3533be8c289dSNicolas Barral ierr = DMPlexCreateFromCellListParallelPetsc(comm, dim, numCells, numVertices, PETSC_DECIDE, numCorners, interpolate, pintCells, spaceDim, vertexCoords, vertexSF, NULL, dm);CHKERRQ(ierr); 3534a4a685f2SJacob Faibussowitsch if (sizeof(int) != sizeof(PetscInt)) { 3535a4a685f2SJacob Faibussowitsch ierr = PetscFree(pintCells);CHKERRQ(ierr); 3536a4a685f2SJacob Faibussowitsch } 3537a4a685f2SJacob Faibussowitsch PetscFunctionReturn(0); 3538a4a685f2SJacob Faibussowitsch } 3539a4a685f2SJacob Faibussowitsch 3540b09969d6SVaclav Hapla /*@C 3541b09969d6SVaclav Hapla DMPlexBuildFromCellList - Build DMPLEX topology from a list of vertices for each cell (common mesh generator output) 35429298eaa6SMatthew G Knepley 35439298eaa6SMatthew G Knepley Input Parameters: 3544b09969d6SVaclav Hapla + dm - The DM 3545b09969d6SVaclav Hapla . numCells - The number of cells owned by this process 354625b6865aSVaclav Hapla . numVertices - The number of vertices owned by this process, or PETSC_DECIDE 35479298eaa6SMatthew G Knepley . numCorners - The number of vertices for each cell 35485e488331SVaclav Hapla - cells - An array of numCells*numCorners numbers, the global vertex numbers for each cell 35499298eaa6SMatthew G Knepley 3550b09969d6SVaclav Hapla Level: advanced 35519298eaa6SMatthew G Knepley 3552b09969d6SVaclav Hapla Notes: 3553b09969d6SVaclav Hapla Two triangles sharing a face 35549298eaa6SMatthew G Knepley $ 35559298eaa6SMatthew G Knepley $ 2 35569298eaa6SMatthew G Knepley $ / | \ 35579298eaa6SMatthew G Knepley $ / | \ 35589298eaa6SMatthew G Knepley $ / | \ 35599298eaa6SMatthew G Knepley $ 0 0 | 1 3 35609298eaa6SMatthew G Knepley $ \ | / 35619298eaa6SMatthew G Knepley $ \ | / 35629298eaa6SMatthew G Knepley $ \ | / 35639298eaa6SMatthew G Knepley $ 1 35649298eaa6SMatthew G Knepley would have input 35659298eaa6SMatthew G Knepley $ numCells = 2, numVertices = 4 35669298eaa6SMatthew G Knepley $ cells = [0 1 2 1 3 2] 35679298eaa6SMatthew G Knepley $ 35689298eaa6SMatthew G Knepley which would result in the DMPlex 35699298eaa6SMatthew G Knepley $ 35709298eaa6SMatthew G Knepley $ 4 35719298eaa6SMatthew G Knepley $ / | \ 35729298eaa6SMatthew G Knepley $ / | \ 35739298eaa6SMatthew G Knepley $ / | \ 35749298eaa6SMatthew G Knepley $ 2 0 | 1 5 35759298eaa6SMatthew G Knepley $ \ | / 35769298eaa6SMatthew G Knepley $ \ | / 35779298eaa6SMatthew G Knepley $ \ | / 35789298eaa6SMatthew G Knepley $ 3 35799298eaa6SMatthew G Knepley 358025b6865aSVaclav Hapla If numVertices is PETSC_DECIDE, it is computed by PETSc as the maximum vertex index in cells + 1. 358125b6865aSVaclav Hapla 3582b09969d6SVaclav Hapla Not currently supported in Fortran. 35839298eaa6SMatthew G Knepley 3584b09969d6SVaclav Hapla .seealso: DMPlexBuildFromCellListParallel(), DMPlexBuildCoordinatesFromCellList(), DMPlexCreateFromCellListPetsc() 3585b09969d6SVaclav Hapla @*/ 35865e488331SVaclav Hapla PetscErrorCode DMPlexBuildFromCellList(DM dm, PetscInt numCells, PetscInt numVertices, PetscInt numCorners, const PetscInt cells[]) 3587b09969d6SVaclav Hapla { 3588961cfab0SVaclav Hapla PetscInt *cones, c, p, dim; 3589b09969d6SVaclav Hapla PetscErrorCode ierr; 3590b09969d6SVaclav Hapla 3591b09969d6SVaclav Hapla PetscFunctionBegin; 3592b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 3593b09969d6SVaclav Hapla ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 359425b6865aSVaclav Hapla /* Get/check global number of vertices */ 359525b6865aSVaclav Hapla { 359625b6865aSVaclav Hapla PetscInt NVerticesInCells, i; 359725b6865aSVaclav Hapla const PetscInt len = numCells * numCorners; 359825b6865aSVaclav Hapla 359925b6865aSVaclav Hapla /* NVerticesInCells = max(cells) + 1 */ 360025b6865aSVaclav Hapla NVerticesInCells = PETSC_MIN_INT; 360125b6865aSVaclav Hapla for (i=0; i<len; i++) if (cells[i] > NVerticesInCells) NVerticesInCells = cells[i]; 360225b6865aSVaclav Hapla ++NVerticesInCells; 360325b6865aSVaclav Hapla 360425b6865aSVaclav Hapla if (numVertices == PETSC_DECIDE) numVertices = NVerticesInCells; 36052c71b3e2SJacob 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); 360625b6865aSVaclav Hapla } 3607b09969d6SVaclav Hapla ierr = DMPlexSetChart(dm, 0, numCells+numVertices);CHKERRQ(ierr); 3608b09969d6SVaclav Hapla for (c = 0; c < numCells; ++c) { 3609b09969d6SVaclav Hapla ierr = DMPlexSetConeSize(dm, c, numCorners);CHKERRQ(ierr); 3610b09969d6SVaclav Hapla } 3611b09969d6SVaclav Hapla ierr = DMSetUp(dm);CHKERRQ(ierr); 3612961cfab0SVaclav Hapla ierr = DMPlexGetCones(dm,&cones);CHKERRQ(ierr); 3613b09969d6SVaclav Hapla for (c = 0; c < numCells; ++c) { 3614b09969d6SVaclav Hapla for (p = 0; p < numCorners; ++p) { 3615961cfab0SVaclav Hapla cones[c*numCorners+p] = cells[c*numCorners+p]+numCells; 3616b09969d6SVaclav Hapla } 3617b09969d6SVaclav Hapla } 3618b09969d6SVaclav Hapla ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 3619b09969d6SVaclav Hapla ierr = DMPlexStratify(dm);CHKERRQ(ierr); 3620b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildFromCellList,dm,0,0,0);CHKERRQ(ierr); 3621b09969d6SVaclav Hapla PetscFunctionReturn(0); 3622b09969d6SVaclav Hapla } 3623b09969d6SVaclav Hapla 3624b09969d6SVaclav Hapla /*@C 3625b09969d6SVaclav Hapla DMPlexBuildCoordinatesFromCellList - Build DM coordinates from a list of coordinates for each owned vertex (common mesh generator output) 3626b09969d6SVaclav Hapla 3627b09969d6SVaclav Hapla Input Parameters: 3628b09969d6SVaclav Hapla + dm - The DM 3629b09969d6SVaclav Hapla . spaceDim - The spatial dimension used for coordinates 3630b09969d6SVaclav Hapla - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex 3631b09969d6SVaclav Hapla 3632b09969d6SVaclav Hapla Level: advanced 3633b09969d6SVaclav Hapla 3634b09969d6SVaclav Hapla Notes: 3635b09969d6SVaclav Hapla Not currently supported in Fortran. 3636b09969d6SVaclav Hapla 3637b09969d6SVaclav Hapla .seealso: DMPlexBuildCoordinatesFromCellListParallel(), DMPlexCreateFromCellListPetsc(), DMPlexBuildFromCellList() 3638b09969d6SVaclav Hapla @*/ 36391edcf0b2SVaclav Hapla PetscErrorCode DMPlexBuildCoordinatesFromCellList(DM dm, PetscInt spaceDim, const PetscReal vertexCoords[]) 3640b09969d6SVaclav Hapla { 3641b09969d6SVaclav Hapla PetscSection coordSection; 3642b09969d6SVaclav Hapla Vec coordinates; 3643b09969d6SVaclav Hapla DM cdm; 3644b09969d6SVaclav Hapla PetscScalar *coords; 36451edcf0b2SVaclav Hapla PetscInt v, vStart, vEnd, d; 3646b09969d6SVaclav Hapla PetscErrorCode ierr; 3647b09969d6SVaclav Hapla 3648b09969d6SVaclav Hapla PetscFunctionBegin; 3649b09969d6SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 36501edcf0b2SVaclav Hapla ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 36512c71b3e2SJacob Faibussowitsch PetscCheckFalse(vStart < 0 || vEnd < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "DM is not set up properly. DMPlexBuildFromCellList() should be called first."); 3652b09969d6SVaclav Hapla ierr = DMSetCoordinateDim(dm, spaceDim);CHKERRQ(ierr); 3653b09969d6SVaclav Hapla ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 3654b09969d6SVaclav Hapla ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 3655b09969d6SVaclav Hapla ierr = PetscSectionSetFieldComponents(coordSection, 0, spaceDim);CHKERRQ(ierr); 36561edcf0b2SVaclav Hapla ierr = PetscSectionSetChart(coordSection, vStart, vEnd);CHKERRQ(ierr); 36571edcf0b2SVaclav Hapla for (v = vStart; v < vEnd; ++v) { 3658b09969d6SVaclav Hapla ierr = PetscSectionSetDof(coordSection, v, spaceDim);CHKERRQ(ierr); 3659b09969d6SVaclav Hapla ierr = PetscSectionSetFieldDof(coordSection, v, 0, spaceDim);CHKERRQ(ierr); 3660b09969d6SVaclav Hapla } 3661b09969d6SVaclav Hapla ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 3662b09969d6SVaclav Hapla 3663b09969d6SVaclav Hapla ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 3664b09969d6SVaclav Hapla ierr = DMCreateLocalVector(cdm, &coordinates);CHKERRQ(ierr); 3665b09969d6SVaclav Hapla ierr = VecSetBlockSize(coordinates, spaceDim);CHKERRQ(ierr); 3666b09969d6SVaclav Hapla ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 366799946890SBarry Smith ierr = VecGetArrayWrite(coordinates, &coords);CHKERRQ(ierr); 36681edcf0b2SVaclav Hapla for (v = 0; v < vEnd-vStart; ++v) { 3669b09969d6SVaclav Hapla for (d = 0; d < spaceDim; ++d) { 3670b09969d6SVaclav Hapla coords[v*spaceDim+d] = vertexCoords[v*spaceDim+d]; 3671b09969d6SVaclav Hapla } 3672b09969d6SVaclav Hapla } 367399946890SBarry Smith ierr = VecRestoreArrayWrite(coordinates, &coords);CHKERRQ(ierr); 3674b09969d6SVaclav Hapla ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 3675b09969d6SVaclav Hapla ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 3676b09969d6SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_BuildCoordinatesFromCellList,dm,0,0,0);CHKERRQ(ierr); 3677b09969d6SVaclav Hapla PetscFunctionReturn(0); 3678b09969d6SVaclav Hapla } 3679b09969d6SVaclav Hapla 3680b09969d6SVaclav Hapla /*@ 36813df08285SMatthew 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 36823df08285SMatthew G. Knepley 36833df08285SMatthew G. Knepley Collective on comm 3684b09969d6SVaclav Hapla 3685b09969d6SVaclav Hapla Input Parameters: 3686b09969d6SVaclav Hapla + comm - The communicator 3687b09969d6SVaclav Hapla . dim - The topological dimension of the mesh 36883df08285SMatthew G. Knepley . numCells - The number of cells, only on process 0 36893df08285SMatthew G. Knepley . numVertices - The number of vertices owned by this process, or PETSC_DECIDE, only on process 0 36903df08285SMatthew G. Knepley . numCorners - The number of vertices for each cell, only on process 0 3691b09969d6SVaclav Hapla . interpolate - Flag indicating that intermediate mesh entities (faces, edges) should be created automatically 36923df08285SMatthew G. Knepley . cells - An array of numCells*numCorners numbers, the vertices for each cell, only on process 0 3693b09969d6SVaclav Hapla . spaceDim - The spatial dimension used for coordinates 36943df08285SMatthew G. Knepley - vertexCoords - An array of numVertices*spaceDim numbers, the coordinates of each vertex, only on process 0 3695b09969d6SVaclav Hapla 3696b09969d6SVaclav Hapla Output Parameter: 36973df08285SMatthew G. Knepley . dm - The DM, which only has points on process 0 3698b09969d6SVaclav Hapla 3699b09969d6SVaclav Hapla Notes: 3700b09969d6SVaclav Hapla This function is just a convenient sequence of DMCreate(), DMSetType(), DMSetDimension(), DMPlexBuildFromCellList(), 3701b09969d6SVaclav Hapla DMPlexInterpolate(), DMPlexBuildCoordinatesFromCellList() 3702b09969d6SVaclav Hapla 370325b6865aSVaclav Hapla See DMPlexBuildFromCellList() for an example and details about the topology-related parameters. 370425b6865aSVaclav Hapla See DMPlexBuildCoordinatesFromCellList() for details about the geometry-related parameters. 37053df08285SMatthew G. Knepley See DMPlexCreateFromCellListParallelPetsc() for parallel input 370625b6865aSVaclav Hapla 3707b09969d6SVaclav Hapla Level: intermediate 3708b09969d6SVaclav Hapla 3709b09969d6SVaclav Hapla .seealso: DMPlexCreateFromCellListParallelPetsc(), DMPlexBuildFromCellList(), DMPlexBuildCoordinatesFromCellList(), DMPlexCreateFromDAG(), DMPlexCreate() 37109298eaa6SMatthew G Knepley @*/ 3711a4a685f2SJacob 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) 37129298eaa6SMatthew G Knepley { 37133df08285SMatthew G. Knepley PetscMPIInt rank; 37149298eaa6SMatthew G Knepley PetscErrorCode ierr; 37159298eaa6SMatthew G Knepley 37169298eaa6SMatthew G Knepley PetscFunctionBegin; 37172c71b3e2SJacob 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."); 37183df08285SMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 37199298eaa6SMatthew G Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 37209298eaa6SMatthew G Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 3721c73cfb54SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 37223df08285SMatthew G. Knepley if (!rank) {ierr = DMPlexBuildFromCellList(*dm, numCells, numVertices, numCorners, cells);CHKERRQ(ierr);} 37233df08285SMatthew G. Knepley else {ierr = DMPlexBuildFromCellList(*dm, 0, 0, 0, NULL);CHKERRQ(ierr);} 37249298eaa6SMatthew G Knepley if (interpolate) { 37255fd9971aSMatthew G. Knepley DM idm; 37269298eaa6SMatthew G Knepley 37279298eaa6SMatthew G Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 37289298eaa6SMatthew G Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 37299298eaa6SMatthew G Knepley *dm = idm; 37309298eaa6SMatthew G Knepley } 37313df08285SMatthew G. Knepley if (!rank) {ierr = DMPlexBuildCoordinatesFromCellList(*dm, spaceDim, vertexCoords);CHKERRQ(ierr);} 37323df08285SMatthew G. Knepley else {ierr = DMPlexBuildCoordinatesFromCellList(*dm, spaceDim, NULL);CHKERRQ(ierr);} 37339298eaa6SMatthew G Knepley PetscFunctionReturn(0); 37349298eaa6SMatthew G Knepley } 37359298eaa6SMatthew G Knepley 3736939f6067SMatthew G. Knepley /*@ 3737a4a685f2SJacob Faibussowitsch DMPlexCreateFromCellList - Deprecated, use DMPlexCreateFromCellListPetsc() 3738a4a685f2SJacob Faibussowitsch 3739a4a685f2SJacob Faibussowitsch Level: deprecated 3740a4a685f2SJacob Faibussowitsch 3741a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromCellListPetsc() 3742a4a685f2SJacob Faibussowitsch @*/ 3743a4a685f2SJacob 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) 3744a4a685f2SJacob Faibussowitsch { 3745a4a685f2SJacob Faibussowitsch PetscErrorCode ierr; 3746a4a685f2SJacob Faibussowitsch PetscInt i; 3747a4a685f2SJacob Faibussowitsch PetscInt *pintCells; 3748a4a685f2SJacob Faibussowitsch PetscReal *prealVC; 3749a4a685f2SJacob Faibussowitsch 3750a4a685f2SJacob Faibussowitsch PetscFunctionBegin; 37512c71b3e2SJacob 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)); 3752a4a685f2SJacob Faibussowitsch if (sizeof(int) == sizeof(PetscInt)) { 3753a4a685f2SJacob Faibussowitsch pintCells = (PetscInt *) cells; 3754a4a685f2SJacob Faibussowitsch } else { 3755a4a685f2SJacob Faibussowitsch ierr = PetscMalloc1(numCells*numCorners, &pintCells);CHKERRQ(ierr); 3756a4a685f2SJacob Faibussowitsch for (i = 0; i < numCells*numCorners; i++) { 3757a4a685f2SJacob Faibussowitsch pintCells[i] = (PetscInt) cells[i]; 3758a4a685f2SJacob Faibussowitsch } 3759a4a685f2SJacob Faibussowitsch } 37602c71b3e2SJacob 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)); 3761a4a685f2SJacob Faibussowitsch if (sizeof(double) == sizeof(PetscReal)) { 3762a4a685f2SJacob Faibussowitsch prealVC = (PetscReal *) vertexCoords; 3763a4a685f2SJacob Faibussowitsch } else { 3764a4a685f2SJacob Faibussowitsch ierr = PetscMalloc1(numVertices*spaceDim, &prealVC);CHKERRQ(ierr); 3765a4a685f2SJacob Faibussowitsch for (i = 0; i < numVertices*spaceDim; i++) { 3766a4a685f2SJacob Faibussowitsch prealVC[i] = (PetscReal) vertexCoords[i]; 3767a4a685f2SJacob Faibussowitsch } 3768a4a685f2SJacob Faibussowitsch } 3769a4a685f2SJacob Faibussowitsch ierr = DMPlexCreateFromCellListPetsc(comm, dim, numCells, numVertices, numCorners, interpolate, pintCells, spaceDim, prealVC, dm);CHKERRQ(ierr); 3770a4a685f2SJacob Faibussowitsch if (sizeof(int) != sizeof(PetscInt)) { 3771a4a685f2SJacob Faibussowitsch ierr = PetscFree(pintCells);CHKERRQ(ierr); 3772a4a685f2SJacob Faibussowitsch } 3773a4a685f2SJacob Faibussowitsch if (sizeof(double) != sizeof(PetscReal)) { 3774a4a685f2SJacob Faibussowitsch ierr = PetscFree(prealVC);CHKERRQ(ierr); 3775a4a685f2SJacob Faibussowitsch } 3776a4a685f2SJacob Faibussowitsch PetscFunctionReturn(0); 3777a4a685f2SJacob Faibussowitsch } 3778a4a685f2SJacob Faibussowitsch 3779a4a685f2SJacob Faibussowitsch /*@ 3780939f6067SMatthew 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 3781939f6067SMatthew G. Knepley 3782939f6067SMatthew G. Knepley Input Parameters: 3783c73cfb54SMatthew G. Knepley + dm - The empty DM object, usually from DMCreate() and DMSetDimension() 3784939f6067SMatthew G. Knepley . depth - The depth of the DAG 3785367003a6SStefano Zampini . numPoints - Array of size depth + 1 containing the number of points at each depth 3786939f6067SMatthew G. Knepley . coneSize - The cone size of each point 3787939f6067SMatthew G. Knepley . cones - The concatenation of the cone points for each point, the cone list must be oriented correctly for each point 3788939f6067SMatthew G. Knepley . coneOrientations - The orientation of each cone point 3789367003a6SStefano Zampini - vertexCoords - An array of numPoints[0]*spacedim numbers representing the coordinates of each vertex, with spacedim the value set via DMSetCoordinateDim() 3790939f6067SMatthew G. Knepley 3791939f6067SMatthew G. Knepley Output Parameter: 3792939f6067SMatthew G. Knepley . dm - The DM 3793939f6067SMatthew G. Knepley 3794939f6067SMatthew G. Knepley Note: Two triangles sharing a face would have input 3795939f6067SMatthew G. Knepley $ depth = 1, numPoints = [4 2], coneSize = [3 3 0 0 0 0] 3796939f6067SMatthew G. Knepley $ cones = [2 3 4 3 5 4], coneOrientations = [0 0 0 0 0 0] 3797939f6067SMatthew G. Knepley $ vertexCoords = [-1.0 0.0 0.0 -1.0 0.0 1.0 1.0 0.0] 3798939f6067SMatthew G. Knepley $ 3799939f6067SMatthew G. Knepley which would result in the DMPlex 3800939f6067SMatthew G. Knepley $ 3801939f6067SMatthew G. Knepley $ 4 3802939f6067SMatthew G. Knepley $ / | \ 3803939f6067SMatthew G. Knepley $ / | \ 3804939f6067SMatthew G. Knepley $ / | \ 3805939f6067SMatthew G. Knepley $ 2 0 | 1 5 3806939f6067SMatthew G. Knepley $ \ | / 3807939f6067SMatthew G. Knepley $ \ | / 3808939f6067SMatthew G. Knepley $ \ | / 3809939f6067SMatthew G. Knepley $ 3 3810939f6067SMatthew G. Knepley $ 3811a4a685f2SJacob Faibussowitsch $ Notice that all points are numbered consecutively, unlike DMPlexCreateFromCellListPetsc() 3812939f6067SMatthew G. Knepley 3813939f6067SMatthew G. Knepley Level: advanced 3814939f6067SMatthew G. Knepley 3815a4a685f2SJacob Faibussowitsch .seealso: DMPlexCreateFromCellListPetsc(), DMPlexCreate() 3816939f6067SMatthew G. Knepley @*/ 38179298eaa6SMatthew G Knepley PetscErrorCode DMPlexCreateFromDAG(DM dm, PetscInt depth, const PetscInt numPoints[], const PetscInt coneSize[], const PetscInt cones[], const PetscInt coneOrientations[], const PetscScalar vertexCoords[]) 38189298eaa6SMatthew G Knepley { 38199298eaa6SMatthew G Knepley Vec coordinates; 38209298eaa6SMatthew G Knepley PetscSection coordSection; 38219298eaa6SMatthew G Knepley PetscScalar *coords; 3822811e8653SToby Isaac PetscInt coordSize, firstVertex = -1, pStart = 0, pEnd = 0, p, v, dim, dimEmbed, d, off; 38239298eaa6SMatthew G Knepley PetscErrorCode ierr; 38249298eaa6SMatthew G Knepley 38259298eaa6SMatthew G Knepley PetscFunctionBegin; 3826c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 3827811e8653SToby Isaac ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr); 38282c71b3e2SJacob Faibussowitsch PetscCheckFalse(dimEmbed < dim,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Embedding dimension %D cannot be less than intrinsic dimension %d",dimEmbed,dim); 38299298eaa6SMatthew G Knepley for (d = 0; d <= depth; ++d) pEnd += numPoints[d]; 38309298eaa6SMatthew G Knepley ierr = DMPlexSetChart(dm, pStart, pEnd);CHKERRQ(ierr); 38319298eaa6SMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 38329298eaa6SMatthew G Knepley ierr = DMPlexSetConeSize(dm, p, coneSize[p-pStart]);CHKERRQ(ierr); 383397e052ccSToby Isaac if (firstVertex < 0 && !coneSize[p - pStart]) { 383497e052ccSToby Isaac firstVertex = p - pStart; 38359298eaa6SMatthew G Knepley } 383697e052ccSToby Isaac } 38372c71b3e2SJacob Faibussowitsch PetscCheckFalse(firstVertex < 0 && numPoints[0],PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Expected %D vertices but could not find any", numPoints[0]); 38389298eaa6SMatthew G Knepley ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ 38399298eaa6SMatthew G Knepley for (p = pStart, off = 0; p < pEnd; off += coneSize[p-pStart], ++p) { 38409298eaa6SMatthew G Knepley ierr = DMPlexSetCone(dm, p, &cones[off]);CHKERRQ(ierr); 38419298eaa6SMatthew G Knepley ierr = DMPlexSetConeOrientation(dm, p, &coneOrientations[off]);CHKERRQ(ierr); 38429298eaa6SMatthew G Knepley } 38439298eaa6SMatthew G Knepley ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); 38449298eaa6SMatthew G Knepley ierr = DMPlexStratify(dm);CHKERRQ(ierr); 38459298eaa6SMatthew G Knepley /* Build coordinates */ 3846c2166f76SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 38479298eaa6SMatthew G Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 3848811e8653SToby Isaac ierr = PetscSectionSetFieldComponents(coordSection, 0, dimEmbed);CHKERRQ(ierr); 38499298eaa6SMatthew G Knepley ierr = PetscSectionSetChart(coordSection, firstVertex, firstVertex+numPoints[0]);CHKERRQ(ierr); 38509298eaa6SMatthew G Knepley for (v = firstVertex; v < firstVertex+numPoints[0]; ++v) { 3851811e8653SToby Isaac ierr = PetscSectionSetDof(coordSection, v, dimEmbed);CHKERRQ(ierr); 3852811e8653SToby Isaac ierr = PetscSectionSetFieldDof(coordSection, v, 0, dimEmbed);CHKERRQ(ierr); 38539298eaa6SMatthew G Knepley } 38549298eaa6SMatthew G Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 38559298eaa6SMatthew G Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 38568b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 38576f8cbbeeSMatthew G Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 38589298eaa6SMatthew G Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 38598b9ced59SLisandro Dalcin ierr = VecSetBlockSize(coordinates, dimEmbed);CHKERRQ(ierr); 38602eb5907fSJed Brown ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 38619318fe57SMatthew G. Knepley if (vertexCoords) { 38629298eaa6SMatthew G Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 38639298eaa6SMatthew G Knepley for (v = 0; v < numPoints[0]; ++v) { 38649298eaa6SMatthew G Knepley PetscInt off; 38659298eaa6SMatthew G Knepley 38669298eaa6SMatthew G Knepley ierr = PetscSectionGetOffset(coordSection, v+firstVertex, &off);CHKERRQ(ierr); 3867811e8653SToby Isaac for (d = 0; d < dimEmbed; ++d) { 3868811e8653SToby Isaac coords[off+d] = vertexCoords[v*dimEmbed+d]; 38699298eaa6SMatthew G Knepley } 38709298eaa6SMatthew G Knepley } 38719318fe57SMatthew G. Knepley } 38729298eaa6SMatthew G Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 38739298eaa6SMatthew G Knepley ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); 38749298eaa6SMatthew G Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 38759298eaa6SMatthew G Knepley PetscFunctionReturn(0); 38769298eaa6SMatthew G Knepley } 38778415267dSToby Isaac 3878ca522641SMatthew G. Knepley /*@C 38798ca92349SMatthew G. Knepley DMPlexCreateCellVertexFromFile - Create a DMPlex mesh from a simple cell-vertex file. 38808ca92349SMatthew G. Knepley 38818ca92349SMatthew G. Knepley + comm - The MPI communicator 38828ca92349SMatthew G. Knepley . filename - Name of the .dat file 38838ca92349SMatthew G. Knepley - interpolate - Create faces and edges in the mesh 38848ca92349SMatthew G. Knepley 38858ca92349SMatthew G. Knepley Output Parameter: 38868ca92349SMatthew G. Knepley . dm - The DM object representing the mesh 38878ca92349SMatthew G. Knepley 38888ca92349SMatthew G. Knepley Note: The format is the simplest possible: 38898ca92349SMatthew G. Knepley $ Ne 38908ca92349SMatthew G. Knepley $ v0 v1 ... vk 38918ca92349SMatthew G. Knepley $ Nv 38928ca92349SMatthew G. Knepley $ x y z marker 38938ca92349SMatthew G. Knepley 38948ca92349SMatthew G. Knepley Level: beginner 38958ca92349SMatthew G. Knepley 38968ca92349SMatthew G. Knepley .seealso: DMPlexCreateFromFile(), DMPlexCreateMedFromFile(), DMPlexCreateGmsh(), DMPlexCreate() 38978ca92349SMatthew G. Knepley @*/ 38988ca92349SMatthew G. Knepley PetscErrorCode DMPlexCreateCellVertexFromFile(MPI_Comm comm, const char filename[], PetscBool interpolate, DM *dm) 38998ca92349SMatthew G. Knepley { 39008ca92349SMatthew G. Knepley DMLabel marker; 39018ca92349SMatthew G. Knepley PetscViewer viewer; 39028ca92349SMatthew G. Knepley Vec coordinates; 39038ca92349SMatthew G. Knepley PetscSection coordSection; 39048ca92349SMatthew G. Knepley PetscScalar *coords; 39058ca92349SMatthew G. Knepley char line[PETSC_MAX_PATH_LEN]; 39068ca92349SMatthew G. Knepley PetscInt dim = 3, cdim = 3, coordSize, v, c, d; 39078ca92349SMatthew G. Knepley PetscMPIInt rank; 3908f8d5e320SMatthew G. Knepley int snum, Nv, Nc, Ncn, Nl; 39098ca92349SMatthew G. Knepley PetscErrorCode ierr; 39108ca92349SMatthew G. Knepley 39118ca92349SMatthew G. Knepley PetscFunctionBegin; 3912ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 39138ca92349SMatthew G. Knepley ierr = PetscViewerCreate(comm, &viewer);CHKERRQ(ierr); 39148ca92349SMatthew G. Knepley ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr); 39158ca92349SMatthew G. Knepley ierr = PetscViewerFileSetMode(viewer, FILE_MODE_READ);CHKERRQ(ierr); 39168ca92349SMatthew G. Knepley ierr = PetscViewerFileSetName(viewer, filename);CHKERRQ(ierr); 3917dd400576SPatrick Sanan if (rank == 0) { 3918f8d5e320SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 4, NULL, PETSC_STRING);CHKERRQ(ierr); 3919f8d5e320SMatthew G. Knepley snum = sscanf(line, "%d %d %d %d", &Nc, &Nv, &Ncn, &Nl); 39202c71b3e2SJacob Faibussowitsch PetscCheckFalse(snum != 4,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 392125ce1634SJed Brown } else { 3922f8d5e320SMatthew G. Knepley Nc = Nv = Ncn = Nl = 0; 39238ca92349SMatthew G. Knepley } 39248ca92349SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 39258ca92349SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 39268ca92349SMatthew G. Knepley ierr = DMPlexSetChart(*dm, 0, Nc+Nv);CHKERRQ(ierr); 39278ca92349SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 39288ca92349SMatthew G. Knepley ierr = DMSetCoordinateDim(*dm, cdim);CHKERRQ(ierr); 39298ca92349SMatthew G. Knepley /* Read topology */ 3930dd400576SPatrick Sanan if (rank == 0) { 3931f8d5e320SMatthew G. Knepley char format[PETSC_MAX_PATH_LEN]; 3932f8d5e320SMatthew G. Knepley PetscInt cone[8]; 39338ca92349SMatthew G. Knepley int vbuf[8], v; 39348ca92349SMatthew G. Knepley 3935f8d5e320SMatthew G. Knepley for (c = 0; c < Ncn; ++c) {format[c*3+0] = '%'; format[c*3+1] = 'd'; format[c*3+2] = ' ';} 3936f8d5e320SMatthew G. Knepley format[Ncn*3-1] = '\0'; 3937f8d5e320SMatthew G. Knepley for (c = 0; c < Nc; ++c) {ierr = DMPlexSetConeSize(*dm, c, Ncn);CHKERRQ(ierr);} 39388ca92349SMatthew G. Knepley ierr = DMSetUp(*dm);CHKERRQ(ierr); 39398ca92349SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 3940f8d5e320SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, Ncn, NULL, PETSC_STRING);CHKERRQ(ierr); 3941f8d5e320SMatthew G. Knepley switch (Ncn) { 3942f8d5e320SMatthew G. Knepley case 2: snum = sscanf(line, format, &vbuf[0], &vbuf[1]);break; 3943f8d5e320SMatthew G. Knepley case 3: snum = sscanf(line, format, &vbuf[0], &vbuf[1], &vbuf[2]);break; 3944f8d5e320SMatthew G. Knepley case 4: snum = sscanf(line, format, &vbuf[0], &vbuf[1], &vbuf[2], &vbuf[3]);break; 3945f8d5e320SMatthew G. Knepley case 6: snum = sscanf(line, format, &vbuf[0], &vbuf[1], &vbuf[2], &vbuf[3], &vbuf[4], &vbuf[5]);break; 3946f8d5e320SMatthew 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; 394798921bdaSJacob Faibussowitsch default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No cell shape with %D vertices", Ncn); 3948f8d5e320SMatthew G. Knepley } 39492c71b3e2SJacob Faibussowitsch PetscCheckFalse(snum != Ncn,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 3950f8d5e320SMatthew G. Knepley for (v = 0; v < Ncn; ++v) cone[v] = vbuf[v] + Nc; 39518ca92349SMatthew G. Knepley /* Hexahedra are inverted */ 3952f8d5e320SMatthew G. Knepley if (Ncn == 8) { 39538ca92349SMatthew G. Knepley PetscInt tmp = cone[1]; 39548ca92349SMatthew G. Knepley cone[1] = cone[3]; 39558ca92349SMatthew G. Knepley cone[3] = tmp; 39568ca92349SMatthew G. Knepley } 39578ca92349SMatthew G. Knepley ierr = DMPlexSetCone(*dm, c, cone);CHKERRQ(ierr); 39588ca92349SMatthew G. Knepley } 39598ca92349SMatthew G. Knepley } 39608ca92349SMatthew G. Knepley ierr = DMPlexSymmetrize(*dm);CHKERRQ(ierr); 39618ca92349SMatthew G. Knepley ierr = DMPlexStratify(*dm);CHKERRQ(ierr); 39628ca92349SMatthew G. Knepley /* Read coordinates */ 39638ca92349SMatthew G. Knepley ierr = DMGetCoordinateSection(*dm, &coordSection);CHKERRQ(ierr); 39648ca92349SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 39658ca92349SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, cdim);CHKERRQ(ierr); 39668ca92349SMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, Nc, Nc + Nv);CHKERRQ(ierr); 39678ca92349SMatthew G. Knepley for (v = Nc; v < Nc+Nv; ++v) { 39688ca92349SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, cdim);CHKERRQ(ierr); 39698ca92349SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, cdim);CHKERRQ(ierr); 39708ca92349SMatthew G. Knepley } 39718ca92349SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 39728ca92349SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 39738ca92349SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 39748ca92349SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 39758ca92349SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 39768ca92349SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, cdim);CHKERRQ(ierr); 39778ca92349SMatthew G. Knepley ierr = VecSetType(coordinates, VECSTANDARD);CHKERRQ(ierr); 39788ca92349SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 3979dd400576SPatrick Sanan if (rank == 0) { 3980f8d5e320SMatthew G. Knepley char format[PETSC_MAX_PATH_LEN]; 39818ca92349SMatthew G. Knepley double x[3]; 3982f8d5e320SMatthew G. Knepley int l, val[3]; 39838ca92349SMatthew G. Knepley 3984f8d5e320SMatthew G. Knepley if (Nl) { 3985f8d5e320SMatthew G. Knepley for (l = 0; l < Nl; ++l) {format[l*3+0] = '%'; format[l*3+1] = 'd'; format[l*3+2] = ' ';} 3986f8d5e320SMatthew G. Knepley format[Nl*3-1] = '\0'; 39878ca92349SMatthew G. Knepley ierr = DMCreateLabel(*dm, "marker");CHKERRQ(ierr); 39888ca92349SMatthew G. Knepley ierr = DMGetLabel(*dm, "marker", &marker);CHKERRQ(ierr); 3989f8d5e320SMatthew G. Knepley } 39908ca92349SMatthew G. Knepley for (v = 0; v < Nv; ++v) { 3991f8d5e320SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 3+Nl, NULL, PETSC_STRING);CHKERRQ(ierr); 3992f8d5e320SMatthew G. Knepley snum = sscanf(line, "%lg %lg %lg", &x[0], &x[1], &x[2]); 39932c71b3e2SJacob Faibussowitsch PetscCheckFalse(snum != 3,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 3994f8d5e320SMatthew G. Knepley switch (Nl) { 3995f8d5e320SMatthew G. Knepley case 0: snum = 0;break; 3996f8d5e320SMatthew G. Knepley case 1: snum = sscanf(line, format, &val[0]);break; 3997f8d5e320SMatthew G. Knepley case 2: snum = sscanf(line, format, &val[0], &val[1]);break; 3998f8d5e320SMatthew G. Knepley case 3: snum = sscanf(line, format, &val[0], &val[1], &val[2]);break; 399998921bdaSJacob Faibussowitsch default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Request support for %D labels", Nl); 4000f8d5e320SMatthew G. Knepley } 40012c71b3e2SJacob Faibussowitsch PetscCheckFalse(snum != Nl,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse cell-vertex file: %s", line); 40028ca92349SMatthew G. Knepley for (d = 0; d < cdim; ++d) coords[v*cdim+d] = x[d]; 4003f8d5e320SMatthew G. Knepley for (l = 0; l < Nl; ++l) {ierr = DMLabelSetValue(marker, v+Nc, val[l]);CHKERRQ(ierr);} 40048ca92349SMatthew G. Knepley } 40058ca92349SMatthew G. Knepley } 40068ca92349SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 40078ca92349SMatthew G. Knepley ierr = DMSetCoordinatesLocal(*dm, coordinates);CHKERRQ(ierr); 40088ca92349SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 40098ca92349SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 40108ca92349SMatthew G. Knepley if (interpolate) { 40118ca92349SMatthew G. Knepley DM idm; 40128ca92349SMatthew G. Knepley DMLabel bdlabel; 40138ca92349SMatthew G. Knepley 40148ca92349SMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 40158ca92349SMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 40168ca92349SMatthew G. Knepley *dm = idm; 40178ca92349SMatthew G. Knepley 4018f8d5e320SMatthew G. Knepley if (!Nl) { 4019f8d5e320SMatthew G. Knepley ierr = DMCreateLabel(*dm, "marker");CHKERRQ(ierr); 40208ca92349SMatthew G. Knepley ierr = DMGetLabel(*dm, "marker", &bdlabel);CHKERRQ(ierr); 40218ca92349SMatthew G. Knepley ierr = DMPlexMarkBoundaryFaces(*dm, PETSC_DETERMINE, bdlabel);CHKERRQ(ierr); 40228ca92349SMatthew G. Knepley ierr = DMPlexLabelComplete(*dm, bdlabel);CHKERRQ(ierr); 40238ca92349SMatthew G. Knepley } 4024f8d5e320SMatthew G. Knepley } 40258ca92349SMatthew G. Knepley PetscFunctionReturn(0); 40268ca92349SMatthew G. Knepley } 40278ca92349SMatthew G. Knepley 40288ca92349SMatthew G. Knepley /*@C 4029ca522641SMatthew G. Knepley DMPlexCreateFromFile - This takes a filename and produces a DM 4030ca522641SMatthew G. Knepley 4031ca522641SMatthew G. Knepley Input Parameters: 4032ca522641SMatthew G. Knepley + comm - The communicator 4033ca522641SMatthew G. Knepley . filename - A file name 4034cd7e8a5eSksagiyam . plexname - The object name of the resulting DM, also used for intra-datafile lookup by some formats 4035ca522641SMatthew G. Knepley - interpolate - Flag to create intermediate mesh pieces (edges, faces) 4036ca522641SMatthew G. Knepley 4037ca522641SMatthew G. Knepley Output Parameter: 4038ca522641SMatthew G. Knepley . dm - The DM 4039ca522641SMatthew G. Knepley 404002ef0d99SVaclav Hapla Options Database Keys: 404102ef0d99SVaclav Hapla . -dm_plex_create_from_hdf5_xdmf - use the PETSC_VIEWER_HDF5_XDMF format for reading HDF5 404202ef0d99SVaclav Hapla 4043bca97951SVaclav Hapla Use -dm_plex_create_ prefix to pass options to the internal PetscViewer, e.g. 4044bca97951SVaclav Hapla $ -dm_plex_create_viewer_hdf5_collective 4045bca97951SVaclav Hapla 4046cd7e8a5eSksagiyam Notes: 4047cd7e8a5eSksagiyam Using PETSCVIEWERHDF5 type with PETSC_VIEWER_HDF5_PETSC format, one can save multiple DMPlex 4048cd7e8a5eSksagiyam meshes in a single HDF5 file. This in turn requires one to name the DMPlex object with PetscObjectSetName() 4049cd7e8a5eSksagiyam before saving it with DMView() and before loading it with DMLoad() for identification of the mesh object. 4050cd7e8a5eSksagiyam The input parameter name is thus used to name the DMPlex object when DMPlexCreateFromFile() internally 4051cd7e8a5eSksagiyam calls DMLoad(). Currently, name is ignored for other viewer types and/or formats. 4052cd7e8a5eSksagiyam 4053ca522641SMatthew G. Knepley Level: beginner 4054ca522641SMatthew G. Knepley 4055cd7e8a5eSksagiyam .seealso: DMPlexCreateFromDAG(), DMPlexCreateFromCellListPetsc(), DMPlexCreate(), PetscObjectSetName(), DMView(), DMLoad() 4056ca522641SMatthew G. Knepley @*/ 4057cd7e8a5eSksagiyam PetscErrorCode DMPlexCreateFromFile(MPI_Comm comm, const char filename[], const char plexname[], PetscBool interpolate, DM *dm) 4058ca522641SMatthew G. Knepley { 4059ca522641SMatthew G. Knepley const char *extGmsh = ".msh"; 4060de78e4feSLisandro Dalcin const char *extGmsh2 = ".msh2"; 4061de78e4feSLisandro Dalcin const char *extGmsh4 = ".msh4"; 4062ca522641SMatthew G. Knepley const char *extCGNS = ".cgns"; 4063ca522641SMatthew G. Knepley const char *extExodus = ".exo"; 406490c68965SMatthew G. Knepley const char *extGenesis = ".gen"; 40652f0bd6dcSMichael Lange const char *extFluent = ".cas"; 4066cc2f8f65SMatthew G. Knepley const char *extHDF5 = ".h5"; 4067707dd687SMichael Lange const char *extMed = ".med"; 4068f2801cd6SMatthew G. Knepley const char *extPLY = ".ply"; 4069c1cad2e7SMatthew G. Knepley const char *extEGADSLite = ".egadslite"; 4070c1cad2e7SMatthew G. Knepley const char *extEGADS = ".egads"; 4071c1cad2e7SMatthew G. Knepley const char *extIGES = ".igs"; 4072c1cad2e7SMatthew G. Knepley const char *extSTEP = ".stp"; 40738ca92349SMatthew G. Knepley const char *extCV = ".dat"; 4074ca522641SMatthew G. Knepley size_t len; 4075c1cad2e7SMatthew G. Knepley PetscBool isGmsh, isGmsh2, isGmsh4, isCGNS, isExodus, isGenesis, isFluent, isHDF5, isMed, isPLY, isEGADSLite, isEGADS, isIGES, isSTEP, isCV; 4076ca522641SMatthew G. Knepley PetscMPIInt rank; 4077ca522641SMatthew G. Knepley PetscErrorCode ierr; 4078ca522641SMatthew G. Knepley 4079ca522641SMatthew G. Knepley PetscFunctionBegin; 40805d80c0bfSVaclav Hapla PetscValidCharPointer(filename, 2); 40810d862eaeSPierre Jolivet if (plexname) PetscValidCharPointer(plexname, 3); 4082cd7e8a5eSksagiyam PetscValidPointer(dm, 5); 4083f1f45c63SVaclav Hapla ierr = DMInitializePackage();CHKERRQ(ierr); 4084f1f45c63SVaclav Hapla ierr = PetscLogEventBegin(DMPLEX_CreateFromFile,0,0,0,0);CHKERRQ(ierr); 4085ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 4086ca522641SMatthew G. Knepley ierr = PetscStrlen(filename, &len);CHKERRQ(ierr); 40872c71b3e2SJacob Faibussowitsch PetscCheckFalse(!len,comm, PETSC_ERR_ARG_WRONG, "Filename must be a valid path"); 4088ca522641SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extGmsh, 4, &isGmsh);CHKERRQ(ierr); 4089de78e4feSLisandro Dalcin ierr = PetscStrncmp(&filename[PetscMax(0,len-5)], extGmsh2, 5, &isGmsh2);CHKERRQ(ierr); 4090de78e4feSLisandro Dalcin ierr = PetscStrncmp(&filename[PetscMax(0,len-5)], extGmsh4, 5, &isGmsh4);CHKERRQ(ierr); 4091ca522641SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-5)], extCGNS, 5, &isCGNS);CHKERRQ(ierr); 4092ca522641SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extExodus, 4, &isExodus);CHKERRQ(ierr); 409390c68965SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extGenesis, 4, &isGenesis);CHKERRQ(ierr); 40942f0bd6dcSMichael Lange ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extFluent, 4, &isFluent);CHKERRQ(ierr); 4095cc2f8f65SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-3)], extHDF5, 3, &isHDF5);CHKERRQ(ierr); 4096707dd687SMichael Lange ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extMed, 4, &isMed);CHKERRQ(ierr); 4097f2801cd6SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extPLY, 4, &isPLY);CHKERRQ(ierr); 4098c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-10)], extEGADSLite, 10, &isEGADSLite);CHKERRQ(ierr); 4099c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-6)], extEGADS, 6, &isEGADS);CHKERRQ(ierr); 4100c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extIGES, 4, &isIGES);CHKERRQ(ierr); 4101c1cad2e7SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extSTEP, 4, &isSTEP);CHKERRQ(ierr); 41028ca92349SMatthew G. Knepley ierr = PetscStrncmp(&filename[PetscMax(0,len-4)], extCV, 4, &isCV);CHKERRQ(ierr); 4103de78e4feSLisandro Dalcin if (isGmsh || isGmsh2 || isGmsh4) { 41047d282ae0SMichael Lange ierr = DMPlexCreateGmshFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4105ca522641SMatthew G. Knepley } else if (isCGNS) { 4106ca522641SMatthew G. Knepley ierr = DMPlexCreateCGNSFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 410790c68965SMatthew G. Knepley } else if (isExodus || isGenesis) { 4108ca522641SMatthew G. Knepley ierr = DMPlexCreateExodusFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 41092f0bd6dcSMichael Lange } else if (isFluent) { 41102f0bd6dcSMichael Lange ierr = DMPlexCreateFluentFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4111cc2f8f65SMatthew G. Knepley } else if (isHDF5) { 41129c48423bSVaclav Hapla PetscBool load_hdf5_xdmf = PETSC_FALSE; 4113cc2f8f65SMatthew G. Knepley PetscViewer viewer; 4114cc2f8f65SMatthew G. Knepley 411543b242b4SVaclav 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 */ 411643b242b4SVaclav Hapla ierr = PetscStrncmp(&filename[PetscMax(0,len-8)], ".xdmf", 5, &load_hdf5_xdmf);CHKERRQ(ierr); 41179c48423bSVaclav Hapla ierr = PetscOptionsGetBool(NULL, NULL, "-dm_plex_create_from_hdf5_xdmf", &load_hdf5_xdmf, NULL);CHKERRQ(ierr); 4118cc2f8f65SMatthew G. Knepley ierr = PetscViewerCreate(comm, &viewer);CHKERRQ(ierr); 4119cc2f8f65SMatthew G. Knepley ierr = PetscViewerSetType(viewer, PETSCVIEWERHDF5);CHKERRQ(ierr); 4120bca97951SVaclav Hapla ierr = PetscViewerSetOptionsPrefix(viewer, "dm_plex_create_");CHKERRQ(ierr); 4121bca97951SVaclav Hapla ierr = PetscViewerSetFromOptions(viewer);CHKERRQ(ierr); 4122cc2f8f65SMatthew G. Knepley ierr = PetscViewerFileSetMode(viewer, FILE_MODE_READ);CHKERRQ(ierr); 4123cc2f8f65SMatthew G. Knepley ierr = PetscViewerFileSetName(viewer, filename);CHKERRQ(ierr); 4124cd7e8a5eSksagiyam 4125cc2f8f65SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 4126cd7e8a5eSksagiyam ierr = PetscObjectSetName((PetscObject)(*dm), plexname);CHKERRQ(ierr); 4127cc2f8f65SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 41289c48423bSVaclav Hapla if (load_hdf5_xdmf) {ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_HDF5_XDMF);CHKERRQ(ierr);} 4129cc2f8f65SMatthew G. Knepley ierr = DMLoad(*dm, viewer);CHKERRQ(ierr); 41309c48423bSVaclav Hapla if (load_hdf5_xdmf) {ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);} 4131cc2f8f65SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 41325fd9971aSMatthew G. Knepley 41335fd9971aSMatthew G. Knepley if (interpolate) { 41345fd9971aSMatthew G. Knepley DM idm; 41355fd9971aSMatthew G. Knepley 41365fd9971aSMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 41375fd9971aSMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 41385fd9971aSMatthew G. Knepley *dm = idm; 41395fd9971aSMatthew G. Knepley } 4140707dd687SMichael Lange } else if (isMed) { 4141707dd687SMichael Lange ierr = DMPlexCreateMedFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4142f2801cd6SMatthew G. Knepley } else if (isPLY) { 4143f2801cd6SMatthew G. Knepley ierr = DMPlexCreatePLYFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 4144c1cad2e7SMatthew G. Knepley } else if (isEGADSLite || isEGADS || isIGES || isSTEP) { 4145c1cad2e7SMatthew G. Knepley if (isEGADSLite) {ierr = DMPlexCreateEGADSLiteFromFile(comm, filename, dm);CHKERRQ(ierr);} 4146c1cad2e7SMatthew G. Knepley else {ierr = DMPlexCreateEGADSFromFile(comm, filename, dm);CHKERRQ(ierr);} 41477bee2925SMatthew Knepley if (!interpolate) { 41487bee2925SMatthew Knepley DM udm; 41497bee2925SMatthew Knepley 41507bee2925SMatthew Knepley ierr = DMPlexUninterpolate(*dm, &udm);CHKERRQ(ierr); 41517bee2925SMatthew Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 41527bee2925SMatthew Knepley *dm = udm; 41537bee2925SMatthew Knepley } 41548ca92349SMatthew G. Knepley } else if (isCV) { 41558ca92349SMatthew G. Knepley ierr = DMPlexCreateCellVertexFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); 415698921bdaSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot load file %s: unrecognized extension", filename); 4157ed5e4e85SVaclav Hapla ierr = PetscStrlen(plexname, &len);CHKERRQ(ierr); 4158ed5e4e85SVaclav Hapla if (len) {ierr = PetscObjectSetName((PetscObject)(*dm), plexname);CHKERRQ(ierr);} 4159f1f45c63SVaclav Hapla ierr = PetscLogEventEnd(DMPLEX_CreateFromFile,0,0,0,0);CHKERRQ(ierr); 4160ca522641SMatthew G. Knepley PetscFunctionReturn(0); 4161ca522641SMatthew G. Knepley } 4162