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

Last change on this file was 4157, checked in by jbclement, 20 hours ago

PEM:

  • Separate variables ownership between the module "planet" for persistent climate state and the program "pem" for transient workflow logic. It provides a meaningful structure.
  • Add lifecycle helpers for clear allocation/deallocation logic.
  • Simplify string suffix for slopes variables.

JBC

File size: 8.6 KB
RevLine 
[4134]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,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
[4157]97use clim_state_rec,   only: write_restart, write_restartfi, write_restartevo
[4134]98use layered_deposits, only: layering
99
100! DECLARATION
101! -----------
102implicit none
103
104! ARGUMENTS
105! ---------
106real(dp),       dimension(:),     intent(in)    :: ps_avg, ps_dev
107real(dp),                         intent(in)    :: ps_avg_glob, ps_avg_glob_ini
108real(dp),       dimension(:,:),   intent(in)    :: tsurf_avg, tsurf_dev, icetable_depth, icetable_thickness
109real(dp),       dimension(:,:,:), intent(in)    :: tsoil_avg, tsoil_dev, ice_porefilling, h2o_ads_reg, co2_ads_reg
110type(layering), dimension(:,:),   intent(in)    :: layerings_map
111integer(di), optional,            intent(in)    :: backup_idt
112real(dp),       dimension(:,:),   intent(inout) :: h2o_ice, co2_ice
113
114! LOCAL VARIABLES
115! ---------------
[4135]116real(dp),    dimension(ngrid,nslope)           :: h2o_ice4PCM, co2_ice4PCM, tsurf4PCM, flux_geo4PCM, albedo4PCM, emissivity4PCM
117real(dp),    dimension(ngrid,nlayer)           :: teta4PCM, air_mass4PCM
118real(dp),    dimension(ngrid,nsoil_PCM,nslope) :: tsoil4PCM, inertiesoil4PCM
119real(dp),    dimension(ngrid,nlayer,nq)        :: q4PCM
120real(dp),    dimension(ngrid)                  :: ps4PCM
121logical(k4), dimension(ngrid)                  :: is_h2o_perice
122real(dp)                                       :: pa4PCM, preff4PCM
[4134]123
124! CODE
125! ----
126! Build ice for the PCM
127call build4PCM_perice(h2o_ice,co2_ice,is_h2o_perice,h2o_ice4PCM,co2_ice4PCM)
128
129! Build surface temperature for the PCM
130call build4PCM_tsurf(tsurf_avg,tsurf_dev,tsurf4PCM)
131
132! Build soil for the PCM
[4135]133if (do_soil) call build4PCM_soil(tsoil_avg,tsoil_dev,inertiesoil4PCM,tsoil4PCM,flux_geo4PCM)
[4134]134
135! Build atmosphere for the PCM
136call build4PCM_atmosphere(ps_avg,ps_dev,ps_avg_glob,ps_avg_glob_ini,ps4PCM,pa4PCM,preff4PCM,teta4PCM,air_mass4PCM)
137
138! Build tracers for the PCM
139call build4PCM_tracers(ps4PCM,q4PCM)
140
141! Build surface radiative properties state for the PCM
142call build4PCM_surf_rad_prop(h2o_ice,co2_ice,albedo4PCM,emissivity4PCM)
143
144! Write restart files
[4157]145call write_restartevo(h2o_ice,co2_ice,tsoil_avg,TI,icetable_depth,icetable_thickness,ice_porefilling,h2o_ads_reg,co2_ads_reg,layerings_map)
[4134]146call write_restartfi(is_h2o_perice,h2o_ice4PCM,co2_ice4PCM,tsurf4PCM,tsoil4PCM,inertiesoil4PCM,albedo4PCM,emissivity4PCM,flux_geo4PCM)
147call write_restart(ps4PCM,pa4PCM,preff4PCM,q4PCM,teta4PCM,air_mass4PCM)
148
149if (present(backup_idt)) then
150    if (backup_idt > 0) call backup_restarts(backup_idt)
151end if
152
153END SUBROUTINE save_clim_state
154!=======================================================================
155
156!=======================================================================
[4135]157SUBROUTINE backup_restarts(backup_idt)
[4134]158!-----------------------------------------------------------------------
159! NAME
160!     backup_restarts
161!
162! DESCRIPTION
163!     Duplicate restart files to timestep-tagged backup files.
164!
165! AUTHORS & DATE
166!     JB Clement, 03/2026
167!
168! NOTES
169!
170!-----------------------------------------------------------------------
171
172! DEPENDENCIES
173! ------------
174use geometry,  only: ngrid
175use io_netcdf, only: start_name, start1D_name, startfi_name, startevo_name
176use display,   only: print_msg, LVL_NFO
177use utility,   only: int2str
178
179! DECLARATION
180! -----------
181implicit none
182
183! ARGUMENTS
184! ---------
[4135]185integer(di), intent(in) :: backup_idt
[4134]186
187! LOCAL VARIABLES
188! ---------------
189character(:), allocatable :: suffix
190
191! CODE
192! ----
[4157]193suffix = ''
194suffix = suffix//'_ts'//int2str(backup_idt)
[4134]195
[4135]196call print_msg('> Backup of "restart" files at dt = '//int2str(backup_idt),LVL_NFO)
[4134]197call copy_restart_if_present('re'//startevo_name,suffix2filename(startevo_name,suffix))
198call copy_restart_if_present('re'//startfi_name,suffix2filename(startfi_name,suffix))
199if (ngrid == 1) then
200    call copy_restart_if_present('re'//start1D_name,suffix2filename(start1D_name,suffix))
201else
202    call copy_restart_if_present('re'//start_name,suffix2filename(start_name,suffix))
203end if
204
205END SUBROUTINE backup_restarts
206!=======================================================================
207
208!=======================================================================
209SUBROUTINE copy_restart_if_present(src_name,dst_name)
210!-----------------------------------------------------------------------
211! NAME
212!     copy_restart_if_present
213!
214! DESCRIPTION
215!     Copy file if present. Used for restart backup files.
216!
217! AUTHORS & DATE
218!     JB Clement, 03/2026
219!
220! NOTES
221!
222!-----------------------------------------------------------------------
223
224! DEPENDENCIES
225! ------------
226use stoppage, only: stop_clean
227
228! DECLARATION
229! -----------
230implicit none
231
232! ARGUMENTS
233! ---------
234character(*), intent(in) :: src_name, dst_name
235
236! LOCAL VARIABLES
237! ---------------
238logical(k4) :: here
239integer(di) :: cstat
240
241! CODE
242! ----
243inquire(file = src_name,exist = here)
244if (.not. here) return
245
246call execute_command_line('cp '//src_name//' '//dst_name,cmdstat = cstat)
247if (cstat > 0) then
248    call stop_clean(__FILE__,__LINE__,'command execution failed!',1)
249else if (cstat < 0) then
250    call stop_clean(__FILE__,__LINE__,'command execution not supported!',1)
251end if
252
253END SUBROUTINE copy_restart_if_present
254!=======================================================================
255
256!=======================================================================
257FUNCTION suffix2filename(filename,suffix_in) RESULT(name_out)
258!-----------------------------------------------------------------------
259! NAME
260!     suffix2filename
261!
262! DESCRIPTION
263!     Insert suffix before the extension of a filename.
264!
265! AUTHORS & DATE
266!     JB Clement, 03/2026
267!
268! NOTES
269!
270!-----------------------------------------------------------------------
271
272! DECLARATION
273! -----------
274implicit none
275
276! ARGUMENTS
277! ---------
278character(*), intent(in) :: filename, suffix_in
279
280! LOCAL VARIABLES
281! ---------------
282character(:), allocatable :: name_out
283integer(di)               :: ipos
284
285! CODE
286! ----
287ipos = index(filename,'.',back = .true.)
288if (ipos > 0) then
289    name_out = filename(:ipos - 1)//suffix_in//filename(ipos:)
290else
291    name_out = filename//suffix_in
292end if
293
294END FUNCTION suffix2filename
295!=======================================================================
296
297END MODULE backup
Note: See TracBrowser for help on using the repository browser.