Actual source code: ex1f90.F90

  1: #include <petsc/finclude/petscdmplex.h>
  2: #include <petsc/finclude/petscdmlabel.h>
  3: program DMPlexTestField
  4:   use petscdm
  5:   use petscdmplex
  6:   implicit none

  8:   DM :: dm
  9:   DMLabel :: label
 10:   Vec :: u
 11:   PetscViewer :: viewer
 12:   PetscSection :: section
 13:   PetscInt :: dim, numFields, numBC
 14:   PetscInt :: i, val
 15:   PetscInt, target, dimension(3) ::  numComp
 16:   PetscInt, pointer :: pNumComp(:)
 17:   PetscInt, target, dimension(12) ::  numDof
 18:   PetscInt, pointer :: pNumDof(:)
 19:   PetscInt, target, dimension(1) ::  bcField
 20:   PetscInt, pointer :: pBcField(:)
 21:   PetscInt, parameter :: zero = 0, one = 1, two = 2, eight = 8
 22:   PetscMPIInt :: size
 23:   IS, target, dimension(1) ::   bcCompIS
 24:   IS, target, dimension(1) ::   bcPointIS
 25:   IS, pointer :: pBcCompIS(:)
 26:   IS, pointer :: pBcPointIS(:)
 27:   PetscErrorCode :: ierr

 29:   PetscCallA(PetscInitialize(ierr))
 30:   PetscCallMPIA(MPI_Comm_size(PETSC_COMM_WORLD, size, ierr))
 31: !     Create a mesh
 32:   PetscCallA(DMCreate(PETSC_COMM_WORLD, dm, ierr))
 33:   PetscCallA(DMSetType(dm, DMPLEX, ierr))
 34:   PetscCallA(DMSetFromOptions(dm, ierr))
 35:   PetscCallA(DMViewFromOptions(dm, PETSC_NULL_OBJECT, '-dm_view', ierr))
 36:   PetscCallA(DMGetDimension(dm, dim, ierr))
 37: !     Create a scalar field u, a vector field v, and a surface vector field w
 38:   numFields = 3
 39:   numComp(1) = 1
 40:   numComp(2) = dim
 41:   numComp(3) = dim - 1
 42:   pNumComp => numComp
 43:   do i = 1, numFields*(dim + 1)
 44:     numDof(i) = 0
 45:   end do
 46: !     Let u be defined on vertices
 47:   numDof(0*(dim + 1) + 1) = 1
 48: !     Let v be defined on cells
 49:   numDof(1*(dim + 1) + dim + 1) = dim
 50: !     Let v be defined on faces
 51:   numDof(2*(dim + 1) + dim) = dim - 1
 52:   pNumDof => numDof
 53: !     Setup boundary conditions
 54:   numBC = 1
 55: !     Test label retrieval
 56:   PetscCallA(DMGetLabel(dm, 'marker', label, ierr))
 57:   PetscCallA(DMLabelGetValue(label, zero, val, ierr))
 58:   PetscCheckA(size /= 1 .or. val == -1, PETSC_COMM_SELF, PETSC_ERR_PLIB, 'Error in library')
 59:   PetscCallA(DMLabelGetValue(label, eight, val, ierr))
 60:   PetscCheckA(size /= 1 .or. val == 1, PETSC_COMM_SELF, PETSC_ERR_PLIB, 'Error in library')
 61: !     Prescribe a Dirichlet condition on u on the boundary
 62: !       Label "marker" is made by the mesh creation routine
 63:   bcField(1) = 0
 64:   pBcField => bcField
 65:   PetscCallA(ISCreateStride(PETSC_COMM_WORLD, one, zero, one, bcCompIS(1), ierr))
 66:   pBcCompIS => bcCompIS
 67:   PetscCallA(DMGetStratumIS(dm, 'marker', one, bcPointIS(1), ierr))
 68:   pBcPointIS => bcPointIS
 69: !     Create a PetscSection with this data layout
 70:   PetscCallA(DMSetNumFields(dm, numFields, ierr))
 71:   PetscCallA(DMPlexCreateSection(dm, PETSC_NULL_DMLABEL_ARRAY, pNumComp, pNumDof, numBC, pBcField, pBcCompIS, pBcPointIS, PETSC_NULL_IS, section, ierr))
 72:   PetscCallA(ISDestroy(bcCompIS(1), ierr))
 73:   PetscCallA(ISDestroy(bcPointIS(1), ierr))
 74: !     Name the Field variables
 75:   PetscCallA(PetscSectionSetFieldName(section, zero, 'u', ierr))
 76:   PetscCallA(PetscSectionSetFieldName(section, one, 'v', ierr))
 77:   PetscCallA(PetscSectionSetFieldName(section, two, 'w', ierr))
 78:   if (size == 1) then
 79:     PetscCallA(PetscSectionView(section, PETSC_VIEWER_STDOUT_WORLD, ierr))
 80:   end if
 81: !     Tell the DM to use this data layout
 82:   PetscCallA(DMSetLocalSection(dm, section, ierr))
 83: !     Create a Vec with this layout and view it
 84:   PetscCallA(DMGetGlobalVector(dm, u, ierr))
 85:   PetscCallA(PetscViewerCreate(PETSC_COMM_WORLD, viewer, ierr))
 86:   PetscCallA(PetscViewerSetType(viewer, PETSCVIEWERVTK, ierr))
 87:   PetscCallA(PetscViewerFileSetName(viewer, 'sol.vtu', ierr))
 88:   PetscCallA(VecView(u, viewer, ierr))
 89:   PetscCallA(PetscViewerDestroy(viewer, ierr))
 90:   PetscCallA(DMRestoreGlobalVector(dm, u, ierr))
 91: !     Cleanup
 92:   PetscCallA(PetscSectionDestroy(section, ierr))
 93:   PetscCallA(DMDestroy(dm, ierr))

 95:   PetscCallA(PetscFinalize(ierr))
 96: end program DMPlexTestField

 98: !/*TEST
 99: !  test:
100: !    suffix: 0
101: !    requires: triangle
102: !    args: -info :~sys,mat:
103: !
104: !  test:
105: !    suffix: 0_2
106: !    requires: triangle
107: !    nsize: 2
108: !    args: -info :~sys,mat,partitioner:
109: !
110: !  test:
111: !    suffix: 1
112: !    requires: ctetgen
113: !    args: -dm_plex_dim 3 -info :~sys,mat:
114: !
115: !TEST*/