/* There is a problem here with uninterpolated meshes. The index in numDof[] is not dimension in this case, but sieve depth. */ PetscErrorCode SetupSection(DM dm, AppCtx *user) { PetscSection section; const PetscInt numFields = NUM_FIELDS; PetscInt dim = user->dim; PetscInt numBC = 0; PetscInt bcFields[1] = {0}; IS bcPoints[1] = {NULL}; PetscInt numComp[NUM_FIELDS]; const PetscInt *numFieldDof[NUM_FIELDS]; PetscInt *numDof; PetscInt f, d; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = PetscFEGetNumComponents(user->fe[0], &numComp[0]);CHKERRQ(ierr); ierr = PetscFEGetNumComponents(user->fe[1], &numComp[1]);CHKERRQ(ierr); ierr = PetscFEGetNumDof(user->fe[0], &numFieldDof[0]);CHKERRQ(ierr); ierr = PetscFEGetNumDof(user->fe[1], &numFieldDof[1]);CHKERRQ(ierr); ierr = PetscMalloc(NUM_FIELDS*(dim+1) * sizeof(PetscInt), &numDof);CHKERRQ(ierr); for (f = 0; f < NUM_FIELDS; ++f) { for (d = 0; d <= dim; ++d) { numDof[f*(dim+1)+d] = numFieldDof[f][d]; } } for (f = 0; f < numFields; ++f) { for (d = 1; d < dim; ++d) { if ((numDof[f*(dim+1)+d] > 0) && !user->interpolate) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated when unknowns are specified on edges or faces."); } } if (user->bcType == DIRICHLET) { numBC = 1; ierr = DMPlexGetStratumIS(dm, "marker", 1, &bcPoints[0]);CHKERRQ(ierr); } ierr = DMPlexCreateSection(dm, dim, numFields, numComp, numDof, numBC, bcFields, bcPoints, §ion);CHKERRQ(ierr); ierr = PetscSectionSetFieldName(section, 0, "velocity");CHKERRQ(ierr); ierr = PetscSectionSetFieldName(section, 1, "pressure");CHKERRQ(ierr); ierr = DMSetDefaultSection(dm, section);CHKERRQ(ierr); ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); if (user->bcType == DIRICHLET) { ierr = ISDestroy(&bcPoints[0]);CHKERRQ(ierr); } ierr = PetscFree(numDof);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* There is a problem here with uninterpolated meshes. The index in numDof[] is not dimension in this case, but sieve depth. */ PetscErrorCode SetupSection(DM dm, AppCtx *user) { PetscSection section; const PetscInt numFields = NUM_FIELDS; PetscInt dim = user->dim; PetscInt numBC = 0; PetscInt numComp[NUM_FIELDS] = {NUM_BASIS_COMPONENTS_0, NUM_BASIS_COMPONENTS_1}; PetscInt bcFields[1] = {0}; IS bcPoints[1] = {NULL}; PetscInt numDof[NUM_FIELDS*(SPATIAL_DIM_0+1)]; PetscInt f, d; PetscErrorCode ierr; PetscFunctionBeginUser; if (dim != SPATIAL_DIM_0) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_SIZ, "Spatial dimension %d should be %d", dim, SPATIAL_DIM_0); if (dim != SPATIAL_DIM_1) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_SIZ, "Spatial dimension %d should be %d", dim, SPATIAL_DIM_1); for (d = 0; d <= dim; ++d) { numDof[0*(dim+1)+d] = numDof_0[d]; numDof[1*(dim+1)+d] = numDof_1[d]; } for (f = 0; f < numFields; ++f) { for (d = 1; d < dim; ++d) { if ((numDof[f*(dim+1)+d] > 0) && !user->interpolate) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated when unknowns are specified on edges or faces."); } } if (user->bcType == DIRICHLET) { numBC = 1; ierr = DMPlexGetStratumIS(dm, "marker", 1, &bcPoints[0]);CHKERRQ(ierr); } ierr = DMPlexCreateSection(dm, dim, numFields, numComp, numDof, numBC, bcFields, bcPoints, §ion);CHKERRQ(ierr); ierr = PetscSectionSetFieldName(section, 0, "velocity");CHKERRQ(ierr); ierr = PetscSectionSetFieldName(section, 1, "pressure");CHKERRQ(ierr); ierr = DMSetDefaultSection(dm, section);CHKERRQ(ierr); if (user->bcType == DIRICHLET) { ierr = ISDestroy(&bcPoints[0]);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode ApplyBC(DM dm, PetscReal time, Vec locX, User user) { const char *name = "Face Sets"; /*Set up in the function DMPlexCreateExodus. is the side set*/ DM dmFace; IS idIS; const PetscInt *ids; PetscScalar *x; const PetscScalar *facegeom; PetscInt numFS, fs; PetscErrorCode ierr; PetscMPIInt rank; PetscFunctionBeginUser; ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = VecGetDM(user->facegeom,&dmFace);CHKERRQ(ierr); ierr = DMPlexGetLabelIdIS(dm, name, &idIS);CHKERRQ(ierr); // ISView(idIS, PETSC_VIEWER_STDOUT_SELF); if (!idIS) PetscFunctionReturn(0); ierr = ISGetLocalSize(idIS, &numFS);CHKERRQ(ierr); ierr = ISGetIndices(idIS, &ids);CHKERRQ(ierr); ierr = VecGetArrayRead(user->facegeom, &facegeom);CHKERRQ(ierr); ierr = VecGetArray(locX, &x);CHKERRQ(ierr); for (fs = 0; fs < numFS; ++fs) { IS faceIS; const PetscInt *faces; PetscInt numFaces, f; ierr = DMPlexGetStratumIS(dm, name, ids[fs], &faceIS);CHKERRQ(ierr); ierr = ISGetLocalSize(faceIS, &numFaces);CHKERRQ(ierr); ierr = ISGetIndices(faceIS, &faces);CHKERRQ(ierr); for (f = 0; f < numFaces; ++f) { // PetscPrintf(PETSC_COMM_SELF, "rank[%d]: ids[%d] = %d, faceIS[%d] = %d, numFaces = %d\n", rank, fs, ids[fs], f, faces[f], numFaces); const PetscInt face = faces[f], *cells; const PetscScalar *xI; /*Inner point*/ PetscScalar *xG; /*Ghost point*/ const FaceGeom *fg; ierr = DMPlexPointLocalRead(dmFace, face, facegeom, &fg);CHKERRQ(ierr); ierr = DMPlexGetSupport(dm, face, &cells);CHKERRQ(ierr); ierr = DMPlexPointLocalRead(dm, cells[0], x, &xI);CHKERRQ(ierr); ierr = DMPlexPointLocalRef(dm, cells[1], x, &xG);CHKERRQ(ierr); if (ids[fs]==1){ //PetscPrintf(PETSC_COMM_SELF, "Set Inlfow Boundary Condition! \n"); ierr = BoundaryInflow(time, fg->centroid, fg->normal, xI, xG, user);CHKERRQ(ierr); // DM dmCell; // const PetscScalar *cellgeom; // const CellGeom *cgL, *cgR; // ierr = VecGetDM(user->cellgeom,&dmCell);CHKERRQ(ierr); // ierr = VecGetArrayRead(user->cellgeom, &cellgeom);CHKERRQ(ierr); // ierr = DMPlexPointLocalRead(dmCell, cells[0], cellgeom, &cgL);CHKERRQ(ierr); // ierr = DMPlexPointLocalRead(dmCell, cells[1], cellgeom, &cgR);CHKERRQ(ierr); // ierr = PetscPrintf(PETSC_COMM_WORLD,"cells[0] = (%f, %f, %f), cells[1] = (%f, %f, %f)\n",cgL->centroid[0], cgL->centroid[1], cgL->centroid[2],cgR->centroid[0], cgR->centroid[1], cgR->centroid[2]);CHKERRQ(ierr); }else if (ids[fs]==2){ //PetscPrintf(PETSC_COMM_SELF, "Set Outlfow Boundary Condition! \n"); ierr = BoundaryOutflow(time, fg->centroid, fg->normal, xI, xG, user);CHKERRQ(ierr); }else if (ids[fs]==3){ //PetscPrintf(PETSC_COMM_SELF, "Set Wall Boundary Condition! \n"); ierr = BoundaryWallflow(time, fg->centroid, fg->normal, xI, xG, user);CHKERRQ(ierr); }else { SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Wrong type of boundary condition setup!!! \n The set up of the boundary should be: 1 for the inflow, 2 for the outflow, and 3 for the wallflow"); } } // PetscPrintf(PETSC_COMM_SELF, " \n"); ierr = ISRestoreIndices(faceIS, &faces);CHKERRQ(ierr); ierr = ISDestroy(&faceIS);CHKERRQ(ierr); } ierr = VecRestoreArray(locX, &x);CHKERRQ(ierr); ierr = VecRestoreArrayRead(user->facegeom,&facegeom);CHKERRQ(ierr); ierr = ISRestoreIndices(idIS, &ids);CHKERRQ(ierr); ierr = ISDestroy(&idIS);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc, char **argv) { DM dm, dmDist = NULL; Vec u; PetscSection section; PetscViewer viewer; PetscInt dim = 2, numFields, numBC, i; PetscInt numComp[3]; PetscInt numDof[12]; PetscInt bcField[1]; IS bcPointIS[1]; PetscBool interpolate = PETSC_TRUE; PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, NULL, help);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL, "-dim", &dim, NULL);CHKERRQ(ierr); /* Create a mesh */ ierr = DMPlexCreateBoxMesh(PETSC_COMM_WORLD, dim, interpolate, &dm);CHKERRQ(ierr); /* Distribute mesh over processes */ ierr = DMPlexDistribute(dm, 0, NULL, &dmDist);CHKERRQ(ierr); if (dmDist) {ierr = DMDestroy(&dm);CHKERRQ(ierr); dm = dmDist;} /* Create a scalar field u, a vector field v, and a surface vector field w */ numFields = 3; numComp[0] = 1; numComp[1] = dim; numComp[2] = dim-1; for (i = 0; i < numFields*(dim+1); ++i) numDof[i] = 0; /* Let u be defined on vertices */ numDof[0*(dim+1)+0] = 1; /* Let v be defined on cells */ numDof[1*(dim+1)+dim] = dim; /* Let v be defined on faces */ numDof[2*(dim+1)+dim-1] = dim-1; /* Setup boundary conditions */ numBC = 1; /* Prescribe a Dirichlet condition on u on the boundary Label "marker" is made by the mesh creation routine */ bcField[0] = 0; ierr = DMPlexGetStratumIS(dm, "marker", 1, &bcPointIS[0]);CHKERRQ(ierr); /* Create a PetscSection with this data layout */ ierr = DMPlexCreateSection(dm, dim, numFields, numComp, numDof, numBC, bcField, bcPointIS, NULL, §ion);CHKERRQ(ierr); ierr = ISDestroy(&bcPointIS[0]);CHKERRQ(ierr); /* Name the Field variables */ ierr = PetscSectionSetFieldName(section, 0, "u");CHKERRQ(ierr); ierr = PetscSectionSetFieldName(section, 1, "v");CHKERRQ(ierr); ierr = PetscSectionSetFieldName(section, 2, "w");CHKERRQ(ierr); ierr = PetscSectionView(section, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* Tell the DM to use this data layout */ ierr = DMSetDefaultSection(dm, section);CHKERRQ(ierr); /* Create a Vec with this layout and view it */ ierr = DMGetGlobalVector(dm, &u);CHKERRQ(ierr); ierr = PetscViewerCreate(PETSC_COMM_WORLD, &viewer);CHKERRQ(ierr); ierr = PetscViewerSetType(viewer, PETSCVIEWERVTK);CHKERRQ(ierr); ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr); ierr = PetscViewerFileSetName(viewer, "sol.vtk");CHKERRQ(ierr); ierr = VecView(u, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dm, &u);CHKERRQ(ierr); /* Cleanup */ ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); ierr = DMDestroy(&dm);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }