MODULE INIT_VAR_MOD use LAKE_DATATYPES, only : ireals, iintegers contains SUBROUTINE INIT_VAR & ( M, Mice, ns, ms, ml, nsoilcols, ndatamax, & & init_T, skin, zero_model, & & h10, l10, hs10, ls10, tempair, Ts0, Tb0, Tm, Tbb0, & & Sals0, Salb0, us0, vs0, h_ML0, & & rosoil, rosdry, por, depth_area, ip, isp, & & flag_snow, flag_snow_init, itop, nstep, itherm, & & h1, l1, hs1, ls1, & & hx1, hx2, hy1, hy2, & & hx1t, hx2t, hy1t, hy2t, & & hx1ml, hx2ml, hy1ml, hy2ml, & & veg, snmelt, snowmass, cdmw, velfrict_prev, & & roughness, eflux0_kinem, Elatent, & & totalevap, totalmelt, totalprecip, totalwat, totalpen, & & time, dhwfsoil, dhw, dhw0, dhi, dhi0, dls0, & & E1, eps1, zsoilcols, Tsoil1, wi1, wl1, Sals1, & & rootss, qsoil, TgrAnn, qwater, & & oxyg, DIC, phosph, oxygsoil, Sal1, u1, v1, Tw1, Tskin, T_0dim, Eseiches, & & Ti1, salice, porice, Tis1, z_full, ddz, & & dz, T, wl, dens, lamw, & & dzeta_int, zsoil, pressure) ! Subroutine INIT_VAR initializes the prognostic variables of the model use PHYS_FUNC, only : & & MELTPNT, & & UNFRWAT, & & WL_MAX, & & WI_MAX, & & HENRY_CONST, & & MELTINGPOINT use PHYS_CONSTANTS, only : & & row0, g, Kelvin0, R_univ, poricebot use METH_OXYG_CONSTANTS, only : & & ch4_atm0, o2_atm0, co2_atm0, & & rel_conc_ebul_crit, & & Henry_const0_ch4, & & Henry_temp_dep_ch4, & & Henry_temp_ref, & & molmass_p use DRIVING_PARAMS, only : & & tricemethhydr, & & nmeltpoint, & & initprof ! derived datatype use NUMERIC_PARAMS, only : & & small_value implicit none real(kind=ireals), save :: E_init real(kind=ireals), save :: eps_init ! Input variables integer, intent(in) :: M, Mice, ns, ms, ml, nsoilcols, ndatamax ! Grid dimensions integer, intent(in) :: init_T, skin, zero_model ! Driving parameters real(kind=ireals), intent(in) :: h10, l10, hs10, ls10 real(kind=ireals), intent(in) :: tempair, Ts0, Tb0, Tm, Tbb0 real(kind=ireals), intent(in) :: Sals0, Salb0 real(kind=ireals), intent(in) :: us0, vs0 real(kind=ireals), intent(in) :: h_ML0 real(kind=ireals), intent(in) :: rosoil(1:ns), rosdry(1:ns), por(1:ns) real(kind=ireals), intent(in) :: depth_area(1:ndatamax,1:2) ! Data for lake bathymetry type(initprof), intent(in) :: ip, isp real(kind=ireals), intent(in) :: zsoil(1:ns) real(kind=ireals), intent(in) :: pressure real(kind=ireals), intent(in) :: dzeta_int(1:M+1) real(kind=ireals), intent(in) :: ddz(1:M) ! Output variables integer(kind=iintegers), intent(out) :: flag_snow, flag_snow_init, itop integer(kind=iintegers), intent(out) :: nstep integer(kind=iintegers), intent(inout), allocatable :: itherm(:) real(kind=ireals), intent(out) :: h1, l1, hs1, ls1 real(kind=ireals), intent(out) :: hx1, hx2, hy1, hy2 real(kind=ireals), intent(out) :: hx1t, hx2t, hy1t, hy2t real(kind=ireals), intent(inout), allocatable :: hx1ml(:), hx2ml(:), hy1ml(:), hy2ml(:) real(kind=ireals), intent(out) :: veg real(kind=ireals), intent(out) :: snmelt, snowmass real(kind=ireals), intent(out) :: cdmw, velfrict_prev real(kind=ireals), intent(out) :: roughness real(kind=ireals), intent(out) :: eflux0_kinem, Elatent real(kind=ireals), intent(out) :: totalevap, totalmelt, totalprecip, totalwat, totalpen real(kind=ireals), intent(out) :: time real(kind=ireals), intent(out) :: dhwfsoil real(kind=ireals), intent(out) :: dhw, dhw0, dhi, dhi0, dls0 real(kind=ireals), intent(out) :: E1(1:M+1), eps1(1:M+1) real(kind=ireals), intent(out) :: zsoilcols(1:nsoilcols+1) real(kind=ireals), intent(out) :: Tsoil1(1:ns,1:nsoilcols), Sals1(1:ns,1:nsoilcols) real(kind=ireals), intent(out) :: wi1 (1:ns,1:nsoilcols), wl1 (1:ns,1:nsoilcols) real(kind=ireals), intent(out) :: rootss(1:ns), qsoil(1:ns,1:nsoilcols), TgrAnn(1:ns), qwater(1:M+1) real(kind=ireals), intent(out) :: oxyg(1:M+1), DIC(1:M+1), phosph(1:M+1) real(kind=ireals), intent(out) :: oxygsoil(1:nsoilcols) real(kind=ireals), intent(out) :: Sal1(1:M+1) real(kind=ireals), intent(out) :: u1(1:M+1), v1(1:M+1) real(kind=ireals), intent(out) :: Tw1(1:M+1), Tskin(1:2) real(kind=ireals), intent(out) :: Ti1(1:Mice+1), Tis1(1:Mice+1) real(kind=ireals), intent(out) :: salice(1:Mice+1), porice(1:Mice+1) real(kind=ireals), intent(out) :: z_full(1:M+1) real(kind=ireals), intent(out) :: dz(1:ms), T(1:ml), wl(1:ml), dens(1:ms) real(kind=ireals), intent(out) :: lamw(1:M) real(kind=ireals), intent(out) :: T_0dim real(kind=ireals), intent(out) :: Eseiches ! Local variables real(kind=ireals), parameter :: Ct_d_Ch = 2. ! Using results by West & Plug, 2007, may be estimated ! from 1.7 to 2.8 real(kind=ireals) :: work, work1 real(kind=ireals), allocatable :: pressoil(:), workarr(:) real(kind=ireals) :: z, h_ML0zv, h_talik, ch4_bot real(kind=ireals) :: Ti10, Ti11 integer(kind=iintegers) :: i, j, i_ML, i_talik, k integer(kind=iintegers) :: n_1cm, n_5cm logical :: flag logical, save :: firstcall = .true. logical, parameter :: soil_thermokarst_init = .false. real(kind=ireals), parameter :: relch4_0 = 1. if (firstcall) then E_init = 10.d0**(-5.5) eps_init = 1.d-9 endif h1 = h10 hx1 = 0.; hx2 = 0. hy1 = 0.; hy2 = 0. hx1t = 0.; hx2t = 0. hy1t = 0.; hy2t = 0. if (allocated(hx1ml)) then hx1ml(1:M+1) = 0.; hx2ml(1:M+1) = 0. hy1ml(1:M+1) = 0.; hy2ml(1:M+1) = 0. endif if (allocated(itherm)) itherm(1:M+2) = -1 l1 = l10 hs1 = hs10 ls1 = ls10 do i = 1, M E1(i) = E_init !+ float(i)/float(M)*(1.d-10 - 1.d-8) eps1(i) = eps_init !+ float(i)/float(M)*(1.d-18 - 1.d-14) enddo do i = 1, M+1 z_full (i) = dzeta_int(i)*h1 enddo i_ML = int((M+1)*h_ML0/h1) ! The index of level of mixed-layer depth ! Water temperature initialization if (init_T == 2) then h_ML0zv = (Tm - 0.5*(Tb0 + Ts0))/(Ts0/h1 - 0.5*(Ts0 + Tb0)/h1) i_ML = int(M*h_ML0zv/h1) endif if (init_T == 1 .or. init_T == 2) then Tw1(1:max(i_ML,1)) = Ts0 do i = max(i_ML+1,2), M+1 Tw1(i) = Ts0 + (Tb0-Ts0)*float(i-i_ML)/float(M+1-i_ML) enddo ! The initial temperature profile is given from the input file elseif (init_T == 3) then call LININTERPOL (ip%zTinitprof,ip%Tinitprof,ip%lenprof, & & z_full,Tw1,M+1,flag,.true.) call LININTERPOL (ip%zTinitprof,ip%Sinitprof,ip%lenprof, & & z_full,Sal1,M+1,flag,.true.) if (.not.flag) then print*, 'The error while interpolating the initial & &temperature profile: terminating program' STOP endif endif ! Lake depth intervals for the tops of soil columns. ! An alternative - to calculate from the vertical grid of depth-area data. if (nsoilcols > 1 .and. depth_area(1,2) >= 0.) then !work = h10/real(nsoilcols) work1 = maxval(depth_area(:,1)) work = ( work1 - h10*0.5*ddz(M) )/real(nsoilcols-1) zsoilcols(nsoilcols+1) = work1 do i = 1, nsoilcols zsoilcols(i) = (i-1)*work enddo endif Sals1(1:ns,1:nsoilcols) = Salb0*row0/( rosdry(1)*(1 - por(1)) ) ! assuming, that salinity in ground ! is the same ! as one in near bottom layer of water allocate(pressoil(1:ns)) do i = 1, ns pressoil(i) = pressure + row0*g*(h10 + zsoil(i)) enddo ! Temperature distribution in talik assuming homogeneous distribution of salinity in ground flag = (h10 > 0. .and. Tb0 > MELTINGPOINT(Sals1(1,nsoilcols),pressoil(1),tricemethhydr%par) & & .and. Tbb0 < MELTINGPOINT(Sals1(ns,nsoilcols),pressoil(ns),tricemethhydr%par)) if (flag .and. soil_thermokarst_init) then ! Initializing the talik depth, assuming thermokarst lake, following West and Plug, 2007 h_talik = min(Ct_d_Ch*h10,0.8*zsoil(ns)) do i = 1, ns if (zsoil(i) >= h_talik) then i_talik = i ! i_talik is the number of the first level below the estimated talik depth exit endif enddo ! Temperature distribution in the talik work = MELTINGPOINT(Sals1(i_talik,nsoilcols),pressoil(i_talik),tricemethhydr%par) do i = 1, i_talik Tsoil1(i,nsoilcols) = Tb0 + float(i-1)/float(i_talik-1) * (work - Tb0) enddo ! Temperature distribution below the talik do i = i_talik+1, ns Tsoil1(i,nsoilcols) = work + float(i-i_talik)/float(ns-i_talik)*(Tbb0 - work) enddo else h_talik = 0. ! Linear temperature profile in soil if (init_T == 1 .or. init_T == 2) then do i = 1, ns Tsoil1(i,nsoilcols) = Tb0 + float(i-1)/float(ns-1)*(Tbb0-Tb0) enddo ! The initial soil temperature profile is given from the input file elseif (init_T == 3) then call LININTERPOL (isp%zTinitprof,isp%Tinitprof,isp%lenprof, & & zsoil,Tsoil1(1,nsoilcols),ns,flag,.true.) if (.not.flag) then print*, 'The error while interpolating the initial & &soil temperature profile: terminating program' STOP endif endif endif ! Ice and liquid water content initialization in soil do i = 1, ns if (Tsoil1(i,nsoilcols) > MELTINGPOINT(Sals1(i,nsoilcols),pressoil(i),tricemethhydr%par)) then wi1(i,nsoilcols) = 0. wl1(i,nsoilcols) = WL_MAX(por(i),rosoil(i),0.e0_ireals,tricemethhydr%par) - 0.01 else wl1(i,nsoilcols) = UNFRWAT(Tsoil1(i,nsoilcols),i) wi1(i,nsoilcols) = WI_MAX(por(i),rosoil(i),tricemethhydr%par) - wl1(i,nsoilcols) - 0.01 endif enddo ! Identical initialization of all soil columns if (nsoilcols > 1 .and. depth_area(1,2) >= 0.) then do i = 1, ns wl1 (i,1:nsoilcols-1) = wl1 (i,nsoilcols) wi1 (i,1:nsoilcols-1) = wi1 (i,nsoilcols) enddo !Temperature in side soil columns is initialized as a linear function from !a water temperature at respective depth to Tbb0 allocate(workarr(1:M+1)) do j = 1, nsoilcols-1 work = 0.5*(zsoilcols(j) + zsoilcols(j+1)) workarr(1:M+1) = abs(z_full(1:M+1) - work) k = minloc(workarr,1) do i = 1, ns !Tsoil1(i,j) = Tw1(k) + float(i-1)/float(ns-1)*(Tbb0 - Tw1(k)) Tsoil1(i,j) = Tw1(k) + (Tbb0 - Tw1(k))*(1. - exp( - 10.*float(i-1)/float(ns-1) ) ) enddo enddo deallocate(workarr) endif ! Methane variables initialization rootss(1:ns) = 0.e0_ireals ! No roots veg = 0.e0_ireals ! No vegetation at the bottom !i_ML = int((M+1)*h_ML0/h1) if (init_T /= 3) then ch4_bot = relch4_0*rel_conc_ebul_crit*(pressure + row0*g*h10)* & & HENRY_CONST(Henry_const0_ch4, Henry_temp_dep_ch4, & & Henry_temp_ref, Tb0 + Kelvin0) ! Saturated concentration at the bottom do i = 1, M+1 if (i <= i_ML) then qwater(i) = ch4_atm0 ! Atmospheric concentration else qwater(i) = qwater(max(i_ML,1)) + & & (ch4_bot - qwater(max(i_ML,1)))*(h_ML0 - dzeta_int(i)*h10)/(h_ML0 - h10) endif enddo else call LININTERPOL (ip%zTinitprof,ip%ch4initprof,ip%lenprof, & & z_full,qwater,M+1,flag,.true.) endif ! qwater2(1:M+1,1,1:2) = 0.5*ch4_atm0 ! two-meth TgrAnn(1:ns) = Tsoil1(1:ns,nsoilcols) ! qsoil(1) = ch4_bot ! qsoil2(1,1:2) = 0.5*ch4_atm0 ! two-meth ! Initialization of methane in soil columns at the lake's slopes if (nsoilcols > 1 .and. depth_area(1,2) >= 0.) then do j = 1, nsoilcols-1 do i = 1, ns qsoil(i,j) = relch4_0*rel_conc_ebul_crit*por(i) * & & (pressure + row0*g*(0.5*(zsoilcols(j) + zsoilcols(j+1)) + zsoil(i))) * & ! assuming hydrostatic pressure in soil & HENRY_CONST(Henry_const0_ch4, Henry_temp_dep_ch4, & & Henry_temp_ref, Tsoil1(i,j) + Kelvin0) ! qsoil2(i,1:2) = 0.5*qsoil(i) ! two-meth enddo enddo endif ! Initialization of methane in deepest soil column qsoil(1,nsoilcols) = qwater(M+1)*por(1) ! Boundary condition do i = 2, ns qsoil(i,nsoilcols) = relch4_0*rel_conc_ebul_crit*por(i) * & & (pressure + row0*g*(h10 + zsoil(i))) * & ! assuming hydrostatic pressure in soil & HENRY_CONST(Henry_const0_ch4, Henry_temp_dep_ch4, & & Henry_temp_ref, Tsoil1(i,nsoilcols) + Kelvin0) ! qsoil2(i,1:2) = 0.5*qsoil(i) ! two-meth enddo !qwater(M+1) = qsoil(1,nsoilcols)/por(1) ! Boundary condition ! Dissolved inorganic carbon initialization if (init_T /= 3) then DIC(1:M+1) = 10.*co2_atm0 ! Atmospheric concentration else call LININTERPOL (ip%zTinitprof,ip%co2initprof,ip%lenprof, & & z_full,DIC,M+1,flag,.true.) endif ! Inorganic dissolved phosphorus if (init_T /= 3) then phosph(:) = 0.01/molmass_p else call LININTERPOL (ip%zTinitprof,ip%phosphinitprof,ip%lenprof, & & z_full,phosph,M+1,flag,.true.) endif ! Oxygen initialization if (init_T /= 3) then do i = 1, M+1 if (i <= i_ML) then oxyg(i) = o2_atm0 ! Atmospheric concentration else oxyg(i) = oxyg(max(i_ML,1)) - oxyg(max(i_ML,1))*(h_ML0 - dzeta_int(i)*h10)/(h_ML0 - h10) endif oxyg(i) = max(oxyg(i),small_value) enddo else call LININTERPOL (ip%zTinitprof,ip%o2initprof,ip%lenprof, & & z_full,oxyg,M+1,flag,.true.) endif oxygsoil(1:nsoilcols) = 0. !Zero initial oxygen concentration in the aerobic soil layer u1(1:max(i_ML,1)) = us0 v1(1:max(i_ML,1)) = vs0 do i = max(i_ML+1,2), M+1 u1(i) = us0 + (0.e0_ireals - us0)*float(i-i_ML)/float(M+1-i_ML) v1(i) = vs0 + (0.e0_ireals - vs0)*float(i-i_ML)/float(M+1-i_ML) enddo if (init_T /= 3) then Sal1(1:max(i_ML,1)) = Sals0 do i = max(i_ML+1,2), M+1 Sal1(i) = Sals0 + (Salb0-Sals0)*float(i-i_ML)/float(M+1-i_ML) enddo endif if (skin == 0) then Tskin(1:2) = 0.e0_ireals else Tskin(1) = Tw1(1) endif ! Initial temperature for zero-dimensional model if (zero_model == 1) then T_0dim = Tw1(1)*0.5*ddz(1) + Tw1(M+1)*0.5*ddz(M) do i = 2, M T_0dim = T_0dim + Tw1(i)*0.5*(ddz(i-1) + ddz(i) ) enddo else T_0dim = 0. endif Ti1 = 0. salice(:) = 0. porice(:) = poricebot Tis1 = 0. Ti10 = min(tempair,-1.d-1) ! Initial ice surface temperature, Celsius if (l1 /= 0) then if (h1 > 0.) then ! Ice over water Ti11 = MELTPNT(Sals0,0.e0_ireals,nmeltpoint%par) else ! Ice over soil Ti11 = Tb0 endif do i = 1, Mice+1 Ti1(i)= Ti10 + (Ti11 - Ti10)*float(i-1)/float(Mice) ! Linear profile, if dzetai-grid is regular, enddo ! water layer underneath is assumed to exist endif if (hs1 == 0.) then flag_snow = 0 flag_snow_init = 1 itop = 1 else flag_snow = 1 flag_snow_init = 0 hs1 = max(2.d-2, hs1) hs1 = int(hs1/0.01)*0.01 n_5cm = int(hs1/0.05) n_1cm = int((hs1-n_5cm*0.05)/0.01) if (n_1cm == 0) then n_1cm = 1 hs1 = hs1 + 0.01 endif itop = ms - (n_1cm + n_5cm) do i = itop, itop + n_1cm - 1 dz(i) = 0.01 T(i) = min(tempair,-5.d0) wl(i) = 0 dens(i) = 150. enddo do i = itop + n_1cm, ms-1 dz(i) = 0.05 T(i) = min(tempair,-5.d0) wl(i) = 0 dens(i) = 150. enddo dz(ms) = 0.5d0*dz(ms-1) T(ms) = min(tempair,-5.d0) wl(ms) = 0.e0_ireals dens(ms) = 150.d0 endif snmelt = 0.e0_ireals snowmass = 0.e0_ireals cdmw = 1.d-15 velfrict_prev = 1.d-2 roughness = 1.d-3 eflux0_kinem = 0.e0_ireals Elatent = 0. totalevap = 0 totalmelt = 0 totalprecip = 0. totalwat = 0 totalpen = 0 time = 0 nstep = 0 dhwfsoil = 0. dhw = 0. dhw0 = 0. dhi = 0. dhi0 = 0. dls0 = 0. lamw(:) = 1.d+3 Eseiches = 0. !initial seiche energy deallocate(pressoil) if (firstcall) firstcall = .false. END SUBROUTINE INIT_VAR END MODULE INIT_VAR_MOD