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

Last change on this file since 3393 was 3389, checked in by jbclement, 19 months ago

PEM:
Correction to r3387 for the time limit stopping criterion.
JBC

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