main Program

Uses

  • program~~main~4~~UsesGraph program~main~4 main module~leapblock leapBlock program~main~4->module~leapblock module~leapeulerian leapEulerian program~main~4->module~leapeulerian module~leapkinds leapKinds program~main~4->module~leapkinds module~leapparallel leapParallel program~main~4->module~leapparallel module~leapparser leapParser program~main~4->module~leapparser module~leapblock->module~leapkinds module~leapblock->module~leapparallel iso_fortran_env iso_fortran_env module~leapblock->iso_fortran_env module~leapio_hdf5 leapIO_hdf5 module~leapblock->module~leapio_hdf5 mpi_f08 mpi_f08 module~leapblock->mpi_f08 module~leapeulerian->module~leapblock module~leapeulerian->module~leapkinds module~leapeulerian->module~leapparallel module~leapeulerian->iso_fortran_env module~leapio leapIO module~leapeulerian->module~leapio module~leaputils leapUtils module~leapeulerian->module~leaputils module~leapeulerian->mpi_f08 module~leapkinds->iso_fortran_env module~leapparallel->module~leapkinds module~leapparallel->iso_fortran_env module~leapparallel->mpi_f08 module~leapparser->module~leapkinds module~leapparser->iso_fortran_env module~leapcli leapCli module~leapparser->module~leapcli module~leapcli->module~leapkinds module~leapio->module~leapio_hdf5 module~leapio_h5hut leapIO_h5hut module~leapio->module~leapio_h5hut module~leapio_silo leapIO_silo module~leapio->module~leapio_silo module~leapio_xdmf leapIO_xdmf module~leapio->module~leapio_xdmf module~leapio_hdf5->module~leapkinds module~leapio_hdf5->module~leapparallel module~leapio_hdf5->module~leaputils hdf5 hdf5 module~leapio_hdf5->hdf5 module~leaputils->module~leapkinds module~leapio_h5hut->module~leapkinds module~leapio_h5hut->module~leapparallel module~leapio_h5hut->module~leapio_hdf5 module~leapio_silo->module~leapkinds module~leapio_silo->module~leapparallel module~leapio_silo->module~leaputils module~leapio_silo->mpi_f08 module~leapio_xdmf->module~leapkinds module~leapio_xdmf->module~leaputils

Solver: GRANS

Description: Performs various collisions between a spherical resolved particle (RP) and immersed boundaries or other resolved particles.

References:


Calls

program~~main~4~~CallsGraph program~main~4 main none~get parser_obj%Get program~main~4->none~get proc~block_obj_final block_obj%block_obj_Final program~main~4->proc~block_obj_final proc~parser_obj_init parser_obj%parser_obj_init program~main~4->proc~parser_obj_init proc~parser_obj_parsefile parser_obj%parser_obj_ParseFile program~main~4->proc~parser_obj_parsefile proc~setupcasebcs~4 SetUpCaseBCS program~main~4->proc~setupcasebcs~4 proc~setupcaseblock~4 SetUpCaseBlock program~main~4->proc~setupcaseblock~4 proc~setupcaseib~2 SetUpCaseIB program~main~4->proc~setupcaseib~2 proc~setupcaserp~2 SetUpCaseRP program~main~4->proc~setupcaserp~2 proc~parser_obj_read0d parser_obj%parser_obj_read0D none~get->proc~parser_obj_read0d proc~parser_obj_read1d parser_obj%parser_obj_read1D none~get->proc~parser_obj_read1d mpi_type_free mpi_type_free proc~block_obj_final->mpi_type_free proc~axis_obj_final axis_obj%axis_obj_Final proc~block_obj_final->proc~axis_obj_final proc~cli_obj_get cli_obj%cli_obj_Get proc~parser_obj_parsefile->proc~cli_obj_get proc~parser_obj_parseline parser_obj%parser_obj_ParseLine proc~parser_obj_parsefile->proc~parser_obj_parseline proc~bc_set_add bc_set%bc_set_Add proc~setupcasebcs~4->proc~bc_set_add proc~bc_set_final bc_set%bc_set_Final proc~setupcasebcs~4->proc~bc_set_final proc~bc_set_getbcpointer bc_set%bc_set_GetBCPointer proc~setupcasebcs~4->proc~bc_set_getbcpointer proc~bc_set_init bc_set%bc_set_Init proc~setupcasebcs~4->proc~bc_set_init proc~bc_set_setbc bc_set%bc_set_SetBC proc~setupcasebcs~4->proc~bc_set_setbc proc~setupcaseblock~4->none~get none~initialize~10 block_obj%Initialize proc~setupcaseblock~4->none~initialize~10 proc~block_obj_partition block_obj%block_obj_Partition proc~setupcaseblock~4->proc~block_obj_partition proc~block_obj_setconveniencepointers block_obj%block_obj_SetConveniencePointers proc~setupcaseblock~4->proc~block_obj_setconveniencepointers proc~block_obj_setperiodicity block_obj%block_obj_SetPeriodicity proc~setupcaseblock~4->proc~block_obj_setperiodicity proc~block_obj_setupuniformgrid block_obj%block_obj_SetupUniformGrid proc~setupcaseblock~4->proc~block_obj_setupuniformgrid proc~setupcaseib~2->none~get none~finalize~27 marker_set%Finalize proc~setupcaseib~2->none~finalize~27 none~initialize~27 marker_set%Initialize proc~setupcaseib~2->none~initialize~27 proc~lagrangian_set_applyperiodicity lagrangian_set%lagrangian_set_ApplyPeriodicity proc~setupcaseib~2->proc~lagrangian_set_applyperiodicity proc~lagrangian_set_communicate lagrangian_set%lagrangian_set_Communicate proc~setupcaseib~2->proc~lagrangian_set_communicate proc~lagrangian_set_localize lagrangian_set%lagrangian_set_Localize proc~setupcaseib~2->proc~lagrangian_set_localize proc~lagrangian_set_setwritefilename lagrangian_set%lagrangian_set_SetWriteFileName proc~setupcaseib~2->proc~lagrangian_set_setwritefilename proc~marker_set_addplane marker_set%marker_set_AddPlane proc~setupcaseib~2->proc~marker_set_addplane proc~parallel_obj_rankisroot parallel_obj%parallel_obj_RankIsRoot proc~setupcaseib~2->proc~parallel_obj_rankisroot proc~setupcaserp~2->none~get none~finalize~26 ResPart_set%Finalize proc~setupcaserp~2->none~finalize~26 none~initialize~26 ResPart_set%Initialize proc~setupcaserp~2->none~initialize~26 particle particle proc~setupcaserp~2->particle proc~setupcaserp~2->proc~lagrangian_set_applyperiodicity proc~setupcaserp~2->proc~lagrangian_set_communicate proc~setupcaserp~2->proc~lagrangian_set_localize proc~lagrangian_set_resize lagrangian_set%lagrangian_set_Resize proc~setupcaserp~2->proc~lagrangian_set_resize proc~marker_set_addsphere marker_set%marker_set_AddSphere proc~setupcaserp~2->proc~marker_set_addsphere proc~setupcaserp~2->proc~parallel_obj_rankisroot proc~respart_set_setwritefilename ResPart_set%ResPart_set_SetWriteFileName proc~setupcaserp~2->proc~respart_set_setwritefilename proc~respart_set_final ResPart_set%ResPart_set_Final none~finalize~26->proc~respart_set_final none~finalize~27->proc~respart_set_final proc~block_obj_init block_obj%block_obj_Init none~initialize~10->proc~block_obj_init proc~block_obj_init2 block_obj%block_obj_Init2 none~initialize~10->proc~block_obj_init2 proc~respart_set_init ResPart_set%ResPart_set_Init none~initialize~26->proc~respart_set_init none~initialize~27->proc~respart_set_init proc~bc_set_checkbounds bc_set%bc_set_CheckBounds proc~bc_set_add->proc~bc_set_checkbounds proc~bc_set_expand bc_set%bc_set_Expand proc~bc_set_add->proc~bc_set_expand proc~bc_set_getsidedirbynormal bc_set%bc_set_GetSideDirByNormal proc~bc_set_add->proc~bc_set_getsidedirbynormal proc~bc_set_updateextents bc_set%bc_set_UpdateExtents proc~bc_set_add->proc~bc_set_updateextents proc~hashtbl_obj_hashstring hashtbl_obj%hashtbl_obj_HashString proc~bc_set_add->proc~hashtbl_obj_hashstring proc~hashtbl_obj_put hashtbl_obj%hashtbl_obj_Put proc~bc_set_add->proc~hashtbl_obj_put proc~region_obj_init region_obj%region_obj_Init proc~bc_set_add->proc~region_obj_init proc~region_obj_final region_obj%region_obj_Final proc~bc_set_final->proc~region_obj_final proc~bc_set_getregionindex bc_set%bc_set_GetRegionIndex proc~bc_set_getbcpointer->proc~bc_set_getregionindex proc~region_obj_getbcindex region_obj%region_obj_GetBCIndex proc~bc_set_getbcpointer->proc~region_obj_getbcindex proc~hashtbl_obj_init hashtbl_obj%hashtbl_obj_Init proc~bc_set_init->proc~hashtbl_obj_init proc~bc_set_getextents bc_set%bc_set_GetExtents proc~bc_set_setbc->proc~bc_set_getextents proc~bc_set_setbc->proc~bc_set_getregionindex proc~region_obj_add region_obj%region_obj_Add proc~bc_set_setbc->proc~region_obj_add proc~block_obj_partition->proc~axis_obj_final proc~block_obj_partition->proc~block_obj_setconveniencepointers proc~axis_obj_init axis_obj%axis_obj_Init proc~block_obj_partition->proc~axis_obj_init proc~block_obj_setupmpitypes block_obj%block_obj_SetupMPITypes proc~block_obj_partition->proc~block_obj_setupmpitypes proc~block_obj_subdivideblock block_obj%block_obj_SubDivideBlock proc~block_obj_partition->proc~block_obj_subdivideblock proc~block_obj_updategridghostcells block_obj%block_obj_UpdateGridGhostCells proc~block_obj_partition->proc~block_obj_updategridghostcells proc~block_obj_updatemidpoints block_obj%block_obj_UpdateMidPoints proc~block_obj_partition->proc~block_obj_updatemidpoints proc~block_obj_updatespacing block_obj%block_obj_UpdateSpacing proc~block_obj_partition->proc~block_obj_updatespacing proc~parallel_obj_topology parallel_obj%parallel_obj_Topology proc~block_obj_partition->proc~parallel_obj_topology proc~block_obj_setupuniformgrid->proc~block_obj_setconveniencepointers proc~block_obj_setupuniformgrid->proc~axis_obj_init proc~block_obj_setupuniformgrid->proc~block_obj_setupmpitypes proc~block_obj_setupuniformgrid->proc~block_obj_updategridghostcells proc~block_obj_setupuniformgrid->proc~block_obj_updatemidpoints proc~block_obj_setupuniformgrid->proc~block_obj_updatespacing proc~lagrangian_set_communicate->proc~lagrangian_set_resize mpi_gather mpi_gather proc~lagrangian_set_communicate->mpi_gather mpi_recv mpi_recv proc~lagrangian_set_communicate->mpi_recv mpi_send mpi_send proc~lagrangian_set_communicate->mpi_send proc~lagrangian_set_recycle lagrangian_set%lagrangian_set_Recycle proc~lagrangian_set_communicate->proc~lagrangian_set_recycle proc~block_obj_getowningcell block_obj%block_obj_GetOwningCell proc~lagrangian_set_localize->proc~block_obj_getowningcell proc~marker_set_addplane->proc~lagrangian_set_resize markers markers proc~marker_set_addplane->markers proc~marker_set_addsphere->proc~lagrangian_set_resize proc~marker_set_addsphere->markers p p proc~marker_set_addsphere->p proc~parser_obj_addentry parser_obj%parser_obj_AddEntry proc~parser_obj_parseline->proc~parser_obj_addentry proc~parser_obj_fetchlabelid parser_obj%parser_obj_FetchLabelID proc~parser_obj_parseline->proc~parser_obj_fetchlabelid proc~parser_obj_reformatline parser_obj%parser_obj_ReformatLine proc~parser_obj_parseline->proc~parser_obj_reformatline none~assigndefault parser_obj%AssignDefault proc~parser_obj_read0d->none~assigndefault proc~parser_obj_read0d->proc~parser_obj_fetchlabelid proc~parser_obj_read1d->none~assigndefault proc~parser_obj_read1d->proc~parser_obj_fetchlabelid proc~stringtool_obj_removeextension stringtool_obj%stringtool_obj_RemoveExtension proc~respart_set_setwritefilename->proc~stringtool_obj_removeextension proc~parser_obj_assigndefault0d parser_obj%parser_obj_AssignDefault0D none~assigndefault->proc~parser_obj_assigndefault0d proc~parser_obj_assigndefault1d parser_obj%parser_obj_AssignDefault1D none~assigndefault->proc~parser_obj_assigndefault1d proc~bc_set_getextents->proc~bc_set_getregionindex proc~bc_set_getregionindex->proc~hashtbl_obj_hashstring none~get~4 hashtbl_obj%Get proc~bc_set_getregionindex->none~get~4 proc~bc_set_updateextents->proc~bc_set_getregionindex proc~block_obj_init2->proc~block_obj_setupuniformgrid proc~block_obj_setupmpitypes->mpi_type_free mpi_type_commit mpi_type_commit proc~block_obj_setupmpitypes->mpi_type_commit mpi_type_vector mpi_type_vector proc~block_obj_setupmpitypes->mpi_type_vector mpi_irecv mpi_irecv proc~block_obj_updategridghostcells->mpi_irecv mpi_isend mpi_isend proc~block_obj_updategridghostcells->mpi_isend mpi_wait mpi_wait proc~block_obj_updategridghostcells->mpi_wait mpi_waitall mpi_waitall proc~block_obj_updategridghostcells->mpi_waitall proc~block_obj_updateextents block_obj%block_obj_UpdateExtents proc~block_obj_updategridghostcells->proc~block_obj_updateextents proc~sllist_obj_put sllist_obj%sllist_obj_Put proc~hashtbl_obj_put->proc~sllist_obj_put proc~lagrangian_set_recycle->proc~lagrangian_set_resize mpi_cart_coords mpi_cart_coords proc~parallel_obj_topology->mpi_cart_coords mpi_cart_create mpi_cart_create proc~parallel_obj_topology->mpi_cart_create mpi_cart_rank mpi_cart_rank proc~parallel_obj_topology->mpi_cart_rank mpi_cart_shift mpi_cart_shift proc~parallel_obj_topology->mpi_cart_shift mpi_comm_rank mpi_comm_rank proc~parallel_obj_topology->mpi_comm_rank mpi_dims_create mpi_dims_create proc~parallel_obj_topology->mpi_dims_create proc~region_obj_add->proc~hashtbl_obj_hashstring proc~region_obj_add->proc~hashtbl_obj_put proc~region_obj_expand region_obj%region_obj_Expand proc~region_obj_add->proc~region_obj_expand proc~hashtbl_obj_final hashtbl_obj%hashtbl_obj_Final proc~region_obj_final->proc~hashtbl_obj_final proc~region_obj_getbcindex->proc~hashtbl_obj_hashstring proc~region_obj_getbcindex->none~get~4 proc~region_obj_init->proc~hashtbl_obj_init proc~respart_set_final->none~finalize~27 proc~lagrangian_set_freempitype lagrangian_set%lagrangian_set_FreeMPIType proc~respart_set_final->proc~lagrangian_set_freempitype proc~respart_set_init->none~initialize~27 proc~respart_set_init->proc~lagrangian_set_resize proc~lagrangian_set_creatempitype lagrangian_set%lagrangian_set_CreateMPIType proc~respart_set_init->proc~lagrangian_set_creatempitype proc~respart_set_setobjecttype ResPart_set%ResPart_set_SetObjectType proc~respart_set_init->proc~respart_set_setobjecttype proc~hashtbl_obj_get_int4 hashtbl_obj%hashtbl_obj_Get_int4 none~get~4->proc~hashtbl_obj_get_int4 proc~hashtbl_obj_get_int8 hashtbl_obj%hashtbl_obj_Get_int8 none~get~4->proc~hashtbl_obj_get_int8 proc~hashtbl_obj_get_real_dp hashtbl_obj%hashtbl_obj_Get_real_dp none~get~4->proc~hashtbl_obj_get_real_dp proc~hashtbl_obj_get_real_sp hashtbl_obj%hashtbl_obj_Get_real_sp none~get~4->proc~hashtbl_obj_get_real_sp proc~block_obj_updateextents->proc~axis_obj_init proc~lagrangian_set_creatempitype->mpi_type_commit SetMPIDataTypeParams SetMPIDataTypeParams proc~lagrangian_set_creatempitype->SetMPIDataTypeParams mpi_type_create_resized mpi_type_create_resized proc~lagrangian_set_creatempitype->mpi_type_create_resized mpi_type_create_struct mpi_type_create_struct proc~lagrangian_set_creatempitype->mpi_type_create_struct mpi_type_get_extent mpi_type_get_extent proc~lagrangian_set_creatempitype->mpi_type_get_extent mpi_type_size mpi_type_size proc~lagrangian_set_creatempitype->mpi_type_size proc~lagrangian_set_freempitype->mpi_type_free proc~sllist_obj_put->proc~sllist_obj_put none~get~3 sllist_obj%Get proc~hashtbl_obj_get_int4->none~get~3 proc~hashtbl_obj_get_int8->none~get~3 proc~hashtbl_obj_get_real_dp->none~get~3 proc~hashtbl_obj_get_real_sp->none~get~3 proc~sllist_obj_get_int4 sllist_obj%sllist_obj_Get_int4 none~get~3->proc~sllist_obj_get_int4 proc~sllist_obj_get_int8 sllist_obj%sllist_obj_Get_int8 none~get~3->proc~sllist_obj_get_int8 proc~sllist_obj_get_real_dp sllist_obj%sllist_obj_Get_real_dp none~get~3->proc~sllist_obj_get_real_dp proc~sllist_obj_get_real_sp sllist_obj%sllist_obj_Get_real_sp none~get~3->proc~sllist_obj_get_real_sp proc~sllist_obj_get_int4->proc~sllist_obj_get_int4 proc~sllist_obj_get_int8->proc~sllist_obj_get_int8 proc~sllist_obj_get_real_dp->proc~sllist_obj_get_real_dp proc~sllist_obj_get_real_sp->proc~sllist_obj_get_real_sp

Variables

Type Attributes Name Initial
integer, parameter :: CASE_CHANNEL_IB = 5
integer, parameter :: CASE_CHANNEL_WALL = 4
integer :: CASE_ID

Case to run Configurations

integer, parameter :: CASE_NORMAL_IB = 3
integer, parameter :: CASE_NORMAL_PAIR = 2
integer, parameter :: CASE_NORMAL_WALL = 1
type(block_obj) :: block

block object

character(len=str64) :: configuration

Configuration

type(parallel_obj) :: parallel

Utility that interfaces with MPI API

type(parser_obj) :: parser

Parses input files

logical :: use_IB

Switch to activate Immersed Boundaries

logical :: use_RP

Switch to activate Resolved Particles


Subroutines

subroutine SetUpCaseBCS()

Defines boundary conditions.

Arguments

None

subroutine SetUpCaseBlock()

Builds and writes block file.

Arguments

None

subroutine SetUpCaseIB()

Builds and writes immersed boundary.

Arguments

None

subroutine SetUpCaseRP()

Builds and writes resolved particles.

Arguments

None

Source Code

program main
  !>--------------------------------------------------------------------------
  ! Program: Sphere Collisions
  ! Author: Mohamed Houssem Kasbaoui
  !
  ! Solver: GRANS
  !
  ! Description: Performs various collisions between a spherical resolved
  ! particle (RP) and immersed boundaries or other resolved particles.
  !
  ! References:
  ! --------------------------------------------------------------------------
  use leapKinds
  use leapParser
  use leapParallel
  use leapBlock
  use leapEulerian
  implicit none
  type(parallel_obj)   :: parallel                                             !! Utility that interfaces with MPI API
  type(parser_obj)     :: parser                                               !! Parses input files
  type(block_obj)      :: block                                                !! block object
  character(len=str64) :: configuration                                        !! Configuration
  logical              :: use_RP                                               !! Switch to activate Resolved Particles
  logical              :: use_IB                                               !! Switch to activate Immersed Boundaries
  integer              :: CASE_ID                                              !! Case to run
  !> Configurations
  integer, parameter :: CASE_NORMAL_WALL  = 1
  integer, parameter :: CASE_NORMAL_PAIR  = 2
  integer, parameter :: CASE_NORMAL_IB    = 3
  integer, parameter :: CASE_CHANNEL_WALL = 4
  integer, parameter :: CASE_CHANNEL_IB   = 5

  ! Initialize parser
  call parser%Initialize()

  ! Parse input file
  call parser%ParseFile()

  ! Initialize parallel environment
  call parallel%Initialize()

  ! Chose configuration to run
  call parser%Get('Configuration',  configuration, default = "normal wall" )
  select case (trim(adjustl(configuration)))
  case ('normal wall')
    CASE_ID = CASE_NORMAL_WALL
    use_RP  = .true.
    use_IB  = .false.
  case ('normal pair')
    CASE_ID = CASE_NORMAL_PAIR
    use_RP  = .true.
    use_IB  = .false.
  case ('normal IB'  )
    CASE_ID = CASE_NORMAL_IB
    use_RP  = .true.
    use_IB  = .true.
  case ('channel wall')
    CASE_ID = CASE_CHANNEL_WALL
    use_RP  = .true.
    use_IB  = .false.
  case ('channel IB' )
    CASE_ID = CASE_CHANNEL_IB
    use_RP  = .true.
    use_IB  = .true.
  case default
    call parallel%Stop("Unknown case: "//trim(adjustl(configuration)))
  end select

  ! Set the block info
  call SetUpCaseBlock()

  ! Activate optional components
  if (use_RP) call SetUpCaseRP()
  if (use_IB) call SetUpCaseIB()

  ! Set boundary conditions
  call SetUpCaseBCS()

  ! Free up data
  call block%Finalize()
  call parser%Finalize()
  call parallel%Finalize()
  contains
    subroutine SetUpCaseBlock()
      !> Builds and writes block file.
      implicit none
      ! Work variables
      character(str64) :: filename
      real(wp)         :: L(3),xlo(3),xhi(3)
      integer          :: N(3), ngc, ilo(3),ihi(3), Nb(3)
      integer          :: dir
      integer          :: i,j,k
      real(wp)         :: r

      call parser%Get('Block file',  filename)
      call parser%Get("Domain size", L       )
      call parser%Get("Grid points", N       )
      call parser%Get("Ghost cells", ngc     )
      call parser%Get("Partition",   Nb      )

      ! Domain extents
      xlo = [-0.5_wp*L(1), 0.0_wp,-0.5_wp*L(3)]
      xhi = [ 0.5_wp*L(1), L(2),   0.5_wp*L(3)]
      ilo = [1,1,1] ; ihi = N

      ! Initialize the main block
      call block%Initialize(ngc,parallel)

      ! Setup the domain periodicity
      call block%SetPeriodicity([.true.,.false.,.true.])

      select case (CASE_ID)
      case (CASE_NORMAL_WALL, CASE_NORMAL_PAIR,CASE_NORMAL_IB)

        ! Create a uniform block
        call block%SetupUniformGrid(xlo,xhi,ilo,ihi)

      case (CASE_CHANNEL_WALL,CASE_CHANNEL_IB)

        ! Create a grid, locally refined at the wall
        ! ------------------------------------------
        call parser%Get("Stretching",  r  )

        associate (lo =>block%lo, hi=>block%hi)
          ! Setup bounds
          lo = [1,1,1]
          hi = N

          ! Initialize axes
          do dir=1,3
            call block%axis(dir)%Initialize(lo(dir),hi(dir),ngc)
          end do
          call block%SetConveniencePointers()
        end associate

        associate (x=>block%x, y=>block%y, z=>block%z, &
          lo =>block%lo, hi=>block%hi)
          ! Uniform x-axis
          do i=lo(1),hi(1)+1
            x(i)= (i-lo(1))*L(1)/real(hi(1)-lo(1)+1,wp)
          end do

          ! Stretched y-axis
          do j=lo(2),hi(2)+1
            y(j)= (j-lo(2))*L(2)/real(hi(2)-lo(2)+1,wp) - 0.5_wp*L(2)
            y(j)= 0.5_wp*L(2)*tanh(r*y(j)/(0.5_wp*L(2)))/tanh(r)
          end do

          ! Uniform z-axis
          do k=lo(3),hi(3)+1
            z(k)= (k-lo(3))*L(3)/real(hi(3)-lo(3)+1,wp) - 0.5_wp*L(3)
          end do
        end associate

      end select

      ! Partition block for parallel initializations
      call block%Partition(Nb)

      ! Write block to disk
      call block%Write(filename)

      return
    end subroutine SetUpCaseBlock
    subroutine SetUpCaseRP()
      !> Builds and writes resolved particles.
      use particles_resolved
      implicit none
      ! Work variables
      type(ResPart_set) :: RP                                                  !! Resolved particles
      real(wp)          :: diam
      real(wp)          :: rhop(2)
      real(wp)          :: dl
      real(wp)          :: center(3,2)
      real(wp)          :: velp(3,2)
      character(str64)  :: filename
      integer           :: n

      select case (CASE_ID)
      case (CASE_NORMAL_WALL,CASE_NORMAL_IB,CASE_CHANNEL_WALL,CASE_CHANNEL_IB)
        call parser%Get('RP IC file',          filename    )
        call parser%Get("Particle diameter",   diam        )
        call parser%Get("Particle density",    rhop(1)     )
        call parser%Get("Particle center",     center(:,1) )
        call parser%Get("Particle velocity",   velp(:,1),  &
                           default = [0.0_wp,0.0_wp,0.0_wp])

        RP%count = 1
      case (CASE_NORMAL_PAIR)
        call parser%Get('RP IC file',          filename    )
        call parser%Get("Particle diameter",   diam        )
        call parser%Get("Particle 1 density",  rhop(1)     )
        call parser%Get("Particle 2 density",  rhop(2)     )
        call parser%Get("Particle 1 center",   center(:,1) )
        call parser%Get("Particle 2 center",   center(:,2) )
        call parser%Get("Particle 1 velocity", velp(:,1),  &
                           default = [0.0_wp,0.0_wp,0.0_wp])
        call parser%Get("Particle 2 velocity", velp(:,2),  &
                           default = [0.0_wp,0.0_wp,0.0_wp])

        RP%count = 2
      end select

      ! Initialze resolved particles
      call RP%Initialize('ResPart',block,parallel)

      ! Seed particles on root
      if (parallel%RankIsRoot()) then
        ! Activate particle
        call RP%Resize(RP%count)

        dl=0.5_wp*minval(block%dx)

        select type(particle => RP%p)
        type is (ResPart_obj)
          do n=1,RP%count
            ! Particle globabl ID
            particle(n)%id   = int(n,kind=8)
            ! Diameter
            particle(n)%d    = diam
            ! Position
            particle(n)%p    = center(:,n)
            ! Velocity
            particle(n)%v    = velp(:,n)
            ! Angular velocity
            particle(n)%w    = 0.0_wp
            ! Density
            particle(n)%rho  = rhop(n)
            ! Zero force and torque
            particle(n)%Fh   = 0.0_wp
            particle(n)%Th   = 0.0_wp
            particle(n)%Fc   = 0.0_wp
            particle(n)%Tc   = 0.0_wp

            ! Add surface markers
            call RP%ib%AddSphere(particle(n)%p,particle(n)%d/2.0_wp,particle(n)%v,dl,particle(n)%id)
          end do
        end select

      end if

      ! Treatment for periodicity
      call RP%ApplyPeriodicity
      call RP%ib%ApplyPeriodicity

      ! Send to the right rank
      call RP%Communicate
      call RP%ib%Communicate

      ! Localize centers and markers on grid
      call RP%Localize
      call RP%ib%Localize

      ! Write data to disk
      call RP%SetWriteFileName(filename)
      call RP%Write(0,0.0_WP)

      ! Finalize
      call RP%Finalize
    end subroutine SetUpCaseRP
    subroutine SetUpCaseIB()
      !> Builds and writes immersed boundary.
      use immersed_boundaries
      implicit none
      ! Work variables
      character(str64) :: filename
      type(marker_set) :: IB                                                   !! IB
      real(wp)         :: IBy(2)                                               !! IB plane vertical position
      real(wp)         :: center(3,2)                                          !! IB plane centroid
      character(len=3) :: normal(2)                                            !! IB plane normal direction
      real(wp)         :: width(3,2)                                           !! IB plane width
      real(wp)         :: vel(3,2)                                             !! IB plane velocity
      real(wp)         :: dl                                                   !! IB plane resolution (marker spacing)

      select case (CASE_ID)
      case (CASE_NORMAL_IB)
        call parser%Get('IB IC file',    filename   )
        call parser%Get("IB 1 position", IBy(1)    )
      case (CASE_CHANNEL_IB)
        call parser%Get('IB IC file',    filename   )
        call parser%Get("IB 1 position", IBy(1)    )
        call parser%Get("IB 2 position", IBy(2)    )
      end select

      ! Initialze resolved particles
      call IB%Initialize('IB',block,parallel)

      ! Root creates planes
      if (parallel%RankIsRoot()) then

        ! Plane 1 (bottom)
        center(:,1) = [ 0.5_wp*(block%pmin(1)+block%pmax(1)), &
                        IBy(1),                               &
                        0.5_wp*(block%pmin(3)+block%pmax(3))]
        normal(1)   = '+x2'
        width(:,1)  = [ block%pmax(1)-block%pmin(1),          &
                        0.0_wp,                               &
                        block%pmax(3)-block%pmin(3)           ]
        vel(:,1)    = 0.0_wp
        dl          = 0.5_wp*minval(block%dx)

        call IB%AddPlane(center(:,1),normal(1),width(:,1),vel(:,1),dl)

        ! Plane 2 (top)
        if (CASE_ID.eq.CASE_CHANNEL_IB) then
          center(:,2) = [ 0.5_wp*(block%pmin(1)+block%pmax(1)), &
                          IBy(2),                               &
                          0.5_wp*(block%pmin(3)+block%pmax(3))]
          normal(2)   = '-x2'
          width(:,2)  = [ block%pmax(1)-block%pmin(1),          &
                          0.0_wp,                               &
                          block%pmax(3)-block%pmin(3)           ]
          vel(:,2)    = 0.0_wp
          dl          = 0.5_wp*minval(block%dx)

          call IB%AddPlane(center(:,2),normal(2),width(:,2),vel(:,2),dl)
        end if
      end if

      ! Treatment for periodicity
      call IB%ApplyPeriodicity

      ! Send to the right rank
      call IB%Communicate

      ! Localize centers and markers on grid
      call IB%Localize

      ! Write data to disk
      call IB%SetWriteFileName(filename)
      call IB%Write(0,0.0_WP)

      ! Finalize
      call IB%Finalize
    end subroutine SetUpCaseIB
    subroutine SetUpCaseBCS()
      !> Defines boundary conditions.
      use leapBC
      implicit none
      ! Work variables
      type(bc_set)      :: bcs
      real(wp)          :: xhi(3),xlo(3)
      real(wp), pointer :: BCVal(:,:,:)

      ! Initialize utility that handles boundary conditions
      call bcs%Initialize(block,parallel)

      ! Setup regions where boundary conditions apply
      associate (pmin => block%pmin, pmax => block%pmax)

        xlo = [pmin(1),pmin(2),pmin(3)]
        xhi = [pmax(1),pmin(2),pmax(3)]
        call bcs%Add('yL', xlo, xhi, normal = '+x2')

        xlo = [pmin(1),pmax(2),pmin(3)]
        xhi = [pmax(1),pmax(2),pmax(3)]
        call bcs%Add('yR', xlo, xhi, normal = '-x2')

      end associate

      call bcs%SetBC('yL', BC_DIRICHLET,'ibVF')
      call bcs%SetBC('yR', BC_DIRICHLET,'ibVF')

      select case (CASE_ID)
      case (CASE_NORMAL_WALL, CASE_NORMAL_PAIR,CASE_CHANNEL_WALL)
        call bcs%GetBCPointer('yL','ibVF',BCVal); BCVal=0.0_wp
        call bcs%GetBCPointer('yR','ibVF',BCVal); BCVal=0.0_wp
      case (CASE_NORMAL_IB)
        call bcs%GetBCPointer('yL','ibVF',BCVal); BCVal=1.0_wp
        call bcs%GetBCPointer('yR','ibVF',BCVal); BCVal=0.0_wp
      case (CASE_CHANNEL_IB)
        call bcs%GetBCPointer('yL','ibVF',BCVal); BCVal=1.0_wp
        call bcs%GetBCPointer('yR','ibVF',BCVal); BCVal=1.0_wp
      end select

      ! Write boundary conditions
      call bcs%Write(0,0.0_wp)

      ! Clear data
      call bcs%Finalize()

      return
    end subroutine SetUpCaseBCS
end program main