source: trunk/LMDZ.COMMON/libf/evolution/pem.F90 @ 3446

Last change on this file since 3446 was 3446, checked in by jbclement, 8 weeks ago

PEM:
Correction of the launching script for a relaunch situation.
JBC

File size: 60.4 KB
Line 
1!------------------------
2! I   Initialization
3!    I_a Read the "run.def"
4!    I_b Read the "start.nc" and "startfi.nc"
5!    I_c Subslope parametrisation
6!    I_d Read the PCM data and convert them to the physical grid
7!    I_e Initialization of the PEM variable and soil
8!    I_f Compute tendencies
9!    I_g Save the initial situation
10!    I_h Read the "startpem.nc"
11!    I_i Compute orbit criterion
12
13! II  Run
14!    II_a Update pressure, ice and tracers
15!    II_b Evolution of ice
16!    II_c Flow of glaciers
17!    II_d Update surface and soil temperatures
18!    II_e Outputs
19!    II_f Update the tendencies
20!    II_g Checking the stopping criterion
21
22! III Output
23!    III_a Update surface value for the PCM start files
24!    III_b Write the "restart.nc" and "restartfi.nc"
25!    III_c Write the "restartpem.nc"
26!------------------------
27
28PROGRAM pem
29
30use phyetat0_mod,               only: phyetat0
31use phyredem,                   only: physdem0, physdem1
32use netcdf,                     only: nf90_open, NF90_NOWRITE, nf90_get_var, nf90_inq_varid, nf90_close
33use turb_mod,                   only: q2, wstar
34use comslope_mod,               only: nslope, def_slope, def_slope_mean, subslope_dist, iflat, ini_comslope_h
35use logic_mod,                  only: iflag_phys
36use mod_const_mpi,              only: COMM_LMDZ
37use infotrac
38use geometry_mod,               only: latitude_deg
39use conf_pem_mod,               only: conf_pem
40use pemredem,                   only: pemdem0, pemdem1
41use glaciers_mod,               only: flow_co2glaciers, flow_h2oglaciers, co2ice_flow, h2oice_flow, inf_h2oice_threshold, &
42                                      metam_h2oice_threshold, metam_co2ice_threshold, metam_h2oice, metam_co2ice
43use stopping_crit_mod,          only: stopping_crit_h2o_ice, stopping_crit_co2
44use constants_marspem_mod,      only: alpha_clap_co2, beta_clap_co2, alpha_clap_h2o, beta_clap_h2o, m_co2, m_noco2
45use evol_ice_mod,               only: evol_co2_ice, evol_h2o_ice
46use comsoil_h_PEM,              only: soil_pem, ini_comsoil_h_PEM, end_comsoil_h_PEM, nsoilmx_PEM, &
47                                      TI_PEM,               & ! soil thermal inertia
48                                      tsoil_PEM, layer_PEM, & ! Soil temp, number of subsurface layers, soil mid layer depths
49                                      fluxgeo                 ! Geothermal flux for the PEM and PCM
50use adsorption_mod,             only: regolith_adsorption, adsorption_pem,        & ! Bool to check if adsorption, main subroutine
51                                      ini_adsorption_h_PEM, end_adsorption_h_PEM, & ! Allocate arrays
52                                      co2_adsorbded_phys, h2o_adsorbded_phys        ! Mass of co2 and h2O adsorbded
53use time_evol_mod,              only: dt_pem, evol_orbit_pem, Max_iter_pem, convert_years, year_bp_ini
54use orbit_param_criterion_mod,  only: orbit_param_criterion
55use recomp_orb_param_mod,       only: recomp_orb_param
56use ice_table_mod,              only: porefillingice_depth, porefillingice_thickness, end_ice_table_porefilling, &
57                                      ini_ice_table_porefilling, icetable_equilibrium, computeice_table_equilibrium,compute_massh2o_exchange_ssi
58use soil_thermalproperties_mod, only: update_soil_thermalproperties
59use time_phylmdz_mod,           only: daysec, dtphys
60use abort_pem_mod,              only: abort_pem
61use soil_settings_PEM_mod,      only: soil_settings_PEM
62use compute_tend_mod,           only: compute_tend
63use info_PEM_mod,               only: info_PEM
64use interpol_TI_PEM2PCM_mod,    only: interpol_TI_PEM2PCM
65use nb_time_step_PCM_mod,       only: nb_time_step_PCM
66use pemetat0_mod,               only: pemetat0
67use read_data_PCM_mod,          only: read_data_PCM
68use recomp_tend_co2_slope_mod,  only: recomp_tend_co2_slope
69use compute_soiltemp_mod,       only: compute_tsoil_pem
70use writediagpem_mod,           only: writediagpem, writediagsoilpem
71use co2condens_mod,             only: CO2cond_ps
72use layering_mod,               only: tend_dust, ptrarray, stratum, layering, ini_layering, del_layering, make_layering, get_nb_str_max, nb_str_max, layering_algo
73
74#ifndef CPP_STD
75    use comsoil_h,          only: tsoil, nsoilmx, ini_comsoil_h, inertiedat, mlayer, inertiesoil, flux_geo, nqsoil, qsoil
76    use surfdat_h,          only: tsurf, emis, qsurf, watercap, ini_surfdat_h, &
77                                  albedodat, zmea, zstd, zsig, zgam, zthe,     &
78                                  albedo_h2o_frost,frost_albedo_threshold,     &
79                                  emissiv, watercaptag, perennial_co2ice, emisice, albedice
80    use dimradmars_mod,     only: totcloudfrac, albedo
81    use dust_param_mod,     only: tauscaling
82    use tracer_mod,         only: noms, igcm_h2o_ice, igcm_co2, mmol, igcm_h2o_vap ! Tracer names and molar masses
83    use mod_phys_lmdz_para, only: is_parallel, is_sequential, is_mpi_root, is_omp_root, is_master
84    use planete_h,          only: aphelie, periheli, year_day, peri_day, obliquit, iniorbit
85    use comcstfi_h,         only: pi, rad, g, mugaz, r
86    use surfini_mod,        only: surfini
87    use comconst_mod,       only: kappa, cpp
88#else
89    use tracer_h,           only: noms, igcm_h2o_ice, igcm_co2 ! Tracer names
90    use phys_state_var_mod, only: cloudfrac, totcloudfrac, albedo_snow_SPECTV,HICE,RNAT,   &
91                                  PCTSRF_SIC, TSLAB, TSEA_ICE, SEA_ICE, ALBEDO_BAREGROUND, &
92                                  ALBEDO_CO2_ICE_SPECTV, phys_state_var_init
93    use aerosol_mod,        only: iniaerosol
94    use planete_mod,        only: apoastr, periastr, year_day, peri_day, obliquit
95    use comcstfi_mod,       only: pi, rad, g, mugaz, r
96#endif
97
98#ifndef CPP_1D
99    use iniphysiq_mod,            only: iniphysiq
100    use control_mod,              only: iphysiq, day_step, nsplit_phys
101#else
102    use time_phylmdz_mod,         only: iphysiq, steps_per_sol
103    use regular_lonlat_mod,       only: init_regular_lonlat
104    use physics_distribution_mod, only: init_physics_distribution
105    use mod_grid_phy_lmdz,        only: regular_lonlat
106    use init_testphys1d_mod,      only: init_testphys1d
107    use comvert_mod,              only: ap, bp
108    use writerestart1D_mod,       only: writerestart1D
109#endif
110
111implicit none
112
113include "dimensions.h"
114include "paramet.h"
115include "comgeom.h"
116include "iniprint.h"
117include "callkeys.h"
118
119integer ngridmx
120parameter(ngridmx = 2 + (jjm - 1)*iim - 1/jjm)
121
122! Same variable names as in the PCM
123integer, parameter :: nlayer = llm ! Number of vertical layer
124integer            :: ngrid        ! Number of physical grid points
125integer            :: nq           ! Number of tracer
126integer            :: day_ini      ! First day of the simulation
127real               :: pday         ! Physical day
128real               :: time_phys    ! Same as in PCM
129real               :: ptimestep    ! Same as in PCM
130real               :: ztime_fin     ! Same as in PCM
131
132! Variables to read start.nc
133character(*), parameter :: start_name = "start.nc" ! Name of the file used to initialize the PEM
134
135! Dynamic variables
136real, dimension(ip1jm,llm)          :: vcov          ! vents covariants
137real, dimension(ip1jmp1,llm)        :: ucov          ! vents covariants
138real, dimension(ip1jmp1,llm)        :: teta          ! temperature potentielle
139real, dimension(:,:,:), allocatable :: q             ! champs advectes
140real, dimension(ip1jmp1)            :: ps            ! pression au sol
141real, dimension(ip1jmp1)            :: ps0           ! pression au sol initiale
142real, dimension(:),     allocatable :: ps_start_PCM  ! (ngrid) surface pressure
143real, dimension(:,:),   allocatable :: ps_timeseries ! (ngrid x timelen) instantaneous surface pressure
144real, dimension(ip1jmp1,llm)        :: masse         ! masse d'air
145real, dimension(ip1jmp1)            :: phis          ! geopotentiel au sol
146real                                :: time_0
147
148! Variables to read starfi.nc
149character(*), parameter :: startfi_name = "startfi.nc" ! Name of the file used to initialize the PEM
150character(2)            :: str2
151integer                 :: ncid, status                           ! Variable for handling opening of files
152integer                 :: lonvarid, latvarid, areavarid, sdvarid ! Variable ID for Netcdf files
153integer                 :: apvarid, bpvarid                       ! Variable ID for Netcdf files
154
155! Variables to read starfi.nc and write restartfi.nc
156real, dimension(:), allocatable :: longitude     ! Longitude read in startfi_name and written in restartfi
157real, dimension(:), allocatable :: latitude      ! Latitude read in startfi_name and written in restartfi
158real, dimension(:), allocatable :: cell_area     ! Cell_area read in startfi_name and written in restartfi
159real                            :: Total_surface ! Total surface of the planet
160
161! Variables for h2o_ice evolution
162real, dimension(:,:),    allocatable  :: h2o_ice              ! h2o ice in the PEM
163real, dimension(:,:,:),  allocatable  :: min_h2o_ice          ! Minima of h2o ice at each point for the PCM years [kg/m^2]
164real                                  :: h2oice_ini_surf      ! Initial surface of sublimating h2o ice
165logical, dimension(:,:), allocatable  :: ini_h2oice_sublim    ! Logical array to know if h2o ice is sublimating
166real                                  :: global_avg_press_PCM ! constant: global average pressure retrieved in the PCM [Pa]
167real                                  :: global_avg_press_old ! constant: Global average pressure of initial/previous time step
168real                                  :: global_avg_press_new ! constant: Global average pressure of current time step
169real,   dimension(:,:),   allocatable :: zplev_new            ! Physical x Atmospheric field: mass of the atmospheric  layers in the pem at current time step [kg/m^2]
170real,   dimension(:,:),   allocatable :: zplev_PCM            ! same but retrieved from the PCM [kg/m^2]
171real,   dimension(:,:,:), allocatable :: zplev_new_timeseries ! Physical x Atmospheric x Time: same as zplev_new, but in times series [kg/m ^2]
172real,   dimension(:,:,:), allocatable :: zplev_old_timeseries ! same but with the time series, for oldest time step
173integer                               :: stopPEM              ! which criterion is reached? 0 = no stopping; 1 = h2o ice surf; 2 = no h2o ice; 3 = co2 ice surf; 4 = ps; 5 = orb param; 6 = end of simu
174real, save                            :: A, B, mmean          ! Molar mass: intermediate A, B for computations of the  mean molar mass of the layer [mol/kg]
175real,   dimension(:,:),   allocatable :: q_h2o_PEM_phys       ! Physics x Times: h2o mass mixing ratio computed in the PEM, first value comes from PCM [kg/kg]
176integer                               :: timelen              ! # time samples
177real                                  :: ave                  ! intermediate varibale to compute average
178real,   dimension(:,:),   allocatable :: p                    ! Physics x Atmosphere: pressure to recompute and write in restart (ngrid,llmp1)
179real                                  :: extra_mass           ! Intermediate variables Extra mass of a tracer if it is greater than 1
180
181! Variables for co2_ice evolution
182real,    dimension(:,:), allocatable :: co2_ice           ! co2 ice in the PEM
183logical, dimension(:,:), allocatable :: is_co2ice_ini     ! Was there co2 ice initially in the PEM?
184real,  dimension(:,:,:), allocatable :: min_co2_ice       ! Minimum of co2 ice at each point for the first year [kg/m^2]
185real                                 :: co2ice_ini_surf   ! Initial surface of sublimating co2 ice
186logical, dimension(:,:), allocatable :: ini_co2ice_sublim ! Logical array to know if co2 ice is sublimating
187real,    dimension(:,:), allocatable :: vmr_co2_PCM       ! Physics x Times co2 volume mixing ratio retrieve from the PCM [m^3/m^3]
188real,    dimension(:,:), allocatable :: vmr_co2_PEM_phys  ! Physics x Times co2 volume mixing ratio used in the PEM
189real,    dimension(:,:), allocatable :: q_co2_PEM_phys    ! Physics x Times co2 mass mixing ratio in the first layer computed in the PEM, first value comes from PCM [kg/kg]
190
191! Variables for stratification (layering) evolution
192type(layering), dimension(:,:), allocatable :: stratif                     ! Layering (linked list of "stratum") for each grid point and slope
193type(ptrarray), dimension(:,:), allocatable :: current1, current2          ! Current active stratum in the layering
194logical,        dimension(:,:), allocatable :: new_str, new_lag1, new_lag2 ! Flags for the layering algorithm
195
196! Variables for slopes
197real, dimension(:,:),   allocatable :: tend_co2_ice       ! physical point x slope field: Tendency of evolution of perennial co2 ice over a year
198real, dimension(:,:),   allocatable :: tend_co2_ice_ini   ! physical point x slope field: Tendency of evolution of perennial co2 ice over a year in the PCM
199real, dimension(:,:),   allocatable :: tend_h2o_ice       ! physical point x slope field: Tendency of evolution of perennial h2o ice
200real, dimension(:,:),   allocatable :: flag_co2flow       ! (ngrid,nslope): Flag where there is a CO2 glacier flow
201real, dimension(:),     allocatable :: flag_co2flow_mesh  ! (ngrid)       : Flag where there is a CO2 glacier flow
202real, dimension(:,:),   allocatable :: flag_h2oflow       ! (ngrid,nslope): Flag where there is a H2O glacier flow
203real, dimension(:),     allocatable :: flag_h2oflow_mesh  ! (ngrid)       : Flag where there is a H2O glacier flow
204
205! Variables for surface and soil
206real, dimension(:,:),     allocatable :: tsurf_avg                          ! Physic x SLOPE field: Averaged Surface Temperature [K]
207real, dimension(:,:,:),   allocatable :: tsoil_avg                          ! Physic x SOIL x SLOPE field: Averaged Soil Temperature [K]
208real, dimension(:,:,:),   allocatable :: tsurf_PCM_timeseries               ! ngrid x SLOPE x TIMES field: Surface Temperature in timeseries [K]
209real, dimension(:,:,:,:), allocatable :: tsoil_phys_PEM_timeseries          ! IG x SOIL x SLOPE x TIMES field: Non averaged Soil Temperature [K]
210real, dimension(:,:,:,:), allocatable :: tsoil_anom                         ! IG x SOIL x SLOPE x TIMES field: Amplitude between instataneous and yearly average soil temperature at the beginning [K]
211real, dimension(:,:),     allocatable :: tsurf_avg_yr1                      ! Physic x SLOPE field: Averaged Surface Temperature of first call of the PCM [K]
212real, dimension(:,:),     allocatable :: Tsoil_locslope                     ! Physic x Soil: Intermediate when computing Tsoil [K]
213real, dimension(:),       allocatable :: Tsurf_locslope                     ! Physic x Soil: Intermediate surface temperature to compute Tsoil [K]
214real, dimension(:,:,:,:), allocatable :: watersoil_density_timeseries       ! Physic x Soil x Slope x Times water soil density, time series [kg /m^3]
215real, dimension(:,:),     allocatable :: watersurf_density_avg              ! Physic x Slope, water surface density, yearly averaged [kg/m^3]
216real, dimension(:,:,:,:), allocatable :: watersoil_density_PEM_timeseries   ! Physic x Soil x Slope x Times, water soil density, time series [kg/m^3]
217real, dimension(:,:,:),   allocatable :: watersoil_density_PEM_avg          ! Physic x Soil x Slopes, water soil density, yearly averaged [kg/m^3]
218real, dimension(:,:),     allocatable :: Tsurfavg_before_saved              ! Surface temperature saved from previous time step [K]
219real, dimension(:),       allocatable :: delta_co2_adsorbded                ! Physics: quantity of CO2 that is exchanged because of adsorption / desorption [kg/m^2]
220real, dimension(:),       allocatable :: delta_h2o_adsorbded                ! Physics: quantity of H2O that is exchanged because of adsorption / desorption [kg/m^2]
221real                                  :: totmassco2_adsorbded               ! Total mass of CO2 that is exchanged because of adsorption / desoprtion over the planets [kg]
222real                                  :: totmassh2o_adsorbded               ! Total mass of H2O that is exchanged because of adsorption / desoprtion over the planets [kg]
223logical                               :: bool_sublim                        ! logical to check if there is sublimation or not
224logical, dimension(:,:),  allocatable :: co2ice_disappeared                 ! logical to check if a co2 ice reservoir already disappeared at a previous timestep
225real, dimension(:,:),     allocatable :: porefillingice_thickness_prev_iter ! ngrid x nslope: Thickness of the ice table at the previous iteration [m]
226real, dimension(:),       allocatable :: delta_h2o_icetablesublim           ! ngrid x Total mass of the H2O that has sublimated / condenses from the ice table [kg]
227
228! Some variables for the PEM run
229real, parameter :: year_step = 1   ! Timestep for the pem
230integer         :: year_iter       ! Number of iteration
231integer         :: year_iter_max   ! Maximum number of iterations before stopping
232integer         :: i_myear         ! Global number of Martian years of the chained simulations
233integer         :: n_myear         ! Maximum number of Martian years of the chained simulations
234real            :: timestep        ! Timestep [s]
235character(20)   :: job_id          ! Job id provided as argument passed on the command line when the program was invoked
236logical         :: timewall        ! Flag to use the time limit stopping criterion in case of a PEM job
237integer(kind=8) :: cr              ! Number of clock ticks per second (count rate)
238integer(kind=8) :: c1, c2          ! Counts of processor clock
239character(100)  :: chtimelimit     ! Time limit for the PEM job outputted by the SLURM command
240real            :: timelimit       ! Time limit for the PEM job in seconds
241real, parameter :: antetime = 1200 ! Anticipation time to prevent reaching the time limit: 1200 s = 20 min by default
242integer         :: cstat, days, hours, minutes, seconds
243character(1)    :: sep
244
245#ifdef CPP_STD
246    real                                :: frost_albedo_threshold = 0.05 ! frost albedo threeshold to convert fresh frost to old ice
247    real                                :: albedo_h2o_frost              ! albedo of h2o frost
248    real, dimension(:),     allocatable :: tsurf_read_generic            ! Temporary variable to do the subslope transfert dimension when reading form generic
249    real, dimension(:,:),   allocatable :: qsurf_read_generic            ! Temporary variable to do the subslope transfert dimension when reading form generic
250    real, dimension(:,:),   allocatable :: tsoil_read_generic            ! Temporary variable to do the subslope transfert dimension when reading form generic
251    real, dimension(:),     allocatable :: emis_read_generic             ! Temporary variable to do the subslope transfert dimension when reading form generic
252    real, dimension(:,:),   allocatable :: albedo_read_generic           ! Temporary variable to do the subslope transfert dimension when reading form generic
253    real, dimension(:,:),   allocatable :: tsurf                         ! Subslope variable, only needed in the GENERIC case
254    real, dimension(:,:,:), allocatable :: qsurf                         ! Subslope variable, only needed in the GENERIC case
255    real, dimension(:,:,:), allocatable :: tsoil                         ! Subslope variable, only needed in the GENERIC case
256    real, dimension(:,:),   allocatable :: emis                          ! Subslope variable, only needed in the GENERIC case
257    real, dimension(:,:),   allocatable :: watercap                      ! Subslope variable, only needed in the GENERIC case =0 no watercap in generic model
258    logical, dimension(:),  allocatable :: watercaptag                   ! Subslope variable, only needed in the GENERIC case =false no watercaptag in generic model
259    real, dimension(:,:,:), allocatable :: albedo                        ! Subslope variable, only needed in the GENERIC case
260    real, dimension(:,:,:), allocatable :: inertiesoil                   ! Subslope variable, only needed in the GENERIC case
261#endif
262
263#ifdef CPP_1D
264    integer            :: nsplit_phys
265    integer, parameter :: jjm_value = jjm - 1
266    integer            :: day_step
267
268    ! Dummy variables to use the subroutine 'init_testphys1d'
269    logical                             :: therestart1D, therestartfi
270    integer                             :: ndt, day0
271    real                                :: ptif, pks, day, gru, grv, atm_wat_profile, atm_wat_tau
272    real, dimension(:),     allocatable :: zqsat
273    real, dimension(:,:,:), allocatable :: dq, dqdyn
274    real, dimension(nlayer)             :: play, w
275    real, dimension(nlayer + 1)         :: plev
276#else
277    integer, parameter              :: jjm_value = jjm
278    real, dimension(:), allocatable :: ap ! Coefficient ap read in start_name and written in restart
279    real, dimension(:), allocatable :: bp ! Coefficient bp read in start_name and written in restart
280#endif
281
282! Loop variables
283integer :: i, l, ig, nnq, t, islope, ig_loop, islope_loop, isoil, icap
284
285! Elapsed time with system clock
286call system_clock(count_rate = cr)
287call system_clock(c1)
288timewall = .true.
289timelimit = 86400 ! 86400 seconds = 24 h by default
290if (command_argument_count() > 0) then
291    ! Read the job id passed as argument to the program
292    call get_command_argument(1,job_id)
293    ! Execute the system command
294    call execute_command_line('squeue -j '//trim(job_id)//' -h --Format TimeLimit > tmp_cmdout.txt',cmdstat = cstat)
295    if (cstat /= 0) then
296        call execute_command_line('qstat -f '//trim(job_id)//' | grep "Walltime" | awk ''{print $3}'' > tmp_cmdout.txt', cmdstat = cstat)
297        if (cstat > 0) then
298            error stop 'pem: command execution failed!'
299        else if (cstat < 0) then
300            error stop 'pem: command execution not supported (neither SLURM nor PBS/TORQUE is installed)!'
301        endif
302    endif
303    ! Read the output
304    open(1,file = 'tmp_cmdout.txt',status = 'old')
305    read(1,'(a)') chtimelimit
306    close(1)
307    chtimelimit = trim(chtimelimit)
308    call execute_command_line('rm tmp_cmdout.txt',cmdstat = cstat)
309    if (cstat > 0) then
310        error stop 'pem: command execution failed!'
311    else if (cstat < 0) then
312        error stop 'pem: command execution not supported!'
313    endif
314    if (index(chtimelimit,'-') > 0) then ! 'chtimelimit' format is "D-HH:MM:SS"
315        read(chtimelimit,'(i1,a1,i2,a1,i2,a1,i2)') days, sep, hours, sep, minutes, sep, seconds
316        timelimit = days*86400 + hours*3600 + minutes*60 + seconds
317    else if (index(chtimelimit,':') > 0 .and. len_trim(chtimelimit) > 5) then ! 'chtimelimit' format is "HH:MM:SS"
318        read(chtimelimit,'(i2,a1,i2,a1,i2)') hours, sep, minutes, sep, seconds
319        timelimit = hours*3600 + minutes*60 + seconds
320    else ! 'chtimelimit' format is "MM:SS"
321        read(chtimelimit,'(i2,a1,i2)') minutes, sep, seconds
322        timelimit = minutes*60 + seconds
323    endif
324else
325    timewall = .false.
326endif
327
328! Parallel variables
329#ifndef CPP_STD
330    is_sequential = .true.
331    is_parallel = .false.
332    is_mpi_root = .true.
333    is_omp_root = .true.
334    is_master = .true.
335#endif
336
337! Some constants
338day_ini = 0    ! test
339time_phys = 0. ! test
340ngrid = ngridmx
341A = (1/m_co2 - 1/m_noco2)
342B = 1/m_noco2
343year_day = 669
344daysec = 88775.
345timestep = year_day*daysec*year_step
346
347!----------------------------- INITIALIZATION --------------------------
348!------------------------
349! I   Initialization
350!    I_a Read the "run.def"
351!------------------------
352#ifndef CPP_1D
353    dtphys = daysec/48. ! Dummy value (overwritten in phyetat0)
354    call conf_gcm(99,.true.)
355    call infotrac_init
356    nq = nqtot
357    allocate(q(ip1jmp1,llm,nqtot))
358    allocate(longitude(ngrid),latitude(ngrid),cell_area(ngrid))
359#else
360    allocate(q(1,llm,nqtot))
361    allocate(longitude(1),latitude(1),cell_area(1))
362
363    therestart1D = .false. ! Default value
364    inquire(file = 'start1D.txt',exist = therestart1D)
365    if (.not. therestart1D) then
366        write(*,*) 'There is no "start1D.txt" file!'
367        error stop 'Initialization cannot be done for the 1D PEM.'
368    endif
369    therestartfi = .false. ! Default value
370    inquire(file = 'startfi.nc',exist = therestartfi)
371    if (.not. therestartfi) then
372        write(*,*) 'There is no "startfi.nc" file!'
373        error stop 'Initialization cannot be done for the 1D PEM.'
374    endif
375
376    call init_testphys1d('start1D.txt','startfi.nc',therestart1D,therestartfi,ngrid,nlayer,610.,nq,q,        &
377                         time_0,ps(1),ucov,vcov,teta,ndt,ptif,pks,dtphys,zqsat,dq,dqdyn,day0,day,gru,grv,w,  &
378                         play,plev,latitude,longitude,cell_area,atm_wat_profile,atm_wat_tau)
379    ps(2) = ps(1)
380    nsplit_phys = 1
381    day_step = steps_per_sol
382#endif
383
384call conf_pem(i_myear,n_myear)
385
386!------------------------
387! I   Initialization
388!    I_b Read of the "start.nc" and starfi_evol.nc
389!------------------------
390! I_b.1 Read "start.nc"
391allocate(ps_start_PCM(ngrid))
392#ifndef CPP_1D
393    call dynetat0(start_name,vcov,ucov,teta,q,masse,ps,phis,time_0)
394
395    call gr_dyn_fi(1,iip1,jjp1,ngridmx,ps,ps_start_PCM)
396
397    call iniconst !new
398    call inigeom
399
400    allocate(ap(nlayer + 1))
401    allocate(bp(nlayer + 1))
402    status = nf90_open(start_name,NF90_NOWRITE,ncid)
403    status = nf90_inq_varid(ncid,"ap",apvarid)
404    status = nf90_get_var(ncid,apvarid,ap)
405    status = nf90_inq_varid(ncid,"bp",bpvarid)
406    status = nf90_get_var(ncid,bpvarid,bp)
407    status = nf90_close(ncid)
408
409    call iniphysiq(iim,jjm,llm,(jjm-1)*iim+2,comm_lmdz,daysec,day_ini,dtphys/nsplit_phys,rlatu,rlatv,rlonu,rlonv,aire,cu,cv,rad,g,r,cpp,iflag_phys)
410#else
411    ps_start_PCM(1) = ps(1)
412#endif
413
414! Save initial surface pressure
415ps0 = ps
416
417! In the PCM, these values are given to the physic by the dynamic.
418! Here we simply read them in the "startfi.nc" file
419status = nf90_open(startfi_name, NF90_NOWRITE, ncid)
420
421status = nf90_inq_varid(ncid,"longitude",lonvarid)
422status = nf90_get_var(ncid,lonvarid,longitude)
423
424status = nf90_inq_varid(ncid,"latitude",latvarid)
425status = nf90_get_var(ncid,latvarid,latitude)
426
427status = nf90_inq_varid(ncid,"area",areavarid)
428status = nf90_get_var(ncid,areavarid,cell_area)
429
430status = nf90_inq_varid(ncid,"soildepth",sdvarid)
431status = nf90_get_var(ncid,sdvarid,mlayer)
432
433status = nf90_close(ncid)
434
435! I_b.2 Read the "startfi.nc"
436! First we read the initial state (starfi.nc)
437#ifndef CPP_STD
438    call phyetat0(startfi_name,0,0,nsoilmx,ngrid,nlayer,nq,nqsoil,day_ini,time_phys,tsurf, &
439                  tsoil,albedo,emis,q2,qsurf,qsoil,tauscaling,totcloudfrac,wstar,          &
440                  watercap,perennial_co2ice,def_slope,def_slope_mean,subslope_dist)
441
442    ! Remove unphysical values of surface tracer
443    where (qsurf < 0.) qsurf = 0.
444
445    call surfini(ngrid,nslope,qsurf)
446#else
447    call phys_state_var_init(nq)
448    if (.not. allocated(noms)) allocate(noms(nq)) ! (because noms is an argument of physdem1 whether or not tracer is on)
449    call initracer(ngrid,nq)
450    call iniaerosol()
451    allocate(tsurf_read_generic(ngrid))
452    allocate(qsurf_read_generic(ngrid,nq))
453    allocate(tsoil_read_generic(ngrid,nsoilmx))
454    allocate(qsoil_read_generic(ngrid,nsoilmx,nqsoil,nslope))
455    allocate(emis_read_generic(ngrid))
456    allocate(tsurf(ngrid,1))
457    allocate(qsurf(ngrid,nq,1))
458    allocate(tsoil(ngrid,nsoilmx,1))
459    allocate(emis(ngrid,1))
460    allocate(watercap(ngrid,1))
461    allocate(watercaptag(ngrid))
462    allocate(albedo_read_generic(ngrid,2))
463    allocate(albedo(ngrid,2,1))
464    allocate(inertiesoil(ngrid,nsoilmx,1))
465    call phyetat0(.true.,ngrid,nlayer,startfi_name,0,0,nsoilmx,nq,nqsoil,day_ini,time_phys, &
466                  tsurf_read_generic,tsoil_read_generic,emis_read_generic,q2,               &
467                  qsurf_read_generic,qsoil_read_generic,cloudfrac,totcloudfrac,hice,        &
468                  rnat,pctsrf_sic,tslab,tsea_ice,sea_ice)
469    call surfini(ngrid,nq,qsurf_read_generic,albedo_read_generic,albedo_bareground,albedo_snow_SPECTV,albedo_co2_ice_SPECTV)
470
471    nslope = 1
472    call ini_comslope_h(ngrid,1)
473
474    qsurf(:,:,1) = qsurf_read_generic
475    tsurf(:,1) = tsurf_read_generic
476    tsoil(:,:,1) = tsoil_read_generic
477    emis(:,1) = emis_read_generic
478    watercap(:,1) = 0.
479    watercaptag(:) = .false.
480    albedo(:,1,1) = albedo_read_generic(:,1)
481    albedo(:,2,1) = albedo_read_generic(:,2)
482    inertiesoil(:,:,1) = inertiedat
483
484    if (nslope == 1) then
485        def_slope(1) = 0
486        def_slope(2) = 0
487        def_slope_mean = 0
488        subslope_dist(:,1) = 1.
489    endif
490
491    ! Remove unphysical values of surface tracer
492    qsurf(:,:,1) = qsurf_read_generic
493    where (qsurf < 0.) qsurf = 0.
494#endif
495
496do nnq = 1,nqtot  ! Why not using ini_tracer ?
497    if (noms(nnq) == "h2o_ice") igcm_h2o_ice = nnq
498    if (noms(nnq) == "h2o_vap") then
499        igcm_h2o_vap = nnq
500        mmol(igcm_h2o_vap) = 18.
501    endif
502    if (noms(nnq) == "co2") igcm_co2 = nnq
503enddo
504r = 8.314511*1000./mugaz
505
506!------------------------
507! I   Initialization
508!    I_c Subslope parametrisation
509!------------------------
510! Define some slope statistics
511iflat = 1
512do islope = 2,nslope
513    if (abs(def_slope_mean(islope)) < abs(def_slope_mean(iflat))) iflat = islope
514enddo
515
516write(*,*) 'Flat slope for islope = ',iflat
517write(*,*) 'corresponding criterium = ',def_slope_mean(iflat)
518
519allocate(flag_co2flow(ngrid,nslope))
520allocate(flag_co2flow_mesh(ngrid))
521allocate(flag_h2oflow(ngrid,nslope))
522allocate(flag_h2oflow_mesh(ngrid))
523
524flag_co2flow = 0
525flag_co2flow_mesh = 0
526flag_h2oflow = 0
527flag_h2oflow_mesh = 0
528
529!------------------------
530! I   Initialization
531!    I_d Read the PCM data and convert them to the physical grid
532!------------------------
533! First we read the evolution of water and co2 ice (and the mass mixing ratio) over the first year of the PCM run, saving only the minimum value
534call nb_time_step_PCM("data_PCM_Y1.nc",timelen)
535
536allocate(tsoil_avg(ngrid,nsoilmx,nslope))
537allocate(watersoil_density_PEM_avg(ngrid,nsoilmx_PEM,nslope))
538allocate(vmr_co2_PCM(ngrid,timelen))
539allocate(ps_timeseries(ngrid,timelen))
540allocate(min_co2_ice(ngrid,nslope,2))
541allocate(min_h2o_ice(ngrid,nslope,2))
542allocate(tsurf_avg_yr1(ngrid,nslope))
543allocate(tsurf_avg(ngrid,nslope))
544allocate(tsurf_PCM_timeseries(ngrid,nslope,timelen))
545allocate(tsoil_anom(ngrid,nsoilmx,nslope,timelen))
546allocate(q_co2_PEM_phys(ngrid,timelen))
547allocate(q_h2o_PEM_phys(ngrid,timelen))
548allocate(watersurf_density_avg(ngrid,nslope))
549allocate(watersoil_density_timeseries(ngrid,nsoilmx,nslope,timelen))
550allocate(Tsurfavg_before_saved(ngrid,nslope))
551allocate(tsoil_phys_PEM_timeseries(ngrid,nsoilmx_PEM,nslope,timelen))
552allocate(watersoil_density_PEM_timeseries(ngrid,nsoilmx_PEM,nslope,timelen))
553allocate(delta_co2_adsorbded(ngrid))
554allocate(co2ice_disappeared(ngrid,nslope))
555allocate(porefillingice_thickness_prev_iter(ngrid,nslope))
556allocate(delta_h2o_icetablesublim(ngrid))
557allocate(delta_h2o_adsorbded(ngrid))
558allocate(vmr_co2_PEM_phys(ngrid,timelen))
559
560write(*,*) "Downloading data Y1..."
561call read_data_PCM("data_PCM_Y1.nc",timelen,iim,jjm_value,ngrid,nslope,vmr_co2_PCM,ps_timeseries,min_co2_ice(:,:,1),min_h2o_ice(:,:,1), &
562                   tsurf_avg_yr1,tsoil_avg,tsurf_PCM_timeseries,tsoil_anom,q_co2_PEM_phys,q_h2o_PEM_phys,                     &
563                   watersurf_density_avg,watersoil_density_timeseries)
564write(*,*) "Downloading data Y1 done!"
565
566! Then we read the evolution of water and co2 ice (and the mass mixing ratio) over the second year of the PCM run, saving only the minimum value
567write(*,*) "Downloading data Y2..."
568call read_data_PCM("data_PCM_Y2.nc",timelen,iim,jjm_value,ngrid,nslope,vmr_co2_PCM,ps_timeseries,min_co2_ice(:,:,2),min_h2o_ice(:,:,2), &
569                   tsurf_avg,tsoil_avg,tsurf_PCM_timeseries,tsoil_anom,q_co2_PEM_phys,q_h2o_PEM_phys,                         &
570                   watersurf_density_avg,watersoil_density_timeseries)
571write(*,*) "Downloading data Y2 done!"
572
573!------------------------
574! I   Initialization
575!    I_e Initialization of the PEM variables and soil
576!------------------------
577call end_comsoil_h_PEM
578call ini_comsoil_h_PEM(ngrid,nslope)
579call end_adsorption_h_PEM
580call ini_adsorption_h_PEM(ngrid,nslope,nsoilmx_PEM)
581call end_ice_table_porefilling
582call ini_ice_table_porefilling(ngrid,nslope)
583
584if (soil_pem) then
585    do t = 1,timelen
586        tsoil_anom(:,:,:,t) = tsoil_anom(:,:,:,t) - tsoil_avg ! compute anomaly between Tsoil(t) in the startfi - <Tsoil> to recompute properly tsoil in the restart
587    enddo
588    call soil_settings_PEM(ngrid,nslope,nsoilmx_PEM,nsoilmx,inertiesoil,TI_PEM)
589    tsoil_PEM(:,1:nsoilmx,:) = tsoil_avg
590    tsoil_phys_PEM_timeseries(:,1:nsoilmx,:,:) = tsoil_anom
591    watersoil_density_PEM_timeseries(:,1:nsoilmx,:,:) = watersoil_density_timeseries
592    do l = nsoilmx + 1,nsoilmx_PEM
593        tsoil_PEM(:,l,:) = tsoil_avg(:,nsoilmx,:)
594        watersoil_density_PEM_timeseries(:,l,:,:) = watersoil_density_timeseries(:,nsoilmx,:,:)
595    enddo
596    watersoil_density_PEM_avg = sum(watersoil_density_PEM_timeseries,4)/timelen
597endif !soil_pem
598deallocate(tsoil_avg)
599
600!------------------------
601! I   Initialization
602!    I_f Compute tendencies
603!------------------------
604allocate(tend_co2_ice(ngrid,nslope),tend_h2o_ice(ngrid,nslope))
605allocate(tend_co2_ice_ini(ngrid,nslope))
606
607! Compute the tendencies of the evolution of ice over the years
608call compute_tend(ngrid,nslope,min_co2_ice,tend_co2_ice)
609call compute_tend(ngrid,nslope,min_h2o_ice,tend_h2o_ice)
610tend_co2_ice_ini = tend_co2_ice
611deallocate(min_co2_ice,min_h2o_ice)
612
613!------------------------
614! I   Initialization
615!    I_g Save the initial situation
616!------------------------
617allocate(zplev_PCM(ngrid,nlayer + 1))
618Total_surface = 0.
619do ig = 1,ngrid
620    Total_surface = Total_surface + cell_area(ig)
621    zplev_PCM(ig,:) = ap + bp*ps_start_PCM(ig)
622enddo
623global_avg_press_old = sum(cell_area*ps_start_PCM)/Total_surface
624global_avg_press_PCM = global_avg_press_old
625global_avg_press_new = global_avg_press_old
626write(*,*) "Total surface of the planet =", Total_surface
627write(*,*) "Initial global average pressure =", global_avg_press_PCM
628
629!------------------------
630! I   Initialization
631!    I_h Read the "startpem.nc"
632!------------------------
633allocate(co2_ice(ngrid,nslope),h2o_ice(ngrid,nslope))
634
635allocate(stratif(ngrid,nslope))
636if (layering_algo) then
637    do islope = 1,nslope
638        do i = 1,ngrid
639            call ini_layering(stratif(i,islope))
640        enddo
641    enddo
642endif
643
644call pemetat0("startpem.nc",ngrid,nsoilmx,nsoilmx_PEM,nslope,timelen,timestep,TI_PEM,tsoil_PEM,porefillingice_depth, &
645              porefillingice_thickness,tsurf_avg_yr1,tsurf_avg,q_co2_PEM_phys,q_h2o_PEM_phys,ps_timeseries,          &
646              tsoil_phys_PEM_timeseries,tend_h2o_ice,tend_co2_ice,co2_ice,h2o_ice,global_avg_press_PCM,              &
647              watersurf_density_avg,watersoil_density_PEM_avg,co2_adsorbded_phys,delta_co2_adsorbded,                &
648              h2o_adsorbded_phys,delta_h2o_adsorbded,stratif)
649
650! We save the places where h2o ice is sublimating
651! We compute the surface of h2o ice sublimating
652allocate(ini_co2ice_sublim(ngrid,nslope),ini_h2oice_sublim(ngrid,nslope),is_co2ice_ini(ngrid,nslope))
653co2ice_ini_surf = 0.
654h2oice_ini_surf = 0.
655ini_co2ice_sublim = .false.
656ini_h2oice_sublim = .false.
657is_co2ice_ini = .false.
658co2ice_disappeared = .false.
659do i = 1,ngrid
660    do islope = 1,nslope
661        if (co2_ice(i,islope) > 0.) is_co2ice_ini(i,islope) = .true.
662        if (tend_co2_ice(i,islope) < 0. .and. co2_ice(i,islope) > 0.) then
663            ini_co2ice_sublim(i,islope) = .true.
664            co2ice_ini_surf = co2ice_ini_surf + cell_area(i)*subslope_dist(i,islope)
665        endif
666        if (tend_h2o_ice(i,islope) < 0. .and. h2o_ice(i,islope) > 0.) then
667            ini_h2oice_sublim(i,islope) = .true.
668            h2oice_ini_surf = h2oice_ini_surf + cell_area(i)*subslope_dist(i,islope)
669        endif
670    enddo
671enddo
672write(*,*) "Total initial surface of co2 ice sublimating (slope) =", co2ice_ini_surf
673write(*,*) "Total initial surface of h2o ice sublimating (slope) =", h2oice_ini_surf
674
675delta_h2o_icetablesublim = 0.
676
677if (adsorption_pem) then
678    totmassco2_adsorbded = 0.
679    totmassh2o_adsorbded = 0.
680    do ig = 1,ngrid
681        do islope = 1,nslope
682            do l = 1,nsoilmx_PEM - 1
683                if (l==1) then
684                   totmassco2_adsorbded = totmassco2_adsorbded + co2_adsorbded_phys(ig,l,islope)*(layer_PEM(l))* &
685                                       subslope_dist(ig,islope)/cos(pi*def_slope_mean(islope)/180.)*cell_area(ig)
686                   totmassh2o_adsorbded = totmassh2o_adsorbded + h2o_adsorbded_phys(ig,l,islope)*(layer_PEM(l))* &
687                                       subslope_dist(ig,islope)/cos(pi*def_slope_mean(islope)/180.)*cell_area(ig)
688                else
689                   totmassco2_adsorbded = totmassco2_adsorbded + co2_adsorbded_phys(ig,l,islope)*(layer_PEM(l) - layer_PEM(l-1))* &
690                                       subslope_dist(ig,islope)/cos(pi*def_slope_mean(islope)/180.)*cell_area(ig)
691                   totmassh2o_adsorbded = totmassh2o_adsorbded + h2o_adsorbded_phys(ig,l,islope)*(layer_PEM(l) - layer_PEM(l-1))* &
692                                       subslope_dist(ig,islope)/cos(pi*def_slope_mean(islope)/180.)*cell_area(ig)
693                endif
694            enddo
695        enddo
696    enddo
697    write(*,*) "Tot mass of CO2 in the regolith =", totmassco2_adsorbded
698    write(*,*) "Tot mass of H2O in the regolith =", totmassh2o_adsorbded
699endif ! adsorption
700deallocate(tsurf_avg_yr1)
701
702!------------------------
703! I   Initialization
704!    I_i Compute orbit criterion
705!------------------------
706#ifndef CPP_STD
707    call iniorbit(aphelie,periheli,year_day,peri_day,obliquit)
708#else
709    call iniorbit(apoastr,periastr,year_day,peri_day,obliquit)
710#endif
711
712year_iter_max = Max_iter_pem
713if (evol_orbit_pem) call orbit_param_criterion(i_myear,year_iter_max)
714
715!-------------------------- END INITIALIZATION -------------------------
716
717!-------------------------------- RUN ----------------------------------
718!------------------------
719! II  Run
720!    II_a Update pressure, ice and tracers
721!------------------------
722year_iter = 0
723stopPEM = 0
724if (layering_algo) then
725    allocate(new_str(ngrid,nslope),new_lag1(ngrid,nslope),new_lag2(ngrid,nslope),current1(ngrid,nslope),current2(ngrid,nslope))
726    new_str = .true.
727    new_lag1 = .true.
728    new_lag2 = .true.
729    do islope = 1,nslope
730        do ig = 1,ngrid
731            current1(ig,islope)%p => stratif(ig,islope)%top
732            current2(ig,islope)%p => stratif(ig,islope)%top
733        enddo
734    enddo
735endif
736
737do while (year_iter < year_iter_max .and. i_myear < n_myear)
738! II.a.1. Compute updated global pressure
739    write(*,*) "Recomputing the new pressure..."
740    do i = 1,ngrid
741        do islope = 1,nslope
742            global_avg_press_new = global_avg_press_new - CO2cond_ps*g*cell_area(i)*tend_co2_ice(i,islope)*subslope_dist(i,islope)/cos(pi*def_slope_mean(islope)/180.)/Total_surface
743        enddo
744    enddo
745
746    if (adsorption_pem) then
747        do i = 1,ngrid
748            global_avg_press_new = global_avg_press_new - g*cell_area(i)*delta_co2_adsorbded(i)/Total_surface
749        enddo
750    endif
751    write(*,*) 'Global average pressure old time step',global_avg_press_old
752    write(*,*) 'Global average pressure new time step',global_avg_press_new
753
754! II.a.2. Old pressure levels for the timeseries, this value is deleted when unused and recreated each time (big memory consumption)
755    allocate(zplev_old_timeseries(ngrid,nlayer + 1,timelen))
756    write(*,*) "Recomputing the old pressure levels timeserie adapted to the old pressure..."
757    do l = 1,nlayer + 1
758        do ig = 1,ngrid
759            zplev_old_timeseries(ig,l,:) = ap(l) + bp(l)*ps_timeseries(ig,:)
760        enddo
761    enddo
762
763! II.a.3. Surface pressure timeseries
764    write(*,*) "Recomputing the surface pressure timeserie adapted to the new pressure..."
765    do ig = 1,ngrid
766        ps_timeseries(ig,:) = ps_timeseries(ig,:)*global_avg_press_new/global_avg_press_old
767    enddo
768
769! II.a.4. New pressure levels timeseries
770    allocate(zplev_new_timeseries(ngrid,nlayer + 1,timelen))
771    write(*,*) "Recomputing the new pressure levels timeserie adapted to the new pressure..."
772    do l = 1,nlayer + 1
773        do ig = 1,ngrid
774            zplev_new_timeseries(ig,l,:) = ap(l) + bp(l)*ps_timeseries(ig,:)
775        enddo
776    enddo
777
778! II.a.5. Tracers timeseries
779    write(*,*) "Recomputing of tracer VMR timeseries for the new pressure..."
780
781    l = 1
782    do ig = 1,ngrid
783        do t = 1,timelen
784            q_h2o_PEM_phys(ig,t) = q_h2o_PEM_phys(ig,t)*(zplev_old_timeseries(ig,l,t) - zplev_old_timeseries(ig,l + 1,t))/ &
785                                   (zplev_new_timeseries(ig,l,t) - zplev_new_timeseries(ig,l + 1,t))
786            if (q_h2o_PEM_phys(ig,t) < 0) then
787                q_h2o_PEM_phys(ig,t) = 1.e-30
788            else if (q_h2o_PEM_phys(ig,t) > 1) then
789                q_h2o_PEM_phys(ig,t) = 1.
790            endif
791        enddo
792    enddo
793
794    do ig = 1,ngrid
795        do t = 1,timelen
796            q_co2_PEM_phys(ig,t) = q_co2_PEM_phys(ig,t)*(zplev_old_timeseries(ig,l,t) - zplev_old_timeseries(ig,l + 1,t))/ &
797                                   (zplev_new_timeseries(ig,l,t) - zplev_new_timeseries(ig,l + 1,t))                       &
798                                + ((zplev_new_timeseries(ig,l,t) - zplev_new_timeseries(ig,l + 1,t))                       &
799                                -  (zplev_old_timeseries(ig,l,t) - zplev_old_timeseries(ig,l + 1,t)))/                     &
800                                   (zplev_new_timeseries(ig,l,t) - zplev_new_timeseries(ig,l + 1,t))
801            if (q_co2_PEM_phys(ig,t) < 0) then
802                q_co2_PEM_phys(ig,t) = 1.e-30
803            else if (q_co2_PEM_phys(ig,t) > 1) then
804                q_co2_PEM_phys(ig,t) = 1.
805            endif
806            mmean=1/(A*q_co2_PEM_phys(ig,t) + B)
807            vmr_co2_PEM_phys(ig,t) = q_co2_PEM_phys(ig,t)*mmean/m_co2
808        enddo
809    enddo
810
811    deallocate(zplev_new_timeseries,zplev_old_timeseries)
812
813!------------------------
814! II  Run
815!    II_b Evolution of ice
816!------------------------
817    call evol_h2o_ice(ngrid,nslope,cell_area,delta_h2o_adsorbded,delta_h2o_icetablesublim,h2o_ice,tend_h2o_ice,stopPEM)
818    call evol_co2_ice(ngrid,nslope,co2_ice,tend_co2_ice)
819    if (layering_algo) then
820        do islope = 1,nslope
821            do ig = 1,ngrid
822                call make_layering(stratif(ig,islope),tend_co2_ice(ig,islope),tend_h2o_ice(ig,islope),tend_dust,new_str(ig,islope),new_lag1(ig,islope),new_lag2(ig,islope),stopPEM,current1(ig,islope)%p,current2(ig,islope)%p)
823            enddo
824        enddo
825    endif
826
827!------------------------
828! II  Run
829!    II_c Flow of glaciers
830!------------------------
831    if (co2ice_flow .and. nslope > 1) call flow_co2glaciers(timelen,ngrid,nslope,iflat,subslope_dist,def_slope_mean,vmr_co2_PEM_phys,ps_timeseries, &
832                                            global_avg_press_PCM,global_avg_press_new,co2_ice,flag_co2flow,flag_co2flow_mesh)
833    if (h2oice_flow .and. nslope > 1) call flow_h2oglaciers(timelen,ngrid,nslope,iflat,subslope_dist,def_slope_mean,tsurf_avg,h2o_ice,flag_h2oflow,flag_h2oflow_mesh)
834
835!------------------------
836! II  Run
837!    II_d Update surface and soil temperatures
838!------------------------
839! II_d.1 Update Tsurf
840    write(*,*) "Updating the new Tsurf"
841    bool_sublim = .false.
842    Tsurfavg_before_saved = tsurf_avg
843    do ig = 1,ngrid
844        do islope = 1,nslope
845            if (is_co2ice_ini(ig,islope) .and. co2_ice(ig,islope) < 1.e-10 .and. .not. co2ice_disappeared(ig,islope)) then ! co2 ice disappeared, look for closest point without co2ice
846                co2ice_disappeared(ig,islope) = .true.
847                if (latitude_deg(ig) > 0) then
848                    do ig_loop = ig,ngrid
849                        do islope_loop = islope,iflat,-1
850                            if (.not. is_co2ice_ini(ig_loop,islope_loop) .and. co2_ice(ig_loop,islope_loop) < 1.e-10) then
851                                tsurf_avg(ig,islope) = tsurf_avg(ig_loop,islope_loop)
852                                bool_sublim = .true.
853                                exit
854                            endif
855                        enddo
856                        if (bool_sublim) exit
857                    enddo
858                else
859                    do ig_loop = ig,1,-1
860                        do islope_loop = islope,iflat
861                            if (.not. is_co2ice_ini(ig_loop,islope_loop) .and. co2_ice(ig_loop,islope_loop) < 1.e-10) then
862                                tsurf_avg(ig,islope) = tsurf_avg(ig_loop,islope_loop)
863                                bool_sublim = .true.
864                                exit
865                            endif
866                        enddo
867                        if (bool_sublim) exit
868                    enddo
869                endif
870                if ((co2_ice(ig,islope) < 1.e-10) .and. (h2o_ice(ig,islope) > frost_albedo_threshold)) then
871                    albedo(ig,1,islope) = albedo_h2o_frost
872                    albedo(ig,2,islope) = albedo_h2o_frost
873                else
874                    albedo(ig,1,islope) = albedodat(ig)
875                    albedo(ig,2,islope) = albedodat(ig)
876                    emis(ig,islope) = emissiv
877                endif
878            else if ((co2_ice(ig,islope) > 1.e-3) .and. (tend_co2_ice(ig,islope) > 1.e-10)) then ! Put tsurf as tcond co2
879                ave = 0.
880                do t = 1,timelen
881                    ave = ave + beta_clap_co2/(alpha_clap_co2 - log(vmr_co2_PEM_phys(ig,t)*ps_timeseries(ig,t)/100.))
882                enddo
883                tsurf_avg(ig,islope) = ave/timelen
884            endif
885        enddo
886    enddo
887
888    do t = 1,timelen
889        tsurf_PCM_timeseries(:,:,t) = tsurf_PCM_timeseries(:,:,t) + tsurf_avg - Tsurfavg_before_saved
890    enddo
891    ! for the start
892    do ig = 1,ngrid
893        do islope = 1,nslope
894            tsurf(ig,islope) =  tsurf(ig,islope) - (Tsurfavg_before_saved(ig,islope) - tsurf_avg(ig,islope))
895        enddo
896    enddo
897
898    if (soil_pem) then
899
900! II_d.2 Update soil temperature
901        write(*,*)"Updating soil temperature"
902        allocate(Tsoil_locslope(ngrid,nsoilmx_PEM))
903        do islope = 1,nslope
904            call compute_tsoil_pem(ngrid,nsoilmx_PEM,.true.,TI_PEM(:,:,islope),timestep,tsurf_avg(:,islope),tsoil_PEM(:,:,islope))
905            call compute_tsoil_pem(ngrid,nsoilmx_PEM,.false.,TI_PEM(:,:,islope),timestep,tsurf_avg(:,islope),tsoil_PEM(:,:,islope))
906
907            do t = 1,timelen
908                Tsoil_locslope(:,1:nsoilmx) = tsoil_PEM(:,1:nsoilmx,islope) + tsoil_anom(:,:,islope,t)
909                Tsoil_locslope(:,nsoilmx + 1:) = tsoil_PEM(:,nsoilmx + 1:,islope)
910                do ig = 1,ngrid
911                    do isoil = 1,nsoilmx_PEM
912                        watersoil_density_PEM_timeseries(ig,isoil,islope,t) = exp(beta_clap_h2o/Tsoil_locslope(ig,isoil) + alpha_clap_h2o)/Tsoil_locslope(ig,isoil)*mmol(igcm_h2o_vap)/(mugaz*r)
913                        if (isnan(tsoil_PEM(ig,isoil,islope))) call abort_pem("PEM - Update Tsoil","NaN detected in tsoil_PEM",1)
914                    enddo
915                enddo
916            enddo
917        enddo
918        watersoil_density_PEM_avg = sum(watersoil_density_PEM_timeseries,4)/timelen
919
920        write(*,*) "Update of soil temperature done"
921
922        deallocate(Tsoil_locslope)
923
924! II_d.3 Update the ice table
925        if (icetable_equilibrium) then
926            write(*,*) "Compute ice table"
927            porefillingice_thickness_prev_iter = porefillingice_thickness
928            call computeice_table_equilibrium(ngrid,nslope,nsoilmx_PEM,watercaptag,watersurf_density_avg,watersoil_density_PEM_avg,TI_PEM(:,1,:),porefillingice_depth,porefillingice_thickness)
929            call compute_massh2o_exchange_ssi(ngrid,nslope,nsoilmx_PEM,porefillingice_thickness_prev_iter,porefillingice_thickness,porefillingice_depth,tsurf_avg, tsoil_PEM,delta_h2o_icetablesublim) ! Mass of H2O exchange between the ssi and the atmosphere
930        endif
931! II_d.4 Update the soil thermal properties
932        call update_soil_thermalproperties(ngrid,nslope,nsoilmx_PEM,tend_h2o_ice,h2o_ice,global_avg_press_new,porefillingice_depth,porefillingice_thickness,TI_PEM)
933
934! II_d.5 Update the mass of the regolith adsorbed
935        if (adsorption_pem) then
936            call regolith_adsorption(ngrid,nslope,nsoilmx_PEM,timelen,tend_h2o_ice,tend_co2_ice,                   &
937                                     h2o_ice,co2_ice,tsoil_PEM,TI_PEM,ps_timeseries,q_co2_PEM_phys,q_h2o_PEM_phys, &
938                                     h2o_adsorbded_phys,delta_h2o_adsorbded,co2_adsorbded_phys,delta_co2_adsorbded)
939
940            totmassco2_adsorbded = 0.
941            totmassh2o_adsorbded = 0.
942            do ig = 1,ngrid
943                do islope =1, nslope
944                    do l = 1,nsoilmx_PEM
945                        if (l==1) then
946                            totmassco2_adsorbded = totmassco2_adsorbded + co2_adsorbded_phys(ig,l,islope)*(layer_PEM(l))* &
947                                       subslope_dist(ig,islope)/cos(pi*def_slope_mean(islope)/180.)*cell_area(ig)
948                            totmassh2o_adsorbded = totmassh2o_adsorbded + h2o_adsorbded_phys(ig,l,islope)*(layer_PEM(l))* &
949                                       subslope_dist(ig,islope)/cos(pi*def_slope_mean(islope)/180.)*cell_area(ig)
950                        else
951                            totmassco2_adsorbded = totmassco2_adsorbded + co2_adsorbded_phys(ig,l,islope)*(layer_PEM(l) - layer_PEM(l-1))* &
952                                       subslope_dist(ig,islope)/cos(pi*def_slope_mean(islope)/180.)*cell_area(ig)
953                            totmassh2o_adsorbded = totmassh2o_adsorbded + h2o_adsorbded_phys(ig,l,islope)*(layer_PEM(l) - layer_PEM(l-1))* &
954                                       subslope_dist(ig,islope)/cos(pi*def_slope_mean(islope)/180.)*cell_area(ig)
955                        endif
956                    enddo
957                enddo
958            enddo
959            write(*,*) "Tot mass of CO2 in the regolith=", totmassco2_adsorbded
960            write(*,*) "Tot mass of H2O in the regolith=", totmassh2o_adsorbded
961        endif
962    endif !soil_pem
963
964!------------------------
965! II  Run
966!    II_e Outputs
967!------------------------
968    call writediagpem(ngrid,'ps_avg','Global average pressure','Pa',0,(/global_avg_press_new/))
969    do islope = 1,nslope
970        write(str2(1:2),'(i2.2)') islope
971        call writediagpem(ngrid,'h2o_ice_slope'//str2,'H2O ice','kg.m-2',2,h2o_ice(:,islope))
972        call writediagpem(ngrid,'co2_ice_slope'//str2,'CO2 ice','kg.m-2',2,co2_ice(:,islope))
973        call writediagpem(ngrid,'tend_h2o_ice_slope'//str2,'H2O ice tend','kg.m-2.year-1',2,tend_h2o_ice(:,islope))
974        call writediagpem(ngrid,'tend_co2_ice_slope'//str2,'CO2 ice tend','kg.m-2.year-1',2,tend_co2_ice(:,islope))
975        call writediagpem(ngrid,'Flow_co2ice_slope'//str2,'CO2 ice flow','Boolean',2,flag_co2flow(:,islope))
976        call writediagpem(ngrid,'tsurf_slope'//str2,'tsurf','K',2,tsurf(:,islope))
977        if (icetable_equilibrium) then
978            call writediagpem(ngrid,'ssi_depth_slope'//str2,'ice table depth','m',2,porefillingice_depth(:,islope))
979            call writediagpem(ngrid,'ssi_thick_slope'//str2,'ice table depth','m',2,porefillingice_thickness(:,islope))
980        endif
981        if (soil_pem) then
982            call writediagsoilpem(ngrid,'tsoil_PEM_slope'//str2,'tsoil_PEM','K',3,tsoil_PEM(:,:,islope))
983            call writediagsoilpem(ngrid,'inertiesoil_PEM_slope'//str2,'TI_PEM','K',3,TI_PEM(:,:,islope))
984            if (adsorption_pem) then
985                call writediagsoilpem(ngrid,'co2_ads_slope'//str2,'co2_ads','K',3,co2_adsorbded_phys(:,:,islope))
986                call writediagsoilpem(ngrid,'h2o_ads_slope'//str2,'h2o_ads','K',3,h2o_adsorbded_phys(:,:,islope))
987            endif                       
988        endif
989    enddo
990
991!------------------------
992! II  Run
993!    II_f Update the tendencies
994!------------------------
995    call recomp_tend_co2_slope(ngrid,nslope,timelen,tend_co2_ice,tend_co2_ice_ini,co2_ice,emis,vmr_co2_PCM,vmr_co2_PEM_phys,ps_timeseries, &
996                               global_avg_press_PCM,global_avg_press_new)
997
998!------------------------
999! II  Run
1000!    II_g Checking the stopping criterion
1001!------------------------
1002
1003    write(*,*) "Checking the stopping criteria..."
1004    call stopping_crit_h2o_ice(cell_area,h2oice_ini_surf,ini_h2oice_sublim,h2o_ice,stopPEM,ngrid)
1005    call stopping_crit_co2(cell_area,co2ice_ini_surf,ini_co2ice_sublim,co2_ice,stopPEM,ngrid,global_avg_press_PCM,global_avg_press_new,nslope)
1006    year_iter = year_iter + dt_pem
1007    i_myear = i_myear + dt_pem
1008    if (stopPEM <= 0 .and. year_iter >= year_iter_max) stopPEM = 5
1009    if (stopPEM <= 0 .and. i_myear >= n_myear) stopPEM = 6
1010    call system_clock(c2)
1011    if (stopPEM <= 0 .and. timewall .and. real((c2 - c1)/cr) >= timelimit - antetime) stopPEM = 7
1012    if (stopPEM > 0) then
1013        select case (stopPEM)
1014            case(1)
1015                write(*,*) "STOPPING because surface of h2o ice sublimating is too low:", stopPEM, "See message above."
1016            case(2)
1017                write(*,*) "STOPPING because tendencies on h2o ice = 0:", stopPEM, "See message above."
1018            case(3)
1019                write(*,*) "STOPPING because surface of co2 ice sublimating is too low:", stopPEM, "See message above."
1020            case(4)
1021                write(*,*) "STOPPING because surface global pressure changed too much:", stopPEM, "See message above."
1022            case(5)
1023                write(*,*) "STOPPING because maximum number of iterations is reached (possibly due to orbital parameters):", stopPEM
1024            case(6)
1025                write(*,*) "STOPPING because maximum number of Martian years to be simulated is reached:", stopPEM
1026            case(7)
1027                write(*,*) "STOPPING because the time limit for the PEM job will be reached soon:", stopPEM
1028            case(8)
1029                write(*,*) "STOPPING because the layering algorithm met an hasty end:", stopPEM
1030            case default
1031                write(*,*) "STOPPING with unknown stopping criterion code:", stopPEM
1032        end select
1033        exit
1034    else
1035        write(*,*) "The PEM can continue!"
1036        write(*,*) "Number of iterations of the PEM: year_iter =", year_iter
1037        write(*,*) "Number of simulated Martian years: i_myear =", i_myear
1038    endif
1039
1040    global_avg_press_old = global_avg_press_new
1041
1042enddo ! big time iteration loop of the pem
1043!------------------------------ END RUN --------------------------------
1044
1045!------------------------------- OUTPUT --------------------------------
1046!------------------------
1047! III Output
1048!    III_a Update surface value for the PCM start files
1049!------------------------
1050! III_a.1 Ice update (for startfi)
1051
1052watercap = 0.
1053perennial_co2ice = co2_ice
1054do ig = 1,ngrid
1055    ! H2O ice metamorphism
1056    if (metam_h2oice .and. sum(qsurf(ig,igcm_h2o_ice,:)*subslope_dist(ig,:)/cos(pi*def_slope_mean(:)/180.)) > metam_h2oice_threshold) then
1057        h2o_ice(ig,:) = h2o_ice(ig,:) + qsurf(ig,igcm_h2o_ice,:) - metam_h2oice_threshold
1058        qsurf(ig,igcm_h2o_ice,:) = metam_h2oice_threshold
1059    endif
1060
1061    ! Is H2O ice still considered as an infinite reservoir for the PCM?
1062    if (sum(h2o_ice(ig,:)*subslope_dist(ig,:)/cos(pi*def_slope_mean(:)/180.)) > inf_h2oice_threshold) then
1063        ! There is enough ice to be considered as an infinite reservoir
1064        watercaptag(ig) = .true.
1065    else
1066        ! There too little ice to be considered as an infinite reservoir so ice is transferred to the frost
1067        watercaptag(ig) = .false.
1068        qsurf(ig,igcm_h2o_ice,:) = qsurf(ig,igcm_h2o_ice,:) + h2o_ice(ig,:)
1069        h2o_ice(ig,:) = 0.
1070    endif
1071
1072    ! CO2 ice metamorphism
1073    if (metam_co2ice .and. sum(qsurf(ig,igcm_co2,:)*subslope_dist(ig,:)/cos(pi*def_slope_mean(:)/180.)) > metam_co2ice_threshold) then
1074        perennial_co2ice(ig,:) = perennial_co2ice(ig,:) + qsurf(ig,igcm_co2,:) - metam_co2ice_threshold
1075        qsurf(ig,igcm_co2,:) = metam_co2ice_threshold
1076    endif
1077enddo
1078
1079! III_a.2 Tsoil update (for startfi)
1080if (soil_pem) then
1081    call interpol_TI_PEM2PCM(ngrid,nslope,nsoilmx_PEM,nsoilmx,TI_PEM,inertiesoil)
1082    tsoil = tsoil_PEM(:,1:nsoilmx,:) + tsoil_anom(:,:,:,timelen)
1083#ifndef CPP_STD
1084    flux_geo = fluxgeo
1085#endif
1086endif
1087deallocate(tsoil_anom)
1088
1089! III_a.4 Pressure (for start)
1090ps = ps*global_avg_press_new/global_avg_press_PCM
1091ps_start_PCM = ps_start_PCM*global_avg_press_new/global_avg_press_PCM
1092
1093! III_a.5 Tracer (for start)
1094allocate(zplev_new(ngrid,nlayer + 1))
1095
1096do l = 1,nlayer + 1
1097    zplev_new(:,l) = ap(l) + bp(l)*ps_start_PCM
1098enddo
1099
1100do nnq = 1,nqtot
1101    if (noms(nnq) /= "co2") then
1102        do l = 1,llm - 1
1103            do ig = 1,ngrid
1104                q(ig,l,nnq) = q(ig,l,nnq)*(zplev_PCM(ig,l) - zplev_PCM(ig,l + 1))/(zplev_new(ig,l) - zplev_new(ig,l + 1))
1105            enddo
1106            q(:,llm,nnq) = q(:,llm - 1,nnq)
1107        enddo
1108    else
1109        do l = 1,llm - 1
1110            do ig = 1,ngrid
1111                q(ig,l,nnq) = q(ig,l,nnq)*(zplev_PCM(ig,l) - zplev_PCM(ig,l + 1))/(zplev_new(ig,l) - zplev_new(ig,l + 1)) &
1112                              + ((zplev_new(ig,l) - zplev_new(ig,l + 1)) - (zplev_PCM(ig,l) - zplev_PCM(ig,l + 1)))/(zplev_new(ig,l) - zplev_new(ig,l + 1))
1113            enddo
1114            q(:,llm,nnq) = q(:,llm - 1,nnq)
1115        enddo
1116    endif
1117enddo
1118
1119! Conserving the tracers mass for PCM start files
1120do nnq = 1,nqtot
1121    do ig = 1,ngrid
1122        do l = 1,llm - 1
1123            if (q(ig,l,nnq) > 1 .and. (noms(nnq) /= "dust_number") .and. (noms(nnq) /= "ccn_number") .and. (noms(nnq) /= "stormdust_number") .and. (noms(nnq) /= "topdust_number")) then
1124                extra_mass = (q(ig,l,nnq) - 1)*(zplev_new(ig,l) - zplev_new(ig,l + 1))
1125                q(ig,l,nnq) = 1.
1126                q(ig,l + 1,nnq) = q(ig,l + 1,nnq) + extra_mass*(zplev_new(ig,l + 1) - zplev_new(ig,l + 2))
1127                write(*,*) 'extra ',noms(nnq),extra_mass, noms(nnq) /= "dust_number",noms(nnq) /= "ccn_number"
1128           endif
1129            if (q(ig,l,nnq) < 0) q(ig,l,nnq) = 1.e-30
1130        enddo
1131    enddo
1132enddo
1133
1134if (evol_orbit_pem) call recomp_orb_param(i_myear,year_iter)
1135
1136!------------------------
1137! III Output
1138!    III_b Write "restart.nc" and "restartfi.nc"
1139!------------------------
1140! III_b.1 Write "restart.nc"
1141ptimestep = iphysiq*daysec/real(day_step)/nsplit_phys ! dtphys/nsplit_phys
1142pday = day_ini
1143ztime_fin = time_phys
1144
1145allocate(p(ip1jmp1,nlayer + 1))
1146#ifndef CPP_1D
1147    ! Correction on teta due to surface pressure changes
1148    do l = 1,nlayer
1149        do i = 1,ip1jmp1
1150            teta(i,l)= teta(i,l)*(1 + (ps(i) - ps0(i))*year_iter/ps(i))**kappa
1151        enddo
1152    enddo
1153    ! Correction on atmospheric pressure
1154    call pression(ip1jmp1,ap,bp,ps,p)
1155    ! Correction on the mass of atmosphere
1156    call massdair(p,masse)
1157    call dynredem0("restart.nc",day_ini,phis)
1158    call dynredem1("restart.nc",time_0,vcov,ucov,teta,q,masse,ps)
1159    write(*,*) "restart.nc has been written"
1160#else
1161    call writerestart1D('restart1D.txt',ps(1),tsurf(1,:),nlayer,size(tsurf,2),teta,ucov,vcov,nq,noms,qsurf(1,:,:),q)
1162    write(*,*) "restart1D.txt has been written"
1163#endif
1164
1165! III_b.2 Write the "restartfi.nc"
1166#ifndef CPP_STD
1167    call physdem0("restartfi.nc",longitude,latitude,nsoilmx,ngrid, &
1168                  nlayer,nq,ptimestep,pday,0.,cell_area,albedodat, &
1169                  inertiedat,def_slope,subslope_dist)
1170    call physdem1("restartfi.nc",nsoilmx,ngrid,nlayer,nq,nqsoil,      &
1171                  ptimestep,ztime_fin,tsurf,tsoil,inertiesoil,        &
1172                  albedo,emis,q2,qsurf,qsoil,tauscaling,totcloudfrac, &
1173                  wstar,watercap,perennial_co2ice)
1174#else
1175    call physdem0("restartfi.nc",longitude,latitude,nsoilmx,ngrid, &
1176                  nlayer,nq,ptimestep,pday,time_phys,cell_area,    &
1177                  albedo_bareground,inertiedat,zmea,zstd,zsig,zgam,zthe)
1178    call physdem1("restartfi.nc",nsoilmx,ngrid,nlayer,nq,nqsoil,       &
1179                  ptimestep,ztime_fin,tsurf,tsoil,emis,q2,qsurf,qsoil, &
1180                  cloudfrac,totcloudfrac,hice,rnat,pctsrf_sic,tslab,   &
1181                  tsea_ice,sea_ice)
1182#endif
1183write(*,*) "restartfi.nc has been written"
1184
1185!------------------------
1186! III Output
1187!    III_c Write the "restartpem.nc"
1188!------------------------
1189if (layering_algo) nb_str_max = get_nb_str_max(stratif,ngrid,nslope) ! Get the maximum number of "stratum" in the stratification (layerings)
1190call pemdem0("restartpem.nc",longitude,latitude,cell_area,ngrid,nslope,def_slope,subslope_dist)
1191call pemdem1("restartpem.nc",i_myear,nsoilmx_PEM,ngrid,nslope,tsoil_PEM, &
1192             TI_PEM,porefillingice_depth,porefillingice_thickness,       &
1193             co2_adsorbded_phys,h2o_adsorbded_phys,h2o_ice,stratif)
1194write(*,*) "restartpem.nc has been written"
1195
1196call info_PEM(year_iter,stopPEM,i_myear,n_myear)
1197
1198write(*,*) "The PEM has run for", year_iter, "Martian years."
1199write(*,*) "The chained simulation has run for", i_myear, "Martian years =", i_myear*convert_years, "Earth years."
1200write(*,*) "The reached date is now", (year_bp_ini + i_myear)*convert_years, "Earth years."
1201write(*,*) "LL & RV & JBC: so far, so good!"
1202
1203if (layering_algo) then
1204    do islope = 1,nslope
1205        do i = 1,ngrid
1206            call del_layering(stratif(i,islope))
1207        enddo
1208    enddo
1209    deallocate(new_str,new_lag1,new_lag2,current1,current2)
1210endif
1211deallocate(vmr_co2_PCM,ps_timeseries,tsurf_PCM_timeseries,q_co2_PEM_phys,q_h2o_PEM_phys)
1212deallocate(watersurf_density_avg,watersoil_density_timeseries,Tsurfavg_before_saved)
1213deallocate(tsoil_phys_PEM_timeseries,watersoil_density_PEM_timeseries,watersoil_density_PEM_avg)
1214deallocate(delta_co2_adsorbded,delta_h2o_adsorbded,vmr_co2_PEM_phys,delta_h2o_icetablesublim,porefillingice_thickness_prev_iter)
1215deallocate(is_co2ice_ini,co2ice_disappeared,ini_co2ice_sublim,ini_h2oice_sublim,stratif)
1216!----------------------------- END OUTPUT ------------------------------
1217
1218END PROGRAM pem
Note: See TracBrowser for help on using the repository browser.