source: trunk/LMDZ.COMMON/libf/evolution/info.F90 @ 4066

Last change on this file since 4066 was 4065, checked in by jbclement, 3 weeks ago

PEM:
Major refactor following the previous ones (r3989 and r3991) completing the large structural reorganization and cleanup of the PEM codebase. This revision introduces newly designed modules, standardizes interfaces with explicit ini/end APIs and adds native NetCDF I/O together with explicit PCM/PEM adapters. In detail:

  • Some PEM models were corrected or improved:
    • Frost/perennial ice semantics are clarified via renaming;
    • Soil temperature remapping clarified, notably by removing the rescaling of temperature deviation;
    • Geothermal flux for the PCM is computed based on the PEM state;
  • New explicit PEM/PCM adapters ("set_*"/"build4PCM_*") to decouple PEM internal representation from PCM file layouts and reconstruct consistent fields returned to the PCM;
  • New explicit build/teardown routines that centralize allocation and initialization ordering, reducing accidental use of uninitialized data and making the model lifecycle explicit;
  • Add native read/write helpers for NetCDF that centralize all low-level NetCDF interactions with major improvements (and more simplicity) compared to legacy PEM/PCM I/O (see the modules "io_netcdf" and "output"). They support reading, creation and writing of "diagevol.nc" (renamed from "diagpem.nc") and start/restart files;
  • Provide well-focused modules ("numerics"/"maths"/"utility"/"display") to host commonly-used primitives:
    • "numerics" defines numerical types and constants for reproducibility, portability across compilers and future transitions (e.g. quadruple precision experiments);
    • "display" provides a single controlled interface for runtime messages, status output and diagnostics, avoiding direct 'print'/'write' to enable silent mode, log redirection, and MPI-safe output in the future.
    • "utility" (new module) hosts generic helpers used throughout the code (e.g. "int2str" or "real2str");
  • Add modules "clim_state_init"/"clim_state_rec" which provide robust read/write logic for "start/startfi/startpem", including 1D fallbacks, mesh conversions and dimension checks. NetCDF file creation is centralized and explicit. Restart files are now self-consistent and future-proof, requiring changes only to affected variables;
  • Add module "atmosphere" which computes pressure fields, reconstructs potential temperature and air mass. It also holds the whole logic to define sigma or hybrid coordinates for altitudes;
  • Add module "geometry" to centrilize dimensions logic and grid conversions routines (including 2 new ones "dyngrd2vect"/"vect2dyngrd");
  • Add module "slopes" to isolate slopes handling;
  • Add module "surface" to isolate surface management. Notably, albedo and emissivity are now fully reconstructed following the PCM settings;
  • Add module "allocation" to check the dimension initialization and centrilize allocation/deallocation;
  • Finalize module decomposition and renaming to consolidate domain-based modules, purpose-based routines and physics/process-based variables;
  • The main program now drives a clearer sequence of conceptual steps (initialization / reading / evolution / update / build / writing) and fails explicitly instead of silently defaulting;
  • Ice table logic is made restart-safe;
  • 'Open'/'read' intrinsic logic is made safe and automatic;
  • Improve discoverability and standardize the data handling (private vs protected vs public);
  • Apply consistent documentation/header style already introduced;
  • Update deftank scripts to reflect new names and launch wrappers;

This revision is a structural milestone aiming to be behavior-preserving where possible. It has been tested via compilation and short integration runs. However, due to extensive renames, moves, and API changes, full validation is still ongoing.
Note: the revision includes one (possibly two) easter egg hidden in the code for future archaeologists of the PEM. No physics were harmed.
JBC

File size: 4.8 KB
Line 
1MODULE info
2!-----------------------------------------------------------------------
3! NAME
4!     info
5!
6! DESCRIPTION
7!     Handles counters for PCM/PEM coupled runs and duration information
8!     of the simulation metadata.
9!
10! AUTHORS & DATE
11!     JB Clement, 2023-2025
12!
13! NOTES
14!
15!-----------------------------------------------------------------------
16
17! DEPENDENCIES
18! ------------
19use numerics, only: dp, di, k4
20
21! DECLARATION
22! -----------
23implicit none
24
25! PARAMETERS
26! ----------
27character(14), parameter :: infofile_name = 'launchPEM.info'
28
29! VARIABLES
30! ---------
31integer(di) :: iPCM, iPEM, nPCM, nPCM_ini ! Data about the chained simulation of PCM/PEM runs
32
33contains
34!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
35
36!=======================================================================
37SUBROUTINE read_info()
38!-----------------------------------------------------------------------
39! NAME
40!    read_info
41!
42! DESCRIPTION
43!    Read the file "launchPEM.info" to get the number of simulated
44!    years.
45!
46! AUTHORS & DATE
47!    JB Clement, 12/2025
48!
49! NOTES
50!
51!-----------------------------------------------------------------------
52
53! DEPENDENCIES
54! ------------
55use stoppage,  only: stop_clean
56use evolution, only: n_yr_sim, nmax_yr_sim, set_r_plnt2earth_yr
57use display,   only: print_msg
58
59! DECLARATION
60! -----------
61implicit none
62
63! LOCAL VARIABLES
64! ---------------
65logical(k4) :: here
66real(dp)    :: tmp
67integer(di) :: ierr, funit
68
69! CODE
70! ----
71inquire(file = infofile_name,exist = here)
72if (.not. here) call stop_clean(__FILE__,__LINE__,'cannot find required file "'//infofile_name//'"! It should be created by the launching script.',1)
73call print_msg('> Reading "'//infofile_name//'"')
74open(newunit = funit,file = infofile_name,status = 'old',form = 'formatted',action = 'read',iostat = ierr)
75if (ierr /= 0) call stop_clean(__FILE__,__LINE__,'error opening file "'//infofile_name//'"!',ierr)
76read(funit,*) n_yr_sim, nmax_yr_sim, tmp, iPCM, iPEM, nPCM, nPCM_ini
77call set_r_plnt2earth_yr(tmp)
78close(funit)
79
80END SUBROUTINE read_info
81!=======================================================================
82
83!=======================================================================
84SUBROUTINE update_info(n_yr_run,stopPEM,n_yr_sim,nmax_yr_sim)
85!-----------------------------------------------------------------------
86! NAME
87!    update_info
88!
89! DESCRIPTION
90!    Update the first line of "launchPEM.info" to count the number of
91!    simulated years. Write in "launchPEM.info" the reason why the PEM
92!    stopped and the number of simulated years.
93!
94! AUTHORS & DATE
95!    R. Vandemeulebrouck
96!    JB Clement, 2023-2025
97!
98! NOTES
99!
100!-----------------------------------------------------------------------
101
102! DEPENDENCIES
103! ------------
104use evolution, only: r_plnt2earth_yr, pem_ini_date
105use utility,   only: int2str, nb_digits
106use stoppage,  only: stop_clean
107use display,   only: print_msg
108
109! DECLARATION
110! -----------
111implicit none
112
113! ARGUMENTS
114! ---------
115integer(di), intent(in) :: stopPEM    ! Reason to stop
116real(dp),    intent(in) :: n_yr_run ! # of years
117real(dp),    intent(in) :: n_yr_sim ! Current simulated year
118real(dp),    intent(in) :: nmax_yr_sim ! Maximum number of years to be simulated
119
120! LOCAL VARIABLES
121! ---------------
122logical(k4)   :: here
123integer(di)   :: cstat, ierr, funit
124character(20) :: fch1, fch2, fch3
125
126! CODE
127! ----
128call print_msg('> Updating "'//infofile_name//'"')
129inquire(file = infofile_name,exist = here)
130if (.not. here) call stop_clean(__FILE__,__LINE__,'cannot find required file "'//infofile_name//'"! It should be created by the launching script.',1)
131
132! Modify the header (first line)
133write(fch1,'(f'//int2str(nb_digits(n_yr_sim) + 5)//'.4)') n_yr_sim
134write(fch2,'(f'//int2str(nb_digits(nmax_yr_sim) + 5)//'.4)') nmax_yr_sim
135write(fch3,'(f6.4)') r_plnt2earth_yr ! 4 digits to the right of the decimal point to respect the precision of year in "launch_pem.sh"
136call execute_command_line('sed -i "1s/.*/'//trim(fch1)//' '//trim(fch2)//' '//trim(fch3)//' '//int2str(iPCM)//' '//int2str(iPEM + 1)//' '//int2str(nPCM)//' '//int2str(nPCM_ini)//'/" launchPEM.info',cmdstat = cstat)
137if (cstat > 0) then
138    call stop_clean(__FILE__,__LINE__,'command execution failed!',1)
139else if (cstat < 0) then
140    call stop_clean(__FILE__,__LINE__,'command execution not supported!',1)
141end if
142
143! Add the information of current PEM run at the end of file
144open(newunit = funit,file = infofile_name,status = "old",position = "append",action = "write",iostat = ierr)
145if (ierr /= 0) call stop_clean(__FILE__,__LINE__,'error opening file "'//infofile_name//'"!',ierr)
146! Date, Number of years done by the PEM run, Number of years done by the chainded simulation, Code of the stopping criterion
147write(funit,'(f20.4,f20.4,f20.4,i20)') pem_ini_date + n_yr_sim, n_yr_run, n_yr_sim, stopPEM
148close(funit)
149
150END SUBROUTINE update_info
151!=======================================================================
152
153END MODULE info
Note: See TracBrowser for help on using the repository browser.