! See copyright notice in he COPYRIGHT file.
! ****************************************************************************** !
!> This module contains mus_field_prop_type and modules related
!! to fiels properties.
!!
!! \author Kannan Masilamani, Simon Zimny
!!
module mus_field_prop_module

  ! include treelm modules
  use env_module,         only: rk, labelLen
  use treelmesh_module,   only: treelmesh_type
  use tem_aux_module,     only: tem_abort
  use tem_logging_module, only: logUnit

  ! include aotus modules
  use flu_binding,     only: flu_State
  use aot_out_module,  only: aot_out_type

  ! include musubi modules
  use mus_poisson_module,       only: mus_load_poisson, &
    &                                 mus_poisson_type
  use mus_scheme_header_module, only: mus_scheme_header_type
  use mus_fluid_module,         only: mus_fluid_type, mus_load_fluid, &
    &                                 mus_init_fluid, mus_fluid_save2lua
  use mus_species_module,       only: mus_species_type, mus_load_species,      &
    &                                 mus_species_out
  use mus_physics_module,       only: mus_physics_type
  implicit none

  private

  public :: mus_field_prop_type
  public :: mus_load_field_prop
  public :: mus_field_prop_out

  !> This type contains parameter needed for field
  type mus_field_prop_type
    !> contains fluid information
    type( mus_fluid_type ) :: fluid
    !> contains species information
    type( mus_species_type ) :: species
    !> Contains information for poisson equation
    type( mus_poisson_type) :: poisson
  end type mus_field_prop_type

contains

! ****************************************************************************** !
  !> load fluid properties like fluid and species table from
  !! lua file based on the scheme kind
  subroutine mus_load_field_prop( me, conf, parent, minLevel, maxLevel,    &
    &                             schemeHeader, nFields, physics, scaling, &
    &                             cs_lattice )
    ! --------------------------------------------------------------------------
    !> field property type
    type( mus_field_prop_type ), intent(out) :: me
    !> number of fields defined in lua file
    integer, intent(in) :: nFields
    !> flu state
    type( flu_State ), intent(inout) :: conf
    !> parent lua handle
    integer, intent(in), optional :: parent
    integer, intent(in) :: minLevel, maxLevel
    !> identifier of the scheme
    type( mus_scheme_header_type ), intent(in) :: schemeHeader
    !> physics type to convert physics to lattice unit or vice versa
    type( mus_physics_type ), intent(in) :: physics
    !> scaling type
    character(len=labelLen), intent(in) :: scaling
    !> lattice speed of sound calculated for defined stencil layout
    real(kind=rk), intent(in) :: cs_lattice
    ! --------------------------------------------------------------------------
    ! load fluid info
    select case( trim(schemeHeader%kind) )
      case('lbm', 'lbm_incomp', 'lbm_nNwtn', 'lbm_incomp_nNwtn', &
        &  'isotherm_acEq')
        write(logUnit(1),"(A)") ' Loading the fluid properties.'
        call mus_load_fluid( me         = me%fluid,              &
          &                  conf       = conf,                  &
          &                  parent     = parent,                &
          &                  minLevel   = minLevel,              &
          &                  physics    = physics,               &
          &                  schemeKind = trim(schemeHeader%kind))
        call mus_init_fluid( me         = me%fluid,          &
          &                  physics    = physics,           &
          &                  scaling    = scaling,           &
          &                  minLevel   = minLevel,          &
          &                  maxLevel   = maxLevel           )
      case('poisson', 'poisson_boltzmann_linear', 'poisson_boltzmann_nonlinear')
        write(logUnit(1),"(A)") ' Loading properties for poisson Eq:'
        call mus_load_poisson( me         = me%poisson,             &
          &                    conf       = conf,                   &
          &                    parent     = parent,                 &
          &                    minLevel   = minLevel,               &
          &                    cs_lattice = cs_lattice,             &
          &                    physics    = physics,                &
          &                    schemeKind = trim(schemeHeader%kind) )
      case('passive_scalar')
        write(logUnit(1),"(A)") ' Loading properties for passive scalar:'
        call mus_load_species( me =  me%species, conf = conf, parent = parent, &
          &                    minLevel = minLevel, nFields = nFields,       &
          &                    physics = physics, cs_lattice=cs_lattice )
      case('multi-species_gas','multi-species_liquid','nernst_planck')
        write(logUnit(1),"(A)") ' Loading properties for multi-species:'
        call mus_load_species( me =  me%species, conf = conf, parent = parent, &
          &                    minLevel = minLevel, nFields = nFields,         &
          &                    physics = physics, cs_lattice=cs_lattice )
      case default
        write(logUnit(1),*) 'The selected scheme kind is unknown '//           &
          &             trim(schemeHeader%kind)
        call tem_abort()
    end select

  end subroutine mus_load_field_prop
! ****************************************************************************** !


! ****************************************************************************** !
  !> write field prop into a lua file
  !!
  subroutine mus_field_prop_out( me, conf, schemeHeader )
    ! ---------------------------------------------------------------------------
    !> single field type
    type( mus_field_prop_type ), intent(in) :: me
    !> identifier of the scheme
    type( mus_scheme_header_type ), intent(in) :: schemeHeader
    !> aotus out type
    type(aot_out_type), intent(inout) :: conf
    ! ---------------------------------------------------------------------------

    select case( trim(schemeHeader%kind) )
      case( 'lbm', 'lbm_incomp', 'lbm_nNwtn', 'lbm_incomp_nNwtn' )
        call mus_fluid_save2lua( me = me%fluid, conf = conf )
      case('passive_scalar', 'multi-species_gas', &
        &  'multi-species_liquid')
        call mus_species_out( me = me%species, conf = conf )
    end select

  end subroutine mus_field_prop_out
! ****************************************************************************** !

end module mus_field_prop_module
! ****************************************************************************** !
