Changeset 4065 for trunk/LMDZ.COMMON/libf/evolution/sorption.F90
- Timestamp:
- Feb 12, 2026, 9:09:12 AM (3 weeks ago)
- File:
-
- 1 edited
-
trunk/LMDZ.COMMON/libf/evolution/sorption.F90 (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LMDZ.COMMON/libf/evolution/sorption.F90
r3991 r4065 10 10 ! AUTHORS & DATE 11 11 ! L. Lange, 2023 12 ! JB Clement, 2025 13 ! 14 ! NOTES 15 ! 16 !----------------------------------------------------------------------- 17 18 ! DECLARATION 19 ! ----------- 20 implicit none 21 22 ! MODULE VARIABLES 23 ! ---------------- 24 logical :: do_sorption ! Flag to compute adsorption/desorption 25 real, allocatable, dimension(:,:,:) :: co2_adsorbed_phys ! co2 that is in the regolith [kg/m^2] 26 real, allocatable, dimension(:,:,:) :: h2o_adsorbed_phys ! h2o that is in the regolith [kg/m^2] 12 ! JB Clement, 02/2026 13 ! 14 ! NOTES 15 ! 16 !----------------------------------------------------------------------- 17 18 ! DEPENDENCIES 19 ! ------------ 20 use numerics, only: dp, qp, di, k4, minieps 21 22 ! DECLARATION 23 ! ----------- 24 implicit none 25 26 ! PARAMETERS 27 ! ---------- 28 logical(k4), protected :: do_sorption ! Flag to compute adsorption/desorption 27 29 28 30 contains … … 30 32 31 33 !======================================================================= 32 SUBROUTINE ini_adsorption_h_PEM(ngrid,nslope,nsoilmx_PEM) 33 !----------------------------------------------------------------------- 34 ! NAME 35 ! ini_adsorption_h_PEM 36 ! 37 ! DESCRIPTION 38 ! Allocate CO2 and H2O adsorption arrays. 34 SUBROUTINE set_sorption_config(do_sorption_in) 35 !----------------------------------------------------------------------- 36 ! NAME 37 ! set_sorption_config 38 ! 39 ! DESCRIPTION 40 ! Setter for 'sorption' configuration parameters. 41 ! 42 ! AUTHORS & DATE 43 ! JB Clement, 02/2026 44 ! 45 ! NOTES 46 ! 47 !----------------------------------------------------------------------- 48 49 ! DEPENDENCIES 50 ! ------------ 51 use utility, only: bool2str 52 use display, only: print_msg 53 54 ! DECLARATION 55 ! ----------- 56 implicit none 57 58 ! ARGUMENTS 59 ! --------- 60 logical(k4), intent(in) :: do_sorption_in 61 62 ! CODE 63 ! ---- 64 do_sorption = do_sorption_in 65 call print_msg('do_sorption = '//bool2str(do_sorption)) 66 67 END SUBROUTINE set_sorption_config 68 !======================================================================= 69 70 !======================================================================= 71 SUBROUTINE evolve_regolith_adsorption(d_h2oice,d_co2ice,h2oice,co2ice,tsoil,TI,ps,q_h2o_ts,q_co2_ts,h2o_ads_reg,co2_ads_reg,delta_h2o_ads,delta_co2_ads) 72 !----------------------------------------------------------------------- 73 ! NAME 74 ! evolve_regolith_adsorption 75 ! 76 ! DESCRIPTION 77 ! Compute both H2O and CO2 adsorption in regolith. 78 ! 79 ! AUTHORS & DATE 80 ! L. Lange, 2023 81 ! JB Clement, 12/2025 82 ! C. Metz, 02/2026 83 ! 84 ! NOTES 85 ! 86 !----------------------------------------------------------------------- 87 88 ! DEPENDENCIES 89 ! ------------ 90 use geometry, only: ngrid, nslope, nsoil 91 92 ! DECLARATION 93 ! ----------- 94 implicit none 95 96 ! ARGUMENTS 97 ! --------- 98 real(dp), dimension(:,:), intent(in) :: d_h2oice, d_co2ice ! tendencies on the glaciers [1] 99 real(dp), dimension(:,:), intent(in) :: h2oice ! H2O ice at the surface [kg/m^2] 100 real(dp), dimension(:,:), intent(in) :: co2ice ! CO2 ice at the surface [kg/m^2] 101 real(dp), dimension(:,:,:), intent(in) :: TI ! Soil Thermal inertia [J/K/^2/s^1/2] 102 real(dp), dimension(:,:,:), intent(in) :: tsoil ! Soil temperature [K] 103 real(dp), dimension(:,:), intent(in) :: ps ! Average surface pressure [Pa] 104 real(dp), dimension(:,:), intent(in) :: q_co2_ts ! Mass mixing ratio of co2 in the first layer [kg/kg] 105 real(dp), dimension(:,:), intent(in) :: q_h2o_ts ! Mass mixing ratio of H2o in the first layer [kg/kg] 106 real(dp), dimension(:), intent(out) :: delta_h2o_ads ! Difference density of h2o adsorbed [kg/m^3] 107 real(dp), dimension(:), intent(out) :: delta_co2_ads ! Difference density of co2 adsorbed [kg/m^3] 108 real(dp), dimension(:,:,:), intent(inout) :: h2o_ads_reg, co2_ads_reg 109 110 ! LOCAL VARIABLES 111 ! --------------- 112 real(dp), dimension(ngrid,nsoil,nslope) :: theta_h2o_ads ! Fraction of the pores occupied by H2O molecules 113 114 ! CODE 115 ! ---- 116 call evolve_h2o_ads(d_h2oice,d_co2ice,h2oice,co2ice,ps,q_h2o_ts,q_co2_ts,tsoil,TI,theta_h2o_ads,h2o_ads_reg,delta_h2o_ads) 117 call evolve_co2_ads(d_h2oice,d_co2ice,h2oice,co2ice,ps,q_h2o_ts,q_co2_ts,tsoil,TI,co2_ads_reg,delta_co2_ads) 118 119 END SUBROUTINE evolve_regolith_adsorption 120 !======================================================================= 121 122 !======================================================================= 123 SUBROUTINE evolve_h2o_ads(d_h2oice,d_co2ice,h2oice,co2ice,ps,q_h2o_ts,q_co2_ts,tsoil,TI,theta_h2o_ads,h2o_ads_reg,delta_h2o_ads) 124 !----------------------------------------------------------------------- 125 ! NAME 126 ! evolve_h2o_ads 127 ! 128 ! DESCRIPTION 129 ! Compute H2O adsorption in regolith following Jackosky et al. (1997). 39 130 ! 40 131 ! AUTHORS & DATE … … 46 137 !----------------------------------------------------------------------- 47 138 139 ! DEPENDENCIES 140 ! ------------ 141 use geometry, only: ngrid, nslope, nsoil, nday 142 use soil, only: layer, index_breccia 143 use slopes, only: subslope_dist, def_slope_mean 144 use atmosphere, only: ap, bp 145 use planet, only: alpha_clap_h2o, beta_clap_h2o, m_h2o, m_co2,m_noco2, rho_regolith 146 use maths, only: pi 147 48 148 ! DECLARATION 49 149 ! ----------- … … 52 152 ! ARGUMENTS 53 153 ! --------- 54 integer, intent(in) :: ngrid ! number of atmospheric columns 55 integer, intent(in) :: nslope ! number of slope within a mesh 56 integer, intent(in) :: nsoilmx_PEM ! number of soil layer in the PEM 57 58 ! CODE 59 ! ---- 60 allocate(co2_adsorbed_phys(ngrid,nsoilmx_PEM,nslope)) 61 allocate(h2o_adsorbed_phys(ngrid,nsoilmx_PEM,nslope)) 62 63 END SUBROUTINE ini_adsorption_h_PEM 64 !======================================================================= 65 66 !======================================================================= 67 SUBROUTINE end_adsorption_h_PEM 68 !----------------------------------------------------------------------- 69 ! NAME 70 ! end_adsorption_h_PEM 71 ! 72 ! DESCRIPTION 73 ! Deallocate adsorption arrays. 74 ! 75 ! AUTHORS & DATE 76 ! L. Lange, 2023 77 ! JB Clement, 2025 78 ! 79 ! NOTES 80 ! 81 !----------------------------------------------------------------------- 82 83 ! DECLARATION 84 ! ----------- 85 implicit none 86 87 ! CODE 88 ! ---- 89 if (allocated(co2_adsorbed_phys)) deallocate(co2_adsorbed_phys) 90 if (allocated(h2o_adsorbed_phys)) deallocate(h2o_adsorbed_phys) 91 92 END SUBROUTINE end_adsorption_h_PEM 93 !======================================================================= 94 95 !======================================================================= 96 SUBROUTINE regolith_adsorption(ngrid,nslope,nsoil_PEM,timelen,d_h2oglaciers,d_co2glaciers,waterice,co2ice,tsoil_PEM,TI_PEM,ps,q_co2,q_h2o, & 97 m_h2o_completesoil,delta_mh2oreg, m_co2_completesoil,delta_mco2reg) 98 !----------------------------------------------------------------------- 99 ! NAME 100 ! regolith_adsorption 101 ! 102 ! DESCRIPTION 103 ! Compute both H2O and CO2 adsorption in regolith. 104 ! 105 ! AUTHORS & DATE 106 ! L. Lange, 2023 107 ! JB Clement, 2025 108 ! 109 ! NOTES 110 ! 111 !----------------------------------------------------------------------- 112 113 ! DECLARATION 114 ! ----------- 115 implicit none 116 117 ! ARGUMENTS 118 ! --------- 119 integer, intent(in) :: ngrid, nslope, nsoil_PEM, timelen ! size dimension: physics x subslope x soil x timeseries 120 real, dimension(ngrid,nslope), intent(in) :: d_h2oglaciers, d_co2glaciers ! tendancies on the glaciers [1] 121 real, dimension(ngrid,nslope), intent(in) :: waterice ! water ice at the surface [kg/m^2] 122 real, dimension(ngrid,nslope), intent(in) :: co2ice ! co2 ice at the surface [kg/m^2] 123 real, dimension(ngrid,nsoil_PEM,nslope), intent(in) :: TI_PEM ! Soil Thermal inertia (J/K/^2/s^1/2) 124 real, dimension(ngrid,nsoil_PEM,nslope), intent(in) :: tsoil_PEM ! Soil temperature (K) 125 real, dimension(ngrid,timelen), intent(in) :: ps ! Average surface pressure [Pa] 126 real, dimension(ngrid,timelen), intent(in) :: q_co2 ! Mass mixing ratio of co2 in the first layer (kg/kg) 127 real, dimension(ngrid,timelen), intent(in) :: q_h2o ! Mass mixing ratio of H2o in the first layer (kg/kg) 128 real, dimension(ngrid), intent(out) :: delta_mh2oreg ! Difference density of h2o adsorbed (kg/m^3) 129 real, dimension(ngrid), intent(out) :: delta_mco2reg ! Difference density of co2 adsorbed (kg/m^3) 130 real, dimension(ngrid,nsoil_PEM,nslope), intent(inout) :: m_co2_completesoil ! Density of co2 adsorbed (kg/m^3) 131 real, dimension(ngrid,nsoil_PEM,nslope), intent(inout) :: m_h2o_completesoil ! Density of h2o adsorbed (kg/m^3) 132 133 ! LOCAL VARIABLES 134 ! --------------- 135 real, dimension(ngrid,nsoil_PEM,nslope) :: theta_h2o_adsorbed ! Fraction of the pores occupied by H2O molecules 136 137 ! CODE 138 ! ---- 139 call regolith_h2oadsorption(ngrid,nslope,nsoil_PEM,timelen,d_h2oglaciers,d_co2glaciers,waterice,co2ice,ps,q_co2,q_h2o,tsoil_PEM,TI_PEM, & 140 theta_h2o_adsorbed,m_h2o_completesoil,delta_mh2oreg) 141 call regolith_co2adsorption(ngrid,nslope,nsoil_PEM,timelen,d_h2oglaciers,d_co2glaciers,waterice,co2ice,ps,q_co2,q_h2o, & 142 tsoil_PEM,TI_PEM,m_co2_completesoil,delta_mco2reg) 143 144 END SUBROUTINE regolith_adsorption 145 !======================================================================= 146 147 !======================================================================= 148 SUBROUTINE regolith_h2oadsorption(ngrid,nslope,nsoil_PEM,timelen,d_h2oglaciers,d_co2glaciers,waterice,co2ice,ps,q_co2,q_h2o,tsoil_PEM,TI_PEM, & 149 theta_h2o_adsorbed,m_h2o_completesoil,delta_mreg) 150 !----------------------------------------------------------------------- 151 ! NAME 152 ! regolith_h2oadsorption 153 ! 154 ! DESCRIPTION 155 ! Compute H2O adsorption in regolith following Jackosky et al. (1997). 156 ! 157 ! AUTHORS & DATE 158 ! L. Lange, 2023 159 ! JB Clement, 2025 160 ! 161 ! NOTES 162 ! 163 !----------------------------------------------------------------------- 164 165 ! DEPENDENCIES 166 ! ------------ 167 use soil, only: layer_PEM, index_breccia 168 use comslope_mod, only: subslope_dist, def_slope_mean 169 use vertical_layers_mod, only: ap, bp 170 use constants_marspem_mod, only: alpha_clap_h2o, beta_clap_h2o, m_h2o, m_co2,m_noco2, rho_regolith 171 use phys_constants, only: pi 172 173 ! DECLARATION 174 ! ----------- 175 implicit none 176 177 ! ARGUMENTS 178 ! --------- 179 integer, intent(in) :: ngrid, nslope, nsoil_PEM,timelen ! Size dimension 180 real, dimension(ngrid,nslope), intent(in) :: d_h2oglaciers, d_co2glaciers ! Tendencies on the glaciers () 181 real, dimension(ngrid,nslope), intent(in) :: waterice ! Water ice at the surface [kg/m^2] 182 real, dimension(ngrid,nslope), intent(in) :: co2ice ! CO2 ice at the surface [kg/m^2] 183 real, dimension(ngrid,timelen), intent(in) :: ps ! Surface pressure (Pa) 184 real, dimension(ngrid,timelen), intent(in) :: q_co2 ! Mass mixing ratio of co2 in the first layer (kg/kg) 185 real, dimension(ngrid,timelen), intent(in) :: q_h2o ! Mass mixing ratio of H2o in the first layer (kg/kg) 186 real, dimension(ngrid,nsoil_PEM,nslope), intent(in) :: TI_PEM ! Soil Thermal inertia (J/K/^2/s^1/2) 187 real, dimension(ngrid,nsoil_PEM,nslope), intent(in) :: tsoil_PEM ! Soil temperature (K) 188 real, dimension(ngrid,nsoil_PEM,nslope), intent(inout) :: m_h2o_completesoil ! Density of h2o adsorbed (kg/m^3)(ngrid,nsoil_PEM,nslope) 189 real, dimension(ngrid,nsoil_PEM,nslope), intent(out) :: theta_h2o_adsorbed ! Fraction of the pores occupied by H2O molecules 190 real, dimension(ngrid), intent(out) :: delta_mreg ! Difference density of h2o adsorbed (kg/m^3) 154 real(dp), dimension(:,:), intent(in) :: d_h2oice, d_co2ice ! Tendencies on the glaciers () 155 real(dp), dimension(:,:), intent(in) :: h2oice ! H2O ice at the surface [kg/m^2] 156 real(dp), dimension(:,:), intent(in) :: co2ice ! CO2 ice at the surface [kg/m^2] 157 real(dp), dimension(:,:), intent(in) :: ps ! Surface pressure [Pa] 158 real(dp), dimension(:,:), intent(in) :: q_co2_ts ! Mass mixing ratio of co2 in the first layer [kg/kg] 159 real(dp), dimension(:,:), intent(in) :: q_h2o_ts ! Mass mixing ratio of H2o in the first layer [kg/kg] 160 real(dp), dimension(:,:,:), intent(in) :: TI ! Soil Thermal inertia [J/K/^2/s^1/2] 161 real(dp), dimension(:,:,:), intent(in) :: tsoil ! Soil temperature [K] 162 real(dp), dimension(:,:,:), intent(inout) :: h2o_ads_reg ! Density of h2o adsorbed [kg/m^3] 163 real(dp), dimension(:,:,:), intent(out) :: theta_h2o_ads ! Fraction of the pores occupied by H2O molecules 164 real(dp), dimension(:), intent(out) :: delta_h2o_ads ! Difference density of h2o adsorbed [kg/m^3] 191 165 192 166 ! LOCAL VARIABLES 193 167 ! --------------- 194 168 ! Constants: 195 real :: Ko = 1.57e-8! Jackosky et al. 1997196 real :: e = 2573.9! Jackosky et al. 1997197 real :: mu = 0.48! Jackosky et al. 1997198 real :: m_theta = 2.84e-7! Mass of h2o per m^2 absorbed Jackosky et al. 1997199 ! real :: as = 18.9e3! Specific area, Buhler & Piqueux 2021200 real :: as = 9.48e4! Specific area, Zent201 real :: inertie_thresold = 800.! TI > 800 means cementation202 real , dimension(ngrid,index_breccia,nslope) :: deltam_reg_complete ! Difference in the mass per slope and soil layer (kg/m^3)203 real :: K ! Used to compute theta204 integer :: ig, iloop, islope, it ! For loops205 logical ,dimension(ngrid,nslope) :: ispermanent_co2glaciers ! Check if the co2 glacier is permanent206 logical ,dimension(ngrid,nslope) :: ispermanent_h2oglaciers ! Check if the h2o glacier is permanent207 real , dimension(ngrid,nslope) :: deltam_reg_slope ! Difference density of h2o adsorbed per slope (kg/m^3)208 real , dimension(ngrid,nsoil_PEM,nslope):: dm_h2o_regolith_slope ! Elementary h2o mass adsorded per mesh per slope209 real :: A, B ! Used to compute the mean mass above the surface210 real :: p_sat ! Saturated vapor pressure of ice211 real ,dimension(:,:), allocatable :: mass_mean ! Mean mass above the surface212 real ,dimension(:,:), allocatable :: zplev_mean ! Pressure above the surface213 real ,dimension(:,:), allocatable :: pvapor ! Partial pressure above the surface214 real ,dimension(:) , allocatable :: pvapor_avg ! Yearly averaged169 real(dp) :: Ko = 1.57e-8_dp ! Jackosky et al. 1997 170 real(dp) :: e = 2573.9_dp ! Jackosky et al. 1997 171 real(dp) :: mu = 0.48_dp ! Jackosky et al. 1997 172 real(dp) :: m_theta = 2.84e-7_dp ! Mass of h2o per m^2 absorbed Jackosky et al. 1997 173 ! real(dp) :: as = 18.9e3_dp ! Specific area, Buhler & Piqueux 2021 174 real(dp) :: as = 9.48e4_dp ! Specific area, Zent 175 real(dp) :: inertie_thresold = 800._dp ! TI > 800 means cementation 176 real(dp), dimension(ngrid,index_breccia,nslope) :: deltam_reg_complete ! Difference in the mass per slope and soil layer [kg/m^3] 177 real(dp) :: K ! Used to compute theta 178 integer(di) :: ig, iloop, islope, it ! For loops 179 logical(k4), dimension(ngrid,nslope) :: ispermanent_co2glaciers ! Check if the co2 glacier is permanent 180 logical(k4), dimension(ngrid,nslope) :: ispermanent_h2oglaciers ! Check if the h2o glacier is permanent 181 real(dp), dimension(ngrid,nslope) :: deltam_reg_slope ! Difference density of h2o adsorbed per slope [kg/m^3] 182 real(dp), dimension(ngrid,nsoil,nslope) :: dm_h2o_regolith_slope ! Elementary h2o mass adsorded per mesh per slope 183 real(dp) :: A, B ! Used to compute the mean mass above the surface 184 real(dp) :: p_sat ! Saturated vapor pressure of ice 185 real(dp), dimension(:,:), allocatable :: mass_mean ! Mean mass above the surface 186 real(dp), dimension(:,:), allocatable :: zplev_mean ! Pressure above the surface 187 real(dp), dimension(:,:), allocatable :: pvapor ! Partial pressure above the surface 188 real(dp), dimension(:) , allocatable :: pvapor_avg ! Yearly averaged 215 189 216 190 ! CODE 217 191 ! ---- 218 192 ! 0. Some initializations 219 allocate(mass_mean(ngrid, timelen),zplev_mean(ngrid,timelen),pvapor(ngrid,timelen),pvapor_avg(ngrid))220 A = 1. /m_co2 - 1./m_noco2221 B = 1. /m_noco2222 theta_h2o_ads orbed = 0.223 dm_h2o_regolith_slope = 0. 193 allocate(mass_mean(ngrid,nday),zplev_mean(ngrid,nday),pvapor(ngrid,nday),pvapor_avg(ngrid)) 194 A = 1._dp/m_co2 - 1._dp/m_noco2 195 B = 1._dp/m_noco2 196 theta_h2o_ads = 0._dp 197 dm_h2o_regolith_slope = 0._dp 224 198 ispermanent_h2oglaciers = .false. 225 199 ispermanent_co2glaciers = .false. 226 200 227 201 ! 0.1 Look at perennial ice 228 do ig = 1,ngrid 229 do islope = 1,nslope 230 if (abs(d_h2oglaciers(ig,islope)) > 1.e-5 .and. abs(waterice(ig,islope)) > 0.) ispermanent_h2oglaciers(ig,islope) = .true. 231 if (abs(d_co2glaciers(ig,islope)) > 1.e-5 .and. abs(co2ice(ig,islope)) > 0.) ispermanent_co2glaciers(ig,islope) = .true. 232 enddo 233 enddo 202 where (abs(d_h2oice(:,:)) > 1.e-5 .and. h2oice(:,:) > 0._dp) ispermanent_h2oglaciers(:,:) = .true. 203 where (abs(d_co2ice(:,:)) > 1.e-5 .and. co2ice(:,:) > 0._dp) ispermanent_co2glaciers(:,:) = .true. 234 204 235 205 ! 0.2 Compute the partial pressure of vapor 236 206 ! a. the molecular mass into the column 237 207 do ig = 1,ngrid 238 mass_mean(ig,:) = 1 /(A*q_co2(ig,:) + B)239 end do208 mass_mean(ig,:) = 1._dp/(A*q_co2_ts(ig,:) + B) 209 end do 240 210 241 211 ! b. pressure level 242 do it = 1, timelen212 do it = 1,nday 243 213 do ig = 1,ngrid 244 214 zplev_mean(ig,it) = ap(1) + bp(1)*ps(ig,it) 245 end do246 end do215 end do 216 end do 247 217 248 218 ! c. Vapor pressure 249 pvapor = mass_mean/m_h2o*q_h2o *zplev_mean250 pvapor_avg = sum(pvapor,2)/ timelen219 pvapor = mass_mean/m_h2o*q_h2o_ts*zplev_mean 220 pvapor_avg = sum(pvapor,2)/nday 251 221 deallocate(pvapor,zplev_mean,mass_mean) 252 222 … … 255 225 do islope = 1,nslope 256 226 do iloop = 1,index_breccia 257 K = Ko*exp(e/tsoil _PEM(ig,iloop,islope))258 if (TI _PEM(ig,iloop,islope) < inertie_thresold) then259 theta_h2o_ads orbed(ig,iloop,islope) = (K*pvapor_avg(ig)/(1.+ K*pvapor_avg(ig)))**mu227 K = Ko*exp(e/tsoil(ig,iloop,islope)) 228 if (TI(ig,iloop,islope) < inertie_thresold) then 229 theta_h2o_ads(ig,iloop,islope) = (K*pvapor_avg(ig)/(1._dp + K*pvapor_avg(ig)))**mu 260 230 else 261 p_sat = exp(beta_clap_h2o/tsoil _PEM(ig,iloop,islope) + alpha_clap_h2o) ! we assume fixed temperature in the ice ... not really good but ...262 theta_h2o_ads orbed(ig,iloop,islope) = (K*p_sat/(1.+ K*p_sat))**mu263 end if264 dm_h2o_regolith_slope(ig,iloop,islope) = as*theta_h2o_ads orbed(ig,iloop,islope)*m_theta*rho_regolith265 end do266 end do267 end do231 p_sat = exp(beta_clap_h2o/tsoil(ig,iloop,islope) + alpha_clap_h2o) ! we assume fixed temperature in the ice ... not really good but ... 232 theta_h2o_ads(ig,iloop,islope) = (K*p_sat/(1._dp + K*p_sat))**mu 233 end if 234 dm_h2o_regolith_slope(ig,iloop,islope) = as*theta_h2o_ads(ig,iloop,islope)*m_theta*rho_regolith 235 end do 236 end do 237 end do 268 238 269 239 ! 2. Check the exchange between the atmosphere and the regolith 270 240 do ig = 1,ngrid 271 delta_ mreg(ig) = 0.241 delta_h2o_ads(ig) = 0._dp 272 242 do islope = 1,nslope 273 deltam_reg_slope(ig,islope) = 0. 243 deltam_reg_slope(ig,islope) = 0._dp 274 244 do iloop = 1,index_breccia 275 if (TI _PEM(ig,iloop,islope) < inertie_thresold .and. .not. ispermanent_h2oglaciers(ig,islope) .and. .not. ispermanent_co2glaciers(ig,islope)) then245 if (TI(ig,iloop,islope) < inertie_thresold .and. .not. ispermanent_h2oglaciers(ig,islope) .and. .not. ispermanent_co2glaciers(ig,islope)) then 276 246 if (iloop == 1) then 277 deltam_reg_complete(ig,iloop,islope) = (dm_h2o_regolith_slope(ig,iloop,islope) - m_h2o_completesoil(ig,iloop,islope))*(layer_PEM(iloop))247 deltam_reg_complete(ig,iloop,islope) = (dm_h2o_regolith_slope(ig,iloop,islope) - h2o_ads_reg(ig,iloop,islope))*(layer(iloop)) 278 248 else 279 deltam_reg_complete(ig,iloop,islope) = (dm_h2o_regolith_slope(ig,iloop,islope) - m_h2o_completesoil(ig,iloop,islope))*(layer_PEM(iloop) - layer_PEM(iloop - 1))280 end if249 deltam_reg_complete(ig,iloop,islope) = (dm_h2o_regolith_slope(ig,iloop,islope) - h2o_ads_reg(ig,iloop,islope))*(layer(iloop) - layer(iloop - 1)) 250 end if 281 251 else ! NO EXCHANGE AS ICE BLOCK THE DYNAMIC! 282 deltam_reg_complete(ig,iloop,islope) = 0. 283 end if252 deltam_reg_complete(ig,iloop,islope) = 0._dp 253 end if 284 254 deltam_reg_slope(ig,islope) = deltam_reg_slope(ig,islope) + deltam_reg_complete(ig,iloop,islope) 285 end do286 delta_ mreg(ig) = delta_mreg(ig) + deltam_reg_slope(ig,islope)*subslope_dist(ig,islope)/cos(pi*def_slope_mean(islope)/180.)287 end do288 end do289 m_h2o_completesoil= dm_h2o_regolith_slope290 291 END SUBROUTINE regolith_h2oadsorption292 !======================================================================= 293 294 !======================================================================= 295 SUBROUTINE regolith_co2adsorption(ngrid,nslope,nsoil_PEM,timelen,d_h2oglaciers,d_co2glaciers,waterice,co2ice,ps,q_co2,q_h2o,tsoil_PEM,TI_PEM,m_co2_completesoil,delta_mreg)296 297 !----------------------------------------------------------------------- 298 ! NAME 299 ! regolith_co2adsorption255 end do 256 delta_h2o_ads(ig) = delta_h2o_ads(ig) + deltam_reg_slope(ig,islope)*subslope_dist(ig,islope)/cos(pi*def_slope_mean(islope)/180._dp) 257 end do 258 end do 259 h2o_ads_reg = dm_h2o_regolith_slope 260 261 END SUBROUTINE evolve_h2o_ads 262 !======================================================================= 263 264 !======================================================================= 265 SUBROUTINE evolve_co2_ads(d_h2oice,d_co2ice,h2oice,co2ice,ps,q_h2o_ts,q_co2_ts,tsoil,TI,co2_ads_reg,delta_co2_ads) 266 267 !----------------------------------------------------------------------- 268 ! NAME 269 ! evolve_co2_ads 300 270 ! 301 271 ! DESCRIPTION … … 312 282 ! DEPENDENCIES 313 283 ! ------------ 314 use soil, only: layer_PEM, index_breccia 315 use comslope_mod, only: subslope_dist, def_slope_mean 316 use vertical_layers_mod, only: ap, bp 317 use constants_marspem_mod, only: m_co2, m_noco2, rho_regolith 318 use phys_constants, only: pi 284 use geometry, only: ngrid, nslope, nsoil, nday 285 use soil, only: layer, index_breccia 286 use slopes, only: subslope_dist, def_slope_mean 287 use atmosphere, only: ap, bp 288 use planet, only: m_co2, m_noco2, rho_regolith 289 use maths, only: pi 319 290 320 291 ! DECLARATION … … 324 295 ! ARGUMENTS 325 296 ! --------- 326 integer, intent(in) :: ngrid, nslope, nsoil_PEM,timelen ! Size dimension 327 real, dimension(ngrid,timelen), intent(in) :: ps ! Average surface pressure [Pa] 328 real, dimension(ngrid,nsoil_PEM,nslope), intent(in) :: tsoil_PEM ! Mean Soil Temperature [K] 329 real, dimension(ngrid,nsoil_PEM,nslope), intent(in) :: TI_PEM ! Mean Thermal Inertia [USI] 330 real, dimension(ngrid,nslope), intent(in) :: d_h2oglaciers, d_co2glaciers ! Tendencies on the glaciers () 331 real, dimension(ngrid,timelen), intent(in) :: q_co2, q_h2o ! Mass mixing ratio of co2 and h2o in the first layer (kg/kg) 332 real, dimension(ngrid,nslope), intent(in) :: waterice ! Water ice at the surface [kg/m^2] 333 real, dimension(ngrid,nslope), intent(in) :: co2ice ! CO2 ice at the surface [kg/m^2] 334 real, dimension(ngrid,nsoil_PEM,nslope), intent(inout) :: m_co2_completesoil ! Density of co2 adsorbed (kg/m^3) 335 real, dimension(ngrid), intent(out) :: delta_mreg ! Difference density of co2 adsorbed (kg/m^3) 297 real(dp), dimension(:,:), intent(in) :: ps ! Average surface pressure [Pa] 298 real(dp), dimension(:,:,:), intent(in) :: tsoil ! Mean Soil Temperature [K] 299 real(dp), dimension(:,:,:), intent(in) :: TI ! Mean Thermal Inertia [USI] 300 real(dp), dimension(:,:), intent(in) :: d_h2oice, d_co2ice ! Tendencies on the glaciers () 301 real(dp), dimension(:,:), intent(in) :: q_co2_ts, q_h2o_ts ! Mass mixing ratio of co2 and h2o in the first layer [kg/kg] 302 real(dp), dimension(:,:), intent(in) :: h2oice ! Water ice at the surface [kg/m^2] 303 real(dp), dimension(:,:), intent(in) :: co2ice ! CO2 ice at the surface [kg/m^2] 304 real(dp), dimension(:,:,:), intent(inout) :: co2_ads_reg ! Density of co2 adsorbed [kg/m^3] 305 real(dp), dimension(:), intent(out) :: delta_co2_ads ! Difference density of co2 adsorbed [kg/m^3] 336 306 337 307 ! LOCAL VARIABLES 338 308 ! --------------- 339 309 ! Constants: 340 real :: alpha = 7.512e-6! Zent & Quinn 1995341 real :: beta = -1541.5! Zent & Quinn 1995342 real :: inertie_thresold = 800.! TI > 800 means cementation343 real :: m_theta = 4.27e-7! Mass of co2 per m^2 absorbed344 ! real :: as = 18.9e3! Specific area, Buhler & Piqueux 2021345 real :: as = 9.48e4! Same as previous but from zent346 real :: A, B ! Used to compute the mean mass above the surface347 integer :: ig, islope, iloop, it ! For loops348 real , dimension(ngrid,nsoil_PEM,nslope):: dm_co2_regolith_slope ! Elementary mass adsorded per mesh per slope349 logical , dimension(ngrid,nslope) :: ispermanent_co2glaciers ! Check if the co2 glacier is permanent350 logical , dimension(ngrid,nslope) :: ispermanent_h2oglaciers ! Check if the h2o glacier is permanent351 real , dimension(ngrid,index_breccia,nslope) :: deltam_reg_complete ! Difference in the mass per slope and soil layer (kg/m^3)352 real , dimension(ngrid,nslope) :: deltam_reg_slope ! Difference in the mass per slope (kg/m^3)353 real , dimension(ngrid,nsoil_PEM,nslope) :: m_h2o_adsorbed ! Density of CO2 adsorbed (kg/m^3)354 real , dimension(ngrid,nsoil_PEM,nslope) :: theta_h2o_adsorbed! Fraction of the pores occupied by H2O molecules355 real , dimension(ngrid) :: delta_mh2o ! Difference density of h2o adsorbed (kg/m^3)356 ! timelenarray are allocated because heavy...357 real , dimension(:,:), allocatable :: mass_mean ! Mean mass above the surface358 real , dimension(:,:), allocatable :: zplev_mean ! Pressure above the surface359 real , dimension(:,:), allocatable :: pco2 ! Partial pressure above the surface360 real , dimension(:), allocatable :: pco2_avg ! Yearly averaged310 real(dp) :: alpha = 7.512e-6_dp ! Zent & Quinn 1995 311 real(dp) :: beta = -1541.5_dp ! Zent & Quinn 1995 312 real(dp) :: inertie_thresold = 800._dp ! TI > 800 means cementation 313 real(dp) :: m_theta = 4.27e-7_dp ! Mass of co2 per m^2 absorbed 314 ! real(dp) :: as = 18.9e3_dp ! Specific area, Buhler & Piqueux 2021 315 real(dp) :: as = 9.48e4_dp ! Same as previous but from zent 316 real(dp) :: A, B ! Used to compute the mean mass above the surface 317 integer(di) :: ig, islope, iloop, it ! For loops 318 real(dp), dimension(ngrid,nsoil,nslope) :: dm_co2_regolith_slope ! Elementary mass adsorded per mesh per slope 319 logical(k4), dimension(ngrid,nslope) :: ispermanent_co2glaciers ! Check if the co2 glacier is permanent 320 logical(k4), dimension(ngrid,nslope) :: ispermanent_h2oglaciers ! Check if the h2o glacier is permanent 321 real(dp), dimension(ngrid,index_breccia,nslope) :: deltam_reg_complete ! Difference in the mass per slope and soil layer [kg/m^3] 322 real(dp), dimension(ngrid,nslope) :: deltam_reg_slope ! Difference in the mass per slope [kg/m^3] 323 real(dp), dimension(ngrid,nsoil,nslope) :: m_h2o_adsorbed ! Density of CO2 adsorbed [kg/m^3] 324 real(dp), dimension(ngrid,nsoil,nslope) :: theta_h2o_ads ! Fraction of the pores occupied by H2O molecules 325 real(dp), dimension(ngrid) :: delta_mh2o ! Difference density of h2o adsorbed [kg/m^3] 326 ! nday array are allocated because heavy... 327 real(dp), dimension(:,:), allocatable :: mass_mean ! Mean mass above the surface 328 real(dp), dimension(:,:), allocatable :: zplev_mean ! Pressure above the surface 329 real(dp), dimension(:,:), allocatable :: pco2 ! Partial pressure above the surface 330 real(dp), dimension(:), allocatable :: pco2_avg ! Yearly averaged 361 331 362 332 ! CODE 363 333 ! ---- 364 334 ! 0. Some initializations 365 allocate(mass_mean(ngrid, timelen),zplev_mean(ngrid,timelen),pco2(ngrid,timelen),pco2_avg(ngrid))366 m_h2o_adsorbed = 0. 367 A = 1. /m_co2 - 1./m_noco2368 B = 1. /m_noco2369 dm_co2_regolith_slope = 0. 370 delta_ mreg = 0.335 allocate(mass_mean(ngrid,nday),zplev_mean(ngrid,nday),pco2(ngrid,nday),pco2_avg(ngrid)) 336 m_h2o_adsorbed = 0._dp 337 A = 1._dp/m_co2 - 1._dp/m_noco2 338 B = 1._dp/m_noco2 339 dm_co2_regolith_slope = 0._dp 340 delta_co2_ads = 0._dp 371 341 ispermanent_h2oglaciers = .false. 372 342 ispermanent_co2glaciers = .false. 373 343 374 344 ! 0.1 Look at perennial ice 375 do ig = 1,ngrid 376 do islope = 1,nslope 377 if (abs(d_h2oglaciers(ig,islope)) > 1.e-5 .and. abs(waterice(ig,islope)) > 0.) ispermanent_h2oglaciers(ig,islope) = .true. 378 if (abs(d_co2glaciers(ig,islope)) > 1.e-5 .and. abs(co2ice(ig,islope)) > 0.) ispermanent_co2glaciers(ig,islope) = .true. 379 enddo 380 enddo 345 where (abs(d_h2oice(:,:)) > 1.e-5 .and. h2oice(:,:) > 0._dp) ispermanent_h2oglaciers(:,:) = .true. 346 where (abs(d_co2ice(:,:)) > 1.e-5 .and. co2ice(:,:) > 0._dp) ispermanent_co2glaciers(:,:) = .true. 381 347 382 348 ! 0.2 Compute the partial pressure of CO2 383 349 ! a. the molecular mass into the column 384 350 do ig = 1,ngrid 385 mass_mean(ig,:) = 1. /(A*q_co2(ig,:) + B)386 end do351 mass_mean(ig,:) = 1._dp/(A*q_co2_ts(ig,:) + B) 352 end do 387 353 388 354 ! b. pressure level 389 do it = 1, timelen355 do it = 1,nday 390 356 do ig = 1,ngrid 391 357 zplev_mean(ig,it) = ap(1) + bp(1)*ps(ig,it) 392 end do393 end do358 end do 359 end do 394 360 395 361 ! c. Vapor pressure 396 pco2 = mass_mean/m_co2*q_co2 *zplev_mean397 pco2_avg(:) = sum(pco2(:,:),2)/ timelen362 pco2 = mass_mean/m_co2*q_co2_ts*zplev_mean 363 pco2_avg(:) = sum(pco2(:,:),2)/nday 398 364 399 365 deallocate(zplev_mean,mass_mean,pco2) 400 366 401 367 ! 1. Compute the fraction of the pores occupied by H2O 402 call regolith_h2oadsorption(ngrid,nslope,nsoil_PEM,timelen,d_h2oglaciers,d_co2glaciers,waterice,co2ice,ps,q_co2,q_h2o,tsoil_PEM,TI_PEM, & 403 theta_h2o_adsorbed, m_h2o_adsorbed,delta_mh2o) 368 call evolve_h2o_ads(d_h2oice,d_co2ice,h2oice,co2ice,ps,q_co2_ts,q_h2o_ts,tsoil,TI,theta_h2o_ads,m_h2o_adsorbed,delta_mh2o) 404 369 405 370 ! 2. we compute the mass of co2 adsorded in each layer of the meshes … … 407 372 do islope = 1,nslope 408 373 do iloop = 1,index_breccia 409 if (TI _PEM(ig,iloop,islope) < inertie_thresold .and. .not. ispermanent_h2oglaciers(ig,islope) .and. .not. ispermanent_co2glaciers(ig,islope)) then410 dm_co2_regolith_slope(ig,iloop,islope) = as*rho_regolith*m_theta*(1. - theta_h2o_adsorbed(ig,iloop,islope))*alpha*pco2_avg(ig)/ &411 (alpha*pco2_avg(ig) + sqrt(tsoil _PEM(ig,iloop,islope))*exp(beta/tsoil_PEM(ig,iloop,islope)))374 if (TI(ig,iloop,islope) < inertie_thresold .and. .not. ispermanent_h2oglaciers(ig,islope) .and. .not. ispermanent_co2glaciers(ig,islope)) then 375 dm_co2_regolith_slope(ig,iloop,islope) = as*rho_regolith*m_theta*(1._dp - theta_h2o_ads(ig,iloop,islope))*alpha*pco2_avg(ig)/ & 376 (alpha*pco2_avg(ig) + sqrt(tsoil(ig,iloop,islope))*exp(beta/tsoil(ig,iloop,islope))) 412 377 else 413 if (abs( m_co2_completesoil(ig,iloop,islope)) < 1.e-10) then !!! we are at first call414 dm_co2_regolith_slope(ig,iloop,islope) = as*rho_regolith*m_theta*(1. - theta_h2o_adsorbed(ig,iloop,islope))*alpha*pco2_avg(ig) &415 /(alpha*pco2_avg(ig)+sqrt(tsoil _PEM(ig,iloop,islope))*exp(beta/tsoil_PEM(ig,iloop,islope)))378 if (abs(co2_ads_reg(ig,iloop,islope)) < minieps) then !!! we are at first call 379 dm_co2_regolith_slope(ig,iloop,islope) = as*rho_regolith*m_theta*(1._dp - theta_h2o_ads(ig,iloop,islope))*alpha*pco2_avg(ig) & 380 /(alpha*pco2_avg(ig)+sqrt(tsoil(ig,iloop,islope))*exp(beta/tsoil(ig,iloop,islope))) 416 381 else ! no change: permanent ice stick the atoms of CO2 417 dm_co2_regolith_slope(ig,iloop,islope) = m_co2_completesoil(ig,iloop,islope)418 end if419 end if420 end do421 end do422 end do382 dm_co2_regolith_slope(ig,iloop,islope) = co2_ads_reg(ig,iloop,islope) 383 end if 384 end if 385 end do 386 end do 387 end do 423 388 424 389 ! 3. Check the exchange between the atmosphere and the regolith 425 390 do ig = 1,ngrid 426 delta_ mreg(ig) = 0.391 delta_co2_ads(ig) = 0._dp 427 392 do islope = 1,nslope 428 deltam_reg_slope(ig,islope) = 0. 393 deltam_reg_slope(ig,islope) = 0._dp 429 394 do iloop = 1,index_breccia 430 if (TI _PEM(ig,iloop,islope) < inertie_thresold .and. .not. ispermanent_h2oglaciers(ig,islope) .and. .not. ispermanent_co2glaciers(ig,islope)) then395 if (TI(ig,iloop,islope) < inertie_thresold .and. .not. ispermanent_h2oglaciers(ig,islope) .and. .not. ispermanent_co2glaciers(ig,islope)) then 431 396 if (iloop == 1) then 432 deltam_reg_complete(ig,iloop,islope) = (dm_co2_regolith_slope(ig,iloop,islope) - m_co2_completesoil(ig,iloop,islope))*(layer_PEM(iloop))397 deltam_reg_complete(ig,iloop,islope) = (dm_co2_regolith_slope(ig,iloop,islope) - co2_ads_reg(ig,iloop,islope))*(layer(iloop)) 433 398 else 434 deltam_reg_complete(ig,iloop,islope) = (dm_co2_regolith_slope(ig,iloop,islope) - m_co2_completesoil(ig,iloop,islope))*(layer_PEM(iloop) - layer_PEM(iloop - 1))435 end if399 deltam_reg_complete(ig,iloop,islope) = (dm_co2_regolith_slope(ig,iloop,islope) - co2_ads_reg(ig,iloop,islope))*(layer(iloop) - layer(iloop - 1)) 400 end if 436 401 else ! NO EXCHANGE AS ICE BLOCK THE DYNAMIC! 437 deltam_reg_complete(ig,iloop,islope) = 0. 438 end if402 deltam_reg_complete(ig,iloop,islope) = 0._dp 403 end if 439 404 deltam_reg_slope(ig,islope) = deltam_reg_slope(ig,islope) + deltam_reg_complete(ig,iloop,islope) 440 enddo 441 delta_mreg(ig) = delta_mreg(ig) + deltam_reg_slope(ig,islope)*subslope_dist(ig,islope)/cos(pi*def_slope_mean(islope)/180.) 442 enddo 443 enddo 444 m_co2_completesoil = dm_co2_regolith_slope 445 446 END SUBROUTINE regolith_co2adsorption 405 end do 406 delta_co2_ads(ig) = delta_co2_ads(ig) + deltam_reg_slope(ig,islope)*subslope_dist(ig,islope)/cos(pi*def_slope_mean(islope)/180._dp) 407 end do 408 end do 409 co2_ads_reg = dm_co2_regolith_slope 410 411 END SUBROUTINE evolve_co2_ads 412 !======================================================================= 413 414 !======================================================================= 415 SUBROUTINE compute_totmass_adsorbed(h2o_ads_reg,co2_ads_reg,totmass_adsco2,totmass_adsh2o) 416 !----------------------------------------------------------------------- 417 ! NAME 418 ! compute_totmass_adsorbed 419 ! 420 ! DESCRIPTION 421 ! Compute the total mass of CO2 and H2O adsorbed in the regolith. 422 ! 423 ! AUTHORS & DATE 424 ! L. Lange, 2023 425 ! JB Clement, 12/2025 426 ! C. Metz, 02/2026 427 ! 428 ! NOTES 429 ! 430 !----------------------------------------------------------------------- 431 432 ! DEPENDENCIES 433 ! ------------ 434 use geometry, only: ngrid, nslope, nsoil, cell_area 435 use slopes, only: subslope_dist, def_slope_mean 436 use soil, only: layer 437 use maths, only: pi 438 use display, only: print_msg 439 use utility, only: real2str 440 441 ! DECLARATION 442 ! ----------- 443 implicit none 444 445 ! ARGUMENTS 446 ! --------- 447 real(dp), dimension(:,:,:), intent(in) :: h2o_ads_reg, co2_ads_reg 448 real(qp), intent(out) :: totmass_adsco2, totmass_adsh2o 449 450 ! LOCAL VARIABLES 451 ! --------------- 452 integer(di) :: i, islope, l 453 real(dp) :: thickness, slope_corr 454 455 ! CODE 456 ! ---- 457 totmass_adsco2 = 0._qp 458 totmass_adsh2o = 0._qp 459 do i = 1,ngrid 460 do islope = 1,nslope 461 slope_corr = subslope_dist(i,islope)/cos(pi*def_slope_mean(islope)/180._dp) 462 do l = 1,nsoil 463 if (l == 1) then 464 thickness = layer(l) 465 else 466 thickness = layer(l) - layer(l-1) 467 end if 468 totmass_adsco2 = totmass_adsco2 + co2_ads_reg(i,l,islope)*thickness*slope_corr*cell_area(i) 469 totmass_adsh2o = totmass_adsh2o + h2o_ads_reg(i,l,islope)*thickness*slope_corr*cell_area(i) 470 end do 471 end do 472 end do 473 call print_msg("Total mass of CO2 adsorbed in the regolith [kg] = "//real2str(totmass_adsco2)) 474 call print_msg("Total mass of H2O adsorbed in the regolith [kg] = "//real2str(totmass_adsh2o)) 475 476 END SUBROUTINE compute_totmass_adsorbed 447 477 !======================================================================= 448 478
Note: See TracChangeset
for help on using the changeset viewer.
