! See copyright notice in the COPYRIGHT file.
! ****************************************************************************** !
!> This module contains routines which initiliaze advection relaxation and
!! flow field for lbm model.
module mus_initLBM_module
  use env_module,         only: labelLen
  use tem_aux_module,     only: tem_abort
  use tem_logging_module, only: logUnit

  use mus_bgk_module, only: bgk_advRel_explicit, bgk_advRel_forcing
  use mus_d3q27_module, only: bgk_d3q27, cumulant_d3q27, cascaded_d3q27, &
    &                         trt_d3q27, bgk_d3q27_LES
  use mus_d3q19_module, only: bgk_advRel_d3q19,       &
    &                         bgk_d3q19_block,        &
    &                         bgk_advRel_d3q19_les,   &
    &                         trt_advRel_d3q19_les,   &
    &                         trt_advRel_d3q19
  use mus_d3q19_turb_module, only: bgk_advRel_d3q19_les_new, &
    &                              mrt_advRel_d3q19_LES_new
  use mus_d2q9_module, only: mrt_d2q9, bgk_d2q9
  use mus_mrt_module, only: mrt_advRel_d3q19,                                  &
    &                       mrt_advRel_d3q19_explicit,                         &
    &                       mrt_advRel_explicit,                               &
    &                       mrt_advRel_d3q19_les,                              &
    &                       mrt_advRel_d3q19_les_explicit
  use mus_mrt_d3q27_module, only: mrt_advRel_d3q27,           &
    &                             mrt_advRel_d3q27_les_explicit
  use mus_test_module, only: vec_fma
  use mus_scheme_type_module, only: kernel

  implicit none

  private

  public :: mus_init_advRel_LBM

contains

  ! **************************************************************************** !
  !> Assigning compute kernel routine by scheme relaxation type for LBM kind.
  !!
  subroutine mus_init_advRel_LBM( relaxation, layout, compute )
    ! ---------------------------------------------------------------------------
    character(len=labelLen), intent(inout) :: relaxation
    character(len=labelLen), intent(in) :: layout
    procedure( kernel ), pointer, intent(out) :: compute
    ! ---------------------------------------------------------------------------

    write(logUnit(1),*) 'Choosing relaxation model: '//trim( relaxation )
    select case( trim( relaxation ))
    case( 'cumulant' )
      select case( trim(layout) )
      case( 'd3q27' )
        compute => cumulant_d3q27
      case default
        write(logUnit(1),*) 'Stencil '//trim(layout)//' is not supported yet!'
        call tem_abort()
      end select
    case( 'cascaded' )
      select case( trim(layout) )
      case( 'd3q27' )
        compute => cascaded_d3q27
      case default
        write(logUnit(1),*) 'Stencil '//trim(layout)//' is not supported yet!'
        call tem_abort()
      end select
    case( 'bgk_les' )
      select case( trim(layout) )
      case( 'd3q19' )
        compute => bgk_advRel_d3q19_les
      case( 'd3q27' )
        compute => bgk_d3q27_LES
      case default
        write(logUnit(1),*) 'Stencil '//trim(layout)//' is not supported yet!'
        call tem_abort()
      end select
    case( 'bgk_les_new' )
      select case( trim(layout) )
      case( 'd3q19' )
        compute => bgk_advRel_d3q19_les_new
      case default
        write(logUnit(1),*) 'Stencil '//trim(layout)//' is not supported yet!'
        call tem_abort()
      end select

    case( 'bgk_forcing' )
      compute => bgk_advRel_forcing
    case( 'bgk' )
      select case( trim(layout) )
      case( 'd3q27' )
        compute => bgk_d3q27
      case( 'd3q19' )
        compute => bgk_advRel_d3q19
      case( 'd2q9' )
        compute => bgk_d2q9
      case( 'd1q3', 'new_stencil' )
        compute => bgk_advRel_explicit
      case default
        write(logUnit(1),*) 'Stencil '//trim(layout)//' is not supported yet!'
        call tem_abort()
      end select
    case( 'bgk_explicit' )
      compute => bgk_advRel_explicit
    case( 'bgk_block' )
      if ( trim(layout) == 'd3q19' ) then
        compute => bgk_d3q19_block
      else
        write(logUnit(1),*) 'Stencil '//trim(layout)//' is not supported yet!'
        call tem_abort()
      end if
    case( 'trt' )
      select case( trim(layout) )
      case( 'd3q19' )
        compute => trt_advRel_d3q19
      case( 'd3q27' )
        compute => trt_d3q27
      case default
        write(logUnit(1),*) 'Stencil '//trim(layout)//' is not supported yet!'
        call tem_abort()
      end select
    case( 'trt_les' )
      select case( trim(layout) )
      case( 'd3q19' )
        compute => trt_advRel_d3q19_les
      case default
        write(logUnit(1),*) 'Stencil '//trim(layout)//' is not supported yet!'
        call tem_abort()
      end select
    case( 'mrt' )
      select case( trim(layout) )
      case( 'd3q27' )
        compute => mrt_advRel_d3q27
      case( 'd3q19' )
        compute => mrt_advRel_d3q19
      case( 'd2q9' )
        compute => mrt_d2q9
      case default
        write(logUnit(1),*) 'Stencil '//trim(layout)//' is not supported yet!'
        call tem_abort()
      end select
    case( 'mrt_explicit', 'mrt_bgk' )
      select case( trim(layout) )
      case( 'd3q19' )
        compute => mrt_advRel_d3q19_explicit
      case( 'd2q9', 'd3q27' )
        compute => mrt_advRel_explicit
      case default
        write(logUnit(1),*) 'Stencil '//trim(layout)//' is not supported yet!'
        call tem_abort()
      end select
    case( 'mrt_les' )
      select case( trim(layout) )
      case( 'd3q19' )
        compute => mrt_advRel_d3q19_les
      case default
        write(logUnit(1),*) 'Stencil '//trim(layout)//' is not supported yet!'
        call tem_abort()
      end select
    case( 'mrt_les_explicit' )
      select case( trim(layout) )
      case( 'd3q27' )
        compute => mrt_advRel_d3q27_les_explicit
      case( 'd3q19' )
        compute => mrt_advRel_d3q19_les_explicit
      case default
        write(logUnit(1),*) 'Stencil '//trim(layout)//' is not supported yet!'
        call tem_abort()
      end select
    case( 'mrt_les_new' )
      select case( trim(layout) )
      case( 'd3q19' )
        compute => mrt_advRel_d3q19_LES_new
      case default
        write(logUnit(1),*) 'Stencil '//trim(layout)//' is not supported yet!'
        call tem_abort()
      end select
    case( 'vec_fma', 'test' )
      compute => vec_fma
    case default
      write(logUnit(1),*) 'Relaxation '//trim(relaxation)//' is not supported!'
      call tem_abort()
    end select

  end subroutine mus_init_advRel_LBM
  ! **************************************************************************** !

end module mus_initLBM_module
! ****************************************************************************** !
