source: trunk/LMDZ.COMMON/libf/evolution/deftank/lib_launchPEM.sh @ 3861

Last change on this file since 3861 was 3861, checked in by jbclement, 5 months ago

PEM:

  • Big update of "README" file in the "deftank" folder.
  • Renaming the log files "out_run*" into "run.log".
  • Merging the folders "out_PCM" and "out_PEM" into "logs" where the log files are gathered with convenient renaming.
  • Update of job files.
  • More robust tests in "lib_launchPEM.sh".

JBC

  • Property svn:executable set to *
File size: 17.0 KB
Line 
1#!/bin/bash
2########################################################################
3######## Library of bash functions for the PEM launching script ########
4########################################################################
5
6# To end the launching script
7endlaunch() {
8    # Restore the previous value of LC_NUMERIC
9    LC_NUMERIC=$OLD_LC_NUMERIC
10
11    date
12    echo "Success: the launching script for the PEM simulation completed normally!"
13    exit 0
14}
15
16# To end the launching script with error
17errlaunch() {
18    # Restore the previous value of LC_NUMERIC
19    LC_NUMERIC=$OLD_LC_NUMERIC
20
21    date
22    echo "Error: an issue occured in the launching script for the PEM simulation!"
23    exit 1
24}
25
26# To check what is the job scheduler
27function job_scheduler() {
28    if command -v squeue &> /dev/null; then
29        echo "SLURM is installed on $machine."
30        name_job="#SBATCH --job-name="
31        kill_job="scancel"
32        submit_job="sbatch --parsable"
33        submit_dependjob="sbatch --parsable --dependency"
34    elif command -v qstat &> /dev/null; then
35        echo "PBS/TORQUE is installed on $machine."
36        name_job="#PBS -N "
37        kill_job="qdel"
38        submit_job="qsub"
39        submit_dependjob="qsub -W depend"
40    else
41        echo "Error: neither SLURM nor TORQUE/PBS is installed on $machine!"
42        echo "You need to adapt the script to your job scheduler or set 'mode' to 0."
43        errlaunch
44    fi
45}
46
47# To get the number of slopes for the simulation
48get_nslope() {
49    ns=1
50    if [ -f "startfi.nc" ]; then
51        ns=$(ncdump -h startfi.nc | sed -n 's/.*nslope = \([0-9]*\) ;.*/\1/p')
52    else
53        for f in run_PCM.def callphys.def; do
54            if [[ -f "$f" ]]; then
55                while IFS= read -r line; do
56                    # Remove leading whitespace
57                    trimmed=$(echo "$line" | sed 's/^[[:space:]]*//')
58                    # Skip lines that are commented out
59                    if [[ "$trimmed" == \#* ]]; then
60                        continue
61                    fi
62                    # Check if line contains 'nslope = N'
63                    if [[ "$trimmed" =~ ^nslope[[:space:]]*=[[:space:]]*([0-9]+) ]]; then
64                        ns="${BASH_REMATCH[1]}"
65                        break
66                    fi
67                done < "$f"
68                [[ -n "$ns" ]] && break
69            fi
70        done
71    fi
72}
73
74# To modify the xml file according nslope
75modify_xml() {
76    tmp="tmp_file_def.xml"
77    in_diurnalave=false
78    in_diurnalave_s=false
79
80    sed -i 's/enabled="\.true\.\">/enabled=".false.">/g' file_def_physics_mars.xml
81    while IFS= read -r line; do
82        case "$line" in
83            *'<file id="diurnalave"'*)
84                in_diurnalave=true
85                ;;
86            *'<file id="diurnalave_s"'*)
87                in_diurnalave_s=true
88                ;;
89        esac
90
91        if [[ $line == *'enabled="'* ]]; then
92            if $in_diurnalave; then
93                if [[ $ns -eq 1 ]]; then
94                    line='              enabled=".true.">'
95                else
96                    line='              enabled=".false.">'
97                fi
98            elif $in_diurnalave_s; then
99                if [[ $ns -eq 1 ]]; then
100                    line='              enabled=".false.">'
101                else
102                    line='              enabled=".true.">'
103                fi
104            fi
105        fi
106
107        case "$line" in
108            *'</file>'*)
109                in_diurnalave=false
110                in_diurnalave_s=false
111                ;;
112        esac
113
114        echo "$line" >> "$tmp"
115    done < file_def_physics_mars.xml
116
117    mv "$tmp" file_def_physics_mars.xml
118}
119
120# To check if everything necessary for the launching script is ok
121checklaunch() {
122    # Save the current value of LC_NUMERIC and set it to a locale that uses a dot as the decimal separator
123    OLD_LC_NUMERIC=$LC_NUMERIC
124    LC_NUMERIC=en_US.UTF-8
125
126    if [ -v n_mars_years ] && [ ! -z "$n_mars_years" ]; then
127        if [ $(echo "$n_mars_years <= 0." | bc -l) -eq 1 ]; then
128            echo "Error: 'n_mars_years' must be > 0!"
129            errlaunch
130        fi
131    elif [ -v n_earth_years ] && [ ! -z "$n_earth_years" ]; then
132        if [ $(echo "$n_earth_years <= 0." | bc -l) -eq 1 ]; then
133            echo "Error: 'n_earth_years' must be > 0!"
134            errlaunch
135        fi
136    else
137        echo "Error: the number of years to be simulated is not set!"
138        errlaunch
139    fi
140    if [ $nPCM_ini -lt 2 ] || [ -z "$nPCM_ini" ]; then
141        echo "Error: 'nPCM_ini' must be >= 2!"
142        errlaunch
143    fi
144    if [ $nPCM -lt 2 ] || [ -z "$nPCM" ]; then
145        echo "Error: 'nPCM' must be >= 2!"
146        errlaunch
147    fi
148    if [ ! -f "PCMrun.job" ]; then
149        echo "Error: file \"PCMrun.job\" does not exist in $dir!"
150        errlaunch
151    fi
152    if [ ! -f "PEMrun.job" ]; then
153        echo "Error: file \"PEMrun.job\" does not exist in $dir!"
154        errlaunch
155    fi
156    if [ ! -f "run_PCM.def" ]; then
157        echo "Error: file \"run_PCM.def\" does not exist in $dir!"
158        errlaunch
159    fi
160    if [ ! -f "run_PEM.def" ]; then
161        echo "Error: file \"run_PEM.def\" does not exist in $dir!"
162        errlaunch
163    fi
164    if [ ! -f "context_lmdz_physics.xml" ]; then
165        echo "Error: file \"context_lmdz_physics.xml\" does not exist in $dir!"
166        errlaunch
167    fi
168    if [ ! -f "field_def_physics_mars.xml" ]; then
169        echo "Error: file \"field_def_physics_mars.xml\" does not exist in $dir!"
170        errlaunch
171    fi
172    if [ ! -f "file_def_physics_mars.xml" ]; then
173        echo "Error: file \"file_def_physics_mars.xml\" does not exist in $dir!"
174        errlaunch
175    fi
176    if [ ! -f "iodef.xml" ]; then
177        echo "Error: file \"iodef.xml\" does not exist in $dir!"
178        errlaunch
179    fi
180    if [ ! -d "logs" ]; then
181        mkdir logs
182    fi
183    if [ ! -d "starts" ]; then
184        mkdir starts
185    fi
186    if [ ! -d "diags" ]; then
187        mkdir diags
188    fi
189    if [ $mode -ne 0 ]; then
190        job_scheduler
191    fi
192    # Set automatically the XIOS output file for the PEM according to the number of slopes
193    get_nslope
194    modify_xml
195}
196
197# To convert Earth years into Mars years
198convertyears() {
199    myear=686.9725      # Number of Earth days in Martian year
200    eyear=365.256363004 # Number of days in Earth year
201    convert_years=$(echo "$myear/$eyear" | bc -l)
202    convert_years=$(printf "%.4f" $convert_years) # Rounding to the 4th decimal to respect the precision of Martian year
203    if [ -v n_mars_years ]; then
204        n_myear=$n_mars_years
205        echo "Number of years to be simulated: $n_myear Martian years."
206    elif [ -v n_earth_years ]; then
207        n_myear=$(echo "$n_earth_years/$convert_years" | bc -l)
208        echo "Number of years to be simulated: $n_earth_years Earth years = $n_myear Martian years."
209    fi
210}
211
212# To initialize the launching script
213initlaunch() {
214    echo "This is a chained simulation for PEM and PCM runs in $dir on $machine by $user."
215    convertyears
216    i_myear=0.
217    iPEM=1
218    iPCM=1
219    if [ -f "startfi.nc" ]; then
220        cp startfi.nc starts/
221    fi
222    if [ -f "start.nc" ]; then
223        cp start.nc starts/
224    elif [ -f "start1D.txt" ]; then
225        cp start1D.txt starts/
226    fi
227    if [ -f "startpem.nc" ]; then
228        cp startpem.nc starts/
229    fi
230
231    # Create a file to manage years of the chained simulation and store some info from the PEM runs
232    echo $i_myear $n_myear $convert_years $iPCM $iPEM $nPCM $nPCM_ini > info_PEM.txt
233}
234
235# To submit the PCM runs
236# arg1: launching mode
237# arg2: counting method
238# arg3: number of PCM runs to launch
239# arg4: local number of the PCM run from which to start (optional)
240submitPCM() {
241    find . -type f -name "PCMrun*.job" ! -name "PCMrun.job" -delete
242    ii=1
243    if [ ! -z $4 ]; then
244        ii=$4
245    fi
246    if [ $(echo "$i_myear < $n_myear" | bc -l) -eq 1 ]; then
247        echo "Run \"PCM $iPCM\" ($ii/$3)"
248        if [ $1 -eq 0 ]; then # Mode: processing scripts
249            sed -i "s/^k=-\?[0-9]\+$/k=$(echo "$ii - $3 + 2" | bc)/" PCMrun.job
250            ./PCMrun.job
251            if [ $? -ne 0 ]; then
252                errlaunch
253            fi
254        else # Mode: submitting jobs
255            cp PCMrun.job PCMrun${iPCM}.job
256            sed -i -E "/^$name_job/s/(.*[^0-9])([0-9]+)(_[^0-9]*)?$/\1${iPCM}\3/" PCMrun${iPCM}.job
257            sed -i "s/^k=-\?[0-9]\+$/k=$(echo "$ii - $3 + 2" | bc)/" PCMrun${iPCM}.job
258            jobID=$(eval "$submit_job PCMrun${iPCM}.job")
259            # Create a file to cancel the dependent jobs of the cycle
260            echo "#!/bin/bash" > kill_launchPEM.sh
261            chmod +x kill_launchPEM.sh
262            echo $kill_job $jobID >> kill_launchPEM.sh
263        fi
264        ((iPCM++))
265        if [ $2 -ne 0 ]; then # Counting: PCM runs taken into account
266            i_myear=$(echo "$i_myear + 1." | bc -l)
267        fi
268        ((ii++))
269    else
270        endlaunch
271    fi
272    for ((i = $ii; i <= $3; i++)); do
273        if [ $(echo "$i_myear < $n_myear" | bc -l) -eq 1 ]; then
274            echo "Run \"PCM $iPCM\" ($i/$3)"
275            if [ $1 -eq 0 ]; then # Mode: processing scripts
276                sed -i "s/^k=-\?[0-9]\+$/k=$(echo "$i - $3 + 2" | bc)/" PCMrun.job
277                ./PCMrun.job
278                if [ $? -ne 0 ]; then
279                    errlaunch
280                fi
281            else # Mode: submitting jobs
282                cp PCMrun.job PCMrun${iPCM}.job
283                sed -i -E "/^$name_job/s/(.*[^0-9])([0-9]+)(_[^0-9]*)?$/\1${iPCM}\3/" PCMrun${iPCM}.job
284                sed -i "s/^k=-\?[0-9]\+$/k=$(echo "$i - $3 + 2" | bc)/" PCMrun${iPCM}.job
285                jobID=$(eval "$submit_dependjob=afterok:${jobID} PCMrun${iPCM}.job")
286                echo $kill_job $jobID >> kill_launchPEM.sh
287            fi
288            ((iPCM++))
289            if [ $2 -ne 0 ]; then # Counting: PCM runs taken into account
290                i_myear=$(echo "$i_myear + 1." | bc -l)
291            fi
292        else
293            endlaunch
294        fi
295    done
296}
297
298# To submit the PEM run
299# arg1: launching mode
300submitPEM() {
301    if [ $(echo "$i_myear < $n_myear" | bc -l) -eq 1 ]; then
302        echo "Run \"PEM $iPEM\""
303        if [ $1 -eq 0 ]; then # Mode: processing scripts
304            ./PEMrun.job
305            if [ $? -ne 0 ]; then
306                errlaunch
307            fi
308        else # Mode: submitting jobs
309            sed -i -E "/^$name_job/s/(.*[^0-9])([0-9]+)(_[^0-9]*)?$/\1${iPEM}\3/" PEMrun.job
310            jobID=$(eval "$submit_job PEMrun.job")
311            # Create a file to cancel the dependent jobs of the cycle
312            echo "#!/bin/bash" > kill_launchPEM.sh
313            chmod +x kill_launchPEM.sh
314            echo $kill_job $jobID >> kill_launchPEM.sh
315        fi
316    else
317        endlaunch
318    fi
319}
320
321# To make one cycle of PCM and PEM runs
322# arg1: launching mode
323# arg2: counting method
324# arg3: number of PCM runs to launch
325# arg4: local number of the PCM run from which to start (optional)
326cyclelaunch() {
327    # PCM runs
328    submitPCM $1 $2 $3 $4
329
330    # PEM run
331    if [ $(echo "$i_myear < $n_myear" | bc -l) -eq 1 ]; then
332        echo "Run \"PEM $iPEM\""
333        if [ $1 -eq 0 ]; then # Mode: processing scripts
334            ./PEMrun.job
335            if [ $? -ne 0 ]; then
336                errlaunch
337            fi
338        else # Mode: submitting jobs
339            sed -i -E "/^$name_job/s/(.*[^0-9])([0-9]+)(_[^0-9]*)?$/\1${iPEM}\3/" PEMrun.job
340            jobID=$(eval "$submit_dependjob=afterok:${jobID} PEMrun.job")
341            echo $kill_job $jobID >> kill_launchPEM.sh
342        fi
343    else
344        endlaunch
345    fi
346}
347
348# To clean files after the starting run of the relaunch
349# arg1: file name prefix to clean
350# arg2: file name extension to clean
351# arg3: file number from which to clean
352cleanfiles() {
353    prefix=$1
354    extension=$2
355    if [ -z "$extension" ]; then
356        for file in ${prefix}*; do
357            num=${file#$prefix}
358            if [[ $num =~ ^[0-9]+$ ]] && [ $num -gt $3 ]; then
359                rm $file
360            fi
361        done
362    else
363        for file in ${prefix}*${extension}; do
364            num=${file#$prefix}
365            num=${num%$extension}
366            if [[ $num =~ ^[0-9]+$ ]] && [ $num -gt $3 ]; then
367                rm $file
368            fi
369        done
370    fi
371}
372
373# To relaunch from PCM run
374# arg1: launching mode
375# arg2: counting method
376relaunchPCM() {
377    iPCM=$(($irelaunch + 1))
378    cleanfiles diags/diagfi .nc $irelaunch
379    cleanfiles diags/diagsoil .nc $irelaunch
380    cleanfiles diags/data2reshape .nc $irelaunch
381    cleanfiles logs/runPCM .log $irelaunch
382    cleanfiles starts/restart1D .txt $irelaunch
383    cleanfiles starts/restart .nc $irelaunch
384    cleanfiles starts/restartfi .nc $irelaunch
385    cp starts/restartfi${irelaunch}.nc startfi.nc
386    if [ -f "starts/restart${irelaunch}.nc" ]; then
387        cp starts/restart${irelaunch}.nc start.nc
388    elif [ -f "starts/restart1D${irelaunch}.txt" ]; then
389        cp starts/restart1D${irelaunch}.txt start1D.txt
390    fi
391    if [ $irelaunch -le $nPCM_ini ]; then
392        # PCM relaunch during the initialization cycle
393        iPEM=1
394        if [ $2 -ne 0 ]; then # Counting: PCM runs taken into account
395            i_myear=$irelaunch
396        else # Counting: only PEM runs count
397            i_myear=0
398        fi
399        sed -i "1s/.*/$i_myear $n_myear $convert_years $iPCM $iPEM $nPCM $nPCM_ini/" info_PEM.txt
400        cleanfiles diags/diagpem .nc $(($iPEM - 1))
401        cleanfiles diags/diagsoilpem .nc $(($iPEM - 1))
402        cleanfiles logs/runPEM .log $(($iPEM - 1))
403        cleanfiles starts/restart1D_postPEM .txt $(($iPEM - 1))
404        cleanfiles starts/restart_postPEM .nc $(($iPEM - 1))
405        cleanfiles starts/restartfi_postPEM .nc $(($iPEM - 1))
406        cleanfiles starts/restartpem .nc $(($iPEM - 1))
407        rm -f startpem.nc
408        if [ -f "starts/startpem.nc" ]; then
409            cp starts/startpem.nc .
410        fi
411        if [ $irelaunch -eq $(($nPCM_ini - 1)) ]; then
412            cp diags/data2reshape${irelaunch}.nc data2reshape_Y1.nc
413            cyclelaunch $1 $2 $nPCM_ini $iPCM
414        elif [ $irelaunch -eq $nPCM_ini ]; then
415            cp diags/data2reshape$(($irelaunch - 1)).nc data2reshape_Y1.nc
416            cp diags/data2reshape${irelaunch}.nc data2reshape_Y2.nc
417            submitPEM $1 # The next job is a PEM run
418        else
419            cyclelaunch $1 $2 $nPCM_ini $iPCM
420        fi
421    else
422        # PCM relaunch during a cycle
423        iPEM=$(echo "($iPCM - $nPCM_ini)/$nPCM + 1" | bc)
424        il=$(echo "($irelaunch - $nPCM_ini + 1)%$nPCM + 1" | bc)
425        if [ $2 -ne 0 ]; then # Counting: PCM runs taken into account
426            i_myear=$(echo "$(awk "NR==$iPEM {printf \"%s\n\", \$3}" "info_PEM.txt") + $il" | bc -l)
427        else # Counting: only PEM runs count
428            i_myear=$(awk "NR==$iPEM {printf \"%s\n\", \$3}" "info_PEM.txt")
429        fi
430        sed -i "1s/.*/$i_myear $n_myear $convert_years $iPCM $iPEM $nPCM $nPCM_ini/" info_PEM.txt
431        cleanfiles diags/diagpem .nc $(($iPEM - 1))
432        cleanfiles diags/diagsoilpem .nc $(($iPEM - 1))
433        cleanfiles logs/runPEM .log $(($iPEM - 1))
434        cleanfiles starts/restart1D_postPEM .txt $(($iPEM - 1))
435        cleanfiles starts/restart_postPEM .nc $(($iPEM - 1))
436        cleanfiles starts/restartfi_postPEM .nc $(($iPEM - 1))
437        cleanfiles starts/restartpem .nc $(($iPEM - 1))
438        cp starts/restartpem$(($iPEM - 1)).nc startpem.nc
439        if [ $il -eq $(($nPCM - 1)) ]; then # Second to last PCM run
440            cp diags/data2reshape${irelaunch}.nc data2reshape_Y1.nc
441            cyclelaunch $1 $2 $nPCM $(($il + 1))
442        elif [ $il -eq $nPCM ]; then # Last PCM run so the next job is a PEM run
443            cp diags/data2reshape$(($irelaunch - 1)).nc data2reshape_Y1.nc
444            cp diags/data2reshape${irelaunch}.nc data2reshape_Y2.nc
445            submitPEM $1
446        else
447            cyclelaunch $1 $2 $nPCM $(($il + 1))
448        fi
449    fi
450}
451
452# To relaunch from PEM run
453# arg1: launching mode
454# arg2: counting method
455relaunchPEM() {
456    iPEM=$(echo "$irelaunch + 1" | bc)
457    iPCM=$(echo "$nPCM_ini + $nPCM*($irelaunch - 1) + 1" | bc)
458    i_myear=$(awk "NR==$iPEM {printf \"%s\n\", \$3}" "info_PEM.txt")
459    sed -i "1s/.*/$i_myear $n_myear $convert_years $iPCM $iPEM $nPCM $nPCM_ini/" info_PEM.txt
460    cleanfiles diags/diagfi .nc $(($iPCM - 1))
461    cleanfiles diags/diagsoil .nc $(($iPCM - 1))
462    cleanfiles logs/runPCM .log $(($iPCM - 1))
463    cleanfiles starts/restart1D .txt $(($iPCM - 1))
464    cleanfiles starts/restart .nc $(($iPCM - 1))
465    cleanfiles starts/restartfi .nc $(($iPCM - 1))
466    cleanfiles diags/data2reshape .nc $(($iPCM - 1))
467    cleanfiles diags/diagpem .nc $irelaunch
468    cleanfiles diags/diagsoilpem .nc $irelaunch
469    cleanfiles logs/runPEM .log $irelaunch
470    cleanfiles starts/restart1D_postPEM .txt $irelaunch
471    cleanfiles starts/restart_postPEM .nc $irelaunch
472    cleanfiles starts/restartfi_postPEM .nc $irelaunch
473    cleanfiles starts/restartpem .nc $irelaunch
474    cp starts/restartpem${irelaunch}.nc startpem.nc
475    cp starts/restartfi_postPEM${irelaunch}.nc startfi.nc
476    if [ -f "starts/restart_postPEM${irelaunch}.nc" ]; then
477        cp starts/restart_postPEM${irelaunch}.nc start.nc
478    elif [ -f "starts/restart1D_postPEM${irelaunch}.txt" ]; then
479        cp starts/restart1D_postPEM${irelaunch}.txt start1D.txt
480    fi
481    cyclelaunch $1 $2 $nPCM
482}
Note: See TracBrowser for help on using the repository browser.