/* 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); }
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);if (ierr) return ierr; ierr = PetscOptionsGetInt(NULL,NULL, "-dim", &dim, NULL);CHKERRQ(ierr); /* Create a mesh */ ierr = DMPlexCreateBoxMesh(PETSC_COMM_WORLD, dim, PETSC_TRUE, NULL, NULL, NULL, NULL, 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 = DMGetStratumIS(dm, "marker", 1, &bcPointIS[0]);CHKERRQ(ierr); /* Create a PetscSection with this data layout */ ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr); ierr = DMPlexCreateSection(dm, NULL, numComp, numDof, numBC, bcField, NULL, 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 = DMSetSection(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 = PetscViewerPushFormat(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 ierr; }