[3223] | 1 | subroutine soilwater(ngrid, nlayer, nq, nsoil, nqsoil, ptsrf, ptsoil, ptimestep, & |
---|
[3115] | 2 | exchange, qsat_surf, pq, pa, pb, pc, pd, pdqsdifpot, pqsurf, & |
---|
[3262] | 3 | pqsoil, pplev, rhoatmo, writeoutput, zdqsdifrego, zq1temp2, saturation_water_ice) |
---|
[3115] | 4 | |
---|
| 5 | |
---|
[3272] | 6 | use comsoil_h, only: igcm_h2o_vap_soil, igcm_h2o_ice_soil, igcm_h2o_vap_ads, layer, mlayer, choice_ads, porosity_reg, & |
---|
| 7 | ads_const_D, ads_massive_ice |
---|
[3115] | 8 | use comcstfi_h |
---|
| 9 | use tracer_mod |
---|
| 10 | use surfdat_h, only: watercaptag ! use mis par AP15 essai |
---|
| 11 | use geometry_mod, only: cell_area, latitude_deg |
---|
| 12 | use write_output_mod, only: write_output |
---|
| 13 | implicit none |
---|
| 14 | |
---|
| 15 | ! ================================================================================================= = |
---|
| 16 | ! Description: |
---|
| 17 | ! |
---|
| 18 | ! This subroutine calculates the profile of water vapor, adsorbed water and ice in the regolith, |
---|
| 19 | ! down to depth(nsoil) ~ 18m. It calculates the flux of water vapor (zdqsdifrego) between the |
---|
| 20 | ! suburface and the atmosphere. |
---|
| 21 | ! |
---|
[3245] | 22 | ! Water vapor and adsorbed water are treated as two separate subsurface tracers that are connected |
---|
[3115] | 23 | ! by adsorption / desorption coefficients, including an adsorption / desorption kinetic factor. |
---|
| 24 | ! |
---|
| 25 | ! The water adsorption isotherm is linear, with a saturation plateau corresponding to one monolayer |
---|
| 26 | ! of adsorbed water molecules (i.e. an approximation of a Langmuir - type isotherm). The slope of the |
---|
| 27 | ! isotherm is defined by the enthalpy of adsorption (in kJ / mol). |
---|
[3223] | 28 | ! New since 2020 : the adsorption isotherm is now linear by part, to better simulate Type II or Type III isotherms (and not only Type I) |
---|
[3115] | 29 | ! |
---|
| 30 | ! The linearized adsorption - diffusion equation is solved first, then the water vapor pressure is |
---|
| 31 | ! compared to the saturation vapor pressure, and if the latter is reached, ice is formed, the water vapor |
---|
| 32 | ! pressure is fixed to its saturation value and the adsorption - diffusion equation is solved again. |
---|
| 33 | ! If ice was already present, its sublimation or growth is calculated. |
---|
| 34 | ! |
---|
| 35 | ! This subroutine is called by vdifc.F if the parameters "regolithe" and "water" are set to true in |
---|
| 36 | ! callphys.def. It returns the flux of water vapor that is injected into or out of the regolith, |
---|
| 37 | ! and which serves as a boundary condition to calculate the vertical atmospheric profile of water vapor |
---|
| 38 | ! in vdifc. It also calculates the exchange between the subsurface and surface ice. |
---|
| 39 | ! |
---|
| 40 | ! It requires three subsurface tracers to be defined in traceur.def : |
---|
| 41 | ! - h2o_vap_soil (subsurface water vapor) |
---|
| 42 | ! - h2o_ice_soil (subsurface ice) |
---|
| 43 | ! - h2o_ads_vap (adsorbed water) |
---|
| 44 | ! |
---|
| 45 | ! Author : Pierre - Yves Meslin (pmeslin@irap.omp.eu) |
---|
| 46 | ! |
---|
| 47 | ! ================================================================================================= = |
---|
| 48 | |
---|
| 49 | ! Libraries : |
---|
| 50 | ! =========== = |
---|
| 51 | !#include "dimensions.h" |
---|
| 52 | !#include "dimphys.h" |
---|
| 53 | !#include "comsoil.h" |
---|
| 54 | #include "callkeys.h" |
---|
| 55 | !#include "comcstfi.h" |
---|
| 56 | !#include "tracer.h" |
---|
| 57 | !#include "watercap.h" |
---|
| 58 | |
---|
| 59 | |
---|
| 60 | ! Arguments : |
---|
| 61 | ! ====================================================================== |
---|
| 62 | |
---|
| 63 | ! Inputs : |
---|
| 64 | ! ---------------------------------------------------------------------- |
---|
| 65 | integer, intent(in) :: ngrid ! number of points in the model (all lat and long point in one 1D array) |
---|
| 66 | integer, intent(in) :: nlayer ! number of layers |
---|
| 67 | integer, intent(in) :: nq ! number of tracers |
---|
| 68 | integer, intent(in) :: nsoil |
---|
| 69 | integer, intent(in) :: nqsoil |
---|
| 70 | logical, save :: firstcall_soil = .true. ! triggers the initialization |
---|
[3223] | 71 | real, intent(in) :: ptsoil(ngrid, nsoil) ! Subsurface temperatures |
---|
[3115] | 72 | real, intent(in) :: ptsrf(ngrid) ! Surface temperature |
---|
| 73 | real, intent(in) :: ptimestep ! length of the timestep (unit depends on run.def file) |
---|
| 74 | logical, intent(in) :: exchange(ngrid) ! logical :: array describing whether there is exchange with the atmosphere at the current timestep |
---|
| 75 | |
---|
[3245] | 76 | real, intent(in) :: qsat_surf(ngrid) ! Saturation mixing ratio at the surface at the current surface temperature (formerly qsat) |
---|
[3115] | 77 | real, intent(in) :: pq(ngrid, nlayer, nq) ! Tracer atmospheric mixing ratio |
---|
| 78 | real, intent(in) :: pa(ngrid, nlayer) ! Coefficients za |
---|
| 79 | real, intent(in) :: pb(ngrid, nlayer) ! Coefficients zb |
---|
| 80 | real, intent(in) :: pc(ngrid, nlayer) ! Coefficients zc |
---|
| 81 | real, intent(in) :: pd(ngrid, nlayer) ! Coefficients zd |
---|
[3245] | 82 | real, intent(in) :: pdqsdifpot(ngrid) ! Potential pdqsdif (without subsurface - atmosphere exchange) |
---|
[3115] | 83 | |
---|
| 84 | real, intent(in) :: pplev(ngrid, nlayer+1) ! Atmospheric pressure levels |
---|
| 85 | real, intent(in) :: rhoatmo(ngrid) ! Atmospheric air density (1st layer) (not used right now) |
---|
[3223] | 86 | logical, intent(in) :: writeoutput ! just to check we are at the last subtimestep and we |
---|
[3115] | 87 | |
---|
| 88 | ! Variables modified : |
---|
| 89 | ! ---------------------------------------------------------------------- |
---|
[3245] | 90 | real, intent(inout) :: pqsoil(ngrid, nsoil, nqsoil) ! Subsurface tracers (water vapor and ice) |
---|
| 91 | real, intent(in) :: pqsurf(ngrid) ! Water ice on the surface |
---|
| 92 | ! (in kg.m - 3 : m - 3 of pore air for water vapor and m - 3 of regolith for water ice and adsorbed water) |
---|
[3115] | 93 | ! Outputs : |
---|
| 94 | ! ---------------------------------------------------------------------- |
---|
[3230] | 95 | real, intent(out) :: zdqsdifrego(ngrid) ! Flux from subsurface (positive pointing outwards) |
---|
| 96 | real, intent(out) :: zq1temp2(ngrid) ! Temporary atmospheric mixing ratio after exchange with subsurface (kg / kg) |
---|
| 97 | real*8, intent(out) :: saturation_water_ice(ngrid, nsoil) ! Water pore ice saturation level (formerly Sw) |
---|
[3115] | 98 | |
---|
| 99 | ! Outputs for the output files |
---|
| 100 | real*8 :: preduite(ngrid, nsoil) ! how close the water vapor density is to adsorption saturation |
---|
| 101 | integer :: exch(ngrid) ! translates the logical variable exchange into a -1 or 1 |
---|
| 102 | real*8 :: mass_h2o(ngrid) ! Mass of subsurface water column at each point (kg.m - 2) (formerly mh2otot) |
---|
| 103 | real*8 :: mass_ice(ngrid) ! Mass of subsurface ice at each point (kg.m - 2) (formerly micetot) |
---|
| 104 | real*8 :: mass_h2o_tot ! Mass of subsurface water over the whole planet |
---|
| 105 | real*8 :: mass_ice_tot ! Mass of subsurface ice over the whole planet |
---|
| 106 | real*8 :: nsurf(ngrid) ! surface tracer density in kg/m^3 |
---|
| 107 | real*8 :: close_out(ngrid, nsoil) ! output for close_top and close_bottom |
---|
| 108 | |
---|
| 109 | ! Local (saved) variables : |
---|
| 110 | ! ====================================================================== |
---|
| 111 | |
---|
| 112 | real*8 :: P_sat_soil(ngrid, nsoil) ! water saturation pressure of subsurface cells (at miD-layers) (formerly Psatsoil) |
---|
| 113 | real*8 :: nsatsoil(ngrid, nsoil) ! gas number density at saturation pressure |
---|
| 114 | real*8, allocatable, save :: znsoil(:, :) ! Water vapor soil concentration (kg.m - 3 of pore air) |
---|
| 115 | real*8 :: znsoilprev(ngrid, nsoil) ! value of znsoil in the previous timestep |
---|
| 116 | real*8 :: znsoilprev2(ngrid, nsoil) ! second variable for the value of znsoil in the previous timestep |
---|
| 117 | real*8 :: zdqsoil(ngrid, nsoil) ! Increase of pqsoil if sublimation of ice |
---|
| 118 | real*8, allocatable, save :: ice(:, :) ! Ice content of subsurface cells (at miD-layers) (kg / m3) |
---|
| 119 | real*8 :: iceprev(ngrid, nsoil) |
---|
| 120 | logical :: ice_index_flag(nsoil) ! flag for ice presence |
---|
| 121 | real*8, allocatable, save :: adswater(:, :) ! Adsorbed water in subsurface cells (at miD-layers) (...) |
---|
| 122 | real*8 :: adswater_temp(ngrid, nsoil) ! temprory variable for adsorbed water |
---|
[3223] | 123 | logical, allocatable, save :: over_mono_sat_flag(:, :) ! Formerly ads_water_saturation_flag_2(nsoil) (see descritption of the variable recompute_cell_ads_flag for an explanation ! ARNAU |
---|
[3115] | 124 | real*8 :: adswprev(ngrid, nsoil) |
---|
[3223] | 125 | logical :: recompute_cell_ads_flag(nsoil) ! ARNAU |
---|
| 126 | ! Formerly ads_water_saturation_flag_1 but with a twist. This variable now |
---|
| 127 | ! checks whether coefficients have changed and need recomputing. If the cell |
---|
| 128 | ! is seen to be over the monolayer saturation level (i.e. the cell fulfills the |
---|
| 129 | ! condition adswater_temp(ig, ik) > adswater_sat_mono) but the coefficients |
---|
| 130 | ! have been computed assuming that the cell is below the monolayer saturation |
---|
| 131 | ! layer (i.e. the variable over_mono_sat_flag(ig, ik) had been set to .false.), |
---|
| 132 | ! then the cell needs to have its coefficients recomputed according to the |
---|
| 133 | ! previous condition: adswater_temp(ig, ik) > adswater_sat_mono. Then, |
---|
| 134 | ! the variable recompute_cell_ads_flag(ik) becomes .true.. ! ARNAU |
---|
| 135 | real*8, save :: adswater_sat_mono ! Adsorption monolayer saturation value (kg.m - 3 of regolith) ! ARNAU |
---|
[3115] | 136 | real*8 :: delta0(ngrid) ! Coefficient delta(0) modified |
---|
| 137 | real*8 :: alpha0(ngrid) |
---|
| 138 | real*8 :: beta0(ngrid) |
---|
| 139 | |
---|
| 140 | ! Adsorbtion/Desorption variables and parameters |
---|
[3223] | 141 | real*8 :: Ka(ngrid, nsoil) ! Adsorption time constant (s - 1) before monolayer saturation (first segment of the bilinear function) |
---|
| 142 | real*8 :: Kd(ngrid, nsoil) ! Desorption time constant (s - 1) before monolayer saturation (first segment of the bilinear function) |
---|
| 143 | real*8 :: k_ads_eq(ngrid, nsoil) ! Equilibrium adsorption coefficient (formerly kads) before monolayer saturation (first segment of the bilinear function); unitless (converts kg/m3 into kg/m3) |
---|
| 144 | real*8 :: Ka2(ngrid, nsoil) ! Adsorption time constant (s - 1) after monolayer saturation (second segment of the bilinear function) ! modified 2020 |
---|
| 145 | real*8 :: Kd2(ngrid, nsoil) ! Desorption time constant (s - 1) after monolayer saturation (second segment of the bilinear function) ! modified 2020 |
---|
| 146 | real*8 :: k_ads_eq2(ngrid, nsoil) ! Equilibrium adsorption coefficient (formerly kads) after monolayer saturation (second segment of the bilinear function); unitless ! modified 2020 |
---|
| 147 | real*8 :: c0(ngrid, nsoil) ! Intercept of the second line in the bilinear function ! modified 2020 |
---|
| 148 | real*8, parameter :: kinetic_factor = 0.01 ! (inverse of) Characteristic time to reach adsorption equilibrium (s - 1): |
---|
[3115] | 149 | ! fixed arbitrarily when kinetics factors are unknown |
---|
| 150 | ! possible values: ! = 1 / 1800 s - 1 ! / 1.16D-6 / !( = 10 earth days)! / 1.D0 / ! / 1.2D-5 / ! |
---|
| 151 | |
---|
[3223] | 152 | real*8, allocatable, save :: ztot1(:, :) ! Total (water vapor + ice) content (kg.m - 3 of soil) |
---|
[3115] | 153 | real*8 :: dztot1(nsoil) |
---|
[3223] | 154 | real*8 :: h2otot(ngrid, nsoil) ! Total water content (ice + water vapor + adsorbed water) |
---|
[3115] | 155 | real*8 :: flux(ngrid, 0:nsoil - 1) ! Fluxes at interfaces (kg.m - 2.s - 1) (positive = upward) |
---|
| 156 | real*8 :: rho(ngrid) ! Air density (first subsurface layer) |
---|
| 157 | real*8 :: rhosurf(ngrid) ! Surface air density |
---|
| 158 | |
---|
| 159 | |
---|
| 160 | ! Porosity and tortuosity variables |
---|
| 161 | real*8, allocatable, save :: porosity_ice_free(:, :) ! Porosity with no ice present (formerly eps0) |
---|
| 162 | real*8, allocatable, save :: porosity(:, :) ! Porosity (formerly eps) |
---|
| 163 | real*8 :: porosity_prev(ngrid, nsoil) ! Porosity from previous timestep |
---|
| 164 | real*8, allocatable, save :: tortuosity(:, :) ! Tortuosity factor (formerly tortuo) |
---|
| 165 | |
---|
| 166 | real*8 :: saturation_water_ice_inter(ngrid, nsoil) ! Water pore ice saturation level at the interlayer |
---|
| 167 | |
---|
| 168 | ! Diffussion coefficients |
---|
| 169 | real*8 :: D_mid(ngrid, nsoil) ! Midlayer diffusion coefficients |
---|
| 170 | real*8 :: D_inter(ngrid, nsoil) ! Interlayer diffusion coefficients (formerly D) |
---|
| 171 | real*8, allocatable, save :: D0(:, :) ! Diffusion coefficient prefactor : |
---|
| 172 | ! If (medium = 1) : D0 = value of D_mid for saturation_water_ice = 0, ie. poro / tortuo * Dm (in m2 / s) |
---|
| 173 | ! If (medium = 2) : D0 = porosity_tortuosity factor (dimensionless) |
---|
| 174 | real*8 :: omega(ngrid, nsoil) ! H2O - CO2 collision integral |
---|
| 175 | real*8 :: vth(ngrid, nsoil) ! H2O thermal speed |
---|
| 176 | real*8, parameter :: Dk0 = 0.459D0 ! Knudsen diffusion coefficient (for saturation_water_ice = 0) Value for a (5 / 1) bidispersed random assembly of spheres |
---|
| 177 | ! (dimensionless, ie. divided by thermal speed and characteristic meshsize of the porous medium) |
---|
| 178 | real*8 :: Dk(ngrid, nsoil) ! Knudsen diffusion coefficient (divided by porosity / tortuosity factor) |
---|
| 179 | real*8 :: Dk_inter(ngrid, nsoil) ! Knudsen diffusion coefficient at the interlayer |
---|
| 180 | real*8 :: Dm(ngrid, nsoil) ! Molecular diffusion coefficient |
---|
| 181 | real*8 :: Dm_inter(ngrid, nsoil) ! Molecular diffusion coefficient at the interlayer |
---|
| 182 | |
---|
| 183 | real*8, parameter :: choke_fraction = 0.8D0 ! fraction of ice that prevents further diffusion |
---|
| 184 | logical, allocatable, save :: close_top(:, :) ! closing diffusion at the top of a layer if ice rises over saturation |
---|
| 185 | logical, allocatable, save :: close_bottom(:, :) ! closing diffusion at the bottom of a layer if ice risies over saturation |
---|
[3262] | 186 | logical, parameter :: print_closure_warnings = .true. |
---|
[3115] | 187 | |
---|
| 188 | ! Coefficients for the Diffusion calculations |
---|
| 189 | real*8 :: A(ngrid, nsoil) ! Coefficient in the diffusion formula |
---|
| 190 | real*8 :: B(ngrid, nsoil) ! Coefficient in the diffusion formula |
---|
| 191 | real*8 :: C(ngrid, nsoil) ! Coefficient in the diffusion formula |
---|
[3223] | 192 | real*8 :: E(ngrid, nsoil) ! Coefficient in the diffusion formula (before monolayer saturation) ! added 2020 |
---|
| 193 | real*8 :: F(ngrid, nsoil) ! Coefficient in the diffusion formula (before monolayer saturation) ! added 2020 |
---|
| 194 | real*8 :: E2(ngrid, nsoil) ! Coefficient in the diffusion formula (after monolayer saturation) ! added 2020 |
---|
| 195 | real*8 :: F2(ngrid, nsoil) ! Coefficient in the diffusion formula (after monolayer saturation) ! added 2020 |
---|
[3115] | 196 | real*8, allocatable, save :: zalpha(:, :) ! Alpha coefficients |
---|
| 197 | real*8, allocatable, save :: zbeta(:, :) ! Beta coefficients |
---|
| 198 | real*8 :: zdelta(ngrid, nsoil - 1) ! Delta coefficients |
---|
| 199 | |
---|
| 200 | ! Distances between layers |
---|
| 201 | real*8, allocatable, save :: interlayer_dz(:, :) ! Distance between the interlayer points in m (formerly interdz) |
---|
| 202 | real*8, allocatable, save :: midlayer_dz(:, :) ! Distance between the midcell points in m (formerly middz) |
---|
| 203 | |
---|
[3223] | 204 | real*8 :: nsat(ngrid, nsoil) ! amount of water vapor at (adsorption) monolayer saturation ! modified 2020 |
---|
[3115] | 205 | |
---|
| 206 | real*8, allocatable, save :: meshsize(:, :) ! scaling/dimension factor for the por size |
---|
| 207 | real*8, allocatable, save :: rho_soil(:, :) ! Soil density (bulk - kg / m3) (formerly rhosoil) |
---|
| 208 | real*8, allocatable, save :: cste_ads(:, :) ! Prefactor of adsorption coeff. k |
---|
| 209 | |
---|
| 210 | ! general constants |
---|
| 211 | real*8, parameter :: kb = 1.38065D-23 ! Boltzmann constant |
---|
| 212 | real*8, parameter :: mw = 2.988D-26 ! Water molecular weight |
---|
[3223] | 213 | !real*8, parameter :: rho_H2O_ice = 920.D0 ! Ice density |
---|
[3115] | 214 | |
---|
| 215 | ! adsorption coefficients |
---|
[3223] | 216 | real*8, parameter :: enthalpy_ads = 35.D3 ! Enthalpy of adsorption (J.mole - 1) options 21.D3, 35.D3, and 60.D3 |
---|
| 217 | real*8, parameter :: enthalpy_ads2 = 21.D3 ! Enthalpy of adsorption (J.mole - 1) options 21.D3, 35.D3, and 60.D3 for the second segment ! added 2020 |
---|
| 218 | real*8, parameter :: DeltaQ_ads = 21.D3 ! 10.D3 ! This is the DeltaQ_ads = heat of adsorption - enthalpy of liquefaction/sublimation = E1 - EL and may be equal to RT*ln(c), where c is the BET constant (from BET1938). This is for the first segment (J.mole - 1) ! added 2020 |
---|
| 219 | real*8, parameter :: DeltaQ_ads2 = 21.D3 ! 10.D3 ! This is the DeltaQ_ads = heat of adsorption - enthalpy of liquefaction/sublimation = E1 - EL and may be equal to RT*ln(c), where c is the BET constant (from BET1938). This is for the second segment (J.mole - 1) ! added 2020 |
---|
[3115] | 220 | real*8, parameter :: tau0 = 1D-14 |
---|
| 221 | real*8, parameter :: S = 17.D3 ! Soil specific surface area (m2.kg - 1 of solid) options: 17.D3 and 106.D3 |
---|
| 222 | real*8, parameter:: Sm = 10.6D-20 ! Surface of the water molecule (m2) (only needed in the theoretical formula which is not used right now) |
---|
| 223 | |
---|
| 224 | |
---|
| 225 | ! Reference values for choice_ads = 2 |
---|
| 226 | real*8, parameter :: Tref = 243.15D0 |
---|
[3223] | 227 | real*8, parameter :: nref = 2.31505631D-6 ! calculated as 18.D-3 / (8.314D0 * Tref) * 0.26D0 ! not used anymore (for the time being) |
---|
| 228 | real*8, parameter :: Kd_ref = 0.0206D0 ! Not used for the time being (would require specific measurements to be known, but it is rarely measured) |
---|
| 229 | real*8, parameter :: Ka_ref = 2.4D-4 ! Not used for the time being |
---|
| 230 | ! real*8, parameter :: Kref = 6.27D6 ! Value from data analysis from Pommerol2009 ! Old value 1.23D7 ! Volcanic tuff @ 243.15 K (obtained at low P / Psat) ! ARNAU |
---|
| 231 | ! real*8, parameter :: Kref2 = 5.95D-7 ! Value from data analysis Pommerol2009 ! ARNAU |
---|
| 232 | real*8, parameter :: Kref = 0.205D-6 ! Value obtained from the fit of all adsorption data from Pommmerol (2009) (see Arnau's report - p.28: = yp/xp = 2.6998E-7/3.5562E-2, divided by psat(243.15K=37 Pa; will need to be multiplied by RT/M to be unitless before multiplying by znsoil, which in kg(water)/m3(air) and not in pascals) |
---|
| 233 | real*8, parameter :: Kref2 = 0.108D-7 ! Value obtained from the fit of all adsorption data from Pommmerol (2009) (see Arnau's report - p.28 = m2; divided by psat(243.15K)=37 Pa) |
---|
[3115] | 234 | |
---|
[3223] | 235 | |
---|
| 236 | logical :: recompute_all_cells_ads_flag ! Old saturation_flag but with a behaviour change ! ARNAU |
---|
| 237 | ! The old saturation_flag was used to check whether the cell was saturated or |
---|
| 238 | ! not, and therefore to assign the saturation value adswater(ig, ik) = |
---|
| 239 | ! adswater_sat instead of the usual adswater(ig, ik) = adswater_temp(ig, ik) |
---|
| 240 | ! The old routine using saturation_flag did not require that the A, B, C,... |
---|
| 241 | ! adsorption coefficients be computed, but the new soilwater subroutine |
---|
| 242 | ! does. Therefore, the variable recompute_all_cells_ads_flag checks whether |
---|
| 243 | ! there is a cell of a column that requires recomputing. If at least one cell |
---|
| 244 | ! requires recomputing (i.e. recompute_cell_ads_flag(ik) is .true.), then |
---|
| 245 | ! recompute_all_cells_ads_flag becomes true, and the adsorption coefficients, |
---|
| 246 | ! as well as the recursive equation (appearing in this code as `backward |
---|
| 247 | ! loop over all layers`) ! ARNAU |
---|
[3115] | 248 | logical :: sublimation_flag |
---|
| 249 | logical :: condensation_flag(nsoil) |
---|
| 250 | |
---|
| 251 | ! variables and parameters for the H2O map |
---|
| 252 | integer, parameter :: n_long_H2O = 66!180 ! number of longitudes of the new H2O map |
---|
| 253 | integer, parameter :: n_lat_H2O = 50 !87 ! number of latitudes of the new H2O map |
---|
| 254 | real*8, parameter :: rho_H2O_ice = 920.0D0 ! Ice density (formerly rhoice) |
---|
| 255 | real :: latH2O(n_lat_H2O*n_long_H2O) ! Latitude at H2O map points |
---|
| 256 | real :: longH2O(n_lat_H2O*n_long_H2O) ! Longitude at H2O map points |
---|
| 257 | real :: H2O_depth_data(n_lat_H2O*n_long_H2O) ! depth of the ice layer in in g/cm^2 at H2O map points |
---|
| 258 | real :: H2O_cover_data(n_lat_H2O*n_long_H2O) ! H2O content of the cover layer at H2O map points (not used yet) |
---|
| 259 | real :: dataH2O(n_lat_H2O*n_long_H2O) ! H2O content of the ice layer at H2O map points |
---|
| 260 | real :: latH2O_temp(n_lat_H2O*n_long_H2O) ! intermediate variable |
---|
| 261 | real :: longH2O_temp(n_lat_H2O*n_long_H2O) ! intermediate variable |
---|
| 262 | real :: dataH2O_temp(n_lat_H2O*n_long_H2O) ! intermediate variable |
---|
| 263 | real :: H2O_depth_data_temp(n_lat_H2O*n_long_H2O) ! intermediate variable |
---|
| 264 | real, allocatable, save :: H2O(:) ! H2O map interpolated at GCM grid points (in wt%) |
---|
| 265 | real, allocatable, save :: H2O_depth(:) ! H2O map ice depth interpolated at GCM in g/cm^2 |
---|
| 266 | |
---|
| 267 | ! variables for the 1D case |
---|
| 268 | real*8, parameter :: mmr_h2o = 0.6D-4 ! Water vapor mass mixing ratio (for initialization only) |
---|
| 269 | real*8 :: diff(ngrid, nsoil) ! difference between total water content and ice + vapor content |
---|
| 270 | ! (only used for output, inconstistent: should just be adswater) |
---|
[3274] | 271 | real :: var_flux_soil(ngrid, nsoil) ! Output of the flux between soil layers (kg/m^3/s) |
---|
| 272 | real :: default_diffcoeff = 4e-4 ! Diffusion coefficient by default (no variations with Temperature and pressure (m/s^2) |
---|
| 273 | real :: tol_massiveice = 50. ! Tolerance to account for massive ice (kg/m^3) |
---|
[3115] | 274 | ! Loop variables and counters |
---|
| 275 | integer :: ig, ik, i, j ! loop variables |
---|
| 276 | logical :: output_trigger ! used to limit amount of written output |
---|
| 277 | integer, save :: n ! number of runs of this subroutine |
---|
| 278 | integer :: sublim_n ! number of sublimation loop runs |
---|
[3223] | 279 | integer :: satur_mono_n ! number of monolayer saturation loop runs ! added 2020 |
---|
[3115] | 280 | |
---|
| 281 | |
---|
| 282 | if (.not. allocated(znsoil)) then |
---|
| 283 | allocate( znsoil(ngrid, nsoil) ) |
---|
| 284 | allocate( ice(ngrid, nsoil) ) |
---|
| 285 | allocate( adswater(ngrid, nsoil) ) |
---|
| 286 | allocate( ztot1(ngrid, nsoil) ) |
---|
| 287 | allocate( porosity_ice_free(ngrid, nsoil) ) |
---|
| 288 | allocate( porosity(ngrid, nsoil) ) |
---|
| 289 | allocate( tortuosity(ngrid, nsoil) ) |
---|
| 290 | allocate( D0(ngrid, nsoil) ) |
---|
| 291 | allocate( interlayer_dz(ngrid, nsoil) ) |
---|
| 292 | allocate( midlayer_dz(ngrid, 0:nsoil) ) |
---|
| 293 | ! allocate( zalpha(ngrid, nsoil-1) ) |
---|
| 294 | ! allocate( zbeta(ngrid, nsoil-1) ) |
---|
| 295 | allocate( zalpha(ngrid, nsoil) ) ! extra entry to match output format |
---|
| 296 | allocate( zbeta(ngrid, nsoil) ) ! extra entry to match output format |
---|
| 297 | allocate( meshsize(ngrid, nsoil) ) |
---|
| 298 | allocate( rho_soil(ngrid, nsoil) ) |
---|
| 299 | allocate( cste_ads(ngrid, nsoil) ) |
---|
| 300 | allocate( H2O(ngrid) ) |
---|
| 301 | allocate( H2O_depth(ngrid) ) |
---|
| 302 | allocate( close_top(ngrid, nsoil) ) |
---|
| 303 | allocate( close_bottom(ngrid, nsoil) ) |
---|
[3223] | 304 | allocate( over_mono_sat_flag(ngrid, nsoil) ) |
---|
[3115] | 305 | endif |
---|
| 306 | |
---|
| 307 | ! Used commons |
---|
| 308 | ! mugaz ! Molar mass of the atmosphere (g.mol-1) ~43.49 |
---|
| 309 | |
---|
| 310 | |
---|
| 311 | |
---|
| 312 | ! Initialisation : |
---|
| 313 | ! ================= |
---|
| 314 | |
---|
| 315 | if (firstcall_soil) then |
---|
| 316 | n = 0 |
---|
| 317 | close_top = .false. |
---|
| 318 | close_bottom = .false. |
---|
[3223] | 319 | print *, "adsorption enthalpy first segment: ", enthalpy_ads |
---|
| 320 | print *, "adsorption enthalpy second segment: ", enthalpy_ads2 |
---|
| 321 | print *, "adsorption BET constant C first segment: ", DeltaQ_ads |
---|
| 322 | print *, "adsorption BET constant C second segment: ", DeltaQ_ads2 |
---|
[3115] | 323 | print *, "specific surface area: ", S |
---|
| 324 | |
---|
| 325 | do ig = 1, ngrid |
---|
| 326 | ! if(.not.watercaptag(ig)) then |
---|
| 327 | |
---|
| 328 | ! Initialization of soil parameters |
---|
| 329 | ! =================================== |
---|
| 330 | |
---|
| 331 | ! initialize the midlayer distances |
---|
| 332 | midlayer_dz(ig, 0) = mlayer(0) |
---|
| 333 | |
---|
| 334 | do ik = 1, nsoil - 1 |
---|
| 335 | midlayer_dz(ig, ik) = mlayer(ik) - mlayer(ik - 1) |
---|
| 336 | enddo |
---|
| 337 | |
---|
| 338 | ! initialize the interlayer distances |
---|
| 339 | interlayer_dz(ig, 1) = layer(1) |
---|
| 340 | do ik = 2, nsoil |
---|
| 341 | interlayer_dz(ig, ik) = layer(ik) - layer(ik - 1) |
---|
| 342 | enddo |
---|
| 343 | |
---|
| 344 | ! Choice of porous medium and D0 |
---|
| 345 | ! =============================== = |
---|
| 346 | do ik = 1, nsoil |
---|
| 347 | |
---|
[3223] | 348 | ! These properties are defined here in order to enable custom profiles |
---|
[3272] | 349 | if(ads_massive_ice) then |
---|
[3274] | 350 | if(pqsoil(ig, ik, igcm_h2o_ice_soil).gt.tol_massiveice) then |
---|
| 351 | porosity_ice_free(ig, ik) = 0.999999 |
---|
| 352 | else |
---|
| 353 | porosity_ice_free(ig, ik) = porosity_reg |
---|
| 354 | endif |
---|
[3272] | 355 | else |
---|
| 356 | porosity_ice_free(ig, ik) = porosity_reg |
---|
| 357 | endif |
---|
[3115] | 358 | tortuosity(ig, ik) = 1.5D0 |
---|
[3223] | 359 | rho_soil(ig, ik) = 1.3D3 ! in kg/m3 of regolith (incl. porosity) |
---|
[3115] | 360 | |
---|
| 361 | meshsize(ig, ik) = 5.D-6 ! Characteristic size 1e - 6 = 1 micron : diameter(mode 5) = 10 microns, diameter(mode 1) = 1 microns |
---|
| 362 | ! Example : with meshsize = 5.E - 6 : grain sizes = 50 and 10 microns |
---|
| 363 | D0(ig, ik) = porosity_ice_free(ig, ik) / tortuosity(ig, ik) |
---|
| 364 | |
---|
| 365 | enddo |
---|
| 366 | |
---|
| 367 | ! Choice of adsorption coefficients |
---|
[3223] | 368 | ! =================================== |
---|
| 369 | adswater_sat_mono = 2.6998D-7 * S * rho_soil(ig,1) ! Unit = kg/m3; From best fit of all adsoprtion data from Pommerol et al. (2009) - See Arnau's report |
---|
| 370 | ! adswater_sat_mono = 0.8D-2 * S / 13.7D3 * rho_soil(ig, 1) ! Unit = kg/m3 ; Experimental value for volcanic tuff (Pommerol et al., 2009) |
---|
[3115] | 371 | ! theoretical formula is = rho_soil(ig, 1) * S / Sm * mw |
---|
| 372 | |
---|
[3223] | 373 | ! Numerical values above are for SSA = 13.7 m2 / g and plateau = 0.8wt% |
---|
| 374 | ! adswater_sat_mono = 6D-2 * rho_soil(ig, 1) ! Experimental value for JSC Mars - 1 (Pommerol et al., 2009) |
---|
[3115] | 375 | ! with SSA = 106 m2 / g and plateau (net) = 6wt% |
---|
| 376 | |
---|
| 377 | ! Initialisation of ice, water vapor and adsorbed water profiles |
---|
| 378 | ! =============================================================== = |
---|
| 379 | do ik = 1, nsoil |
---|
| 380 | ! Initialisation of pqsoil(t = 0) |
---|
| 381 | ! in 1D simulations the initialization happens here |
---|
[3223] | 382 | ! if (ngrid.eq.1) then |
---|
| 383 | ! znsoil(ig, ik) = mmr_h2o * mugaz * 1.D-3 * pplev(ig, 1) & |
---|
| 384 | ! / (8.314D0 * ptsoil(ig, nsoil - 4)) |
---|
| 385 | ! ! znsoil(ig, ik) = 0. |
---|
| 386 | ! ice(ig, ik) = 0.D0 ! 0.1D0 !414.D0 |
---|
[3115] | 387 | |
---|
[3223] | 388 | ! saturation_water_ice(ig, ik) = min(ice(ig, ik) / (rho_H2O_ice * porosity_ice_free(ig, ik)), 0.999D-0) |
---|
| 389 | ! porosity(ig, ik) = porosity_ice_free(ig, ik) * (1.D0 - saturation_water_ice(ig, ik)) |
---|
| 390 | |
---|
| 391 | ! if (choice_ads.eq.1) then |
---|
| 392 | ! vth(ig, ik) = dsqrt(8.D0 * 8.314D0 * ptsoil(ig, nsoil - 4) & |
---|
| 393 | ! / (pi * 18.D-3)) |
---|
[3126] | 394 | |
---|
[3223] | 395 | ! first segment of the bilinear function |
---|
| 396 | ! k_ads_eq(ig, ik) = rho_soil(ig, ik) * S * vth(ig, ik) / 4.D0 & |
---|
| 397 | ! / (dexp(-enthalpy_ads & |
---|
| 398 | ! / (8.314D0 * ptsoil(ig, nsoil - 4))) / tau0) |
---|
| 399 | ! Kd(ig, ik) = kinetic_factor & |
---|
| 400 | ! / (1.D0 + k_ads_eq(ig, ik) / porosity(ig, ik)) |
---|
| 401 | ! Ka(ig, ik) = kinetic_factor * k_ads_eq(ig, ik) / & |
---|
| 402 | ! (1.D0 + k_ads_eq(ig, ik) / porosity(ig, ik)) |
---|
[3115] | 403 | |
---|
[3223] | 404 | ! second segment of the bilinear function ! added 2020 |
---|
| 405 | ! k_ads_eq2(ig, ik) = rho_soil(ig, ik) * S * vth(ig, ik) / 4.D0 & |
---|
| 406 | ! / (dexp(-enthalpy_ads2 & |
---|
| 407 | ! / (8.314D0 * ptsoil(ig, nsoil - 4))) / tau0) |
---|
| 408 | ! Kd2(ig, ik) = kinetic_factor & |
---|
| 409 | ! / (1.D0 + k_ads_eq2(ig, ik) / porosity(ig, ik)) |
---|
| 410 | ! Ka2(ig, ik) = kinetic_factor * k_ads_eq2(ig, ik) / & |
---|
| 411 | ! (1.D0 + k_ads_eq2(ig, ik) / porosity(ig, ik)) |
---|
| 412 | ! |
---|
| 413 | ! elseif (choice_ads.eq.2) then ! par rapport \E0 valeur experimentale de reference |
---|
| 414 | ! ! Kd(ig, ik) = Kd_ref * exp(-enthalpy_ads / 8.314 * |
---|
[3246] | 415 | ! ! & (1. / ptsoil(ig, nsoil - 4) - 1. / Tref)) |
---|
[3223] | 416 | ! ! Ka(ig, ik) = rho_soil(ig, ik) * Ka_ref * |
---|
| 417 | ! ! & sqrt(ptsoil(ig, nsoil - 4) / Tref) / nref! |
---|
| 418 | ! |
---|
| 419 | ! ! first segment of the bilinear function |
---|
| 420 | ! k_ads_eq(ig, ik) = 8.314D0 * ptsoil(ig,ik)/18.D-3 * Kref * dexp(DeltaQ_ads / 8.314D0 * (1.D0 / ptsoil(ig, ik) - 1.D0 / Tref)) ! Changed enthalpy_ads to DeltaQ_ads to ensure correct dependance/behaviour of k_ads_eq with temperature ; prefactor RT/M is to convert Kref in proper units to use with znsoil |
---|
| 421 | ! |
---|
| 422 | ! Kd(ig, ik) = kinetic_factor / (1.D0 + k_ads_eq(ig, ik) / porosity(ig, ik)) |
---|
| 423 | ! |
---|
| 424 | ! Ka(ig, ik) = kinetic_factor * k_ads_eq(ig, ik) / (1.D0 + k_ads_eq(ig, ik) / porosity(ig, ik)) |
---|
| 425 | ! |
---|
| 426 | ! ! second segment of the bilinear function ! added 2020 |
---|
| 427 | ! k_ads_eq2(ig, ik) = 8.314D0 * ptsoil(ig,ik)/18.D-3 * Kref2 * dexp(DeltaQ_ads2 / 8.314D0 * (1.D0 / ptsoil(ig, ik) - 1.D0 / Tref)) ! Changed enthalpy_ads2 to DeltaQ_ads2 to ensure correct dependance/behaviour of k_ads_eq with temperature |
---|
| 428 | ! |
---|
| 429 | ! Kd2(ig, ik) = kinetic_factor / (1.D0 + k_ads_eq2(ig, ik) / porosity(ig, ik)) |
---|
| 430 | ! |
---|
| 431 | ! Ka2(ig, ik) = kinetic_factor * k_ads_eq2(ig, ik) / (1.D0 + k_ads_eq2(ig, ik) / porosity(ig, ik)) |
---|
| 432 | ! endif |
---|
| 433 | |
---|
| 434 | ! if (k_ads_eq(ig,ik) * znsoil(ig, ik) .gt. adswater_sat_mono) then ! modified 2024, after correction of c0 expression |
---|
| 435 | ! c0(ig, ik) = ( 1.D0 - (k_ads_eq2(ig, ik) / k_ads_eq(ig, ik))) * adswater_sat_mono |
---|
| 436 | ! adswater(ig, ik) = c0(ig,ik) + k_ads_eq2(ig, ik) * znsoil(ig, ik) |
---|
| 437 | ! else |
---|
| 438 | ! adswater(ig, ik) = k_ads_eq(ig, ik) * znsoil(ig, ik) |
---|
| 439 | ! endif |
---|
[3115] | 440 | |
---|
[3223] | 441 | ! else ! in 3D simulations initialisation happens with newstart.F |
---|
[3115] | 442 | znsoil(ig, ik) = pqsoil(ig, ik, igcm_h2o_vap_soil) |
---|
| 443 | ice(ig, ik) = pqsoil(ig, ik, igcm_h2o_ice_soil) |
---|
| 444 | adswater(ig, ik) = pqsoil(ig, ik, igcm_h2o_vap_ads) |
---|
[3223] | 445 | ! endif |
---|
[3115] | 446 | |
---|
| 447 | saturation_water_ice(ig, ik) = min(ice(ig, ik) / (rho_H2O_ice * porosity_ice_free(ig, ik)), 0.999D-0) |
---|
| 448 | |
---|
| 449 | if (saturation_water_ice(ig, ik).lt.0.D0) then |
---|
| 450 | print *, "WARNING!! soil water ice negative at ", ig, ik |
---|
| 451 | print *, "saturation value: ", saturation_water_ice(ig, ik) |
---|
| 452 | print *, "setting saturation to 0" |
---|
| 453 | saturation_water_ice(ig, ik) = max(saturation_water_ice(ig, ik), 0.D0) |
---|
| 454 | endif |
---|
| 455 | |
---|
| 456 | porosity(ig, ik) = porosity_ice_free(ig, ik) * (1.D0 - saturation_water_ice(ig, ik)) |
---|
[3223] | 457 | |
---|
| 458 | ! Initialise soil as if all points where below the monolayer saturation level (added 2020) => now depends on value of adswater (modified in 2024) |
---|
| 459 | if (adswater(ig,ik).gt.adswater_sat_mono) then |
---|
| 460 | over_mono_sat_flag(ig, ik) = .true. ! |
---|
| 461 | else |
---|
| 462 | over_mono_sat_flag(ig, ik) = .false. |
---|
| 463 | endif |
---|
| 464 | |
---|
[3115] | 465 | enddo |
---|
| 466 | ! endif |
---|
| 467 | enddo |
---|
| 468 | |
---|
| 469 | print *, "initializing H2O data" |
---|
| 470 | ! |
---|
| 471 | ! ! 1.6 intitalization of the water content |
---|
| 472 | ! open(40,file='H2O_data') |
---|
| 473 | ! do i = 1, n_lat_H2O*n_long_H2O |
---|
| 474 | ! read(40,*) latH2O_temp(i), longH2O_temp(i), H2O_cover_data(i), dataH2O_temp(i), H2O_depth_data_temp(i) |
---|
| 475 | ! ! write(*, *) 'depth data ', H2O_depth_data(i) |
---|
| 476 | ! enddo |
---|
| 477 | ! close(40) |
---|
| 478 | ! |
---|
| 479 | ! ! 1.6.2. put latH2O, longH2O and dataH2O in the right format to pass on to mapTh |
---|
| 480 | ! ! in the datafile the latitudes are listed from negative to positive, but mapTh needs them the other way around |
---|
| 481 | ! do i = 0, n_lat_H2O - 1 |
---|
| 482 | ! do j = 1, n_long_H2O |
---|
| 483 | ! latH2O( n_long_H2O * i + j ) = latH2O_temp( n_long_H2O * (n_lat_H2O - (i + 1)) + j) |
---|
| 484 | ! longH2O( n_long_H2O * i + j ) = longH2O_temp( n_long_H2O * (n_lat_H2O - (i + 1)) + j) |
---|
| 485 | ! dataH2O( n_long_H2O * i + j ) = dataH2O_temp( n_long_H2O * (n_lat_H2O - (i + 1)) + j) |
---|
| 486 | ! H2O_depth_data( n_long_H2O * i + j ) = H2O_depth_data_temp( n_long_H2O * (n_lat_H2O - (i + 1)) + j) |
---|
| 487 | ! enddo |
---|
| 488 | ! enddo |
---|
| 489 | ! |
---|
| 490 | ! call mapTh(latH2O, longH2O, dataH2O, n_long_H2O, n_lat_H2O, ngrid, H2O) |
---|
| 491 | |
---|
| 492 | ! call mapTh(latH2O, longH2O, H2O_depth_data, n_long_H2O, n_lat_H2O, ngrid, H2O_depth) |
---|
| 493 | ! |
---|
| 494 | do ig = 1, ngrid |
---|
| 495 | ! convert depth from g/cm^2 to m |
---|
| 496 | ! print *, H2O_depth(ig), rho_soil(ig, 1) |
---|
| 497 | ! H2O_depth(ig) = H2O_depth(ig) * 10 / rho_soil(ig, 1) |
---|
| 498 | ! if ( (latitude_deg(ig).lt.40).and.(latitude_deg(ig).gt.-40)) then |
---|
| 499 | ! H2O(ig) = 0. |
---|
| 500 | ! endif |
---|
| 501 | |
---|
| 502 | output_trigger = .true. |
---|
| 503 | do ik = 1, nsoil |
---|
| 504 | ! if (H2O_depth(ig).le.layer(ik)) then |
---|
| 505 | ! ice(ig, ik) = min(H2O(ig), rho_H2O_ice * porosity_ice_free(ig, ik)) |
---|
| 506 | ! if (output_trigger) then |
---|
| 507 | ! print *, "ice set at: ", ig, ik, "to :", ice(ig,ik), "depth: ", H2O_depth(ig) |
---|
| 508 | ! output_trigger = .false. |
---|
| 509 | ! endif |
---|
| 510 | ! endif |
---|
| 511 | |
---|
| 512 | saturation_water_ice(ig, ik) = min(ice(ig, ik) / (rho_H2O_ice * porosity_ice_free(ig, ik)), 0.999D-0) |
---|
| 513 | saturation_water_ice(ig, ik) = max(saturation_water_ice(ig, ik), 0.D0) |
---|
| 514 | porosity(ig, ik) = porosity_ice_free(ig, ik) * (1.D0 - saturation_water_ice(ig, ik)) |
---|
| 515 | enddo |
---|
| 516 | enddo |
---|
| 517 | |
---|
| 518 | print *, "Kinetic factor: ", kinetic_factor |
---|
| 519 | if (kinetic_factor.eq.0) then |
---|
[3223] | 520 | print *, "WARNING: adsorption is switched off" |
---|
[3115] | 521 | endif |
---|
| 522 | firstcall_soil = .false. |
---|
| 523 | endif ! of "if firstcall_soil" |
---|
| 524 | |
---|
| 525 | |
---|
[3274] | 526 | |
---|
| 527 | |
---|
| 528 | ! Update properties in case of the sublimation of massive ice |
---|
| 529 | |
---|
| 530 | if(ads_massive_ice) then |
---|
| 531 | do ig = 1, ngrid |
---|
| 532 | do ik = 1, nsoil |
---|
| 533 | if(pqsoil(ig, ik, igcm_h2o_ice_soil).gt.tol_massiveice) then |
---|
| 534 | porosity_ice_free(ig, ik) = 0.999999 |
---|
| 535 | else |
---|
| 536 | porosity_ice_free(ig, ik) = porosity_reg |
---|
| 537 | endif |
---|
| 538 | enddo |
---|
| 539 | enddo |
---|
| 540 | endif |
---|
| 541 | |
---|
[3115] | 542 | ! Computation of new (new step) transport coefficients : |
---|
| 543 | ! ======================================================= = |
---|
| 544 | |
---|
| 545 | do ig = 1, ngrid ! loop over all gridpoints |
---|
| 546 | if(.not.watercaptag(ig)) then ! if there is no polar cap |
---|
| 547 | |
---|
| 548 | do ik = 1, nsoil |
---|
| 549 | |
---|
| 550 | ! calculate Water saturation level (pore volume filled by ice / total pore volume) |
---|
| 551 | saturation_water_ice(ig, ik) = min(ice(ig, ik) / (rho_H2O_ice * porosity_ice_free(ig, ik)), 0.999D-0) |
---|
| 552 | |
---|
| 553 | if (saturation_water_ice(ig, ik).lt.0.D0) then |
---|
| 554 | print *, "WARNING!! soil water ice negative at ", ig, ik |
---|
| 555 | print *, "saturation value: ", saturation_water_ice(ig, ik) |
---|
| 556 | print *, "setting saturation to 0" |
---|
| 557 | saturation_water_ice(ig, ik) = max(saturation_water_ice(ig, ik), 0.D0) |
---|
| 558 | endif |
---|
| 559 | |
---|
| 560 | ! save the old porosity |
---|
| 561 | porosity_prev(ig, ik) = porosity(ig, ik) |
---|
| 562 | |
---|
| 563 | ! calculate the new porosity |
---|
| 564 | porosity(ig, ik) = porosity_ice_free(ig, ik) * (1.D0 - saturation_water_ice(ig, ik)) |
---|
| 565 | ! Note : saturation_water_ice and porosity are computed from the ice content of the previous timestep |
---|
| 566 | enddo |
---|
| 567 | |
---|
| 568 | ! calculate the air density in the first subsurface layer |
---|
[3223] | 569 | rho(ig) = pplev(ig, 1) / (r * ptsoil(ig, 1)) |
---|
[3115] | 570 | |
---|
| 571 | ! calculate diffusion coefficients at mid- and interlayers (with ice content from the previous timestep) |
---|
| 572 | ! Dependence on saturation_water_ice taken from the relation obtained by Hudson et al. (2009) and Meslin et al. (SSSAJ, 2010) |
---|
| 573 | do ik = 1, nsoil ! loop over all soil levels |
---|
| 574 | |
---|
| 575 | ! calculate H2O mean thermal velocity |
---|
[3223] | 576 | vth(ig, ik) = dsqrt(8.D0 * 8.314D0 * ptsoil(ig, ik) / (pi * 18.D-3)) |
---|
[3115] | 577 | |
---|
| 578 | ! The diffusion coefficient is calculated |
---|
| 579 | |
---|
| 580 | ! calculate the H2O - CO2 collision integral (after Mellon and Jakosky, JGR, 1993) |
---|
[3223] | 581 | omega(ig, ik) = 1.442D0 - 0.673D0 * dlog(2.516D-3 * ptsoil(ig, ik)) & |
---|
| 582 | + 0.252D0 * (dlog(2.516D-3 * ptsoil(ig, ik))) ** 2.D0 & |
---|
| 583 | - 0.047D0 * (dlog(2.516D-3 * ptsoil(ig, ik))) ** 3.D0 & |
---|
| 584 | + 0.003D0 * (dlog(2.516D-3 * ptsoil(ig, ik))) ** 4.D0 |
---|
[3115] | 585 | |
---|
| 586 | ! calculate the molecular diffusion coefficient |
---|
[3223] | 587 | Dm(ig, ik) = 4.867D0 * ptsoil(ig, ik) ** (3.D0 / 2.D0) & |
---|
[3115] | 588 | / (pplev(ig, 1) * omega(ig, ik)) * 1.D-4 |
---|
| 589 | |
---|
| 590 | ! calculate the Knudsen diffusion coefficient (divided by D0 = porosity / tortuosity in this case) |
---|
| 591 | Dk(ig, ik) = Dk0 / D0(ig, ik) * meshsize(ig, ik) * vth(ig, ik) |
---|
| 592 | |
---|
| 593 | ! calculate the midlayer diffusion coeff. (with dependence on saturation_water_ice from Meslin et al., 2010 - only exact for normal diffusion) |
---|
| 594 | D_mid(ig, ik) = D0(ig, ik) * (1.D0 - saturation_water_ice(ig, ik)) ** 2.D0 * 1.D0 / (1.D0 / Dm(ig, ik) + 1.D0 / Dk(ig, ik)) |
---|
[3262] | 595 | |
---|
[3272] | 596 | if(ads_const_D) D_mid(ig, ik) = default_diffcoeff |
---|
| 597 | |
---|
[3115] | 598 | ! Midlayer diffusion coeff. (correlation by Rogers and Nielson, 1991) |
---|
| 599 | ! D_mid(ig, ik) = D0(ig, ik) * (1. - saturation_water_ice(ig, ik)) * exp(-6. * saturation_water_ice(ig, ik) & |
---|
| 600 | ! * porosity_ice_free(ig, ik) - 6. * saturation_water_ice(ig, ik) ** (14. * porosity_ice_free(ig, ik))) & |
---|
| 601 | ! * 1. / (1. / Dm(ig, ik) + 1. / Dk(ig, ik)) |
---|
| 602 | enddo |
---|
| 603 | |
---|
| 604 | ! calculate the interlayer diffusion coefficient as interpolation of the midlayer coefficients |
---|
| 605 | do ik = 1, nsoil - 1 |
---|
| 606 | Dm_inter(ig, ik) = ( (layer(ik) - mlayer(ik - 1)) * Dm(ig, ik + 1) & |
---|
| 607 | + (mlayer(ik) - layer(ik)) * Dm(ig, ik) ) / (mlayer(ik) - mlayer(ik - 1)) |
---|
| 608 | |
---|
| 609 | Dk_inter(ig, ik) = ( (layer(ik) - mlayer(ik - 1)) * Dk(ig, ik + 1) & |
---|
| 610 | + (mlayer(ik) - layer(ik)) * Dk(ig, ik) ) / (mlayer(ik) - mlayer(ik - 1)) |
---|
| 611 | |
---|
| 612 | ! saturation_water_ice_inter(ig, ik) = ( (layer(ik) - mlayer(ik - 1)) * saturation_water_ice(ig, ik + 1) & |
---|
| 613 | ! + (mlayer(ik) - layer(ik)) * saturation_water_ice(ig, ik) ) / (mlayer(ik) - mlayer(ik - 1)) |
---|
| 614 | |
---|
| 615 | if (close_bottom(ig, ik).or.close_top(ig, ik+1)) then |
---|
| 616 | saturation_water_ice_inter(ig, ik) = 0.999D0 |
---|
| 617 | else |
---|
[3223] | 618 | saturation_water_ice_inter(ig, ik) = min(saturation_water_ice(ig, ik + 1), saturation_water_ice(ig, ik)) ! new diffusion interaction |
---|
[3115] | 619 | endif |
---|
| 620 | |
---|
[3223] | 621 | saturation_water_ice_inter(ig, ik) = min(saturation_water_ice(ig, ik + 1), saturation_water_ice(ig, ik)) ! new diffusion interaction |
---|
[3262] | 622 | |
---|
[3115] | 623 | D_inter(ig, ik) = D0(ig, ik) * (1.D0 - saturation_water_ice_inter(ig, ik)) ** 2.D0 * 1.D0 / (1.D0 / Dm_inter(ig, ik) + 1.D0 / Dk_inter(ig, ik)) |
---|
[3272] | 624 | |
---|
| 625 | if(ads_const_D) D_inter(ig, ik) = default_diffcoeff |
---|
| 626 | |
---|
[3115] | 627 | ! D_inter(ig, ik) = ( (layer(ik) - mlayer(ik - 1)) * D_mid(ig, ik + 1) & ! old implementation with direct interpolation |
---|
| 628 | ! + (mlayer(ik) - layer(ik)) * D_mid(ig, ik) ) / (mlayer(ik) - mlayer(ik - 1)) |
---|
| 629 | enddo |
---|
| 630 | endif |
---|
| 631 | enddo |
---|
| 632 | |
---|
| 633 | ! Computation of new adsorption / desorption constants (Ka, Kd coefficients), and C, E, F coefficients |
---|
| 634 | ! =================================================================================================== |
---|
| 635 | |
---|
| 636 | do ig = 1, ngrid ! loop over all gridpoints |
---|
| 637 | if(.not.watercaptag(ig)) then ! if there is no polar cap |
---|
| 638 | do ik = 1, nsoil ! loop over all soil levels |
---|
| 639 | |
---|
| 640 | if (choice_ads.eq.1) then ! Constant, uniform diffusion coefficient D0 (prescribed) |
---|
| 641 | |
---|
[3223] | 642 | ! first segment of the bilinear function (before monolayer saturation) |
---|
[3115] | 643 | ! calculate the equilibrium adsorption coefficient |
---|
| 644 | k_ads_eq(ig, ik) = rho_soil(ig, ik) * S * vth(ig, ik) / 4.D0 & |
---|
[3223] | 645 | / (dexp(-enthalpy_ads / (8.314D0 * ptsoil(ig, ik))) / tau0) |
---|
[3115] | 646 | |
---|
| 647 | ! calculate the desorption coefficient |
---|
| 648 | Kd(ig, ik) = kinetic_factor / (1.D0 + k_ads_eq(ig, ik) / porosity(ig, ik)) |
---|
| 649 | |
---|
| 650 | ! calculate the absorption coefficient |
---|
| 651 | Ka(ig, ik) = kinetic_factor * k_ads_eq(ig, ik) / (1.D0 + k_ads_eq(ig, ik) / porosity(ig, ik)) |
---|
| 652 | |
---|
[3223] | 653 | |
---|
| 654 | ! second segment of the bilinear function (after monolayer saturation) ! added 2020 |
---|
| 655 | ! calculate the equilibrium adsorption coefficient |
---|
| 656 | k_ads_eq2(ig, ik) = rho_soil(ig, ik) * S * vth(ig, ik) / 4.D0 & |
---|
| 657 | / (dexp(-enthalpy_ads2 / (8.314D0 * ptsoil(ig, ik))) / tau0) ! added 2020 |
---|
| 658 | |
---|
| 659 | ! calculate the desorption coefficient |
---|
| 660 | Kd2(ig, ik) = kinetic_factor / (1.D0 + k_ads_eq2(ig, ik) / porosity(ig, ik)) ! added 2020 |
---|
| 661 | |
---|
| 662 | ! calculate the absorption coefficient |
---|
| 663 | Ka2(ig, ik) = kinetic_factor * k_ads_eq2(ig, ik) / (1.D0 + k_ads_eq2(ig, ik) / porosity(ig, ik)) ! added 2020 |
---|
| 664 | |
---|
| 665 | ! Kd(ig, ik) = exp(-enthalpy_ads / (8.314 * ptsoil(ig, ik))) |
---|
[3115] | 666 | ! & / tau0 ! * 1.D-18 |
---|
| 667 | ! Ka(ig, ik) = rho_soil(ig, ik) * S * vth(ig, ik) / 4. ! * 1.D-18 |
---|
| 668 | |
---|
| 669 | ! if ((ngrid.eq.1).and.(ik.eq.18)) then ! if 1D simulation and uppermost layer |
---|
| 670 | ! print * , 'Ka, Kd, Ka / Kd = ', Ka(ig, ik), Kd(ig, ik), Ka(ig, ik) / Kd(ig, ik) |
---|
| 671 | ! print * , 'k_ads_eq = ', k_ads_eq(ig, ik) |
---|
| 672 | ! print * , 'porosity = ', porosity(ig, ik) |
---|
| 673 | ! endif |
---|
| 674 | |
---|
[3223] | 675 | elseif (choice_ads.eq.2) then ! modified 2020 (with DeltaQ instead of Q) |
---|
[3115] | 676 | ! Kd(ig, ik) = Kd_ref * exp(-enthalpy_ads / 8.314 * |
---|
[3223] | 677 | ! & (1. / ptsoil(ig, ik) - 1. / Tref)) |
---|
| 678 | ! Ka(ig, ik) = rho_soil(ig, ik) * Ka_ref * sqrt(ptsoil(ig, ik) / Tref) |
---|
[3115] | 679 | ! & / nref |
---|
| 680 | |
---|
[3223] | 681 | ! first segment of the bilinear function (before monolayer saturation) |
---|
[3115] | 682 | ! calculate the equilibrium adsorption coefficient |
---|
[3568] | 683 | k_ads_eq(ig, ik) = 8.314D0 * rho_soil(ig, ik) * S * ptsoil(ig,ik)/18.D-3 *Kref * dexp(DeltaQ_ads / 8.314D0 * & |
---|
[3223] | 684 | (1.D0 / ptsoil(ig, ik) - 1.D0 / Tref)) ! Changed enthalpy_ads to DeltaQ_ads to ensure correct dependance/behaviour of k_ads_eq with temperature |
---|
[3115] | 685 | |
---|
| 686 | ! calculate the desorption coefficient |
---|
| 687 | Kd(ig, ik) = kinetic_factor / (1.D0 + k_ads_eq(ig, ik) / porosity(ig, ik)) |
---|
| 688 | |
---|
| 689 | ! calculate the absorption coefficient |
---|
| 690 | Ka(ig, ik) = kinetic_factor * k_ads_eq(ig, ik) / (1.D0 + k_ads_eq(ig, ik) / porosity(ig, ik)) |
---|
[3126] | 691 | |
---|
[3223] | 692 | ! second segment of the bilinear function (after monolayer saturation) ! added 2020 |
---|
| 693 | ! calculate the equilibrium adsorption coefficient |
---|
[3568] | 694 | k_ads_eq2(ig, ik) = 8.314D0 * rho_soil(ig, ik) * S * ptsoil(ig,ik)/18.D-3 * Kref2 * dexp(DeltaQ_ads2 / 8.314D0 * & |
---|
[3223] | 695 | (1.D0 / ptsoil(ig, ik) - 1.D0 / Tref)) ! Changed enthalpy_ads2 to DeltaQ_ads2 to ensure correct dependance/behaviour of k_ads_eq with temperature |
---|
[3126] | 696 | |
---|
[3223] | 697 | ! calculate the desorption coefficient |
---|
| 698 | Kd2(ig, ik) = kinetic_factor / (1.D0 + k_ads_eq2(ig, ik) / porosity(ig, ik)) |
---|
| 699 | |
---|
| 700 | ! calculate the absorption coefficient |
---|
| 701 | Ka2(ig, ik) = kinetic_factor * k_ads_eq2(ig, ik) / (1.D0 + k_ads_eq2(ig, ik) / porosity(ig, ik)) |
---|
[3248] | 702 | |
---|
| 703 | elseif (choice_ads.eq.0) then!No adsorption/desorption |
---|
| 704 | |
---|
| 705 | Ka(ig, ik) = 0. |
---|
| 706 | Kd(ig, ik) = 0. |
---|
| 707 | Ka2(ig, ik) = 0. |
---|
| 708 | Kd2(ig, ik) = 0. |
---|
[3115] | 709 | endif |
---|
| 710 | |
---|
[3223] | 711 | ! calculate the amount of water vapor at monolayer saturation ! modified 2020 |
---|
[3248] | 712 | if(choice_ads.ne.0) nsat(ig, ik) = adswater_sat_mono * Kd(ig, ik) / Ka(ig, ik) |
---|
[3115] | 713 | |
---|
[3223] | 714 | ! calculate the intercept of the second line in the bilinear function ! added 2020; corrected 2024 |
---|
| 715 | c0(ig, ik) = ( 1.D0 - (k_ads_eq2(ig, ik) / k_ads_eq(ig, ik))) * adswater_sat_mono |
---|
| 716 | |
---|
[3115] | 717 | ! calculate C, E, and F coefficients for later calculations |
---|
| 718 | C(ig, ik) = interlayer_dz(ig, ik) / ptimestep |
---|
[3223] | 719 | |
---|
| 720 | ! first segment of the bilinear function (before monolayer saturation) |
---|
[3115] | 721 | E(ig, ik) = Ka(ig, ik) / (1.D0 + ptimestep * Kd(ig, ik)) |
---|
| 722 | F(ig, ik) = Kd(ig, ik) / (1.D0 + ptimestep * Kd(ig, ik)) |
---|
[3223] | 723 | |
---|
| 724 | ! second segment of the bilinear function (after monolayer saturation) ! added 2020 |
---|
| 725 | E2(ig, ik) = Ka2(ig, ik) / (1.D0 + ptimestep * Kd2(ig, ik)) |
---|
| 726 | F2(ig, ik) = Kd2(ig, ik) / (1.D0 + ptimestep * Kd2(ig, ik)) |
---|
| 727 | |
---|
[3115] | 728 | ! save the old water concentration |
---|
| 729 | znsoilprev(ig, ik) = znsoil(ig, ik) |
---|
| 730 | znsoilprev2(ig, ik) = znsoil(ig, ik) ! needed in "special case" loop because adswprev can be changed before this loop |
---|
| 731 | adswprev(ig, ik) = adswater(ig, ik) !!!! Besoin de adswprev2 ??? |
---|
| 732 | iceprev(ig, ik) = ice(ig, ik) ! needed in "special case" loop for the same reason |
---|
| 733 | |
---|
| 734 | ! calculate the total ice + water vapor content |
---|
| 735 | ztot1(ig, ik) = porosity_prev(ig, ik) * znsoil(ig, ik) + ice(ig, ik) |
---|
| 736 | enddo |
---|
| 737 | endif |
---|
| 738 | enddo |
---|
| 739 | |
---|
| 740 | ! Computation of delta, alpha and beta coefficients ETC !!!! |
---|
| 741 | ! =========================================================== |
---|
| 742 | do ig = 1, ngrid ! loop over all gridpoints |
---|
| 743 | ! initialize the flux to zero to avoid undefined values |
---|
| 744 | zdqsdifrego(ig) = 0.D0 |
---|
| 745 | do ik = 0, nsoil - 1 |
---|
| 746 | flux(ig, ik) = 0. |
---|
| 747 | enddo |
---|
| 748 | |
---|
| 749 | if(.not.watercaptag(ig)) then ! if there is no polar cap |
---|
| 750 | do ik = 1, nsoil ! loop over all soil levels |
---|
| 751 | if (ice(ig, ik).eq.0.) then |
---|
| 752 | ice_index_flag(ik) = .false. |
---|
| 753 | else |
---|
| 754 | ice_index_flag(ik) = .true. |
---|
| 755 | endif |
---|
| 756 | enddo |
---|
| 757 | |
---|
[3223] | 758 | |
---|
[3115] | 759 | do ik = 1, nsoil ! loop over all soil levels |
---|
| 760 | |
---|
[3223] | 761 | ! calculate A and B coefficients ! modified 2020 |
---|
| 762 | if ( .not.over_mono_sat_flag(ig, ik) ) then ! Assume cell below the monolayer saturation |
---|
| 763 | ! calculate A and B coefficients (first segment of the bilinear function) |
---|
| 764 | A(ig, ik) = E(ig, ik) * interlayer_dz(ig, ik) |
---|
| 765 | B(ig, ik) = interlayer_dz(ig, ik) * F(ig, ik) * adswprev(ig, ik) |
---|
| 766 | else ! Assume cell over the monolayer saturation ! added 2020 |
---|
| 767 | ! calculate A and B coefficients (second segment of the bilinear function) |
---|
| 768 | A(ig, ik) = E2(ig, ik) * interlayer_dz(ig, ik) |
---|
| 769 | B(ig, ik) = interlayer_dz(ig, ik) * F2(ig, ik) * adswprev(ig, ik) & |
---|
| 770 | + interlayer_dz(ig, ik) * (F2(ig, ik) * Kd2(ig, ik) * c0(ig, ik) * ptimestep - Kd2(ig,ik)*c0(ig,ik)) ! Corrected 2024 |
---|
| 771 | endif |
---|
[3115] | 772 | |
---|
| 773 | ! calculate the saturation pressure |
---|
[3223] | 774 | P_sat_soil(ig, ik) = 611.D0 * dexp(22.5D0 * (1.D0 - 273.16D0 / ptsoil(ig, ik))) ! maybe take a new expression (Hsublim = 51.1 kJ / mol) ? |
---|
[3115] | 775 | |
---|
| 776 | ! calculate the gas number density at saturation pressure |
---|
[3223] | 777 | nsatsoil(ig, ik) = (P_sat_soil(ig, ik) * mw) / (kb * ptsoil(ig, ik)) |
---|
[3115] | 778 | enddo |
---|
| 779 | |
---|
| 780 | ! calculate the alpha, beta, and delta coefficients for the surface layer |
---|
| 781 | delta0(ig) = pa(ig, 1) + pb(ig, 2) * (1.D0 - pd(ig, 2)) + porosity_ice_free(ig, 1) * pb(ig, 1) |
---|
| 782 | alpha0(ig) = porosity_ice_free(ig, 1) * pb(ig, 1) / delta0(ig) |
---|
| 783 | |
---|
[3121] | 784 | beta0(ig) = ( pb(ig, 2) * pc(ig, 2) + pq(ig, 1, igcm_h2o_vap) * pa(ig, 1) + pqsurf(ig) ) & |
---|
[3115] | 785 | / delta0(ig) |
---|
| 786 | |
---|
| 787 | ! set loop flag |
---|
| 788 | do ik = 1, nsoil |
---|
| 789 | condensation_flag = .false. |
---|
| 790 | enddo |
---|
| 791 | |
---|
| 792 | sublimation_flag = .true. |
---|
| 793 | sublim_n = 0 |
---|
| 794 | do while (sublimation_flag) ! while there is sublimation |
---|
| 795 | ! print *, "sublimation loop: ", sublim_n |
---|
| 796 | sublim_n = sublim_n + 1 |
---|
| 797 | |
---|
| 798 | if (sublim_n.gt.100) then |
---|
| 799 | print *, "sublimation not converging in call ", n |
---|
| 800 | print *, "might as well stop now" |
---|
| 801 | stop |
---|
| 802 | endif |
---|
| 803 | |
---|
| 804 | ! reset flag |
---|
| 805 | sublimation_flag = .false. |
---|
| 806 | |
---|
[3223] | 807 | recompute_all_cells_ads_flag = .true. |
---|
| 808 | satur_mono_n = 0 |
---|
| 809 | do while (recompute_all_cells_ads_flag) |
---|
| 810 | ! print *, satur_mono_n |
---|
| 811 | satur_mono_n = satur_mono_n + 1 |
---|
[3115] | 812 | |
---|
| 813 | ! reset loop flag |
---|
[3223] | 814 | recompute_all_cells_ads_flag = .false. |
---|
[3115] | 815 | |
---|
| 816 | ! calculate the surface air density |
---|
| 817 | rhosurf(ig) = pplev(ig, 1) / (r * ptsrf(ig)) |
---|
| 818 | |
---|
| 819 | ! calculate the coefficients in the upermost layer |
---|
| 820 | if (exchange(ig)) then ! if there is surface exchange |
---|
| 821 | |
---|
| 822 | ! calculate the delta, alpha, and beta coefficients |
---|
| 823 | zdelta(ig, 1) = A(ig, 1) + porosity(ig, 1) * C(ig, 1) & |
---|
| 824 | + D_inter(ig, 1) / midlayer_dz(ig, 1) & !!! est - ce que le terme pb inclut le bon rho ? |
---|
| 825 | + porosity_ice_free(ig, 1) * pb(ig, 1) / (rho(ig) * ptimestep) * (1.D0 - alpha0(ig)) |
---|
| 826 | !pourrait remplacer pb/(ptime*rho(1/2)) par zcdv/ptime |
---|
| 827 | |
---|
| 828 | zalpha(ig, 1) = D_inter(ig, 1) / midlayer_dz(ig, 1) * 1.D0 / zdelta(ig, 1) |
---|
| 829 | |
---|
| 830 | zbeta(ig, 1) = ( porosity_ice_free(ig, 1) * pb(ig, 1) / ptimestep * beta0(ig) & |
---|
| 831 | + porosity_prev(ig, 1) * C(ig, 1) * znsoilprev(ig, 1) + B(ig, 1) ) & |
---|
| 832 | / zdelta(ig, 1) |
---|
| 833 | else |
---|
| 834 | ! calculate the delta, alpha, and beta coefficients without exchange |
---|
| 835 | zdelta(ig, 1) = A(ig, 1) + D_inter(ig, 1) / midlayer_dz(ig, 1) & |
---|
| 836 | + D_mid(ig, 1) / midlayer_dz(ig, 0) & |
---|
| 837 | + porosity(ig, 1) * C(ig, 1) |
---|
| 838 | |
---|
| 839 | zalpha(ig, 1) = D_inter(ig, 1) / midlayer_dz(ig, 1) * 1. / zdelta(ig, 1) |
---|
| 840 | |
---|
| 841 | zbeta(ig, 1) = ( D_mid(ig, 1) / midlayer_dz(ig, 0) * qsat_surf(ig) * rhosurf(ig) & |
---|
| 842 | + porosity_prev(ig, 1) * C(ig, 1) * znsoilprev(ig, 1) + B(ig, 1) ) & |
---|
| 843 | / zdelta(ig, 1) |
---|
| 844 | |
---|
| 845 | endif |
---|
| 846 | |
---|
| 847 | ! check for ice |
---|
| 848 | if (ice_index_flag(1)) then |
---|
| 849 | ! set the alpha coefficient to zero |
---|
| 850 | zalpha(ig, 1) = 0.D0 |
---|
| 851 | ! set the beta coefficient to the number density at saturation pressure |
---|
| 852 | zbeta(ig, 1) = nsatsoil(ig, 1) |
---|
| 853 | endif |
---|
| 854 | |
---|
| 855 | do ik = 2, nsoil - 1 ! go through all other layers |
---|
| 856 | |
---|
| 857 | ! calculate delta, alpha, and beta coefficients |
---|
| 858 | |
---|
| 859 | zdelta(ig, ik) = A(ig, ik) + porosity(ig, ik) * C(ig, ik) & |
---|
| 860 | + D_inter(ig, ik) / midlayer_dz(ig, ik) & |
---|
| 861 | + D_inter(ig, ik - 1) / midlayer_dz(ig, ik - 1) * (1.D0 - zalpha(ig, ik - 1)) |
---|
| 862 | |
---|
| 863 | zalpha(ig, ik) = D_inter(ig, ik) / midlayer_dz(ig, ik) * 1.D0 / zdelta(ig, ik) |
---|
| 864 | |
---|
| 865 | zbeta(ig, ik) = ( D_inter(ig, ik - 1) / midlayer_dz(ig, ik - 1) * zbeta(ig, ik - 1) & |
---|
| 866 | + B(ig, ik) & |
---|
| 867 | + porosity_prev(ig, ik) * C(ig, ik) * znsoilprev(ig, ik) ) / zdelta(ig, ik) |
---|
| 868 | |
---|
| 869 | ! check for ice |
---|
| 870 | if (ice_index_flag(ik)) then |
---|
| 871 | ! set the alpha coefficient to zero |
---|
| 872 | zalpha(ig, ik) = 0.D0 |
---|
| 873 | ! set the beta coefficient to the number density at saturation pressure |
---|
| 874 | zbeta(ig, ik) = nsatsoil(ig, ik) |
---|
| 875 | endif |
---|
| 876 | enddo |
---|
| 877 | |
---|
| 878 | ! Computation of pqsoil, ztot1, zq1temp2 and zdqsdifrego |
---|
| 879 | ! ======================================================= = |
---|
| 880 | |
---|
| 881 | ! calculate the preliminary amount of water vapor in the bottom layer |
---|
| 882 | if (ice_index_flag(nsoil)) then ! if there is ice |
---|
| 883 | ! set the vapor number density to saturation |
---|
| 884 | znsoil(ig, nsoil) = nsatsoil(ig, nsoil) |
---|
| 885 | else |
---|
| 886 | ! calculate the vapor number density in the lowest layer |
---|
| 887 | znsoil(ig, nsoil) = ( D_inter(ig, nsoil - 1) / midlayer_dz(ig, nsoil - 1) * zbeta(ig, nsoil - 1) & |
---|
| 888 | + porosity_prev(ig, nsoil) * C(ig, nsoil) * znsoilprev(ig, nsoil) + B(ig, nsoil) ) & |
---|
| 889 | / ( porosity(ig, nsoil) * C(ig, nsoil) + A(ig, nsoil) & |
---|
| 890 | + D_inter(ig, nsoil - 1) / midlayer_dz(ig, nsoil - 1) * (1.D0 - zalpha(ig, nsoil - 1)) ) |
---|
| 891 | endif |
---|
| 892 | |
---|
| 893 | ! calculate the preliminary amount of adsorbed water |
---|
[3223] | 894 | if (.not.over_mono_sat_flag(ig, nsoil)) then ! modified 2024 |
---|
| 895 | adswater_temp(ig, nsoil) = ( Ka(ig, nsoil) * ptimestep * znsoil(ig, nsoil) + adswprev(ig, nsoil) ) & |
---|
| 896 | / (1.D0 + ptimestep * Kd(ig, nsoil)) |
---|
| 897 | else |
---|
| 898 | adswater_temp(ig, nsoil) = ( Ka2(ig, nsoil) * ptimestep * znsoil(ig, nsoil) + adswprev(ig, nsoil) + ptimestep * c0(ig,nsoil) * Kd2(ig,nsoil)) & |
---|
| 899 | / (1.D0 + ptimestep * Kd2(ig, nsoil)) |
---|
| 900 | endif |
---|
| 901 | |
---|
| 902 | |
---|
| 903 | |
---|
[3115] | 904 | do ik = nsoil-1, 1, -1 ! backward loop over all layers |
---|
| 905 | |
---|
| 906 | znsoil(ig, ik) = zalpha(ig, ik) * znsoil(ig, ik + 1) + zbeta(ig, ik) |
---|
[3223] | 907 | |
---|
| 908 | if (.not.over_mono_sat_flag(ig, nsoil)) then ! modified 2024 |
---|
| 909 | adswater_temp(ig, ik) = ( Ka(ig, ik) * ptimestep * znsoil(ig, ik) + adswprev(ig, ik) ) & |
---|
[3115] | 910 | / (1.D0 + ptimestep * Kd(ig, ik)) |
---|
[3223] | 911 | else |
---|
| 912 | adswater_temp(ig, ik) = ( Ka2(ig, ik) * ptimestep * znsoil(ig, ik) + adswprev(ig, ik) + ptimestep * c0(ig,ik) * Kd2(ig,ik)) & |
---|
| 913 | / (1.D0 + ptimestep * Kd2(ig, ik)) |
---|
| 914 | endif |
---|
[3115] | 915 | enddo |
---|
| 916 | |
---|
[3223] | 917 | ! check if any cell is over monolayer saturation |
---|
[3115] | 918 | do ik = 1, nsoil ! loop over all soil levels |
---|
[3223] | 919 | |
---|
| 920 | ! if( (ik.lt.nsoil) .and. (recompute_cell_ads_flag(ik+1) = .true.) ) then ! Make this loop faster as all cells also need to be recomputed if the cell below needs to be recomputed ! ARNAU |
---|
| 921 | ! recompute_cell_ads_flag(ik) = .true. |
---|
| 922 | ! cycle ! Jump loop |
---|
| 923 | ! endif |
---|
[3115] | 924 | |
---|
[3223] | 925 | ! Change of coefficients ! ARNAU |
---|
| 926 | recompute_cell_ads_flag(ik) = .false. ! Assume there is no change of coefficients |
---|
| 927 | if ( adswater_temp(ig, ik).ge.adswater_sat_mono ) then |
---|
| 928 | |
---|
| 929 | print *, "NOTICE: over monolayer saturation" |
---|
| 930 | |
---|
| 931 | if ( .not.over_mono_sat_flag(ig, ik) ) then |
---|
| 932 | ! If the cell enters this scope, it |
---|
| 933 | ! means that the cell is over the monolayer |
---|
| 934 | ! saturation after calculation, but the |
---|
| 935 | ! coefficients assume it is below. Therefore, |
---|
| 936 | ! the cell needs to be recomputed |
---|
[3115] | 937 | |
---|
[3223] | 938 | over_mono_sat_flag(ig, ik) = .true. |
---|
| 939 | recompute_cell_ads_flag(ik) = .true. ! There is a change of coefficients |
---|
| 940 | |
---|
| 941 | ! change the A and B coefficients (change from first segment to second segment of the bilinear function, as we are over the monolayer saturation is_cell_over_monolayer_sat) |
---|
| 942 | A(ig, ik) = E2(ig, ik) * interlayer_dz(ig, ik) |
---|
| 943 | B(ig, ik) = interlayer_dz(ig, ik) * F2(ig, ik) * adswprev(ig, ik) & |
---|
| 944 | + interlayer_dz(ig, ik) * (F2(ig, ik) * Kd2(ig, ik) * c0(ig, ik) * ptimestep - Kd2(ig,ik)*c0(ig,ik)) ! Corrected 2024 |
---|
| 945 | endif |
---|
| 946 | else |
---|
| 947 | if ( over_mono_sat_flag(ig, ik) ) then |
---|
| 948 | ! If the cell enters this scope, it |
---|
| 949 | ! means that the cell is below the monolayer |
---|
| 950 | ! saturation after calculation, but the |
---|
| 951 | ! coefficients assume it is above. Therefore, |
---|
| 952 | ! the cell needs to be recomputed |
---|
[3115] | 953 | |
---|
[3223] | 954 | over_mono_sat_flag(ig, ik) = .false. |
---|
| 955 | recompute_cell_ads_flag(ik) = .true. ! There is a change of coefficients |
---|
| 956 | |
---|
| 957 | ! calculate A and B coefficients (reset to first segment of the bilinear function) |
---|
| 958 | A(ig, ik) = E(ig, ik) * interlayer_dz(ig, ik) |
---|
| 959 | B(ig, ik) = interlayer_dz(ig, ik) * F(ig, ik) * adswprev(ig, ik) |
---|
| 960 | endif |
---|
[3115] | 961 | endif |
---|
| 962 | enddo |
---|
| 963 | |
---|
[3223] | 964 | ! if one cell needs to be recomputed, then all the column is to be recomputed too |
---|
[3115] | 965 | do ik = 1, nsoil |
---|
[3223] | 966 | if ( recompute_cell_ads_flag(ik) ) then |
---|
| 967 | recompute_all_cells_ads_flag = .true. |
---|
| 968 | else |
---|
| 969 | adswater(ig, ik) = adswater_temp(ig, ik) ! if no recomputing is needed, store the value (it may be wrong if the cell below needs to be recomputed. It will be correct in the next loop iterations) |
---|
[3115] | 970 | endif |
---|
| 971 | enddo |
---|
[3223] | 972 | enddo ! end loop while recompute_all_cells_ads_flag (monolayer saturation) |
---|
[3115] | 973 | |
---|
| 974 | !? I'm not sure if this should be calculated here again. I have a feeling that ztot1 is meant |
---|
| 975 | ! as the value from the previous timestep |
---|
| 976 | !do ik = 1, nsoil |
---|
| 977 | ! ztot1(ig, ik) = porosity_prev(ig, ik) * znsoil(ig, ik) + ice(ig, ik) |
---|
| 978 | !enddo |
---|
| 979 | |
---|
| 980 | ! Calculation of Fnet + Fads |
---|
| 981 | ! ============================= |
---|
| 982 | |
---|
| 983 | ! calulate the flux variable |
---|
| 984 | |
---|
| 985 | ! calculate the flux in the top layer |
---|
| 986 | if (exchange(ig)) then ! if there is exchange |
---|
| 987 | ! calculate the flux taking diffusion to the atmosphere into account |
---|
| 988 | flux(ig, 0) = porosity_ice_free(ig, 1) * pb(ig, 1) / ptimestep & |
---|
| 989 | * ( znsoil(ig, 1) / rho(ig) - beta0(ig) - alpha0(ig) * znsoil(ig, 1) / rho(ig) ) |
---|
[3121] | 990 | elseif (pqsurf(ig).gt.0.) then |
---|
[3115] | 991 | ! assume that the surface is covered by waterice (if it is co2ice it should not call this subroutine at all) |
---|
| 992 | flux(ig, 0) = D_mid(ig, 1) / midlayer_dz(ig, 0) * ( znsoil(ig, 1) - qsat_surf(ig) * rhosurf(ig) ) |
---|
| 993 | endif |
---|
| 994 | |
---|
| 995 | ! check if the ground would take up water from the surface but there is none |
---|
[3121] | 996 | if ((.not.exchange(ig)).and.(pqsurf(ig).eq.0.).and.(flux(ig, 0).lt.0.)) then |
---|
[3115] | 997 | flux(ig, 0) = 0. |
---|
| 998 | endif |
---|
| 999 | |
---|
| 1000 | ! calculate the flux in all other layers |
---|
| 1001 | do ik = 1, nsoil - 1 |
---|
| 1002 | flux(ig, ik) = D_inter(ig, ik) * ( znsoil(ig, ik + 1) - znsoil(ig, ik) ) / midlayer_dz(ig, ik) |
---|
| 1003 | enddo |
---|
| 1004 | |
---|
| 1005 | ! calculate dztot1 which descibes the change in ztot1 (water vapor and ice). It is only used for output (directly and indirectly) |
---|
| 1006 | |
---|
| 1007 | ! calculate the change in ztot1 |
---|
| 1008 | |
---|
| 1009 | do ik = 1, nsoil - 1 |
---|
| 1010 | dztot1(ik) = ( flux(ig, ik) - flux(ig, ik - 1) ) / interlayer_dz(ig, ik) & |
---|
| 1011 | - A(ig, ik) / interlayer_dz(ig, ik) * znsoil(ig, ik) & |
---|
| 1012 | + B(ig, ik) / interlayer_dz(ig, ik) |
---|
| 1013 | enddo |
---|
| 1014 | |
---|
| 1015 | dztot1(nsoil) = -flux(ig, nsoil - 1) / interlayer_dz(ig, nsoil) & |
---|
| 1016 | - A(ig, nsoil) / interlayer_dz(ig, nsoil) * znsoil(ig, nsoil) & |
---|
| 1017 | + B(ig, nsoil) / interlayer_dz(ig, nsoil) |
---|
| 1018 | |
---|
| 1019 | ! Condensation / sublimation |
---|
| 1020 | do ik = 1, nsoil ! loop over all layers |
---|
| 1021 | ! print *, "ice in layer ", ik, ": ", ice(ig, ik) |
---|
| 1022 | ! print *, "vapor in layer ", ik, ": ", znsoil(ig, ik) |
---|
| 1023 | ! print *, "sat dens in layer ", ik, ": ", nsatsoil(ig, ik) |
---|
| 1024 | ! print *, "" |
---|
| 1025 | if (ice_index_flag(ik)) then ! if there is ice |
---|
| 1026 | |
---|
| 1027 | ! Compute ice content |
---|
| 1028 | ice(ig, ik) = ztot1(ig, ik) + dztot1(ik) * ptimestep - porosity(ig, ik) * nsatsoil(ig, ik) |
---|
| 1029 | |
---|
| 1030 | if (ice(ig, ik).lt.0.D0) then ! if all the ice is used up |
---|
| 1031 | ! print *, "########complete sublimation in layer", ik, " cell:", ig |
---|
| 1032 | ! print *, "ztot1: ", ztot1(ig, ik) |
---|
| 1033 | ! print *, "dztot1*timestep: ", dztot1(ik) * ptimestep |
---|
| 1034 | ! print *, "vapour: ", porosity(ig, ik) * nsatsoil(ig, ik) |
---|
| 1035 | ! print *, "znsoil: ", znsoil(ig, ik) |
---|
| 1036 | ! print *, "nsatsoil: ", nsatsoil(ig, ik) |
---|
| 1037 | ! print *, "porosity: ", porosity(ig, ik) |
---|
| 1038 | ! print *, "ice: ", ice(ig, ik) |
---|
| 1039 | ! print *, "exchange: ", exchange(ig) |
---|
| 1040 | ! print *, "co2ice: ", co2ice(ig) |
---|
| 1041 | ! print *, "" |
---|
| 1042 | ! print *, "zalpha: ", zalpha(ig, ik) |
---|
| 1043 | ! print *, "zbeta: ", zbeta(ig, ik) |
---|
| 1044 | ! print *, "" |
---|
| 1045 | |
---|
| 1046 | ! set the ice content to zero |
---|
| 1047 | ice(ig, ik) = 0.D0 |
---|
| 1048 | |
---|
| 1049 | ! change the water vapor from the previous timestep. (Watch out! could go wrong) |
---|
| 1050 | znsoilprev(ig, ik) = ztot1(ig, ik) / porosity_prev(ig, ik) |
---|
| 1051 | ! print *, "new znsoilprev", znsoilprev(ig, ik) |
---|
| 1052 | |
---|
| 1053 | ! remove the ice flag and raise the sublimation flag |
---|
| 1054 | ice_index_flag(ik) = .false. |
---|
| 1055 | sublimation_flag = .true. |
---|
| 1056 | endif |
---|
| 1057 | |
---|
| 1058 | elseif (znsoil(ig, ik).gt.nsatsoil(ig, ik)) then ! if there is condenstation |
---|
| 1059 | !ice(ig, ik) = ztot1(ig, ik) + dztot1(ik) * ptimestep - porosity(ig, ik) * nsatsoil(ig, ik) |
---|
| 1060 | |
---|
| 1061 | |
---|
| 1062 | ! print *, "=========== new condensation in layer", ik, " cell:", ig |
---|
| 1063 | ! print *, "znsoil, nsatsoil: ", znsoil(ig, ik), nsatsoil(ig, ik) |
---|
| 1064 | ! print *, "ztot1: ", ztot1(ig, ik) |
---|
| 1065 | ! print *, "dztot1: ", dztot1(ik) |
---|
| 1066 | ! print *, "ice: ", ice(ig,ik) |
---|
| 1067 | ! print *, "" |
---|
| 1068 | ! print *, "zalpha: ", zalpha(ig, ik) |
---|
| 1069 | ! print *, "zbeta: ", zbeta(ig, ik) |
---|
| 1070 | ! print *, "" |
---|
| 1071 | |
---|
| 1072 | !if (ice(ig, ik).lt.0.D0) then |
---|
| 1073 | ! set the ice content to zero |
---|
| 1074 | ! ice(ig, ik) = 0.D0 |
---|
| 1075 | if (.not.condensation_flag(ik)) then |
---|
| 1076 | ! raise the ice and sublimation flags |
---|
| 1077 | ice_index_flag(ik) = .true. |
---|
| 1078 | sublimation_flag = .true. |
---|
| 1079 | ! print *, condensation_flag(ik) |
---|
| 1080 | condensation_flag(ik) = .true. |
---|
| 1081 | ! print *, condensation_flag(ik) |
---|
| 1082 | ! print *, "set condensation flag" |
---|
| 1083 | ! else |
---|
| 1084 | ! print *, "condensation loop supressed" |
---|
| 1085 | endif |
---|
| 1086 | endif |
---|
| 1087 | |
---|
| 1088 | ! calculate the difference between total water content and ice + vapor content (only used for output) |
---|
| 1089 | diff(ig, ik) = ice(ig, ik) + porosity(ig, ik) * znsoil(ig, ik) & |
---|
| 1090 | + adswater(ig, ik) - ztot1(ig, ik) - dztot1(ik) * ptimestep |
---|
| 1091 | enddo ! loop over all layer |
---|
| 1092 | enddo ! end first loop while sublimation_flag (condensation / sublimation) |
---|
| 1093 | |
---|
| 1094 | if (exchange(ig)) then ! if there is exchange |
---|
| 1095 | |
---|
| 1096 | ! calculate the temporty mixing ratio above the surface |
---|
| 1097 | zq1temp2(ig) = beta0(ig) + alpha0(ig) * znsoil(ig, 1) / rho(ig) |
---|
| 1098 | ! calculate the flux from the subsurface |
---|
| 1099 | zdqsdifrego(ig) = porosity_ice_free(ig, 1) * pb(ig, 1) / ptimestep * (zq1temp2(ig) - znsoil(ig, 1) / rho(ig) ) |
---|
| 1100 | |
---|
| 1101 | else |
---|
| 1102 | ! calculate the flux from the subsurface |
---|
[3223] | 1103 | zdqsdifrego(ig) = D_mid(ig, 1) / midlayer_dz(ig, 0) * (znsoil(ig, 1) - qsat_surf(ig) * rhosurf(ig)) ! faut - il faire intervenir la porosite ? |
---|
[3121] | 1104 | if ((pqsurf(ig).eq.0.).and.(zdqsdifrego(ig).lt.0.)) then |
---|
[3115] | 1105 | zdqsdifrego(ig) = 0. |
---|
| 1106 | endif |
---|
| 1107 | endif |
---|
| 1108 | |
---|
| 1109 | ! Special case where there is not enough ice on the surface to supply the subsurface for the whole timestep |
---|
| 1110 | ! (when exchange with the atmosphere is disabled): the upper boundary condition becomes a flux condition |
---|
| 1111 | ! (and not qsat_surf) and all the remaining surface ice is sublimated and transferred to the subsurface. |
---|
| 1112 | ! the actual change in surface ice happens in a higher subroutine |
---|
| 1113 | ! ========================================================================================================= = |
---|
| 1114 | |
---|
| 1115 | if ( (.not.exchange(ig)) & |
---|
[3223] | 1116 | .and. ( (-zdqsdifrego(ig) * ptimestep) & |
---|
[3245] | 1117 | .gt.( pqsurf(ig) + pdqsdifpot(ig) * ptimestep) ) & |
---|
| 1118 | .and.( (pqsurf(ig) + pdqsdifpot(ig) * ptimestep).gt.0. ) ) then |
---|
[3115] | 1119 | |
---|
| 1120 | ! calculate a new flux from the subsurface |
---|
[3245] | 1121 | zdqsdifrego(ig) = -( pqsurf(ig) + pdqsdifpot(ig) * ptimestep ) / ptimestep |
---|
[3115] | 1122 | |
---|
| 1123 | ! ! check case where there is CO2 ice on the surface but qsurf = 0 |
---|
| 1124 | ! if (co2ice(ig).gt.0.) then |
---|
| 1125 | ! zdqsdifrego(ig) = 0.D0 |
---|
| 1126 | ! endif |
---|
[3245] | 1127 | do ik = 1, nsoil |
---|
[3223] | 1128 | |
---|
| 1129 | ! calculate A and B coefficients ! modified 2020 |
---|
| 1130 | if ( .not.over_mono_sat_flag(ig, ik) ) then ! Assume cell below the monolayer saturation |
---|
| 1131 | ! calculate A and B coefficients (first segment of the bilinear function) |
---|
[3115] | 1132 | A(ig, ik) = E(ig, ik) * interlayer_dz(ig, ik) |
---|
| 1133 | B(ig, ik) = interlayer_dz(ig, ik) * F(ig, ik) * adswprev(ig, ik) |
---|
[3223] | 1134 | else ! Assume cell over the monolayer saturation ! added 2020 |
---|
| 1135 | ! calculate A and B coefficients (second segment of the bilinear function) |
---|
| 1136 | A(ig, ik) = E2(ig, ik) * interlayer_dz(ig, ik) |
---|
| 1137 | B(ig, ik) = interlayer_dz(ig, ik) * F2(ig, ik) * adswprev(ig, ik) & |
---|
| 1138 | + interlayer_dz(ig, ik) * (F2(ig, ik) * Kd2(ig, ik) * c0(ig, ik) * ptimestep - Kd2(ig,ik)*c0(ig,ik)) ! Corrected 2024 |
---|
| 1139 | endif |
---|
[3115] | 1140 | |
---|
| 1141 | ! initialize all flags for the loop |
---|
[3245] | 1142 | |
---|
[3115] | 1143 | |
---|
| 1144 | ! initialize the ice |
---|
| 1145 | ice(ig, ik) = iceprev(ig, ik) |
---|
| 1146 | if (iceprev(ig, ik).eq.0.) then |
---|
| 1147 | ice_index_flag(ik) = .false. |
---|
| 1148 | else |
---|
| 1149 | ice_index_flag(ik) = .true. |
---|
| 1150 | endif |
---|
| 1151 | enddo |
---|
| 1152 | |
---|
| 1153 | ! loop while there is new sublimation |
---|
| 1154 | |
---|
| 1155 | sublimation_flag = .true. |
---|
| 1156 | sublim_n = 0 |
---|
| 1157 | do while (sublimation_flag) |
---|
| 1158 | ! print *, "special case sublimation loop: ", sublim_n |
---|
| 1159 | sublim_n = sublim_n + 1 |
---|
| 1160 | if (sublim_n.gt.100) then |
---|
| 1161 | print *, "special case sublimation not converging in call ", n |
---|
| 1162 | print *, "might as well stop now" |
---|
| 1163 | stop |
---|
| 1164 | endif |
---|
| 1165 | |
---|
| 1166 | ! reset the sublimation flag |
---|
| 1167 | sublimation_flag = .false. |
---|
| 1168 | |
---|
[3223] | 1169 | ! loop until good values accounting for monolayer saturation are found |
---|
| 1170 | recompute_all_cells_ads_flag = .true. |
---|
| 1171 | do while (recompute_all_cells_ads_flag) |
---|
[3115] | 1172 | |
---|
[3223] | 1173 | ! reset loop flag |
---|
| 1174 | recompute_all_cells_ads_flag = .false. |
---|
[3115] | 1175 | |
---|
| 1176 | ! calculate the Delta, Alpha, and Beta coefficients in the top layer |
---|
| 1177 | zdelta(ig, 1) = A(ig, 1) + porosity(ig, 1) * C(ig, 1) + D_inter(ig, 1) / midlayer_dz(ig, 1) |
---|
| 1178 | |
---|
| 1179 | zalpha(ig, 1) = D_inter(ig, 1) / midlayer_dz(ig, 1) * 1.D0 / zdelta(ig, 1) |
---|
| 1180 | |
---|
| 1181 | zbeta(ig, 1) = ( porosity_prev(ig, 1) * C(ig, 1) * znsoilprev2(ig, 1) + B(ig, 1) - zdqsdifrego(ig) ) & |
---|
| 1182 | / zdelta(ig, 1) |
---|
| 1183 | |
---|
| 1184 | ! check for ice |
---|
| 1185 | if (ice_index_flag(1)) then |
---|
| 1186 | ! set the alpha coefficient to zero |
---|
| 1187 | zalpha(ig, 1) = 0.D0 |
---|
| 1188 | ! set the beta coefficient to the number density at saturation pressure |
---|
| 1189 | zbeta(ig, 1) = nsatsoil(ig, 1) |
---|
| 1190 | endif |
---|
| 1191 | |
---|
| 1192 | do ik = 2, nsoil - 1 ! loop over all other layers |
---|
| 1193 | |
---|
| 1194 | ! calculate the Delta, Alpha, and Beta coefficients in the layer |
---|
| 1195 | zdelta(ig, ik) = A(ig, ik) + porosity(ig, ik) * C(ig, ik) + D_inter(ig, ik) / midlayer_dz(ig, ik) & |
---|
| 1196 | + D_inter(ig, ik - 1) / midlayer_dz(ig, ik - 1) * (1.D0 - zalpha(ig, ik - 1)) |
---|
| 1197 | |
---|
| 1198 | zalpha(ig, ik) = D_inter(ig, ik) / midlayer_dz(ig, ik) * 1.D0 / zdelta(ig, ik) |
---|
| 1199 | |
---|
| 1200 | zbeta(ig, ik) = ( D_inter(ig, ik - 1) / midlayer_dz(ig, ik - 1) * zbeta(ig, ik - 1) & |
---|
| 1201 | + porosity_prev(ig, ik) * C(ig, ik) * znsoilprev2(ig, ik) + B(ig, ik) ) / zdelta(ig, ik) |
---|
| 1202 | |
---|
| 1203 | ! check for ice |
---|
| 1204 | if (ice_index_flag(ik)) then |
---|
| 1205 | ! set the alpha coefficient to zero |
---|
| 1206 | zalpha(ig, ik) = 0.D0 |
---|
| 1207 | ! set the beta coefficient to the number density at saturation pressure |
---|
| 1208 | zbeta(ig, ik) = nsatsoil(ig, ik) |
---|
| 1209 | endif |
---|
| 1210 | enddo |
---|
| 1211 | |
---|
| 1212 | ! calculate the preliminary amount of water vapor in the bottom layer |
---|
| 1213 | if (ice_index_flag(nsoil)) then |
---|
| 1214 | ! set the vapor number density to saturation |
---|
| 1215 | znsoil(ig, nsoil) = nsatsoil(ig, nsoil) |
---|
| 1216 | else |
---|
| 1217 | ! calculate the vapor number density in the lowest layer |
---|
| 1218 | znsoil(ig, nsoil) = ( D_inter(ig, nsoil - 1) / midlayer_dz(ig, nsoil - 1) * zbeta(ig, nsoil - 1) & |
---|
| 1219 | + porosity_prev(ig, nsoil) * C(ig, nsoil) * znsoilprev2(ig, nsoil) + B(ig, nsoil) ) & |
---|
| 1220 | / ( porosity(ig, nsoil) * C(ig, nsoil) & |
---|
| 1221 | + D_inter(ig, nsoil - 1) / midlayer_dz(ig, nsoil - 1) * (1.D0 - zalpha(ig, nsoil - 1)) & |
---|
| 1222 | + A(ig, nsoil) ) |
---|
| 1223 | endif |
---|
| 1224 | |
---|
[3223] | 1225 | |
---|
| 1226 | ! calculate the preliminary amount of adsorbed water |
---|
| 1227 | if (.not.over_mono_sat_flag(ig, nsoil)) then ! modified 2024 |
---|
| 1228 | adswater_temp(ig, nsoil) = ( Ka(ig, nsoil) * ptimestep * znsoil(ig, nsoil) + adswprev(ig, nsoil) ) & |
---|
| 1229 | / (1.D0 + ptimestep * Kd(ig, nsoil)) |
---|
| 1230 | else |
---|
| 1231 | adswater_temp(ig, nsoil) = ( Ka2(ig, nsoil) * ptimestep * znsoil(ig, nsoil) + adswprev(ig, nsoil) + ptimestep * c0(ig,nsoil) * Kd2(ig,nsoil)) & |
---|
| 1232 | / (1.D0 + ptimestep * Kd2(ig, nsoil)) |
---|
| 1233 | endif |
---|
| 1234 | |
---|
| 1235 | |
---|
| 1236 | |
---|
| 1237 | do ik = nsoil-1, 1, -1 ! backward loop over all layers |
---|
| 1238 | |
---|
| 1239 | znsoil(ig, ik) = zalpha(ig, ik) * znsoil(ig, ik + 1) + zbeta(ig, ik) |
---|
| 1240 | |
---|
| 1241 | if (.not.over_mono_sat_flag(ig, nsoil)) then ! modified 2024 |
---|
[3115] | 1242 | adswater_temp(ig, ik) = ( Ka(ig, ik) * ptimestep * znsoil(ig, ik) + adswprev(ig, ik) ) & |
---|
[3223] | 1243 | / (1.D0 + ptimestep * Kd(ig, ik)) |
---|
| 1244 | else |
---|
| 1245 | adswater_temp(ig, ik) = ( Ka2(ig, ik) * ptimestep * znsoil(ig, ik) + adswprev(ig, ik) + ptimestep * c0(ig,ik) * Kd2(ig,ik)) & |
---|
| 1246 | / (1.D0 + ptimestep * Kd2(ig, ik)) |
---|
| 1247 | endif |
---|
| 1248 | enddo |
---|
| 1249 | |
---|
[3115] | 1250 | |
---|
| 1251 | ! check for any saturation |
---|
| 1252 | do ik = 1, nsoil |
---|
[3223] | 1253 | ! Change of coefficients ! ARNAU |
---|
| 1254 | recompute_cell_ads_flag(ik) = .false. ! Assume there is no change of coefficients ! ARNAU |
---|
| 1255 | if ( adswater_temp(ig, ik).gt.adswater_sat_mono ) then |
---|
| 1256 | |
---|
| 1257 | print *, "NOTICE: over monolayer saturation" |
---|
| 1258 | |
---|
| 1259 | if ( .not.over_mono_sat_flag(ig, ik) ) then |
---|
| 1260 | ! If the cell enters this scope, it |
---|
| 1261 | ! means that the cell is over the monolayer |
---|
| 1262 | ! saturation after calculation, but the |
---|
| 1263 | ! coefficients assume it is below. Therefore, |
---|
| 1264 | ! the cell needs to be recomputed |
---|
[3115] | 1265 | |
---|
[3223] | 1266 | over_mono_sat_flag(ig, ik) = .true. |
---|
| 1267 | recompute_cell_ads_flag(ik) = .true. ! There is a change of coefficients |
---|
| 1268 | |
---|
| 1269 | ! change the A and B coefficients (change from first segment to second segment of the bilinear function, as we are over the monolayer saturation is_cell_over_monolayer_sat) |
---|
| 1270 | A(ig, ik) = E2(ig, ik) * interlayer_dz(ig, ik) |
---|
| 1271 | B(ig, ik) = interlayer_dz(ig, ik) * F2(ig, ik) * adswprev(ig, ik) & |
---|
| 1272 | + interlayer_dz(ig, ik) * (F2(ig, ik) * Kd2(ig, ik) * c0(ig, ik) * ptimestep - Kd2(ig,ik)*c0(ig,ik)) ! Corrected 2024 |
---|
| 1273 | endif |
---|
| 1274 | else |
---|
| 1275 | if ( over_mono_sat_flag(ig, ik) ) then |
---|
| 1276 | ! If the cell enters this scope, it |
---|
| 1277 | ! means that the cell is below the monolayer |
---|
| 1278 | ! saturation after calculation, but the |
---|
| 1279 | ! coefficients assume it is above. Therefore, |
---|
| 1280 | ! the cell needs to be recomputed |
---|
[3115] | 1281 | |
---|
[3223] | 1282 | over_mono_sat_flag(ig, ik) = .false. |
---|
| 1283 | recompute_cell_ads_flag(ik) = .true. ! There is a change of coefficients |
---|
[3115] | 1284 | |
---|
[3223] | 1285 | ! calculate A and B coefficients (reset to first segment of the bilinear function) |
---|
| 1286 | A(ig, ik) = E(ig, ik) * interlayer_dz(ig, ik) |
---|
| 1287 | B(ig, ik) = interlayer_dz(ig, ik) * F(ig, ik) * adswprev(ig, ik) |
---|
| 1288 | endif |
---|
[3115] | 1289 | endif |
---|
| 1290 | enddo |
---|
| 1291 | |
---|
| 1292 | ! raise the saturation flag if any layer has saturated and reset the first layer saturation flag |
---|
[3223] | 1293 | do ik = 1, nsoil ! modified 2020 |
---|
| 1294 | if ( recompute_cell_ads_flag(ik) ) then |
---|
| 1295 | recompute_all_cells_ads_flag = .true. |
---|
| 1296 | else |
---|
| 1297 | adswater(ig, ik) = adswater_temp(ig, ik) ! if no recomputing is needed, store the value (it may be wrong if the cell below needs to be recomputed. It will be correct in the next loop iterations) |
---|
[3115] | 1298 | endif |
---|
| 1299 | enddo |
---|
| 1300 | enddo ! end while loop (adsorption saturation) |
---|
| 1301 | |
---|
| 1302 | ! set the flux to the previously calculated value for the top layer |
---|
| 1303 | flux(ig, 0) = zdqsdifrego(ig) |
---|
| 1304 | |
---|
| 1305 | ! calculate the flux for all other layers |
---|
| 1306 | do ik = 1, nsoil - 1 |
---|
| 1307 | flux(ig, ik) = D_inter(ig, ik) * (znsoil(ig, ik + 1) - znsoil(ig, ik)) / midlayer_dz(ig, ik) |
---|
| 1308 | enddo |
---|
| 1309 | |
---|
| 1310 | ! calculate the change in ztot1 |
---|
| 1311 | do ik = 1, nsoil - 1 |
---|
| 1312 | dztot1(ik) = (flux(ig, ik) - flux(ig, ik - 1)) / interlayer_dz(ig, ik) & |
---|
| 1313 | - A(ig, ik) / interlayer_dz(ig, ik) * znsoil(ig, ik) & |
---|
| 1314 | + B(ig, ik) / interlayer_dz(ig, ik) |
---|
| 1315 | enddo |
---|
| 1316 | |
---|
| 1317 | dztot1(nsoil) = -flux(ig, nsoil - 1) / interlayer_dz(ig, nsoil) & |
---|
| 1318 | - A(ig, nsoil) / interlayer_dz(ig, nsoil) * znsoil(ig, nsoil) & |
---|
| 1319 | + B(ig, nsoil) / interlayer_dz(ig, nsoil) |
---|
| 1320 | |
---|
| 1321 | |
---|
| 1322 | ! Condensation / sublimation |
---|
| 1323 | do ik = 1, nsoil |
---|
| 1324 | if (ice_index_flag(ik)) then |
---|
| 1325 | |
---|
| 1326 | ! Compute ice content |
---|
| 1327 | ice(ig, ik) = ztot1(ig, ik) + dztot1(ik) * ptimestep & |
---|
| 1328 | - porosity(ig, ik) * nsatsoil(ig, ik) |
---|
| 1329 | |
---|
| 1330 | if (ice(ig, ik).lt.0.D0) then ! if all the ice is used up |
---|
| 1331 | |
---|
| 1332 | ! print *, "############complete sublimation in layer ", ik |
---|
| 1333 | ! print *, "ztot1: ", ztot1(ig, ik) |
---|
| 1334 | ! print *, "dztot1*timestep: ", dztot1(ik) * ptimestep |
---|
| 1335 | ! print *, "vapour: ", porosity(ig, ik) * nsatsoil(ig, ik) |
---|
| 1336 | ! print *, "znsoil: ", znsoil(ig, ik) |
---|
| 1337 | ! print *, "nsatsoil: ", nsatsoil(ig, ik) |
---|
| 1338 | ! print *, "porosity: ", porosity(ig, ik) |
---|
| 1339 | ! print *, "ice: ", ice(ig, ik) |
---|
| 1340 | ! print *, "exchange: ", exchange(ig) |
---|
| 1341 | ! print *, "co2ice: ", co2ice(ig) |
---|
| 1342 | ! print *, "" |
---|
| 1343 | ! print *, "zalpha: ", zalpha(ig, ik) |
---|
| 1344 | ! print *, "zbeta: ", zbeta(ig, ik) |
---|
| 1345 | ! print *, "" |
---|
| 1346 | |
---|
| 1347 | ! set the ice content to zero |
---|
| 1348 | ice(ig, ik) = 0.D0 |
---|
| 1349 | |
---|
| 1350 | |
---|
| 1351 | if (znsoil(ig, ik).gt.nsatsoil(ig, ik)) then |
---|
| 1352 | print *, "WARNING! complete sublimation, but vapor is oversaturated" |
---|
| 1353 | print *, "special case loop in cell", ig, ik ,"will be supressed" |
---|
| 1354 | else |
---|
| 1355 | ! change the water vapor from the previous timestep. (Watch out! could go wrong) |
---|
| 1356 | znsoilprev2(ig, ik) = ztot1(ig, ik) / porosity_prev(ig, ik) |
---|
| 1357 | ! print *, "new znsoilprev", znsoilprev(ig, ik) |
---|
| 1358 | |
---|
| 1359 | ! remove the ice flag and raise the sublimation flag |
---|
| 1360 | ice_index_flag(ik) = .false. |
---|
| 1361 | sublimation_flag = .true. |
---|
| 1362 | endif |
---|
| 1363 | endif |
---|
| 1364 | |
---|
[3223] | 1365 | elseif (znsoil(ig, ik).gt.nsatsoil(ig, ik)) then ! if there is new ice through condensation |
---|
[3115] | 1366 | if (.not.condensation_flag(ik)) then |
---|
| 1367 | ! raise the ice and sublimation flags |
---|
| 1368 | ice_index_flag(ik) = .true. |
---|
| 1369 | sublimation_flag = .true. |
---|
| 1370 | ! print *, condensation_flag(ik) |
---|
| 1371 | condensation_flag(ik) = .true. |
---|
| 1372 | ! print *, condensation_flag(ik) |
---|
| 1373 | ! print *, "set condensation flag" |
---|
| 1374 | ! else |
---|
| 1375 | ! print *, "special case condensation loop supressed" |
---|
| 1376 | endif |
---|
| 1377 | endif |
---|
| 1378 | enddo |
---|
| 1379 | enddo ! end first loop while (condensation / sublimation) |
---|
| 1380 | endif ! Special case for all ice on the surface is used up |
---|
| 1381 | |
---|
| 1382 | do ik = 1, nsoil |
---|
| 1383 | |
---|
| 1384 | diff(ig, ik) = ice(ig, ik) + porosity(ig, ik) * znsoil(ig, ik) & ! only used for output |
---|
| 1385 | + adswater(ig, ik) - adswprev(ig, ik) & |
---|
| 1386 | - ztot1(ig, ik) - dztot1(ik) * ptimestep !? This is inconsistent, in the not special case the previous adsorbed water is not counted |
---|
| 1387 | !? also this just overwrites the previous calculation if I see that correctly |
---|
| 1388 | |
---|
| 1389 | ! calculate the total amount of water |
---|
| 1390 | ztot1(ig, ik) = porosity(ig, ik) * znsoil(ig, ik) + ice(ig, ik) |
---|
| 1391 | h2otot(ig, ik) = adswater(ig, ik) + ztot1(ig, ik) |
---|
| 1392 | enddo |
---|
| 1393 | endif ! if there is no polar cap |
---|
| 1394 | enddo ! loop over all gridpoints |
---|
| 1395 | |
---|
| 1396 | ! check for choking condition |
---|
| 1397 | do ig = 1, ngrid |
---|
| 1398 | if(.not.watercaptag(ig)) then |
---|
| 1399 | do ik = 1, nsoil - 1 |
---|
| 1400 | if (ice(ig, ik) / (rho_H2O_ice * porosity_ice_free(ig, ik)).gt.choke_fraction) then ! if the ice is over saturation or choke_fraction |
---|
[3223] | 1401 | if ( flux(ig, ik - 1).gt.0.) then |
---|
[3115] | 1402 | if (.not.close_top(ig, ik).and.print_closure_warnings) then |
---|
| 1403 | print *, "NOTICE: closing top of soil layer due to inward flux", ig, ik |
---|
| 1404 | endif |
---|
| 1405 | close_top(ig, ik) = .true. |
---|
[3223] | 1406 | elseif (flux(ig, ik - 1).lt.0.) then |
---|
[3115] | 1407 | if (close_top(ig, ik).and.print_closure_warnings) then |
---|
| 1408 | print *, "NOTICE: opening top of soil layer due to outward flux", ig, ik |
---|
| 1409 | endif |
---|
| 1410 | close_top(ig, ik) = .false. |
---|
| 1411 | endif |
---|
| 1412 | |
---|
[3223] | 1413 | if ( flux(ig, ik).lt.0.) then |
---|
[3115] | 1414 | if (.not.close_bottom(ig, ik).and.print_closure_warnings) then |
---|
| 1415 | print *, "NOTICE: closing bottom of soil layer due to inward flux", ig, ik |
---|
| 1416 | endif |
---|
| 1417 | close_bottom(ig, ik) = .true. |
---|
[3223] | 1418 | elseif (flux(ig, ik).gt.0.) then |
---|
[3115] | 1419 | if (close_bottom(ig, ik).and.print_closure_warnings) then |
---|
| 1420 | print *, "NOTICE: opening bottom of soil layer due to outward flux", ig, ik |
---|
| 1421 | endif |
---|
| 1422 | close_bottom(ig, ik) = .false. |
---|
| 1423 | endif |
---|
| 1424 | |
---|
| 1425 | ! if ( (flux(ig, ik).lt.flux(ig, ik - 1)).and.(flux(ig, ik).gt.0D0) ) then |
---|
| 1426 | ! if (.not.close_top(ig, ik).and.print_closure_warnings) then |
---|
| 1427 | ! print *, "NOTICE: closing top of soil layer due to ice", ig, ik |
---|
| 1428 | ! endif |
---|
| 1429 | ! close_top(ig, ik) = .true. |
---|
| 1430 | ! |
---|
| 1431 | ! elseif ( (flux(ig, ik).lt.flux(ig, ik - 1)).and.(flux(ig, ik - 1).lt.0D0) ) then |
---|
| 1432 | ! if (.not.close_bottom(ig, ik).and.print_closure_warnings) then |
---|
| 1433 | ! print *, "NOTICE: closing bottom of soil layer due to ice", ig, ik |
---|
| 1434 | ! endif |
---|
| 1435 | ! close_bottom(ig, ik) = .true. |
---|
| 1436 | ! endif |
---|
| 1437 | ! |
---|
| 1438 | ! if (close_top(ig, ik).and.close_bottom(ig, ik)) then |
---|
| 1439 | ! close_top(ig, ik) = .false. |
---|
| 1440 | ! close_bottom(ig, ik) = .false. |
---|
| 1441 | ! if (print_closure_warnings) then |
---|
| 1442 | ! print *, "WARNING: Reopening soil layer after complete closure:", ig, ik |
---|
| 1443 | ! endif |
---|
| 1444 | ! elseif (close_top(ig, ik).or.close_bottom(ig, ik)) then |
---|
| 1445 | ! if ((flux(ig, ik) - flux(ig, ik - 1)).gt.0D0) then |
---|
| 1446 | ! close_top(ig, ik) = .false. |
---|
| 1447 | ! close_bottom(ig, ik) = .false. |
---|
| 1448 | ! if (print_closure_warnings) then |
---|
| 1449 | ! print *, "WARNING: Reopening soil layer due to rising ice:", ig, ik |
---|
| 1450 | ! endif |
---|
| 1451 | ! endif |
---|
| 1452 | ! |
---|
| 1453 | ! if (close_top(ig, ik).and.(flux(ig, ik - 1).lt.0D0)) then |
---|
| 1454 | ! close_top = .false. |
---|
| 1455 | ! if (print_closure_warnings) then |
---|
| 1456 | ! print *, "NOTICE: Reopening top of soil layer due to upward flux:", ig, ik |
---|
| 1457 | ! endif |
---|
| 1458 | ! endif |
---|
| 1459 | ! |
---|
| 1460 | ! if (close_bottom(ig, ik).and.(flux(ig, ik).gt.0D0)) then |
---|
| 1461 | ! close_bottom = .false. |
---|
| 1462 | ! if (print_closure_warnings) then |
---|
| 1463 | ! print *, "NOTICE: Reopening bottom of soil layer due to downward flux:", ig, ik |
---|
| 1464 | ! endif |
---|
| 1465 | ! endif |
---|
| 1466 | ! endif |
---|
| 1467 | else ! opening condition that ice content has fallen sufficiently |
---|
[3223] | 1468 | if (close_top(ig, ik).or.close_bottom(ig, ik).and.print_closure_warnings) then |
---|
[3115] | 1469 | print *, "NOTICE: Reopening soillayer due to decrease in ice", ig, ik |
---|
| 1470 | endif |
---|
| 1471 | close_top(ig, ik) = .false. |
---|
| 1472 | close_bottom(ig, ik) = .false. |
---|
| 1473 | endif |
---|
| 1474 | enddo |
---|
| 1475 | endif |
---|
| 1476 | enddo |
---|
| 1477 | |
---|
| 1478 | ! Computation of total mass |
---|
| 1479 | ! =========================== |
---|
| 1480 | |
---|
| 1481 | do ig = 1, ngrid |
---|
| 1482 | ! initialize the masses to zero |
---|
| 1483 | mass_h2o(ig) = 0.D0 |
---|
| 1484 | mass_ice(ig) = 0.D0 |
---|
| 1485 | |
---|
| 1486 | if(.not.watercaptag(ig)) then |
---|
| 1487 | do ik = 1, nsoil |
---|
| 1488 | ! calculate the total water and ice mass |
---|
| 1489 | mass_h2o(ig) = mass_h2o(ig) + h2otot(ig, ik) * interlayer_dz(ig, ik) |
---|
| 1490 | mass_ice(ig) = mass_ice(ig) + ice(ig, ik) * interlayer_dz(ig, ik) |
---|
| 1491 | |
---|
| 1492 | ! calculate how close the water vapor content is to saturizing the adsorbed water |
---|
[3248] | 1493 | if(choice_ads.ne.0) preduite(ig, ik) = znsoil(ig, ik) / nsat(ig, ik) |
---|
[3115] | 1494 | |
---|
| 1495 | ! write the results to the return variable |
---|
| 1496 | pqsoil(ig, ik, igcm_h2o_vap_soil) = znsoil(ig, ik) |
---|
| 1497 | pqsoil(ig, ik, igcm_h2o_ice_soil) = ice(ig, ik) |
---|
| 1498 | pqsoil(ig, ik, igcm_h2o_vap_ads) = adswater(ig, ik) |
---|
| 1499 | |
---|
| 1500 | |
---|
[3223] | 1501 | if (close_top(ig, ik)) then |
---|
| 1502 | close_out(ig, ik) = 1 |
---|
[3115] | 1503 | elseif (close_bottom(ig, ik)) then |
---|
[3223] | 1504 | close_out(ig, ik) = -1 |
---|
[3115] | 1505 | else |
---|
| 1506 | close_out(ig, ik) = 0 |
---|
| 1507 | endif |
---|
| 1508 | enddo |
---|
| 1509 | endif |
---|
| 1510 | |
---|
| 1511 | if (watercaptag(ig)) then |
---|
| 1512 | do ik = 1, nsoil |
---|
| 1513 | saturation_water_ice(ig, ik) = -1 |
---|
| 1514 | enddo |
---|
| 1515 | endif |
---|
| 1516 | |
---|
| 1517 | ! convert the logical :: flag exchange to a numeric output |
---|
| 1518 | if (watercaptag(ig)) then |
---|
| 1519 | exch(ig) = -2. |
---|
| 1520 | elseif (exchange(ig)) then |
---|
| 1521 | exch(ig) = 1. |
---|
| 1522 | else |
---|
| 1523 | exch(ig) = -1. |
---|
| 1524 | endif |
---|
| 1525 | |
---|
| 1526 | enddo |
---|
| 1527 | |
---|
| 1528 | ! calculate the global total value |
---|
| 1529 | mass_h2o_tot = 0.D0 |
---|
| 1530 | mass_ice_tot = 0.D0 |
---|
| 1531 | do ig = 1, ngrid |
---|
| 1532 | mass_h2o_tot = mass_h2o_tot + mass_h2o(ig) * cell_area(ig) |
---|
| 1533 | mass_ice_tot = mass_ice_tot + mass_ice(ig) * cell_area(ig) |
---|
| 1534 | enddo |
---|
| 1535 | |
---|
| 1536 | ! print and iterate the call number |
---|
| 1537 | ! print * , 'Subsurface call n = ', n |
---|
| 1538 | n = n + 1 |
---|
| 1539 | |
---|
| 1540 | ! ----------------------------------------------------------------------- |
---|
| 1541 | ! Output in diagfi and diagsoil |
---|
| 1542 | ! ----------------------------------------------------------------------- |
---|
| 1543 | |
---|
| 1544 | ! reformat flux, because it has a unusual shape |
---|
| 1545 | do ig = 1, ngrid |
---|
| 1546 | nsurf(ig) = rhosurf(ig) * pq(ig, 1, igcm_h2o_vap) |
---|
| 1547 | |
---|
| 1548 | |
---|
| 1549 | do ik = 1, nsoil - 1 |
---|
| 1550 | var_flux_soil(ig, ik) = flux(ig, ik) |
---|
| 1551 | enddo |
---|
| 1552 | var_flux_soil(ig, nsoil) = 0. |
---|
| 1553 | enddo |
---|
| 1554 | |
---|
| 1555 | if(writeoutput) then |
---|
| 1556 | !print *, "flux shape: ", shape(flux) |
---|
| 1557 | !print *, "adswater shape ", shape(adswater) |
---|
| 1558 | |
---|
| 1559 | !print *, "ngrid= ", ngrid |
---|
| 1560 | |
---|
| 1561 | !if (ngrid.eq.1) then ! if in 1D |
---|
| 1562 | |
---|
| 1563 | ! print *, "writing 1D data" |
---|
| 1564 | |
---|
| 1565 | ! print *, real(adswater(:, :), 4) |
---|
| 1566 | ! print *, shape(adswater(:, :)) |
---|
| 1567 | |
---|
| 1568 | zalpha(1, nsoil) = 0 |
---|
| 1569 | zbeta(1, nsoil) = 0 |
---|
| 1570 | |
---|
| 1571 | ! call write_output("zalpha","diffusion alpha coefficient", "unknown",real(zalpha(1, :))) |
---|
| 1572 | |
---|
| 1573 | ! call write_output("zbeta","diffusion beta coefficient", "unknown",real(zbeta(1, :))) |
---|
| 1574 | |
---|
| 1575 | ! call write_output("adswater","adswater", "kg / m^3",real(adswater(1, :))) |
---|
| 1576 | |
---|
| 1577 | ! call write_output("znsoil","znsoil", "kg / m^3",real(znsoil(1, :))) |
---|
| 1578 | |
---|
| 1579 | ! call write_output("ice","ice", "kg / m^3",real(ice(1, :))) |
---|
| 1580 | |
---|
| 1581 | ! call write_output("h2otot","total water content", "kg / m^3",real(h2otot(1, :))) |
---|
| 1582 | |
---|
| 1583 | ! call write_output("flux_soil","flux_soil", "kg / m^2",real(flux(1, :))) |
---|
| 1584 | |
---|
| 1585 | ! call write_output("flux","flux soil", "kg / m^2",real(zdqsdifrego(:))) |
---|
| 1586 | |
---|
| 1587 | ! call write_output("flux_surf","surface flux", "kg / m^2",real(zdqsdifrego(1))) |
---|
| 1588 | |
---|
| 1589 | ! call write_output("exchange","exchange", "boolean",real(exch(1))) |
---|
| 1590 | |
---|
| 1591 | !else |
---|
| 1592 | |
---|
| 1593 | ! print *, mass_h2o_tot |
---|
| 1594 | ! print *, real(mass_h2o_tot, 4) |
---|
| 1595 | |
---|
| 1596 | ! call write_output("dztot1","change in dztot", "unknown",real(dztot1)) |
---|
| 1597 | |
---|
[3262] | 1598 | call write_output("flux_soillayer","flux of water between the soil layers", "kg m-2 s-1",var_flux_soil) |
---|
[3115] | 1599 | |
---|
| 1600 | ! call write_output("A_coef","A coefficient of dztot1", "unknown",real(B)) |
---|
| 1601 | |
---|
| 1602 | ! call write_output("B_coef","B coefficient of dztot1", "unknown",real(B)) |
---|
| 1603 | |
---|
| 1604 | ! call write_output("H2O_init","initialized H2O", "kg/m^2",real(H2O)) |
---|
| 1605 | |
---|
| 1606 | ! call write_output("H2O_depth_init","initialized H2O depth ", "m",real(H2O_depth)) |
---|
| 1607 | |
---|
| 1608 | call write_output("ice_saturation_soil","Water ice saturation in the soil layers", "Percent",saturation_water_ice) |
---|
| 1609 | |
---|
| 1610 | ! call write_output("mass_h2o_tot","total mass of subsurface water over the planet", "kg",real(mass_h2o_tot)) |
---|
| 1611 | |
---|
| 1612 | ! call write_output("mass_ice_tot","total mass of subsurface ice over the planet", "kg",real(mass_ice_tot)) |
---|
| 1613 | |
---|
| 1614 | call write_output("mass_h2o_soil","Mass of subsurface water column at each point", "kg m-2",(mass_h2o)) |
---|
| 1615 | |
---|
| 1616 | call write_output("mass_ice_soil","Mass of subsurface ice at each point", "kg m-2",(mass_ice)) |
---|
| 1617 | |
---|
| 1618 | call write_output("znsoil","Water vapor soil concentration ", "kg.m - 3 of pore air",znsoil) |
---|
| 1619 | |
---|
| 1620 | call write_output("nsatsoil","subsurface water vapor saturation density", "kg/m^3",real(nsatsoil)) |
---|
| 1621 | |
---|
| 1622 | call write_output("nsurf","surface water vapor density", "kg/m^3",real(nsurf)) |
---|
| 1623 | |
---|
| 1624 | call write_output("adswater","subsurface adsorbed water", "kg/m^3",real(adswater)) |
---|
| 1625 | |
---|
[3262] | 1626 | ! call write_output("subsurfice","subsurface ice", "kg/m^3",real(ice)) |
---|
[3115] | 1627 | |
---|
| 1628 | call write_output("flux_rego",'flux of water from the regolith','kg/m^2',zdqsdifrego) |
---|
| 1629 | |
---|
| 1630 | ! call write_output("exchange",'exchange','no unit',real(exch)) |
---|
| 1631 | |
---|
| 1632 | ! call write_output("close",'close top, bottom, or none (1, -1, 0)','no unit',real(close_out)) |
---|
| 1633 | |
---|
[3262] | 1634 | ! call write_output("coeff_diffusion_soil",'interlayer diffusion coefficient','m^2/s',D_inter) |
---|
[3167] | 1635 | |
---|
[3115] | 1636 | !endif |
---|
| 1637 | endif |
---|
| 1638 | RETURN |
---|
| 1639 | END |
---|
| 1640 | |
---|
[3223] | 1641 | |
---|