! Created by Andrey Debolskiy on 20.11.2024.

module scm_state_data
    !< @brief abl state def.
    implicit none
    type surfBLDataType
        real :: hs !< surface sensible heat flux W/m2
        real :: es !< surface specific humidity  flux kg/m2 s
        real :: cm2u !< Cd * |U| for implicit momentum flux in tridiag solver
    end type surfBLDataType
    type stateBLDataType
        real, allocatable:: u(:) !< u-componet velocity, [m/s]
        real, allocatable:: v(:) !< v-componet velocity, [m/s]
        real, allocatable:: temp(:) !< absolute temperature, [K]
        real, allocatable:: theta(:) !< potential temperature, [K]
        real, allocatable:: qv(:) ! specific humidity,[kg/m3]
        real, allocatable:: theta_v(:) !< virtual potential temperature, [K]
        real, allocatable:: rho(:) !< air density, [K]
        real, allocatable:: lwp(:) !< liquid water path [kg/kg]
        real, allocatable:: cloud_frac(:) !< cloud fraction [0-1]
        real, allocatable:: s_e(:)  !< Static energy [ m2/ s2]
        real, allocatable:: km(:) !< kinematic viscosity koefficient  [m2 / s2]
        real, allocatable:: kh(:) !< kinematic diffusivity koefficient [ K m / s2]
        real, allocatable:: vdcuv(:) !< viscosity koefficient  [kg /m s2]
        real, allocatable:: vdctq(:) !< diffusivity koefficient [ kg K / m2 s2]
        real :: p0 !< surface pressure [bar]
        real :: cor !< in column corioulis parameter [s-1]
        integer :: kmax !< number of vertical cells
        real :: hpbla_diag !< diagnostic boundary layer height [m]
        integer :: ktvdm !< top layer index for diffusion
        integer :: kpbl !< boundary layer height index
        integer :: land_type !< ocean/land flag
        type(surfBLDataType) :: surf

    end type stateBLDataType

    public scm_data_allocate
    public scm_data_deallocate
    public scm_data_copy
    contains
        subroutine scm_data_allocate(bl_data, kmax)
            implicit none
            type(stateBLDataType),intent(inout):: bl_data
            integer:: kmax
            bl_data%kmax = kmax
            allocate(bl_data%u(kmax))
            allocate(bl_data%v(kmax))
            allocate(bl_data%temp(kmax))
            allocate(bl_data%theta(kmax))
            allocate(bl_data%theta_v(kmax))
            allocate(bl_data%qv(kmax))
            allocate(bl_data%lwp(kmax))
            allocate(bl_data%cloud_frac(kmax))
            allocate(bl_data%rho(kmax))
            allocate(bl_data%s_e(kmax))
            allocate(bl_data%km(kmax))
            allocate(bl_data%kh(kmax))
            allocate(bl_data%vdcuv(0:kmax))
            allocate(bl_data%vdctq(0:kmax))
        end subroutine scm_data_allocate

        subroutine scm_data_deallocate(bl_data)
            implicit none
            type(stateBLDataType), intent(inout):: bl_data
            deallocate(bl_data%u)
            deallocate(bl_data%v)
            deallocate(bl_data%temp)
            deallocate(bl_data%theta)
            deallocate(bl_data%theta_v)
            deallocate(bl_data%qv)
            deallocate(bl_data%lwp)
            deallocate(bl_data%cloud_frac)
            deallocate(bl_data%rho)
            deallocate(bl_data%s_e)
            deallocate(bl_data%km)
            deallocate(bl_data%kh)
            deallocate(bl_data%vdcuv)
            deallocate(bl_data%vdctq)
        end subroutine scm_data_deallocate

        subroutine scm_data_copy(bl, bl_old)
            implicit none
            type(stateBLDataType),intent(in):: bl_old
            type(stateBLDataType),intent(inout):: bl
            if (bl%kmax /= bl_old%kmax) then
                write(*,*) 'error in copy BLData: size is not compatible', bl%kmax, bl_old%kmax
            else
                bl%u  = bl_old%u
                bl%v = bl_old%v
                bl%temp = bl_old%temp
                bl%theta = bl_old%theta
                bl%theta_v = bl_old%theta_v
                bl%qv = bl_old%qv
                bl%lwp = bl_old%lwp
                bl%cloud_frac= bl_old%cloud_frac
                bl%s_e = bl_old%s_e
                bl%km = bl_old%km
                bl%kh = bl_old%kh
                bl%vdcuv = bl_old%vdcuv
                bl%vdctq = bl_old%vdctq
                bl%hpbla_diag = bl_old%hpbla_diag
                bl%p0 = bl_old%p0
                bl%ktvdm = bl_old%ktvdm
                bl%kpbl = bl_old%kpbl
                bl%cor = bl_old%cor
            end if

        end subroutine scm_data_copy
end module scm_state_data