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

Last change on this file since 4066 was 4065, checked in by jbclement, 2 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: 25.3 KB
Line 
1MODULE display
2!-----------------------------------------------------------------------
3! NAME
4!     display
5!
6! DESCRIPTION
7!     Contains wrappers to print information.
8!
9! AUTHORS & DATE
10!     JB Clement, 12/2025
11!
12! NOTES
13!
14!-----------------------------------------------------------------------
15
16! DEPENDENCIES
17! ------------
18use, intrinsic :: iso_fortran_env, only: stdout => output_unit
19use, intrinsic :: iso_fortran_env, only: stderr => error_unit
20use, intrinsic :: iso_fortran_env, only: stdin => input_unit
21use numerics,                      only: dp, di, li, k4, minieps
22
23! DECLARATION
24! -----------
25implicit none
26
27! VARIABLES
28! ---------
29character(128) :: dir = ' '      ! Current directory
30character(32)  :: logname = ' '  ! User name
31character(32)  :: hostname = ' ' ! Machine/station name
32
33contains
34!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
35
36!=======================================================================
37SUBROUTINE print_ini()
38!-----------------------------------------------------------------------
39! NAME
40!     print_ini
41!
42! DESCRIPTION
43!     Print the initial display for the PEM.
44!
45! AUTHORS & DATE
46!     JB Clement, 12/2025
47!
48! NOTES
49!
50!-----------------------------------------------------------------------
51
52! DECLARATION
53! -----------
54implicit none
55
56! LOCAL VARIABLES
57! ---------------
58character(8)              :: date
59character(10)             :: time
60character(5)              :: zone
61integer(di), dimension(8) :: values
62
63! CODE
64! ----
65write(stdout,*) '  *    .          .   +     .    *        .  +      .    .       .      '
66write(stdout,*) '           +         _______  ________  ____    ____      *           + '
67write(stdout,*) ' +   .        *     |_   __ \|_   __  ||_   \  /   _|          .       *'
68write(stdout,*) '          .     .     | |__) | | |_ \_|  |   \/   |  *        *      .  '
69write(stdout,*) '       .              |  ___/  |  _| _   | |\  /| |      .        .     '
70write(stdout,*) '.  *          *      _| |_    _| |__/ | _| |_\/_| |_                  * '
71write(stdout,*) '            +       |_____|  |________||_____||_____|   +     .         '
72write(stdout,*) '  .      *          .   *       .   +       *          .        +      .'
73
74! Some user info
75call date_and_time(date,time,zone,values)
76call getcwd(dir)
77call getlog(logname)
78call hostnm(hostname)
79write(stdout,*)
80write(stdout,*) '********* PEM information *********'
81write(stdout,*)                     '+ User     : '//trim(logname)
82write(stdout,*)                     '+ Machine  : '//trim(hostname)
83write(stdout,*)                     '+ Directory: '//trim(dir)
84write(stdout,'(a,i2,a,i2,a,i4)')   ' + Date     : ',values(3),'/',values(2),'/',values(1)
85write(stdout,'(a,i2,a,i2,a,i2,a)') ' + Time     : ',values(5),':',values(6),':',values(7)
86write(stdout,*)
87write(stdout,*) '********* Initialization *********'
88
89END SUBROUTINE print_ini
90!=======================================================================
91
92!=======================================================================
93SUBROUTINE print_end(n_yr_run,dur_secs,r_plnt2earth_yr,pem_ini_date,n_yr_sim)
94!-----------------------------------------------------------------------
95! NAME
96!     print_end
97!
98! DESCRIPTION
99!     Print the ending display for the PEM.
100!
101! AUTHORS & DATE
102!     JB Clement, 01/2026
103!
104! NOTES
105!
106!-----------------------------------------------------------------------
107
108! DEPENDENCIES
109! ------------
110use utility, only: format_duration
111
112! DECLARATION
113! -----------
114implicit none
115
116! ARGUMENTS
117! ---------
118real(dp), intent(in) :: r_plnt2earth_yr, pem_ini_date, n_yr_sim, n_yr_run, dur_secs
119
120! CODE
121! ----
122write(stdout,*)
123write(stdout,*) '****** PEM final information *******'
124write(*,'(a,f16.4,a)')         ' + This run achieved ', n_yr_run, ' Planetary years in '//format_duration(dur_secs)//' (computing time).'
125write(*,'(a,f16.4,a,f16.4,a)') ' + The chained simulation has achieved ', n_yr_sim, ' Planetary years =', n_yr_sim*r_plnt2earth_yr, ' Earth years.'
126write(*,'(a,f16.4,a)')         ' + The reached date is now ', (pem_ini_date + n_yr_sim)*r_plnt2earth_yr, ' Earth years.'
127write(*,*)                      '+ PEM: so far, so good!'
128write(stdout,*) '************************************'
129call but_why(n_yr_run)
130
131END SUBROUTINE print_end
132!=======================================================================
133
134!=======================================================================
135SUBROUTINE print_msg(message,frmt)
136!-----------------------------------------------------------------------
137! NAME
138!     print_msg
139!
140! DESCRIPTION
141!     Print a simple message (string).
142!
143! AUTHORS & DATE
144!     JB Clement, 02/2026
145!
146! NOTES
147!
148!-----------------------------------------------------------------------
149
150! DECLARATION
151! -----------
152implicit none
153
154! ARGUMENTS
155! ---------
156character(*), intent(in)           :: message
157character(*), intent(in), optional :: frmt
158
159! CODE
160! ----
161if (present(frmt)) then
162    write(stdout,frmt) message
163else
164    write(stdout,*) message
165end if
166
167END SUBROUTINE print_msg
168!=======================================================================
169
170!=======================================================================
171SUBROUTINE print_err(message,frmt)
172!-----------------------------------------------------------------------
173! NAME
174!     print_err
175!
176! DESCRIPTION
177!     Print a simple message (string).
178!
179! AUTHORS & DATE
180!     JB Clement, 02/2026
181!
182! NOTES
183!
184!-----------------------------------------------------------------------
185
186! DECLARATION
187! -----------
188implicit none
189
190! ARGUMENTS
191! ---------
192character(*), intent(in)           :: message
193character(*), intent(in), optional :: frmt
194
195! CODE
196! ----
197if (present(frmt)) then
198    write(stderr,frmt) message
199else
200    write(stderr,*) message
201end if
202
203END SUBROUTINE print_err
204!=======================================================================
205
206!=======================================================================
207SUBROUTINE but_why(n_yr_run)
208!-----------------------------------------------------------------------
209! NAME
210!     but_why
211!
212! DESCRIPTION
213!     Print a cool surprise.
214!
215! AUTHORS & DATE
216!     JB Clement, 02/2026
217!
218! NOTES
219!     \(^o^)/
220!     A rare egg may be hidden somewhere in this module... True trainers
221!     will know better than to consult an AI to hatch it.
222!-----------------------------------------------------------------------
223
224! DECLARATION
225! -----------
226implicit none
227
228! ARGUMENTS
229! ---------
230real(dp), intent(in) :: n_yr_run
231
232! LOCAL VARIABLES
233! ---------------
234integer(di), dimension(5,50), parameter  :: exeggcute = transpose(reshape([ &
235                                                        87,104,97,116,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
236                                                        68,69,65,68,66,69,65,84,45,80,76,65,78,69,84,32,105,115,32,101,118,111,108,118,105,110,103,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
237                                                        84,97,45,100,97,32,46,46,46,32,84,97,45,100,97,32,46,46,46,32,84,97,45,100,97,32,46,46,46,32,84,97,32,116,97,45,100,97,32,116,97,45,100,97,33,0,0,0,0,0,0, &
238                                                        67,111,110,103,114,97,116,117,108,97,116,105,111,110,115,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
239                                                        89,111,117,114,32,68,69,65,68,66,69,65,84,45,80,76,65,78,69,84,32,101,118,111,108,118,101,100,32,105,110,116,111,32,70,65,66,85,76,79,85,83,45,80,76,65,78,69,84,33 &
240                                                        ],[50,5]))
241integer(di), dimension(20,42), parameter :: exeggutor = transpose(reshape([ &
242                                                        73,32,119,97,110,110,97,32,98,101,32,116,104,101,32,118,101,114,121,32,98,101,115,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
243                                                        76,105,107,101,32,110,111,32,109,111,100,101,108,32,101,118,101,114,32,119,97,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
244                                                        84,111,32,98,117,105,108,100,32,116,104,101,109,32,114,105,103,104,116,44,32,116,104,97,116,226,128,153,115,32,109,121,32,114,101,97,108,32,116,101,115,116,0,0, &
245                                                        84,111,32,115,105,109,117,108,97,116,101,32,116,104,101,109,32,105,115,32,109,121,32,99,97,117,115,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
246                                                        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
247                                                        73,32,119,105,108,108,32,116,114,97,118,101,108,32,103,114,105,100,115,32,97,110,100,32,108,97,110,100,115,0,0,0,0,0,0,0,0,0,0,0,0,0, &
248                                                        70,114,111,109,32,99,111,114,101,32,116,111,32,115,107,121,32,115,111,32,119,105,100,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
249                                                        84,101,97,99,104,32,112,108,97,110,101,116,115,32,104,111,119,32,116,111,32,117,110,100,101,114,115,116,97,110,100,0,0,0,0,0,0,0,0,0,0,0, &
250                                                        84,104,101,32,112,104,121,115,105,99,115,32,100,101,101,112,32,105,110,115,105,100,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
251                                                        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
252                                                        80,76,65,78,69,84,83,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
253                                                        71,111,116,116,97,32,109,111,100,101,108,32,116,104,101,109,32,97,108,108,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
254                                                        73,116,226,128,153,115,32,115,99,105,101,110,99,101,32,97,110,100,32,99,111,100,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
255                                                        73,32,107,110,111,119,32,105,116,226,128,153,115,32,109,121,32,99,97,108,108,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
256                                                        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
257                                                        80,76,65,78,69,84,83,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
258                                                        70,114,111,109,32,100,117,115,116,32,116,111,32,103,108,111,119,105,110,103,32,115,112,104,101,114,101,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
259                                                        87,105,116,104,32,116,105,109,101,32,97,110,100,32,114,101,115,111,108,118,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, &
260                                                        73,226,128,153,108,108,32,101,118,111,108,118,101,32,116,104,101,109,32,116,104,114,111,117,103,104,32,121,101,97,114,115,0,0,0,0,0,0,0,0,0,0, &
261                                                        32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,226,128,148,32,74,66,67,0,0,0,0 &
262                                                        ],[42,20]))
263real(dp),                      parameter :: first_gen = 151._dp
264character(256), dimension(59)            :: why_not
265character(256), dimension(11)            :: surprise
266integer(di)                              :: i
267
268! CODE
269! ----
270why_not(37) = '⠀⠀⠀⠀⠈⢧⣭⠡⣤⢿⣿⣟⣷⡀⠀⢧⣻⡇⠘⣿⣟⡇⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⢿⣿⣿⣷⣤⣈⠙⠿⠿⣿⣿⣿⣥⣯⣤⣾⡿⠚⠁⠀⢻⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
271why_not(12) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠹⡀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣻⣽⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
272why_not(55) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠓⠦⣤⣀⠀⠉⠉⠉⠀⠀⠉⠉⠉⠍⠀⠀⣀⣤⠴⠀⠉⠛⠂⢿⣷⣦⣌⣙⠛⠻⠿⠿⠿⠷⠙⠛⢁⣴⣿⣷⡇⠀'
273why_not(4)  = '⠀⠀⠀⠀⢀⡴⠚⡉⠍⢉⣉⣉⡁⠒⢂⠄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
274why_not(29) = '⠀⠀⢀⣠⣶⠶⣶⣶⣶⣶⣤⣄⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
275why_not(46) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡎⢇⢻⣿⣇⠘⠆⠱⢄⠀⠙⢿⣦⣈⠻⣿⣮⣛⣷⣄⠑⠶⣶⣦⣐⣮⣽⣿⣿⣿⣯⣶⣾⠻⡿⢟⡹⠃⠀⢁⠀⠀⠀⣠⣶⠇⡀⠀⠀⠀⠀⠀⠀⠀⠀'
276why_not(8)  = '⠀⠀⠀⠀⠀⠱⡠⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
277why_not(21) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠉⠛⠋⠛⢟⡚⠍⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠴⡀⠀⠀⠀⠀'
278why_not(3)  = ' '
279why_not(41) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⡄⠻⣿⣄⠙⣿⣷⡹⣦⡈⠻⣿⣷⡌⠙⢿⣷⣦⣀⠂⢄⣀⡀⠀⠀⠀⡉⠲⠶⠶⠟⠻⠿⣷⣾⣿⣿⣱⠟⠉⠉⠐⢀⣴⢯⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀'
280why_not(18) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠺⣑⠮⡝⢷⡞⡘⢎⠼⡙⢬⠓⡬⠣⢄⠩⢐⠡⡘⡰⢭⣞⡿⠋⠀⠀⠀⠀⠀⠀⠀⠢⠀⠀⠀⠀⠀⠀⠀⠀'
281why_not(52) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠳⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⠂⠀⠀⠀⠀⠀⠀⠛⢿⣿⣷⡽⡢⠙⢿⣿⣿⣿⣶⣤⣀⠀⠬⢄⣀⣀⣠⠔⢁⣾⣿⠇⣰⡄⢿⢀⡏⡇'
282why_not(9)  = '⠀⠀⠀⠀⠀⠀⠳⡡⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
283why_not(33) = '⠀⠸⡏⣾⣿⡄⢻⣿⣿⢱⣿⠁⡔⠋⠉⠉⠐⠀⣩⡴⠋⢹⠁⢸⣿⣜⢿⡌⢻⣦⣿⣷⣄⠙⠦⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢦⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
284why_not(1)  = trim(confusion(exeggcute(1,:)))
285why_not(58) = trim(confusion(exeggcute(4,:)))
286why_not(26) = ' '
287why_not(14) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⢿⣻⣿⡿⣿⣾⢷⣯⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
288why_not(47) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⠈⠢⡙⢿⢷⣤⣄⡀⠑⠠⡀⠛⢿⣷⣌⠛⢿⣷⣝⢿⣦⡈⠙⠛⠛⠛⠒⠒⠂⠀⠀⠈⠛⠛⠉⡠⠒⡉⠉⣦⣴⡴⠋⡾⣀⢿⣄⠀⠀⠀⠀⠀⠀⠀'
289why_not(6)  = '⠀⠀⠀⠀⢹⢸⠘⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⠰⠠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
290why_not(40) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣧⡈⢿⣿⣝⢷⣄⠙⢧⡀⣈⠻⣿⣿⣵⠀⠈⠛⠦⡀⠀⠀⠀⠀⠈⠉⠉⠀⠀⠀⣠⢤⣦⣄⣸⣿⡿⣫⣽⣿⣯⠟⠀⣸⣾⡆⠀⠀⠀⠀⠀⠀⠀⠀'
291why_not(24) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠓⠢⢖⡠⠄⢀⠠⠤⠤⠤⠀⢂⠤⢁⡞⠀⠀⠀⠀'
292why_not(35) = '⠀⠀⠘⣇⢻⣿⣇⠸⣿⣿⣿⡀⠇⠀⠀⡼⣿⣿⡇⠀⠀⠀⡀⠀⠻⣟⢿⣿⣿⣤⡀⠘⢿⣿⣿⣿⣿⣤⣄⣀⠀⠀⠀⠠⠄⠀⣀⣠⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
293why_not(10) = '⠀⠀⠀⠀⠀⠀⠀⠱⡁⡂⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
294why_not(59) = trim(confusion(exeggcute(5,:)))
295why_not(16) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣟⣾⡁⡧⣧⢵⣮⣵⣥⣼⣧⣥⢯⡾⣥⣤⡟⣯⢤⡛⢤⢎⣙⡽⣯⣿⠇⠀⠐⠠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
296why_not(44) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣦⡀⠀⠀⠀⠙⢛⣦⡈⠻⣷⣎⡻⣦⡈⠻⣿⣿⣶⣯⣝⣿⣿⣿⣖⣲⣶⣤⣤⣤⣄⣤⣤⣴⣶⣶⣶⠻⣉⣠⡴⠟⠁⡰⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀'
297why_not(2)  = trim(confusion(exeggcute(2,:)))
298why_not(31) = '⠀⣼⣿⣼⣿⠏⢠⣾⣿⣿⣿⣿⣿⣷⣶⣬⣝⡛⢷⣦⣄⠀⠀⠀⠀⣀⣤⢤⣴⣶⡶⠛⣛⢫⣿⣶⣾⣶⣦⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
299why_not(49) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣯⠀⠀⢀⠰⣤⠙⣿⣷⣤⣀⠀⠀⠀⠀⠉⢳⣶⣌⠻⢿⣷⣽⡿⣦⣄⠀⠀⠀⣀⣠⣤⣤⣥⡴⣾⠿⠒⠁⣠⣾⠃⢂⢻⣿⣧⡙⣿⣧⠀⠀⠀⠀'
300why_not(19) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠶⣩⠖⣭⠻⣷⣨⡑⣢⢉⠔⡡⢊⢄⡃⣖⣡⢗⡯⠞⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⡀⠀⠀⠀⠀⠀⠀'
301why_not(27) = trim(confusion(exeggcute(3,:)))
302why_not(53) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠳⣄⡈⠐⠠⣑⠢⢤⣄⣀⠁⠒⠒⠲⠦⠄⠀⠀⠀⠈⠛⢿⣷⣦⣌⠛⢿⣾⣿⣻⣿⣿⣿⣶⣦⡤⠤⠒⣐⣴⣿⡏⣿⡇⢸⣿⡆⠀'
303why_not(7)  = '⠀⠀⠀⠀⠸⡄⡜⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣥⣤⣶⣶⣶⣶⣶⣶⣦⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
304why_not(42) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠱⠀⠈⠻⣷⣌⠻⣿⣮⡻⣦⡈⠻⣿⣦⡈⠻⢿⣿⣿⣶⣍⣙⠷⠾⣿⣿⣷⣶⣶⣾⣿⠿⠿⠋⡩⠽⠛⠒⠁⠀⢀⣨⣴⢏⣻⠀⠀⠀⠀⠀⠀⠀⠀⠀'
305why_not(25) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠓⠒⠳⠬⠭⡥⠴⠞⠋⠀⠀⠀⠀⠀'
306why_not(57) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠙⠛⠛⠛⠉⠉⠁⠀⠀⠀'
307why_not(11) = '⠀⠀⠀⠀⠀⠀⠀⠀⠘⢆⠀⠀⠀⠀⠀⠀⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
308why_not(34) = '⠀⠀⢻⡸⣿⣷⠈⣿⣿⣟⣿⠀⠀⠀⠀⠀⣠⣾⣇⠀⠀⠈⠀⠸⣿⣿⣿⣾⡢⠙⠻⣿⣿⣿⣦⣈⠙⠛⠿⢶⣭⣍⠉⠯⠭⠔⠃⠈⣻⣧⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
309why_not(20) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠶⣋⢮⣓⢷⡴⡍⢾⣔⣫⢦⣽⡶⠟⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠒⡀⠀⠀⠀⠀⠀'
310why_not(45) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⢷⠻⣯⢦⠀⠀⠀⠀⠙⢿⣦⡈⠻⣿⣮⡻⣦⣀⠙⠪⠝⠛⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢟⣻⣿⣿⣷⠿⢛⠉⠀⠀⠈⠀⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀'
311why_not(5)  = '⠀⠀⠀⠀⣼⢁⠎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠈⠒⠠⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
312why_not(50) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢧⠀⠈⠢⣙⢷⡜⢧⡉⠛⠿⣦⡀⠀⢄⠈⠛⢧⡷⢆⡙⠻⣿⣿⣿⣿⣦⣄⡉⠉⠉⠉⠀⠈⠀⣠⠴⠋⡴⠁⠀⠀⡄⣿⣿⣧⠘⣿⡄⠀⠀⠀'
313why_not(28) = ' '
314why_not(17) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢻⡽⣹⣷⢮⡓⠮⣝⢾⣹⠽⣞⢧⡝⢶⣡⠛⡤⢃⠎⡱⢊⢶⣹⣿⠟⠀⠀⠀⠀⠐⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
315why_not(39) = '⠀⠀⠀⠀⠀⠀⠀⠹⣿⡄⣒⠈⣿⣯⡻⣦⡈⢻⣎⠈⠻⣿⣿⣦⣄⠈⠢⣤⡀⠀⠀⠀⠀⠀⢌⡙⠒⠀⠈⠙⠛⠛⠛⠛⠛⠉⣠⣤⣦⣤⣤⣿⠟⠀⢿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀'
316why_not(13) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢆⠄⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣽⣿⡽⣾⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
317why_not(56) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠙⠛⠒⠲⠒⠶⠒⠒⠛⠋⠉⠁⠀⠀⠀⠀⠀⠀⠀⠈⠙⠻⠿⢿⣿⣶⣶⣶⣶⣶⡿⠿⣿⡿⠋⠀⠀'
318why_not(22) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠚⢴⡠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⢠⢃⠀⠀⠀⠀'
319why_not(32) = '⠀⢹⢻⢻⣿⠀⣿⣿⣿⡿⣭⣶⠾⠟⠺⠿⢿⣿⣷⣦⠝⣫⡴⢺⣿⢿⡇⢻⣿⢿⣧⠀⢿⣮⡿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
320why_not(54) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠦⣄⡀⠉⠓⠢⣭⣿⣷⣶⣾⣿⣟⣛⣓⣀⣀⣀⣠⡌⠙⠻⣿⣦⣤⠙⠛⠿⣶⣭⣿⣛⡿⠿⠿⠿⠟⣫⣾⡿⠁⣼⡿⡇⠀'
321why_not(15) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣷⡟⢿⣏⡟⡿⣻⢿⡫⡟⣿⣯⡟⣿⢭⣯⡏⣦⡛⣽⢝⡻⣝⣿⣷⣿⣿⡧⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
322why_not(36) = '⠀⠀⠀⠘⣇⠻⣿⣄⠻⣿⣿⣷⡈⠀⠞⡁⣿⡜⣿⣶⢦⠀⠐⠀⠀⠙⢮⡛⢿⣿⣿⣷⣦⣌⡙⠻⢿⣿⣿⣿⣿⣿⣶⣶⣾⣿⣿⣿⣿⡿⡩⢷⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
323why_not(48) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣷⡀⠹⡀⠙⠲⣬⣛⢦⡀⠀⠀⠀⠈⠻⣷⣄⠙⠻⣿⣮⡻⣶⣄⡉⠀⠈⠃⠀⠀⠀⠀⠀⠀⠀⠰⠏⢂⣼⠟⠋⠀⣼⢡⣿⣦⠻⣮⣳⡀⠀⠀⠀⠀'
324why_not(23) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠑⠣⣄⡄⡀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡈⠰⢸⠀⠀⠀⠀'
325why_not(38) = '⠀⠀⠀⠀⠀⠈⢻⣷⡉⣤⠻⣿⣿⣿⣄⠈⣿⡿⡌⢾⣿⣧⡀⠀⠀⡀⠀⠀⠀⠀⠀⠙⠷⣮⣙⠛⠿⣿⣿⣿⣿⣿⣿⣿⠿⠟⣋⡀⠀⠀⠁⣠⣾⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
326why_not(30) = '⠀⢠⣿⢟⣵⣿⡿⠛⠛⠛⠛⠛⠻⠿⣷⣦⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀'
327why_not(43) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣄⠁⠀⠀⠉⢿⣧⡈⠻⣿⣮⡻⣦⡈⠻⣿⣦⣕⡿⢿⣶⣭⣉⡛⠒⠦⠄⠉⠉⠑⠛⠻⠗⠒⠀⢀⣤⠶⢀⣴⡾⣿⠟⣡⠏⣸⠀⠀⠀⠀⠀⠀⠀⠀⠀'
328why_not(51) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣷⡄⠀⠀⠉⠁⠀⠙⣦⠀⠂⡍⠑⠀⠉⠀⠀⠉⢻⠓⣶⡄⠈⠹⣿⣿⣿⣿⣶⣤⠀⠀⠐⠉⠀⢠⡞⠁⠀⠀⠀⡇⢸⣿⡟⣧⢱⢸⣿⡆⠀'
329
330surprise(10) = '⠀⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀'
331surprise(9)  = '⠀⠀⠀⢿⣶⣿⣿⣿⣿⣿⡻⣿⡿⣿⣿⣿⣿⣶⣶⣾⣿⣿⠀⠀'
332surprise(3)  = '⠀⠘⢿⣿⣿⣿⣿⣦⣀⣀⣀⣄⣀⣀⣠⣀⣤⣶⣿⣿⣿⣿⣿⠇'
333surprise(11) = '⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀'
334surprise(5)  = '⠀⠀⠀⠀⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⠋⠀⠀⠀'
335surprise(8)  = '⠀⠀⠀⡁⠀⠈⣿⣿⣿⣿⢟⣛⡻⣿⣿⣿⣟⠀⠀⠈⣿⡇⠀⠀'
336surprise(6)  = '⠀⠀⠀⢠⣿⣿⡏⠆⢹⣿⣿⣿⣿⣿⣿⠒⠈⣿⣿⣿⣇⠀⠀⠀'
337surprise(4)  = '⠀⠀⠈⠻⣿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀'
338surprise(7)  = '⠀⠀⠀⣼⣿⣿⣷⣶⣿⣿⣛⣻⣿⣿⣿⣶⣾⣿⣿⣿⣿⡀⠀⠀'
339surprise(2)  = '⠀⣿⣿⣿⣷⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣶⣾⣿'
340surprise(1)  = '⢰⣶⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀'
341
342if (gottacatch_emall_()) then
343    write(stdout,*)
344    if (abs(n_yr_run - first_gen) < minieps) then
345        do i = 1,size(surprise)
346            write(stdout,*) trim(surprise(i))
347        end do
348        write(stdout,*) ' '
349        do i = 1,size(exeggutor,1)
350            write(stdout,*) trim(confusion(exeggutor(i,:)))
351        end do
352    else
353        do i = 1,size(why_not)
354            write(stdout,*) trim(why_not(i))
355        end do
356    end if
357end if
358
359END SUBROUTINE but_why
360!=======================================================================
361
362!=======================================================================
363FUNCTION gottacatch_emall_() RESULT(flag)
364!-----------------------------------------------------------------------
365! NAME
366!     gottacatch_emall_
367!
368! DESCRIPTION
369!     Find the egg.
370!
371! AUTHORS & DATE
372!     JB Clement, 02/2026
373!
374! NOTES
375!     Oh? An egg is about to hatch!
376!-----------------------------------------------------------------------
377
378! DECLARATION
379! -----------
380implicit none
381
382! LOCAL VARIABLES
383! ---------------
384integer(di), dimension(13), parameter :: egg = [80,82,79,70,69,83,83,79,82,95,79,65,75]
385integer(di), dimension(43), parameter :: who = [79,104,63,32,73,116,32,115,101,101,109,115,32,121,111,117,39,114,101,32,110,111,116,32,116,104,101,32,114,105,103,104,116,32,112,101,114,115,111,110,46,46,46]
386character(20)                         :: why_yes
387integer(di)                           :: ierr
388logical(k4)                           :: flag
389
390! CODE
391! ----
392flag = .false.
393call get_environment_variable(trim(confusion(egg)),why_yes,status = ierr)
394if (ierr == 0) then
395    flag = trim(why_yes) == 'yes'
396    if (.not. flag) then
397        write(stdout,*)
398        write(stdout,*) trim(confusion(who))
399    end if
400end if
401
402END FUNCTION gottacatch_emall_
403!=======================================================================
404
405!=======================================================================
406FUNCTION confusion(code) RESULT(msg)
407!-----------------------------------------------------------------------
408! NAME
409!     confusion
410!
411! DESCRIPTION
412!     PEM used confusion!
413!
414! AUTHORS & DATE
415!     JB Clement, 02/2026
416!
417! NOTES
418!     USER is confused! It hurt itself in its confusion!
419!-----------------------------------------------------------------------
420
421! DECLARATION
422! -----------
423implicit none
424
425! ARGUMENTS
426! ---------
427integer(di), dimension(:), intent(in) :: code
428
429! LOCAL VARIABLES
430! ---------------
431integer(di)               :: i
432character(:), allocatable :: msg
433
434! CODE
435! ----
436msg = ''
437do i = 1,size(code)
438    if (code(i) /= 0) msg = msg//achar(code(i))
439end do
440
441END FUNCTION confusion
442!=======================================================================
443
444END MODULE display
Note: See TracBrowser for help on using the repository browser.