source: BOL/Replay/replay_param.sh @ 4530

Last change on this file since 4530 was 4337, checked in by fhourdin, 2 years ago

Import initial des outils Replay

File size: 10.3 KB
RevLine 
[4337]1#!/bin/bash
2
3#=============================================================================
4#  F. Hourdin : 2022/05/03
5#
6#  Objet :
7#  -----
8#  Script préparant les programes pour rejouer (replay) une paramétrisation
9#  ou un morceau de paramétriation.
10#
11#
12#  Applicabilité :
13#  ---------------
14#  Est fait pour rejouer des paramétisation de LMDZ organisées comme
15#    des calcul sur des successions de colonnes indépendantes (boucle
16#    interne en $klon) de $klev niveaux verticaux.
17#  Demande que la paramétrisation répondent aux règles de codage suivantes :
18#  1) Les routines de calcul et les routines ou fonction qu'elles appellent
19#     n'ont que deux interfaces : A) les arguments d'entrée
20#                                 B) le use d'un unique module
21#     Entre autre, les dimensions de la paramétrisation sont passés
22#     en argument, ce qui permet une allocation dynamique implicite
23#     de toutes les variables.
24#  2) le module d'initialisation doit lui même être initialisé par
25#     une unique routine pilotée entièrement par ses arguments.
26#  3) Toutes les variables d'interface doivent être déclarées intent in
27#     ou intent out.
28#  On appelera la paramétriation "param" et l'intialisation "param_ini"
29#     mais les noms de fichiers sont en argument dans le script.
30#
31#
32#  Principe :
33#  ----------
34#  Dans une première simulation, on écrit dans un fichier binaire toutes
35#  les variables "intent in" de la routine d'initialisation et de la routine
36#  de calcul.
37#
38#
39#  En pratique :
40#  -------------
41#
42#  Le script est commandé par les variables suivantes
43#   param=wake             # nom de la subroutine (à l'interireur du fichier)
44#   paramini=wake_ini  # nom de la subroutine d'intialisation
45#   inimod= # nom du module contenant $param_ini
46#   klon=klon ; klev=klev  # nom des dimensions horiz; vert utilisée
47#
48#  Le fichier ${paramfile} contenant $param est detecté automatiquement
49#  Le script crée 4 fichiers
50#  * dump_param.h          : écriture de l'interface "in" de param (dump_param.bin fort.82)
51#  * call_param_replay.F90 : sous programme d'appelle en boucle à la param
52#  * dump_ini_module.F90   : écriture de l'interface "in" de param_ini
53#  * get_ini_module.F90    : lecture de l'interface "in" de param_ini
54#                dans ${param_ini}_mod.bin.
55#  Par ailleurs, un programme replay1d a été ajouté dans phylmd/dyn1d
56#        qui appelle call_param_replay
57#  Le script ajoute par ailleurs quelques lignes dans ${paramfile} et
58#        ${param_ini}.F90
59#  replay_clean.sh élimine toutes les lignes ajoutées
60#
61#
62#  A travailler :
63#  --------------
64#  * détecter automatiquement le fichier contenant l'intialisation
65#  * détecter automatiquement les dimensions
66#  * avoir un moyen de vérifier si les variables intent in et out sont
67#    bien les bonnes.
68#  * test en 3D.
69#  * Initialisation plus simple de la routine getin_p
70#  * Des choix sur la facon de controler l'initialisation et le pb des getin
71#  * Modifier la compilation du 1D pour pouvoir compiler lmdz1d et replay1d
72#  * Comprendre pourquoi le replay de wake ne semble pas donner une convegence
73#      numerique avec la version initiale
74#  * L'identification des variables intent in & out pour l'ecriture dans .h
75#     va sans doute foirer si plusieurs routines dans le même fichier.
76#     On pourrait d'ailleurs sortir toutes les variables locales également.
77#     En option par exemple
78#  * Corriger create_make_gcm (pour le main) et makelmdz (pour les checks
79#     sur la necessitee d'appeler create_make_gcm)
80#  * Mettre en option le fait de pouvoir sortir non seulement toutes
81#     les variables d'interface mais même toutes les variables internes.
82#
83#=============================================================================
84
85param=$1
86case $param in
87   thermcell_main|thermcell_plume_6A|thermcell_env|thermcell_height|thermcell_dry|\
88      thermcell_closure|thermcell_height|thermcell_dq|thermcell_flux2|thermcell_down) \
89      paramini=thermcell_ini ; inimod=thermcell_ini_mod ; klon=ngrid ; klev=nlay ;;
90   wake) paramini=wake_ini ; inimod=wake_ini_mod ; klon=klon ; klev=klev ;;
91   *) echo Cas non prevu ; exit
92esac
93
94replay_comment="replay automatic include"
95
96#-----------------------------------------------------------------------------
97# Transformer l'entete d'une subroutine en un call
98#-----------------------------------------------------------------------------
99
100function get_subroutine_arg(){
101   cat $1 | tr '[A-Z]' '[a-z]' > tmp
102   line1=`sed -n -e '/subrou.*(/=' tmp | head -1 `
103   line2=`tail -n +$line1 tmp | sed -n -e '/)/=' | head -1`
104   tail -n +$line1 tmp | sed -n -e 1,${line2}p
105}
106
107#-----------------------------------------------------------------------------
108function extract_subroutine(){
109#-----------------------------------------------------------------------------
110   # $1 nom de la subroutine
111   # $2 nom du fichier
112   # cat $2 | tr '[A-Z]' '[a-z]' > tmp
113   cpp $2 | tr '[A-Z]' '[a-z]' > tmp
114   name_min=`echo $1 | tr '[A-Z]' '[a-z]'`
115   line1=`sed -n -e "/subrou.*${name_min}.*(/=" tmp | head -1 `
116   tail -n +$line1 tmp > tmp2
117   line2=`sed -n -e "/[Rr][Ee][Tt][Uu][Rr][Nn]/=" tmp2 | head -1`
118   head -$line2 tmp2
119   \rm -f tmp tmp2
120}
121
122#-----------------------------------------------------------------------------
123function get_param_file(){
124#-----------------------------------------------------------------------------
125  grep -i "subro.* $1[\ (]" *.F90 | sed -e 's/ //g' | grep "$1(" | cut -d: -f1
126}
127
128#-----------------------------------------------------------------------------
129# Identification et passage à la casse du bas pour du fichier contenant la param
130#-----------------------------------------------------------------------------
131
132paramfile=`get_param_file $param`
133echo La parametrisation $param est contenue dans le fichier $paramfile
134if [ `echo ${paramfile} | wc -w` != 1 ] ; then exit ; fi
135extract_subroutine $param $paramfile > input
136
137#-----------------------------------------------------------------------------
138# Liste des variables d'intent in pour stokage
139#-----------------------------------------------------------------------------
140
141varin0=`grep inten.*.in input | sed -e '/\!.*$/d' | cut -d: -f3 | sed -e 's/,/ /g'`
142echo varin0 $varin0
143varin=`echo $varin0 | sed -e 's/ /,/g' -e "s/,,,/,/g" -e "s/,,/,/g"`
144echo varin $varin
145output=full # Attention, l'option full ne marche pas a cause de tableaux locaux undef
146nvar0D=0 ; nvar1D=0 ; nvar2D=0
147case $output in
148   light) search_str='real.*intent' ;;
149   full) search_str='real'
150esac
151var_1D=`grep -i "$search_str" input | grep $klon | sed -e 's/!.*$//' -e /$klev/d | cut -d: -f3 | sed -e 's/,/ /g'`
152var_2D=`grep -i "$search_str" input | grep $klon | grep $klev | cut -d: -f3 | sed -e 's/!.*$//' -e 's/,/ /g'`
153echo varin  : $varin
154echo var_1D : $var_1D
155echo var_2D : $var_2D
156
157#-----------------------------------------------------------------------------
158# Ecriture de la routine d'appel a la parametrisation en mode replay
159#-----------------------------------------------------------------------------
160
161cat > call_param_replay.F90 <<eod
162subroutine call_param_replay($klon,$klev)
163IMPLICIT NONE
164integer ifin
165eod
166head -200 input | grep intent | sed -e 's/ //g' -e 's/,intent(.*[nt])//'>> call_param_replay.F90
167cat >> call_param_replay.F90 <<eod
168read(82,iostat=ifin) $varin
169if (ifin<0) stop "Fin du fichier fort.82"
170eod
171get_subroutine_arg $paramfile | sed -e 's/subroutine/call/' >> call_param_replay.F90
172echo return >> call_param_replay.F90
173echo end >> call_param_replay.F90
174
175#-----------------------------------------------------------------------------
176# Creation d'un .h d'ecriture de toutes les variables intent in & out
177#-----------------------------------------------------------------------------
178
179paraminc=dump_param.h
180cat > $paraminc <<eod
181   write(81) $varin
182eod
183for var in $var_1D ; do
184echo "call iotd_ecrit_seq('"$var"',1,'"$var"',' ',"$var")" >> $paraminc
185done
186for var in $var_2D ; do
187echo "call iotd_ecrit_seq('"$var"',"$klev",'"$var"',' ',"$var")" >> $paraminc
188done
189 
190#-----------------------------------------------------------------------------
191# dump_ini_module gere l'ecriture des variables d'interface de l'intialisation
192# du module en mode replay
193#-----------------------------------------------------------------------------
194
195varinmod=`grep -i 'intent.in' $inimod.F90 | sed -e 's/\!.*$//' | cut -d: -f3 | sed -e 's/,/ /g'`
196varinmodv=`echo $varinmod | sed -e 's/ /,/g'`
197cat > dump_ini.h <<eod
198open(90,file='$inimod.bin',form='unformatted')
199write(90) $varinmodv
200close(90)
201eod
202
203
204#-----------------------------------------------------------------------------
205# get_ini_module gere l'initialisation du module en mode replay
206#-----------------------------------------------------------------------------
207
208cat > get_ini_module.F90 <<eod
209subroutine get_ini_module
210use $inimod
211IMPLICIT NONE
212eod
213grep -i intent.in $inimod.F90  |  tr '[A-Z]' '[a-z]' | sed -e 's/,.*intent.i.*)//' >> get_ini_module.F90
214cat >> get_ini_module.F90 <<eod
215open(90,file='$inimod.bin',form='unformatted')
216read(90) $varinmodv
217close(90)
218eod
219get_subroutine_arg $inimod.F90 | sed -e 's/subroutine/call/' >> get_ini_module.F90
220cat >> get_ini_module.F90 <<eod
221return
222end
223eod
224
225#-----------------------------------------------------------------------------
226# On nettoye les inclusions précédente dans les fichiers .F90
227#-----------------------------------------------------------------------------
228
229for file in `grep "$replay_comment" *.F90 2> /dev/null | cut -d: -f1` ; do
230   sed -i"" -e "/$replay_comment/d" $file
231done
232line=`sed -n -e "/CALL wake_ini/=" physiq_mod.F90 | head -1`
233cp physiq_mod.F90 physiq_mod.$$
234sed -i"" -e "${line}s/$/\n   CALL iophys_ini(pdtphys) ! $replay_comment\n   open(81,file='dump_param.bin',form='unformatted')  ! $replay_comment/" physiq_mod.F90
235
236
237#-----------------------------------------------------------------------------
238# Inclusion d'un include dans la parametrisation
239#-----------------------------------------------------------------------------
240
241line=`sed -n -e "/^.*[Rr][Ee][Tt][Uu][Rr][Nn].*$/=" $paramfile | head -1`
242sed -i"" -e "${line}s/^.*$/   include \"$paraminc\" ! $replay_comment \n RETURN/" $paramfile
243
244#-----------------------------------------------------------------------------
245# Inclusion de l'ecriture de l'interface de l'initialisation
246#-----------------------------------------------------------------------------
247
248sed -i'' -e "s/^.*[Rr][Ee][Tt][Uu][Rr][Nn].*$/include \"dump_ini.h\" ! $replay_comment \n RETURN/" $inimod.F90
249
250#\rm -f tmp input
Note: See TracBrowser for help on using the repository browser.