Skip to content
Snippets Groups Projects
pbl_dry_contrgradient.f90 19 KiB
Newer Older
  • Learn to ignore specific revisions
  • Debolskiy Andrey's avatar
    Debolskiy Andrey committed
    !pbl_dry_contrgradient.f90
    !>@brief implements mass-flux contr-gradient parametrization
    module pbl_dry_contrgradient
        implicit none
        type pblContrGradDataType
            real, allocatable :: wu(:), &
                    theta_up(:),  &
                    thetav_up(:),  &
                    ua_up(:), &
                    va_up(:), &
                    qv_up(:), &
                    entr(:)
            real :: theta_up0, thetav_up0, qv_up0
            real :: ua_up0, va_up0
            real :: ua_upH, va_upH
            real :: theta_upH, thetav_upH, qv_upH
        end type pblContrGradDataType
    
    
        real, parameter :: c_entr = 0.38 !< dry entrainment parameterization
        real, parameter :: b1 = 1.8; !< vertical velocity in updraft Bernulli equation constant
        real, parameter :: b2 = 3.5; !< vertical velocity in updraft Bernulli equation constant
        real, parameter :: wstrmin = 1.0e-6 !< minimimal deardorff velocity
        real, parameter :: lmin_entr = 1.0e6 !< maximum entrainement scale above CBL
        real, parameter :: tau_dry_scale = 500.0 !< Time scale for entrainment
        real, parameter :: a0 = 0.08 !< Updraft fraction area
        real, parameter :: alph0 = 0.25 !< amount of surface dispersion to transfer to updraft
    
        public cbl_allocate, cbl_deallocate
    
        public cbl_get_entrainment, cbl_get_up
        public cbl_get_wu, cbl_apply_cntrg
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
    
        contains
    
            subroutine cbl_allocate(cbl, kmax)
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                integer, intent(in):: kmax
                type(pblContrGradDataType), intent(out):: cbl
    
                allocate(cbl%entr(kmax))
                allocate(cbl%theta_up(kmax))
                allocate(cbl%thetav_up(kmax))
                allocate(cbl%qv_up(kmax))
                allocate(cbl%ua_up(kmax))
                allocate(cbl%va_up(kmax))
                allocate(cbl%wu(kmax))
    
            end subroutine cbl_allocate
    
            subroutine cbl_deallocate(cbl)
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                type(pblContrGradDataType), intent(inout):: cbl
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
    
                deallocate(cbl%entr)
                deallocate(cbl%theta_up)
                deallocate(cbl%thetav_up)
                deallocate(cbl%qv_up)
                deallocate(cbl%ua_up)
                deallocate(cbl%va_up)
                deallocate(cbl%wu)
    
            end subroutine cbl_deallocate
            subroutine cbl_get_entrainment(cbl, bl, fluid,  grid)
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                use scm_state_data, only : stateBLDataType
                use pbl_turb_data, only : turbBLDataType
                use phys_fluid, only: fluidParamsDataType
                use pbl_grid, only : pblgridDataType
                implicit none
                type(pblContrGradDataType) :: cbl
                type(stateBLDataType), intent(inout):: bl
                type(fluidParamsDataType), intent(in) :: fluid
                type(pblgridDataType), intent(in) :: grid
    
                integer k
                real dz
    
    
                cbl%entr(:) = 0.0
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                do k = grid%kmax, 2, -1
    
                    dz =(grid%z_cell(k-1) - grid%z_cell(k)) + 1.0
                    if (k  < bl%kpbl+2) then
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                        cbl%entr(k) = 0.0
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                    else
    
                        cbl%entr(k) = c_entr * ( 1.0/(grid%z_cell(k) + dz)  &
                                + 1.0/(bl%hpbla_diag - grid%z_cell(k) + dz) &
                                + 1.0/ lmin_entr)
    
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                    end if
    
                    write(*,*) 'entr, k = ' , cbl%entr(k), k, grid%z_cell(k)
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                end do
                cbl%entr(1) = 0
    
            end subroutine cbl_get_entrainment
    
            subroutine cbl_get_up(cbl, bl, fluid, grid)
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                use scm_state_data, only : stateBLDataType
                use pbl_turb_data, only : turbBLDataType
                use phys_fluid, only: fluidParamsDataType
                use pbl_grid, only : pblgridDataType
                implicit none
                type(pblContrGradDataType) :: cbl
                type(stateBLDataType), intent(inout):: bl
                type(fluidParamsDataType), intent(in) :: fluid
                type(pblgridDataType), intent(in) :: grid
    
                real phys_beta, wstr, dz, dzentrp, dzentrm, temp
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                integer k, kmax
    
    
                cbl%theta_up(:) = 0.0
                cbl%thetav_up(:) = 0
                cbl%qv_up = 0.0
                cbl%ua_up = 0.0
                cbl%va_up = 0.0
    
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                kmax = grid%kmax
                phys_beta = 0.5 * fluid%g /(bl%theta_v(kmax) + bl%theta_v(kmax-1))
    
                write(*,*) 'bl%hs, ', (bl%surf%hs), phys_beta
                if (bl%surf%hs > 0.0) then
                    wstr = (phys_beta * (bl%surf%hs/bl%rho(kmax)) &
                            * bl%hpbla_diag)**(0.33333)
                    wstr = max(wstrmin, wstr)
    
                    cbl%thetav_up0 = (bl%surf%hs/(bl%rho(kmax)*fluid%cp)) / wstr
                    cbl%theta_up0 =  (bl%surf%hs/(bl%rho(kmax)*fluid%cp)) / wstr
                    cbl%qv_up0 =  (bl%surf%es/bl%rho(kmax)) / wstr
                else
                    cbl%thetav_up0 = 0.0
                    cbl%theta_up0 = 0.0
                    cbl%qv_up0 = 0.0
                end if
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                cbl%ua_up0 =  0.0
                cbl%va_up0  =  0.0
    
                cbl%thetav_up(kmax) = cbl%thetav_up0 + bl%theta_v(kmax)
                cbl%theta_up(kmax) = cbl%theta_up0  + bl%theta(kmax)
                cbl%qv_up(kmax) = cbl%qv_up0  + bl%qv(kmax)
                cbl%ua_up(kmax) = cbl%ua_up0  + bl%u(kmax)
                cbl%va_up(kmax) = cbl%va_up0  + bl%v(kmax)
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
    
                do k = kmax-1 ,1,-1
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                    if (k <= bl%kpbl ) then
    
                        cbl%theta_up(k) = bl%theta(k)
                        cbl%thetav_up(k) = bl%theta_v(k)
                        cbl%qv_up(k) = bl%qv(k)
                        cbl%ua_up(k) = bl%u(k)
                        cbl%ua_up(k) = bl%u(k)
                        cbl%va_up(k) = bl%v(k)
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                    else
                        dz = (grid%z_cell(k) - grid%z_cell(k+1))
    
                        cbl%thetav_up(k) = cbl%thetav_up(k+1) - &
                                dz * cbl%entr(k+1) &
                                        * (cbl%thetav_up(k+1) - bl%theta_v(k+1))
                        cbl%theta_up(k) = cbl%theta_up(k+1) - &
                                dz * cbl%entr(k+1) &
                                        * (cbl%theta_up(k+1) - bl%theta(k+1))
                        write(*,*) 'theta_up, k = ' , cbl%theta_up(k) - bl%theta(k), k
                        cbl%qv_up(k) = cbl%qv_up(k+1) - &
                                dz * cbl%entr(k+1) &
                                        * (cbl%qv_up(k+1) - bl%qv(k+1))
                        cbl%ua_up(k) = cbl%ua_up(k+1) + &
                                dz * cbl%entr(k+1) &
                                        * (cbl%ua_up(k+1) - bl%u(k+1))
                        cbl%va_up(k) = cbl%va_up(k+1) - &
                                dz * cbl%entr(k+1) &
                                        * (cbl%va_up(k+1) - bl%v(k+1))
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                    end if
                end do
    
    
            end subroutine cbl_get_up
    
        subroutine cbl_get_wu(cbl, bl, fluid, grid)
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
            use scm_state_data, only : stateBLDataType
            use pbl_turb_data, only : turbBLDataType
            use phys_fluid, only: fluidParamsDataType
            use pbl_grid, only : pblgridDataType
            implicit none
            type(pblContrGradDataType) :: cbl
            type(stateBLDataType), intent(inout):: bl
            type(fluidParamsDataType), intent(in) :: fluid
            type(pblgridDataType), intent(in) :: grid
            real wu, phys_beta, umod, ustr, rhs, a, b, dz
            integer k, kmax
            kmax = grid%kmax
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
            cbl%wu(:) = 0.0
    
    
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
            umod = sqrt(bl%u(kmax)*bl%u(kmax) + bl%v(kmax)*bl%v(kmax))
            ustr = sqrt(bl%surf%cm2u /bl%rho(kmax) * umod)
            phys_beta = 0.5 * fluid%g /(bl%theta_v(kmax) + bl%theta_v(kmax-1))
    
            cbl%wu(kmax) = 2.46 * ((ustr)**3   &
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                        - 0.4 * phys_beta * bl%surf%hs  &
                            * (grid%z_cell(k))/bl%rho(kmax))**(1.0/3.0) &
                                * sqrt(1.0 - grid%z_cell(k) / bl%hpbla_diag)
            do k = kmax - 1, 1, -1
                dz = (grid%z_cell(K) - grid%z_cell(K+1))
                a = 0.0
                if (abs(cbl%entr(k)) >= 1.0e-8 .and. abs(cbl%wu(k+1)) > 1.0e-6 ) then
                    a = b1 * cbl%entr(k) * cbl%wu(k+1) * dz
                    b =  b2 * 9.81 * (dz/cbl%wu(k+1))  &
                            * (cbl%thetav_up(k) - bl%theta_v(k))/bl%theta_v(k);
    
                    rhs = cbl%wu(k+1) -  a  + b;
                    if (rhs > 0) then
                        cbl%wu(k) = rhs;
                    else
                        cbl%wu(k) = 0.0;
                    endif
                else
                    cbl%wu(k) = 0.0;
                endif
            enddo
    
            end subroutine cbl_get_wu
    
            subroutine cbl_apply_cntrg(cbl, bl, fluid, grid, dt)
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                use scm_state_data, only : stateBLDataType
                use pbl_turb_data, only : turbBLDataType
                use phys_fluid, only: fluidParamsDataType
                use pbl_grid, only : pblgridDataType
                implicit none
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                type(pblContrGradDataType), intent(inout) :: cbl
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                type(stateBLDataType), intent(inout):: bl
                type(fluidParamsDataType), intent(in) :: fluid
                type(pblgridDataType), intent(in) :: grid
                real, intent(in) :: dt
    
                real, dimension(grid%kmax) :: rhs_up, rhs
    
                real a0w0
                integer kmax, kpbl, k
                kmax = grid%kmax
                kpbl = bl%kpbl
                a0w0 =  0.15 * cbl%wu(kpbl)
    
                call cbl_get_entrainment(cbl, bl, fluid,  grid)
                call cbl_get_up(cbl, bl, fluid, grid)
                call cbl_get_wu(cbl, bl, fluid, grid)
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                !apply upwind
                rhs_up(:) = 0
                do k = kmax-1, 1, -1
    
                    if (abs(cbl%wu(k)) > 1.0e-7) then
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                        rhs_up(k) =  0.1 * (cbl%wu(k)) *  &
                                (cbl%theta_up(k+1) - cbl%theta_up(k) - bl%theta(k+1) + bl%theta(k))  &
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                                / (grid%z_cell(k) - grid%z_cell(k+1))
                    else
                        rhs_up(k)=0
                    end if
                end do
                bl%theta = bl%theta + dt * rhs_up
    
                rhs_up = 0
                do k = kmax-1, 1, -1
                    if (abs(cbl%wu(k)) > 1.0e-7) then
    
                        rhs_up(k) =  0.1 * (cbl%wu(k)) *  &
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                                (cbl%qv_up(+1) - cbl%qv_up(k)  &
                                        - bl%qv(k+1) + bl%qv(k)) / (grid%z_cell(k) -grid%z_cell(k+1))
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                    else
                        rhs_up(k)=0
                    end if
                end do
                bl%qv(:) = bl%qv(:) + dt * rhs_up(:)
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                rhs_up(:) = 0
                do k = kmax-1, 1, -1
                    if (abs(cbl%wu(k)) > 1.0e-8) then
    
                        rhs_up(k) =  0.1 * (cbl%wu(k)) *  &
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                                (cbl%ua_up(k+1) - cbl%ua_up(k) - bl%u(k+1) + bl%u(k))  &
                                / (grid%z_cell(k) - grid%z_cell(k+1))
                    else
                        rhs_up(k)=0
                    end if
                end do
                bl%u(:) = bl%u(:) + dt * rhs_up(:)
                rhs_up(:) = 0
                do k = kmax-1, 1, -1
                    if (abs(cbl%wu(k)) > 1.0e-8) then
    
                        rhs_up(k) =  0.1 * (cbl%wu(k)) *  &
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
                                (cbl%va_up(k+1) - cbl%va_up(k) - bl%v(k+1) + bl%v(k))  &
                                / (grid%z_cell(k) - grid%z_cell(k+1))
                    else
                        rhs_up(k)=0
                    end if
                end do
                bl%v(:) = bl%v(:) + dt * rhs_up(:)
    
    
                end subroutine cbl_apply_cntrg
    
        subroutine new_cntrg(cbl, bl, fluid, grid, dt)
            use scm_state_data, only : stateBLDataType
            use pbl_turb_data, only : turbBLDataType
            use phys_fluid, only: fluidParamsDataType
            use pbl_grid, only : pblgridDataType
            implicit none
            type(pblContrGradDataType), intent(inout) :: cbl
            type(stateBLDataType), intent(inout):: bl
            type(fluidParamsDataType), intent(in) :: fluid
            type(pblgridDataType), intent(in) :: grid
            real, intent(in) :: dt
    
            ! local variables
            real, save, allocatable ::  rhs_up(:), rhs(:)
            real, save, allocatable :: bouf(:)
            real wu, phys_beta, umod, rhs_ws, a, b
            real   dz, dzentrp, dzentrm, temp,dth
            real sigmaw, sigmath, sigmaqc
            real wstr, ustr, thstar, thvstar, qstar
            real z1, hpb, hpbmf
            real entrint, entexp, entexpu
            real wp, entw, wn2
    
    
            real a0w0
            integer kmax, kpbl, k
            kmax = grid%kmax
            kmax = grid%kmax
            if (.not.(allocated(rhs_up))) then
                allocate(rhs_up(grid%kmax), source=0.0)
            end if
            if (.not.(allocated(rhs))) then
                allocate(rhs(grid%kmax), source=0.0)
            end if
            if (.not.(allocated(bouf))) then
                allocate(bouf(grid%kmax), source=0.0)
            end if
            kpbl = bl%kpbl
            cbl%theta_up(:) = 0.0
            cbl%thetav_up(:) = 0
            cbl%qv_up(:) = 0.0
            cbl%ua_up(:) = 0.0
            cbl%va_up(:) = 0.0
            cbl%entr(:) = 0.0
            cbl%wu(:) = 0.0
            rhs_up(:) = 0.0
            rhs(:) = 0.0
            ! Check if the flux is convective
            if (bl%surf%hs > 0.0) then
                ! get surface properties
                z1  = grid%z_cell(kmax)
                hpb = bl%hpbla_diag
                phys_beta = 0.5 * fluid%g /(bl%theta_v(kmax) + bl%theta_v(kmax-1))
                wstr = (phys_beta * (bl%surf%hs/bl%rho(kmax)/fluid%cp) &
                        * bl%hpbla_diag)**(0.33333)
                wstr = max(wstrmin, wstr)
    
                ! Initial condition for vertical velocity
                umod = sqrt(bl%u(kmax)*bl%u(kmax) + bl%v(kmax)*bl%v(kmax))
                ustr = sqrt(bl%surf%cm2u /bl%rho(kmax) * umod)
                !cbl%wu(kmax) = 1.0 * ((ustr)**3.0   & !2.46
                !        + 0.4 * wstr**3.0)**(1.0/3.0) &
                !        * sqrt(1.0 - grid%z_cell(kmax) / bl%hpbla_diag)
    
                sigmaw = 1.3 * (ustr**3.0 + 0.6 * wstr**3.0 * z1/hpb) * &
                        sqrt(1.0 - z1 / hpb)
    
                thstar = (bl%surf%hs/(bl%rho(kmax))) / wstr
                thvstar =  (bl%surf%hs/(bl%rho(kmax))) / wstr
                qstar = (bl%surf%es/bl%rho(kmax)) / wstr
                cbl%wu(kmax) = 0.5 * sigmaw
    
    
                ! initial perturbation
                cbl%thetav_up0 = (bl%surf%hs/(bl%rho(kmax))) / sigmaw
                cbl%theta_up0 =  (bl%surf%hs/(bl%rho(kmax))) / sigmaw
                cbl%qv_up0 =  (bl%surf%es/bl%rho(kmax)) / sigmaw
                cbl%ua_up0 =  0.5 * (bl%u(kmax) + bl%u(kmax-1))
                cbl%va_up0  =  0.5 *  (bl%v(kmax) + bl%v(kmax-1))
                cbl%thetav_up(kmax) =  alph0 *cbl%thetav_up0 + bl%theta_v(kmax)
                cbl%theta_up(kmax) = alph0 * cbl%theta_up0  + bl%theta(kmax)
                cbl%qv_up(kmax) = alph0 * cbl%qv_up0  + bl%qv(kmax)
                cbl%ua_up(kmax) = cbl%ua_up0  + bl%u(kmax)
                cbl%va_up(kmax) = cbl%va_up0  + bl%v(kmax)
    
    
    
                !Initial entrainment
                !cbl%entr(kmax) = 1.0 / (cbl%wu(kmax) * tau_dry_scale)  &
                                !+ c_entr / grid%z_cell(kmax)
                dz = grid%z_cell(kmax) - grid%z_edge(kmax)
                cbl%entr(kmax) = c_entr * ( 1.0/(grid%z_cell(kmax) + dz)  &
                        + 1.0/(bl%hpbla_diag - grid%z_cell(kmax) + dz))
    
                bl%kpbld_mf = bl%kpbl
                ! get non-entraiened parcel height
                !do k = kmax - 1, 2, -1
                !    dth = cbl%thetav_up(kmax) - bl%theta_v(k)
                !    if (bl%kpbld_mf == 0 .and. dth < 0.0 ) then
                !        bl%kpbld_mf = k
                !    end if
                !end do
                hpbmf = 0.5 * (grid%z_cell(bl%kpbld_mf) + &
                        bl%hpbla_diag)
                write(*,*) 'hbp, hmf', grid%z_cell(bl%kpbld_mf), bl%hpbla_diag, bl%surf%hs
                ! get proper entrainment
                do k = grid%kmax-1,1,-1
                    dz = (grid%z_cell(k) - grid%z_cell(k+1))
                    if (grid%z_cell(k) <= hpbmf) then
                    cbl%entr(k) = c_entr * ( 1.0/(grid%z_cell(k) + dz)  &
                            + 1.0/(hpbmf - grid%z_cell(k) + dz))
                    else
                        cbl%entr(k) = 0.0
                    end if
                end do
    
                !get updrafts
                do k = grid%kmax-1,bl%kpbld_mf,-1
                    dz = (grid%z_cell(k) - grid%z_cell(k+1))
                    entexp = exp( - cbl%entr(k) * dz)
                    entexpu = exp( - cbl%entr(k) * dz / 3.0 )
                    cbl%thetav_up(k) = bl%theta_v(k) * (1.0 - entexp) + &
                            cbl%thetav_up(k+1) * entexp
                    cbl%theta_up(k) = bl%theta(k) * (1.0 - entexp) + &
                            cbl%theta_up(k+1) * entexp
                    cbl%qv_up(k) = bl%qv(k) * (1.0 - entexp) + &
                            cbl%qv_up(k+1) * entexp
                    cbl%ua_up(k) = bl%u(k) * (1.0 - entexpu) + &
                            cbl%ua_up(k+1) * entexpu
                    cbl%va_up(k) = bl%u(k) * (1.0 - entexpu) + &
                            cbl%va_up(k+1) * entexpu
                    bouf(k) = fluid%g *  &
                         (0.5 * (cbl%thetav_up(k) + cbl%thetav_up(k+1)) / &
                            bl%theta_v(k) - 1.0)
                enddo
    
                !get vertical speed
                do k = grid%kmax-1,bl%kpbld_mf,-1
                    dz = (grid%z_cell(k) - grid%z_cell(k+1))
                    wp = b1 * cbl%entr(k)
                    if (wp > 0.0) then
                        entw = exp( -2.0 * wp * dz )
                        wn2 = cbl%wu(k+1) * cbl%wu(k+1) * entw + &
                                b2* bouf(k)*(1.0-entw)/entw
                    else
                        wn2 = cbl%wu(k+1) * cbl%wu(k+1) + &
                                2.0 * b2 * bouf(k) * dz
                    end if
    
                    if ( wn2 > 0.0) then
                        cbl%wu(k) = sqrt(wn2)
                    else
                        cbl%wu(k) = 0.0
                    end if
                end do
    
    
                ! apply upwind
                rhs_up(:) = 0.0
                do k = kmax-1, 1, -1
                    if (cbl%wu(k) > 0.0) then
                        rhs_up(k) =  a0 * (cbl%wu(k)) *  &
                                (cbl%theta_up(k+1) - cbl%theta_up(k) - bl%theta(k+1) + bl%theta(k))  &
                                / (grid%z_cell(k) - grid%z_cell(k+1))
                    else
                        rhs_up(k)=0.0
                    end if
                end do
                bl%theta = bl%theta + dt * rhs_up
    
                rhs_up(:) = 0.0
                do k = kmax-1, 1, -1
                    if (cbl%wu(k) > 0.0) then
                        rhs_up(k) =  a0 * (cbl%wu(k)) *  &
                                (cbl%qv_up(k+1) - cbl%qv_up(k)  &
                                        - bl%qv(k+1) + bl%qv(k)) &
                                / (grid%z_cell(k) -grid%z_cell(k+1))
                    else
                        rhs_up(k)=0.0
                    end if
                end do
                bl%qv(:) = bl%qv(:) + dt * rhs_up(:)
    
                rhs_up(:) = 0.0
                do k = kmax-1, 1, -1
                    if (cbl%wu(k) > 0.0) then
                        rhs_up(k) =  a0 * (cbl%wu(k)) *  &
                                (cbl%ua_up(k+1) - cbl%ua_up(k) - bl%u(k+1) + bl%u(k))  &
                                / (grid%z_cell(k) - grid%z_cell(k+1))
                    else
                        rhs_up(k)=0.0
                    end if
                end do
                bl%u(:) = bl%u(:) + dt * rhs_up(:)
                rhs_up(:) = 0.0
                do k = kmax-1, 1, -1
                    if (cbl%wu(k) > 0.0) then
                        rhs_up(k) =  a0 * (cbl%wu(k)) *  &
                                (cbl%va_up(k+1) - cbl%va_up(k) - bl%v(k+1) + bl%v(k))  &
                                / (grid%z_cell(k) - grid%z_cell(k+1))
                    else
                        rhs_up(k)=0.0
                    end if
                end do
                bl%v(:) = bl%v(:) + dt * rhs_up(:)
            end if
        end subroutine new_cntrg
    
    Debolskiy Andrey's avatar
    Debolskiy Andrey committed
    end module pbl_dry_contrgradient