source: trunk/LMDZ.COMMON/libf/evolution/backup.F90 @ 4175

Last change on this file since 4175 was 4174, checked in by jbclement, 35 hours ago

PEM:
Refactor of H2O flux balancing:

  • centralizes flux balancing logic;
  • removes intermediate variables, especially related to of H2O mass bookkeeping;
  • adds new stopping criterion when H2O flux balance fails8 (sanity check);
  • introduces configurable weighting strategies for H2O flux balancing.

JBC

File size: 8.9 KB
Line 
1MODULE backup
2!-----------------------------------------------------------------------
3! NAME
4!     backup
5!
6! DESCRIPTION
7!     Build and write PEM/PCM restart files, with optional backups.
8!
9! AUTHORS & DATE
10!     JB Clement, 03/2026
11!
12! NOTES
13!
14!-----------------------------------------------------------------------
15
16! DEPENDENCIES
17! ------------
18use numerics, only: dp, di, k4
19
20! DECLARATION
21! -----------
22implicit none
23
24! PARAMETERS
25! ----------
26integer(di), protected :: backup_rate = 0_di ! Backup rate in PEM timesteps (0 disables intermediate backups)
27
28contains
29!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
30
31!=======================================================================
32SUBROUTINE set_backup_config(backup_rate_in)
33!-----------------------------------------------------------------------
34! NAME
35!     set_backup_config
36!
37! DESCRIPTION
38!     Setter for "backup" configuration parameters.
39!
40! AUTHORS & DATE
41!     JB Clement, 03/2026
42!
43! NOTES
44!
45!-----------------------------------------------------------------------
46
47! DEPENDENCIES
48! ------------
49use utility,  only: int2str
50use display,  only: print_msg, LVL_NFO
51use stoppage, only: stop_clean
52
53! DECLARATION
54! -----------
55implicit none
56
57! ARGUMENTS
58! ---------
59integer(di), intent(in) :: backup_rate_in
60
61! CODE
62! ----
63backup_rate = backup_rate_in
64call print_msg('backup_rate = '//int2str(backup_rate),LVL_NFO)
65if (backup_rate < 0) call stop_clean(__FILE__,__LINE__,'''backup_rate'' must be >= 0!',1)
66
67END SUBROUTINE set_backup_config
68!=======================================================================
69
70!=======================================================================
71SUBROUTINE save_clim_state(h2o_ice,co2_ice,tsurf_avg,tsurf_dev,tsoil_avg,tsoil_dev,ps_avg,ps_dev,ps_avg_glob,ps_avg_glob_ini, &
72                           icetable_depth,icetable_thickness,ice_porefilling,h2oice_depth,h2o_ads_reg,co2_ads_reg,layerings_map,backup_idt)
73!-----------------------------------------------------------------------
74! NAME
75!     save_clim_state
76!
77! DESCRIPTION
78!     Build PCM-compatible state and write "restartevo", "restartfi"
79!     and "restart" files. Optionally create timestep-tagged backups.
80!
81! AUTHORS & DATE
82!     JB Clement, 03/2026
83!
84! NOTES
85!
86!-----------------------------------------------------------------------
87
88! DEPENDENCIES
89! ------------
90use geometry,         only: ngrid, nslope, nsoil_PCM, nlayer
91use soil,             only: do_soil, TI, build4PCM_soil
92use surface,          only: build4PCM_surf_rad_prop
93use surf_ice,         only: build4PCM_perice
94use surf_temp,        only: build4PCM_tsurf
95use atmosphere,       only: build4PCM_atmosphere
96use tracers,          only: build4PCM_tracers, nq
97use ice_table,        only: build4PCM_ssice
98use clim_state_rec,   only: write_restart, write_restartfi, write_restartevo
99use layered_deposits, only: layering
100
101! DECLARATION
102! -----------
103implicit none
104
105! ARGUMENTS
106! ---------
107real(dp),       dimension(:),     intent(in)           :: ps_avg, ps_dev
108real(dp),                         intent(in)           :: ps_avg_glob, ps_avg_glob_ini
109real(dp),       dimension(:,:),   intent(in)           :: tsurf_avg, tsurf_dev, icetable_depth, icetable_thickness, h2oice_depth
110real(dp),       dimension(:,:,:), intent(in)           :: tsoil_avg, tsoil_dev, ice_porefilling, h2o_ads_reg, co2_ads_reg
111type(layering), dimension(:,:),   intent(in)           :: layerings_map
112integer(di),                      intent(in), optional :: backup_idt
113real(dp),       dimension(:,:),   intent(inout) :: h2o_ice, co2_ice
114
115! LOCAL VARIABLES
116! ---------------
117real(dp),    dimension(ngrid,nslope)           :: h2o_ice4PCM, co2_ice4PCM, tsurf4PCM, flux_geo4PCM, albedo4PCM, emissivity4PCM, h2oice_depth4PCM
118real(dp),    dimension(ngrid,nlayer)           :: teta4PCM, air_mass4PCM
119real(dp),    dimension(ngrid,nsoil_PCM,nslope) :: tsoil4PCM, inertiesoil4PCM
120real(dp),    dimension(ngrid,nlayer,nq)        :: q4PCM
121real(dp),    dimension(ngrid)                  :: ps4PCM
122logical(k4), dimension(ngrid)                  :: is_h2o_perice
123real(dp)                                       :: pa4PCM, preff4PCM
124
125! CODE
126! ----
127! Build ice for the PCM
128call build4PCM_perice(h2o_ice,co2_ice,is_h2o_perice,h2o_ice4PCM,co2_ice4PCM)
129
130! Build surface temperature for the PCM
131call build4PCM_tsurf(tsurf_avg,tsurf_dev,tsurf4PCM)
132
133if (do_soil) then
134    ! Build soil for the PCM
135    call build4PCM_soil(tsoil_avg,tsoil_dev,inertiesoil4PCM,tsoil4PCM,flux_geo4PCM)
136
137    ! Build subsurface ice for the PCM
138    call build4PCM_ssice(icetable_depth,h2oice_depth,h2oice_depth4PCM)
139end if
140
141! Build atmosphere for the PCM
142call build4PCM_atmosphere(ps_avg,ps_dev,ps_avg_glob,ps_avg_glob_ini,ps4PCM,pa4PCM,preff4PCM,teta4PCM,air_mass4PCM)
143
144! Build tracers for the PCM
145call build4PCM_tracers(ps4PCM,q4PCM)
146
147! Build surface radiative properties state for the PCM
148call build4PCM_surf_rad_prop(h2o_ice,co2_ice,albedo4PCM,emissivity4PCM)
149
150! Write restart files
151call write_restartevo(h2o_ice,co2_ice,tsoil_avg,TI,icetable_depth,icetable_thickness,ice_porefilling,h2o_ads_reg,co2_ads_reg,layerings_map)
152call write_restartfi(is_h2o_perice,h2o_ice4PCM,co2_ice4PCM,tsurf4PCM,tsoil4PCM,inertiesoil4PCM,albedo4PCM,emissivity4PCM,flux_geo4PCM,h2oice_depth4PCM)
153call write_restart(ps4PCM,pa4PCM,preff4PCM,q4PCM,teta4PCM,air_mass4PCM)
154
155if (present(backup_idt)) then
156    if (backup_idt > 0) call backup_restarts(backup_idt)
157end if
158
159END SUBROUTINE save_clim_state
160!=======================================================================
161
162!=======================================================================
163SUBROUTINE backup_restarts(backup_idt)
164!-----------------------------------------------------------------------
165! NAME
166!     backup_restarts
167!
168! DESCRIPTION
169!     Duplicate restart files to timestep-tagged backup files.
170!
171! AUTHORS & DATE
172!     JB Clement, 03/2026
173!
174! NOTES
175!
176!-----------------------------------------------------------------------
177
178! DEPENDENCIES
179! ------------
180use geometry,  only: ngrid
181use io_netcdf, only: start_name, start1D_name, startfi_name, startevo_name
182use display,   only: print_msg, LVL_NFO
183use utility,   only: int2str
184
185! DECLARATION
186! -----------
187implicit none
188
189! ARGUMENTS
190! ---------
191integer(di), intent(in) :: backup_idt
192
193! LOCAL VARIABLES
194! ---------------
195character(:), allocatable :: suffix
196
197! CODE
198! ----
199suffix = '_ts'//int2str(backup_idt)
200
201call print_msg('> Backup of "restart" files at dt = '//int2str(backup_idt),LVL_NFO)
202call copy_restart_if_present('re'//startevo_name,suffix2filename(startevo_name,suffix))
203call copy_restart_if_present('re'//startfi_name,suffix2filename(startfi_name,suffix))
204if (ngrid == 1) then
205    call copy_restart_if_present('re'//start1D_name,suffix2filename(start1D_name,suffix))
206else
207    call copy_restart_if_present('re'//start_name,suffix2filename(start_name,suffix))
208end if
209
210END SUBROUTINE backup_restarts
211!=======================================================================
212
213!=======================================================================
214SUBROUTINE copy_restart_if_present(src_name,dst_name)
215!-----------------------------------------------------------------------
216! NAME
217!     copy_restart_if_present
218!
219! DESCRIPTION
220!     Copy file if present. Used for restart backup files.
221!
222! AUTHORS & DATE
223!     JB Clement, 03/2026
224!
225! NOTES
226!
227!-----------------------------------------------------------------------
228
229! DEPENDENCIES
230! ------------
231use stoppage, only: stop_clean
232
233! DECLARATION
234! -----------
235implicit none
236
237! ARGUMENTS
238! ---------
239character(*), intent(in) :: src_name, dst_name
240
241! LOCAL VARIABLES
242! ---------------
243logical(k4) :: here
244integer(di) :: cstat
245
246! CODE
247! ----
248inquire(file = src_name,exist = here)
249if (.not. here) return
250
251call execute_command_line('cp '//src_name//' '//dst_name,cmdstat = cstat)
252if (cstat > 0) then
253    call stop_clean(__FILE__,__LINE__,'command execution failed!',1)
254else if (cstat < 0) then
255    call stop_clean(__FILE__,__LINE__,'command execution not supported!',1)
256end if
257
258END SUBROUTINE copy_restart_if_present
259!=======================================================================
260
261!=======================================================================
262FUNCTION suffix2filename(filename,suffix_in) RESULT(name_out)
263!-----------------------------------------------------------------------
264! NAME
265!     suffix2filename
266!
267! DESCRIPTION
268!     Insert suffix before the extension of a filename.
269!
270! AUTHORS & DATE
271!     JB Clement, 03/2026
272!
273! NOTES
274!
275!-----------------------------------------------------------------------
276
277! DECLARATION
278! -----------
279implicit none
280
281! ARGUMENTS
282! ---------
283character(*), intent(in) :: filename, suffix_in
284
285! LOCAL VARIABLES
286! ---------------
287character(:), allocatable :: name_out
288integer(di)               :: ipos
289
290! CODE
291! ----
292ipos = index(filename,'.',back = .true.)
293if (ipos > 0) then
294    name_out = filename(:ipos - 1)//suffix_in//filename(ipos:)
295else
296    name_out = filename//suffix_in
297end if
298
299END FUNCTION suffix2filename
300!=======================================================================
301
302END MODULE backup
Note: See TracBrowser for help on using the repository browser.