source: CONFIG_DEVT/IPSLCM6.5_work_ENSEMBLES/libIGCM/libIGCM_ensemble/libIGCM_ensemble.ksh @ 5899

Last change on this file since 5899 was 5899, checked in by aclsce, 3 years ago

Modified libIGCM and configuration to run XIOS ensembles.

File size: 39.6 KB
Line 
1#!/bin/ksh
2#set -vx
3
4#**************************************************************
5# Author: Sebastien Denvil, Sonia Labetoulle, Nicolas Lebas, Sebastien Nguyen
6# Contact: Nicolas.Lebas__at__locean-ipsl.upmc.fr
7# $Revision:: 1489                                     $ Revision of last commit
8# $Author:: flavoni                                    $ Author of last commit
9# $Date:: 2019-09-17 10:55:34 +0200 (Tue, 17 Sep 2019) $ Date of last commit
10# IPSL (2012)
11#  This software is governed by the CeCILL licence see libIGCM/libIGCM_CeCILL.LIC
12#
13# >>> Date ensemble <<<
14# Author: Nicolas Lebas (adapted from Sonia Labetoulle)
15# Contact: Nicolas.Lebas__at__locean-ipsl.upmc.fr
16# IPSL (2014)
17#
18# >>> Add 3D perturbation maps to oceanic restart <<<
19# Author: Sebastien Nguyen
20# Contact: Sebastien.Nguyen__at__locean-ipsl.upmc.fr
21# IPSL (2014)
22#
23# >>> Uniform DATE and PERTURB ensemble (remove old, useless), ADD some functions <<<
24# add : IGCM_ensemble_InitRunDir, IGCM_ensemble_FilesUpdate (unique function)
25# DATE           ensemble : removed periodic case
26#                         : all dates are NON-periodic
27# CAST PERTURBED ensemble : removed NON-periodic case
28#                         : all casts are periodic (*Y or *M)
29#                         : removed Ens_PERTURB_PERTU_MAP_LIST case
30#
31# Author: Simona Flavoni & Nicola Lebas
32# Contact: Simona.Flavoni__at__locean-ipsl.upmc.fr
33# IPSL (2019)
34#**************************************************************
35
36# Read which ensemble type are active
37function IGCM_ensemble_Init
38{
39  IGCM_debug_PushStack "IGCM_ensemble_Init"
40
41  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB active
42  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE active
43 
44  Job_Period=10 # PARAMETER USED in function IGCM_ensemble_FilesUpdate
45
46  IGCM_debug_Print 1 "Ens_PERTURB ACTIVE     = ${ensemble_Ens_PERTURB_active}"
47  IGCM_debug_Print 1 "Ens_DATE ACTIVE        = ${ensemble_Ens_DATE_active}"
48  echo ""
49
50  #====================================================
51  # Define ARCHIVE : Dedicated to large files
52  # Define STORAGE : Dedicated to small/medium files
53  # Define R_OUT   : Output tree located on ARCHIVE
54  # Define R_FIG   : Output tree located on STORAGE hosting figures (monitoring and atlas, and/or small files)
55  # Define R_BUF   : USELESS and DEPRECATED output tree.
56  IGCM_sys_defineArchives
57
58  IGCM_debug_PopStack "IGCM_ensemble_Init"
59}
60
61
62############### ENSEMBLE #################
63function IGCM_ensemble_InitRunDir
64{
65
66  if [ -d ${SUBMIT_DIR}/${JobName} ] ; then
67    IGCM_debug_Print 3 "STOP directory ${SUBMIT_DIR}/${JobName} already exists."
68    exit # SF: stop at this point because in ENSEMBLE case need to be stopped
69  fi
70  IGCM_sys_Mkdir ${RUN_DIR}
71
72  IGCM_sys_Cp ${SUBMIT_DIR}/config.card   ${RUN_DIR}
73  IGCM_sys_Cp ${SUBMIT_DIR}/ensemble.card ${RUN_DIR}
74  IGCM_sys_Cp ${SUBMIT_DIR}/Job_*         ${RUN_DIR}
75  IGCM_sys_Cp ${SUBMIT_DIR}/run.card.init ${RUN_DIR}
76  if [ -f ${SUBMIT_DIR}/Qsub.* ]; then
77    IGCM_sys_Cp ${SUBMIT_DIR}/Qsub.*        ${RUN_DIR}
78  fi
79  if [ -f ${SUBMIT_DIR}/Qclean.* ]; then
80    IGCM_sys_Cp ${SUBMIT_DIR}/Qclean.*      ${RUN_DIR}
81  fi
82
83}
84
85############### Create Member Directory ENSEMBLE #################
86function IGCM_ensemble_CreateMemberDir
87{
88
89 #  if [ ! -d  ${SUBMIT_DIR}/${StartDir}/${MemberDir} ] ; then
90     IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}/${MemberDir}
91     IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}/${MemberDir}
92     ln -s ../../COMP
93     ln -s ../../PARAM
94     ln -s ../../POST
95     ln -s ../../DRIVER
96     IGCM_sys_Cd ${RUN_DIR}
97     IGCM_sys_Cp config.card run.card.init ${SUBMIT_DIR}/${StartDir}/${MemberDir}
98     IGCM_sys_Cp Job_${config_UserChoices_JobName} ${SUBMIT_DIR}/${StartDir}/${MemberDir}/${JobName}
99
100     # Dump command to be lauched
101     echo "cd ${StartDir}/${MemberDir}/ ;"    >> ${RUN_DIR}/Qsub.${StartDir}.sh
102     echo "${SUBMIT} ${JobName} ; cd -"       >> ${RUN_DIR}/Qsub.${StartDir}.sh
103
104     echo "cd ${StartDir}/${MemberDir}/ ;"    >> ${RUN_DIR}/Qclean.latestPackperiod.${StartDir}.sh
105     echo "${libIGCM}/clean_latestPackperiod.job ; cd -"  >> ${RUN_DIR}/Qclean.latestPackperiod.${StartDir}.sh
106
107     echo "cd ${StartDir}/${MemberDir}/ ;"    >> ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh
108     echo "${libIGCM}/clean_PeriodLength.job ; cd -"  >> ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh
109
110}
111
112
113############### FilesUpdate ENSEMBLE #################
114function IGCM_ensemble_FilesUpdate
115{
116  IGCM_debug_PushStack "IGCM_ensemble_FilesUpdate"
117
118  # Debug Print :
119  echo
120  IGCM_debug_Print 1 "IGCM_ensemble_FilesUpdate :"
121
122  EnsembleType=${1}
123  MemberNb=${2}
124  HumanDateBegin=$(   IGCM_date_ConvertFormatToHuman ${3} )
125  HumanDateEnd=$(     IGCM_date_ConvertFormatToHuman ${4} )
126  HumanRestartDate=$( IGCM_date_ConvertFormatToHuman ${5} )
127  if [[ X${6} != "X" ]]; then
128    initFrom=${6} # non periodic config (INITFROM could be different between members)
129  else
130    initFrom=$(eval echo $\ensemble_Ens_${EnsembleType}_INITFROM) # periodic (same INITFROM value)
131  fi
132
133  if [[ X${7} != "X" ]]; then
134    initPath=${7} # non periodic config (INITPATH could be different between members)
135  else
136    initPath=$(eval echo $\ensemble_Ens_${EnsembleType}_INITPATH) # periodic (same INITPATH value)
137  fi
138 
139  # ==> config.card
140  # [ENSEMBLE]
141  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleRun 'y'
142  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleName $(eval echo $\ensemble_Ens_${EnsembleType}_NAME)
143  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleDate ${HumanDateBegin}
144  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleType "Ens_${EnsembleType}"
145 
146  # [UserChoices]
147  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card UserChoices JobName   ${MemberDir}
148  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card UserChoices DateBegin ${HumanDateBegin}
149  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card UserChoices DateEnd   ${HumanDateEnd}
150  # Adhoc exceptioN for CMIP6 : update realisation number in member field.
151  if ( [ X"$( echo ${config_UserChoices_ExpType} | grep CMIP6 )" != "X" ] ) ; then
152      IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card UserChoices Member "r${MemberNb}i1p1f1"
153  fi
154
155  # [Restarts]
156  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Restarts OverRule "n"
157  # [ATM/OCE/...]
158  for comp in ${config_ListOfComponents[*]} ; do
159    IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${comp} Restart "y"
160    IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${comp} RestartDate ${HumanRestartDate}
161    IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${comp} RestartJobName ${initFrom}
162    IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${comp} RestartPath ${initPath}
163
164    # Adhoc exception for CMIP6 : exclude XIOS from the restart overrule mechanism.
165    if ( [ X${comp} = XIOS ] && [ X"$( echo ${config_UserChoices_ExpType} | grep CMIP6 )" != "X" ] ) ; then
166    IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${comp} Restart "n"
167    fi
168  done
169
170  unset initFrom
171
172  # ==> Job
173  sed -e "s/\(#.*Script_Output_\)${config_UserChoices_JobName}\(\.*\)/\1${MemberDir}\2/" \
174      -e "s/\(#.*\)${config_UserChoices_JobName}\(\.*\)/\1${MemberDir} \2/"              \
175      -e "s/^PeriodNb=.*/PeriodNb=${Job_Period}/"                                        \
176      ${SUBMIT_DIR}/${StartDir}/${MemberDir}/Job_${MemberDir} > Job_${MemberDir}.tmp
177  IGCM_sys_Mv Job_${MemberDir}.tmp ${SUBMIT_DIR}/${StartDir}/${MemberDir}/Job_${MemberDir}
178
179  IGCM_debug_PopStack "IGCM_ensemble_FilesUpdate"
180}
181
182
183############### Perturb ENSEMBLE #################
184function IGCM_ensemble_CastInit
185{
186  IGCM_debug_PushStack "IGCM_ensemble_CastInit"
187
188  IGCM_ensemble_InitRunDir
189 
190  ## Init some variables (only periodic case)
191  CastPeriodicStart=true
192 
193  echo " pwd id : ${PWD}"
194
195  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB active
196  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB NAME
197  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB BEGIN_INIT
198  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB END_INIT
199  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB PERIODICITY
200  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB LENGTH
201  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB MEMBER
202  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_PERTURB MEMBER_NAMESLIST
203  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB MEMBER_INITFROM
204  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB MEMBER_INITPATH
205  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_PERTURB PERTURB_BIN
206  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB INITFROM
207  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB INITPATH
208  IGCM_card_DefineVariableFromOption config.card UserChoices JobName
209  IGCM_card_DefineVariableFromOption config.card UserChoices TagName
210  IGCM_card_DefineVariableFromOption config.card UserChoices CalendarType
211  IGCM_card_DefineArrayFromSection   config.card ListOfComponents
212
213  echo
214  IGCM_debug_Print 1 "[Ens_PERTURB]"
215  IGCM_debug_Print 1 "ACTIVE            = ${ensemble_Ens_PERTURB_active}"
216  IGCM_debug_Print 1 "NAME              = ${ensemble_Ens_PERTURB_NAME}"
217  IGCM_debug_Print 1 "BEGIN_INIT        = ${ensemble_Ens_PERTURB_BEGIN_INIT}"
218  IGCM_debug_Print 1 "END_INIT          = ${ensemble_Ens_PERTURB_END_INIT}"
219  IGCM_debug_Print 1 "PERIODICITY       = ${ensemble_Ens_PERTURB_PERIODICITY}"
220  IGCM_debug_Print 1 "LENGTH            = ${ensemble_Ens_PERTURB_LENGTH}"
221  IGCM_debug_Print 1 "MEMBER            = ${ensemble_Ens_PERTURB_MEMBER}"
222  IGCM_debug_Print 1 "MEMBER_NAMESLIST  = ${ensemble_Ens_PERTURB_MEMBER_NAMESLIST[*]}"
223  IGCM_debug_Print 1 "MEMBER_INITFROM   = ${ensemble_Ens_PERTURB_MEMBER_INITFROM}"
224  IGCM_debug_Print 1 "MEMBER_INITPATH   = ${ensemble_Ens_PERTURB_MEMBER_INITPATH}"
225  IGCM_debug_Print 1 "PERTURB_BIN       = ${ensemble_Ens_PERTURB_PERTURB_BIN[*]}"
226  IGCM_debug_Print 1 "INITFROM          = ${ensemble_Ens_PERTURB_INITFROM}"
227  IGCM_debug_Print 1 "INITPATH          = ${ensemble_Ens_PERTURB_INITPATH}"
228  IGCM_debug_Print 1 "JobName           = ${config_UserChoices_JobName}"
229  IGCM_debug_Print 1 "TagName           = ${config_UserChoices_TagName}"
230  IGCM_debug_Print 1 "CalendarType      = ${config_UserChoices_CalendarType}"
231  IGCM_debug_Print 1 "ListOfComponents  = ${config_ListOfComponents[*]}"
232
233
234  ### Check unset variables and set them to empty
235  # Following var are set because they could be unset in some
236  # use case (ex: non periodic if periodic is active...)
237  if [[ "${ensemble_Ens_PERTURB_PERIODICITY}" = _0_ || "${ensemble_Ens_PERTURB_PERIODICITY}" = '' ]];
238  then
239      ensemble_Ens_PERTURB_PERIODICITY=NONE
240  fi
241  if [[ "${ensemble_Ens_PERTURB_MEMBER}" = _0_ || "${ensemble_Ens_PERTURB_MEMBER}" = '' ]];
242  then
243      ensemble_Ens_PERTURB_MEMBER=NONE
244  fi
245  if [[ "${ensemble_Ens_PERTURB_END_INIT}" = _0_ || "${ensemble_Ens_PERTURB_END_INIT}" = '' ]];
246  then
247      ensemble_Ens_PERTURB_END_INIT=${ensemble_Ens_PERTURB_BEGIN_INIT}
248  fi
249
250  ### End check unset variables ###
251  PerturbExe=${ensemble_Ens_PERTURB_PERTURB_BIN[0]}
252
253  case ${PerturbExe} in
254  AddNoise)
255    PerturbComp=${ensemble_Ens_PERTURB_PERTURB_BIN[1]}
256    PerturbFile=${ensemble_Ens_PERTURB_PERTURB_BIN[2]}
257    PerturbVar=${ensemble_Ens_PERTURB_PERTURB_BIN[3]}
258    PerturbAmp=${ensemble_Ens_PERTURB_PERTURB_BIN[4]}
259
260    IGCM_debug_Print 1 "PerturbExe  = ${PerturbExe}"
261    IGCM_debug_Print 1 "PerturbFile = ${PerturbFile}"
262    IGCM_debug_Print 1 "PerturbComp = ${PerturbComp}"
263    IGCM_debug_Print 1 "PerturbVar  = ${PerturbVar}"
264    IGCM_debug_Print 1 "PerturbAmp  = ${PerturbAmp}"
265    ;;
266  AddPertu3DOCE)
267    PerturbComp=${ensemble_Ens_PERTURB_PERTURB_BIN[1]}
268    PerturbFile=${ensemble_Ens_PERTURB_PERTURB_BIN[2]}
269    PerturbVar=${ensemble_Ens_PERTURB_PERTURB_BIN[3]}
270    PerturbMask=${ensemble_Ens_PERTURB_PERTURB_BIN[4]}
271
272    IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB MASKPATH
273   
274    IGCM_debug_Print 1 "PerturbExe  = ${PerturbExe}"
275    IGCM_debug_Print 1 "PerturbFile = ${PerturbFile}"
276    IGCM_debug_Print 1 "PerturbComp = ${PerturbComp}"
277    IGCM_debug_Print 1 "PerturbVar  = ${PerturbVar}"
278    IGCM_debug_Print 1 "PerturbMask = ${PerturbMask}"
279    IGCM_debug_Print 1 "MASK PATH   = ${ensemble_Ens_PERTURB_MASKPATH}"
280    ;;
281  esac
282
283  # A few checks Period case:
284
285  # ... Check PERIODICITY ...
286  case ${ensemble_Ens_PERTURB_PERIODICITY} in
287  NONE)
288    IGCM_debug_Print 1 "periodic start not active"
289    CastPeriodicStart=false
290    ;;
291  *[Yy]|*[Mm])
292    CastPeriodicStart=true
293    IGCM_debug_Print 1 "Periodic length : ${ensemble_Ens_PERTURB_PERIODICITY}" ;;
294  *)
295    IGCM_debug_Exit "IGCM_ensemble_CastInit ${ensemble_Ens_PERTURB_PERIODICITY} : invalid PERIODICITY"
296    IGCM_debug_Exit "Choose a value in *Y or *M"
297    IGCM_debug_Verif_Exit ;;
298  esac
299  # ... Check LENGTH ...
300  case ${ensemble_Ens_PERTURB_LENGTH} in
301  *[Yy]|*[Mm])
302    IGCM_debug_Print 1 "Periodic duration : ${ensemble_Ens_PERTURB_LENGTH}" ;;
303  *)
304    IGCM_debug_Exit "IGCM_ensemble_CastInit ${ensemble_Ens_PERTURB_LENGTH} invalid LENGTH"
305    IGCM_debug_Exit "Choose a value in choose in *Y or *M"
306    IGCM_debug_Verif_Exit ;;
307  esac
308
309  # Need to know all the restart filename of the component we will apply the noise to
310  IGCM_card_DefineArrayFromOption config.card ListOfComponents ${PerturbComp}
311  eval compname=\${config_ListOfComponents_${PerturbComp}[0]} > /dev/null 2>&1
312
313  # Target the component's card we apply the noise to
314  card=${SUBMIT_DIR}/COMP/${compname}.card
315
316  # Read the restart file list. To be used later
317  IGCM_card_DefineArrayFromOption ${card} RestartFiles List
318  ListFilesName=${compname}_RestartFiles_List
319  eval FileName0=\${${ListFilesName}[0]} > /dev/null 2>&1
320  eval NbFiles=\${#${ListFilesName}[@]} > /dev/null 2>&1
321
322  # Check
323  IGCM_debug_Print 1 "Nb Restart Files  = ${NbFiles}"
324
325  IGCM_debug_PopStack "IGCM_ensemble_CastInit"
326}
327
328function IGCM_ensemble_CastPeriodicStarts
329{
330  IGCM_debug_PushStack "IGCM_ensemble_CastPeriodicStarts"
331
332  [ ${CastPeriodicStart} = false ] && return
333
334  echo
335  IGCM_debug_Print 1 "Manage periodic starts"
336
337#.. Manage periodic starts ..
338#   ======================
339
340# ... Loop over DateBegin ...
341  eval DateBegin=\${ensemble_Ens_PERTURB_BEGIN_INIT}
342
343  while [ ${DateBegin} -le ${ensemble_Ens_PERTURB_END_INIT} ] ; do
344    IGCM_date_GetYearMonth ${DateBegin} year month
345
346  # - Determine number of day(s) in PERIODICITY
347    PeriodLengthInDays=$( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${ensemble_Ens_PERTURB_PERIODICITY} )
348
349  # - Determine number of day(s) in LENGTH
350    DurationLengthInDays=$(( $( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${ensemble_Ens_PERTURB_LENGTH} ) - 1 ))
351
352  # - Determine DateEnd
353    (( DateEnd = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${DurationLengthInDays} ) ))
354
355  # - Build directory name
356    #SF IGCM_ensemble_CastDirectoryName ${ensemble_Ens_PERTURB_NAME} ${ensemble_Ens_PERTURB_PERIODICITY} ${year} ${month} ${StartDir}
357    IGCM_ensemble_CastDirectoryName ${ensemble_Ens_PERTURB_NAME} ${ensemble_Ens_PERTURB_PERIODICITY} ${year} ${month}
358    # StartDir="${ensemble_Ens_PERTURB_NAME}"
359
360  # - Determine RestartDate
361    (( Offset = -1 ))
362    (( RestartDate = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${Offset} ) ))
363
364    IGCM_debug_Print 2 "${DateBegin} => ${DateEnd} : ${StartDir}"
365    echo "${DateBegin} ${DateEnd} ${StartDir}" >> ${RUN_DIR}/CreatedDir.txt
366
367  # - Create directory for current DateBegin
368    if [ ! -d  ${StartDir} ] ; then
369      IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}
370      IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}
371      ln -s ../../.resol .
372      ln -s ../../.libmpi .
373      IGCM_sys_Cd ${RUN_DIR}
374    fi
375
376  # - Create directory to store modified restart files
377    RestartDir=${STORAGE}/IGCM_IN/${config_UserChoices_TagName}/${StartDir}
378    IGCM_sys_MkdirArchive ${RestartDir}
379
380  # - Loop over members
381    i=1
382    while [ $i -le ${ensemble_Ens_PERTURB_MEMBER} ] ; do
383      if [ $((i)) -le 9 ] ; then
384        MemberDir="${StartDir}"-0"$((i))"
385      else
386        MemberDir="${StartDir}-$((i))"
387      fi
388      echo
389      IGCM_debug_Print 3 "${MemberDir}"
390
391      JobName="Job_${MemberDir}"
392
393    # * Create directory if it doesn't exist and copy/link files
394      if [ ! -d  ${SUBMIT_DIR}/${StartDir}/${MemberDir} ] ; then
395     
396        # * Create ${SUBMIT_DIR}/${StartDir}/${MemberDir} directories
397        #   link COMP PARAM POST and DRIVER
398        #   cp config.card, run.card.init, Job_
399        #   and Dump command to be launched
400        IGCM_ensemble_CreateMemberDir
401
402        # * Update files : config.card, Job_, COMP/comp.card
403        IGCM_ensemble_FilesUpdate "PERTURB" ${i} ${DateBegin} ${DateEnd} ${RestartDate} 
404
405        # * Apply noise on restart file
406        IGCM_ensemble_CastPerturbFile
407      fi
408
409      (( i = i + 1 ))
410    done
411
412    # Done. Save ${StartDir} submission text file
413    IGCM_sys_Cp ${RUN_DIR}/Qsub.${StartDir}.sh ${SUBMIT_DIR}
414    IGCM_sys_Cp ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh ${SUBMIT_DIR}
415    IGCM_sys_Cp ${RUN_DIR}/Qclean.latestPackperiod.${StartDir}.sh ${SUBMIT_DIR}
416
417  # - Next DateBegin
418    echo "$DateBegin  $PeriodLengthInDays"
419    case ${ensemble_Ens_PERTURB_PERIODICITY} in
420    *[Yy]|*[Mm])
421      (( DateBegin = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${PeriodLengthInDays} ) ))
422      ;;
423    esac
424    echo "New DateBegin = $DateBegin"
425    echo "========================================================================"
426  done
427  IGCM_debug_PopStack "IGCM_ensemble_CastPeriodicStarts"
428}
429
430function IGCM_ensemble_CastMemberList
431{
432  IGCM_debug_PushStack "IGCM_ensemble_CastMemberList"
433
434  if [ ${CastMemberList} = false ] ; then
435    IGCM_debug_PopStack "IGCM_ensemble_CastMemberList"
436    return
437  fi
438
439  echo
440  IGCM_debug_Print 1 "Manage members list"
441
442#.. Manage members list ..
443#   ======================
444
445  # DateBegin
446  eval DateBegin=\${ensemble_Ens_PERTURB_BEGIN_INIT}
447
448  IGCM_date_GetYearMonth ${DateBegin} ${year} ${month}
449
450  # - Determine number of day(s) in LENGTH
451  DurationLengthInDays=$(( $( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${ensemble_Ens_PERTURB_LENGTH} ) - 1 ))
452
453  # - Determine DateEnd
454  DateEnd=$( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${DurationLengthInDays} )
455
456  # bad hack enforce yearly for parent directory name
457  # - Build directory name
458  IGCM_ensemble_CastDirectoryName ${ensemble_Ens_PERTURB_NAME} 1Y ${year} ${month}
459  #SF IGCM_ensemble_CastDirectoryName ${ensemble_Ens_PERTURB_NAME} 1Y ${year} ${month} ${StartDir}
460
461  # - Determine RestartDate
462  (( Offset = -1 ))
463  RestartDate=$( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${Offset} )
464
465  IGCM_debug_Print 2 "${DateBegin} => ${DateEnd} : ${StartDir}"
466  echo "${DateBegin} ${DateEnd} ${StartDir}" >> ${RUN_DIR}/CreatedDir.txt
467
468  # - Create directory for current DateBegin
469  if [ ! -d  ${StartDir} ] ; then
470    IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}
471    IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}
472    ln -s ../../.resol .
473    ln -s ../../.libmpi .
474    IGCM_sys_Cd ${RUN_DIR}
475  fi
476
477  # - Create directory to store modified restart files
478  RestartDir=${STORAGE}/IGCM_IN/${config_UserChoices_TagName}/${StartDir}
479  IGCM_sys_MkdirArchive ${RestartDir}
480
481  # - Loop over members
482  i=1
483  nbmember=${ensemble_Ens_PERTURB_MEMBER}
484  while [ $i -lt $nbmember ] ; do
485    MemberVec=${ensemble_PERTURB_MEMBER_[${i}]}
486    MemberDir=${config_UserChoices_Member}
487    echo
488    IGCM_debug_Print 3 "print nbmember: ${nbmember}"
489    IGCM_debug_Print 3 "print MemberVec: ${ensemble_PERTURB_MEMBER[${i}]}"
490
491    JobName="Job_${MemberDir}"
492    echo
493    IGCM_debug_Print 3 "${MemberDir}"
494
495    # * Create directory if it doesn't exist and copy/link files
496    if [ ! -d  ${SUBMIT_DIR}/${StartDir}/${MemberDir} ] ; then
497
498      # * Create ${SUBMIT_DIR}/${StartDir}/${MemberDir} directories
499      #   link COMP PARAM POST and DRIVER
500      #   cp config.card, run.card.init, Job_
501      #   and Dump command to be launched
502      IGCM_ensemble_CreateMemberDir
503
504      # * Update files : config.card, Job_, COMP/comp.card
505      IGCM_ensemble_FilesUpdate "PERTURB" ${i} ${DateBegin} ${DateEnd} ${RestartDate} ${InitFrom} ${InitPath}
506
507      # * Apply noise on restart file
508      IGCM_ensemble_CastPerturbFile
509    fi
510
511    (( i = i + 1 ))
512  done
513
514  # Done. Save ${StartDir} submission text file
515  IGCM_sys_Cp ${RUN_DIR}/Qsub.${StartDir}.sh ${SUBMIT_DIR}
516  IGCM_sys_Cp ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh ${SUBMIT_DIR}
517
518  IGCM_debug_PopStack "IGCM_ensemble_CastMemberList"
519}
520
521function IGCM_ensemble_CastDirectoryName
522{
523  IGCM_debug_PushStack "IGCM_ensemble_CastDirectoryName"
524
525  #.. Debug Print ..
526  echo
527  IGCM_debug_Print 1 "IGCM_ensemble_CastDirectoryName :"
528  echo
529
530  Name=$1
531  PeriodLen=$2
532  Year=$3
533  Month=$4
534
535  # - Build directory name
536  case ${PeriodLen} in
537  *Y|*y)
538    StartDir="${Name}${year}"
539    ;;
540  esac
541
542  IGCM_debug_PopStack "IGCM_ensemble_CastDirectoryName"
543}
544
545function IGCM_ensemble_CastPerturbFile
546{
547  IGCM_debug_PushStack "IGCM_ensemble_CastPerturbFile"
548
549  typeset i i_ j
550  typeset -Z4 j4
551  typeset file_out file_out_
552
553  #.. Debug Print ..
554  echo
555  IGCM_debug_Print 1 "IGCM_ensemble_CastPerturbFile :"
556
557  #.. FileIn ? => RestartDate ..
558  DirIn="${ensemble_Ens_PERTURB_INITPATH}/${ensemble_Ens_PERTURB_INITFROM}/${PerturbComp}/Restart"
559  DirInTar="${ensemble_Ens_PERTURB_INITPATH}/${ensemble_Ens_PERTURB_INITFROM}/RESTART"
560  FileIn="${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${PerturbFile}"
561  DirOut="${RestartDir}/${MemberDir}/${PerturbComp}/Restart"
562
563  # * Create member restart directory
564  IGCM_sys_TestDirArchive ${DirOut}
565  RET=$?
566  if [ $RET -gt 0 ] ; then
567    IGCM_sys_MkdirArchive ${DirOut}
568  fi
569
570  FileOut="${MemberDir}_${RestartDate}_${PerturbFile}"
571  IGCM_debug_Print 1 "FileIn  = ${DirIn}/${FileIn}"
572  IGCM_debug_Print 1 "FileOut = ${DirOut}/${FileOut}.nc"
573
574  IGCM_sys_TestFileArchive ${DirOut}/${FileOut}.nc
575  RET=$?
576  if [ $RET -gt 0 ] ; then
577
578    # * Look for the restart file we apply the noise to
579
580    # restart file list pertaining to the component we apply the noise to
581    # but not being the precise restart file we will apply the noise to
582    unset OtherFileInList
583    # generic restart filename list (like flxat, sstoc, restart, ...)
584    unset OtherGenericList
585
586    if ( [ X${FileName0} != X${NULL_STR} ] && [ X${FileName0} != XNONE ] ) ; then
587      (( i=0 ))
588      until [ $i -ge ${NbFiles} ]; do
589
590        (( i_ = i+1 ))
591        eval file_out_=\${${ListFilesName}[$i_]} > /dev/null 2>&1
592        eval file_out=${file_out_}
593
594        generic_restart_file_name_out=$( basename ${file_out} .nc )
595
596        if [ ! ${generic_restart_file_name_out} = ${PerturbFile} ] ; then
597          set +A OtherFileInList ${OtherFileInList[*]} ${PerturbComp}_${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic_restart_file_name_out}\*.nc
598          set +A OtherGenericList ${OtherGenericList[*]} ${generic_restart_file_name_out}
599        fi
600
601        (( i=i+3 ))
602      done
603    fi
604    # How many restart files other than the one we will apply the noise to
605    NbOtherFiles=${#OtherGenericList[*]}
606
607    ##########################
608    # TO BE A FUNCTION BEGIN #
609    ##########################
610
611    if [ $( IGCM_sys_TestFileBuffer ${DirIn}/${FileIn}*.nc ; echo $? ) = 0 ] ; then
612      IGCM_debug_Print 3 "Buffered restart"
613      Buffered=true
614      Archived=false
615      Tared=false
616      nb_restart_file=$(IGCM_sys_CountFileBuffer ${DirIn}/${FileIn}_????.nc)
617    elif [ $( IGCM_sys_TestFileArchive ${DirIn}/${FileIn}*.nc ; echo $? ) = 0 ] ; then
618      IGCM_debug_Print 3 "Archived restart"
619      Buffered=false
620      Archived=true
621      Tared=false
622      nb_restart_file=$(IGCM_sys_CountFileArchive ${DirIn}/${FileIn}_????.nc)
623    else
624      IGCM_debug_Print 3 "Tared restart"
625      Buffered=false
626      Archived=false
627      Tared=true
628
629      # Look for the tar file we want if we did not found it already
630      for PotentialTarFile in $( find ${ensemble_Ens_PERTURB_INITPATH}/${ensemble_Ens_PERTURB_INITFROM}/RESTART -name "${ensemble_Ens_PERTURB_INITFROM}_*restart*.tar" -print ) ; do
631        IsMatching=$( echo ${PotentialTarFile##*/} | sed "s:_restart::" | sed "s:^${ensemble_Ens_PERTURB_INITFROM}_::" | sed "s:\.tar$::" | gawk -F_ -v restartdate=${RestartDate} '{if (($1 <= restartdate) && ($2 >= restartdate)) {print $1"_"$2}}' )
632        if [ ! X${IsMatching} = X ] ; then
633          TarFileFound=${PotentialTarFile}
634          break
635        fi
636      done
637
638      # Extract relevant restart files
639      IGCM_debug_Print 1 "tar xvf ${TarFileFound} ${PerturbComp}_${FileIn}*.nc ${OtherFileInList[*]}"
640      tar xvf ${TarFileFound} ${PerturbComp}_${FileIn}*.nc ${OtherFileInList[*]}
641      nb_restart_file=$( IGCM_sys_CountFileBuffer ${PerturbComp}_${FileIn}_????.nc )
642    fi
643
644    # Move around and perturb restart files so as to be able to start hindcast/forecast simulation members
645    if [ ${nb_restart_file} -gt 1 ] ; then
646      j=0
647      until [ $j -ge ${nb_restart_file} ]; do
648        j4=${j}
649        if [ X${Buffered} = Xtrue ] ; then
650          IGCM_sys_GetBuffer ${DirIn}/${FileIn}_${j4}.nc ${RUN_DIR}/${FileOut}_${j4}.nc
651
652          cd ${DirOut}
653          for generic in ${OtherGenericList[*]} ; do
654            ln -s ${DirIn}/${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${MemberDir}_${RestartDate}_${generic}_${j4}.nc
655          done
656          cd -
657
658        elif [ X${Archived} = Xtrue ] ; then
659          IGCM_sys_Get ${DirIn}/${FileIn}_${j4}.nc ${RUN_DIR}/${FileOut}_${j4}.nc
660
661          for generic in ${OtherGenericList[*]} ; do
662            IGCM_sys_RshArchive "cd ${DirOut} ; ln -s ${DirIn}/${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${MemberDir}_${RestartDate}_${generic}_${j4}.nc"
663          done
664
665        elif [ X${Tared} = Xtrue ] ; then
666          IGCM_debug_Print 2 "IGCM_sys_Mv ${PerturbComp}_${FileIn}_${j4}.nc ${RUN_DIR}/${FileOut}_${j4}.nc"
667          IGCM_sys_Mv ${PerturbComp}_${FileIn}_${j4}.nc ${RUN_DIR}/${FileOut}_${j4}.nc
668
669          for generic in ${OtherGenericList[*]} ; do
670            IGCM_sys_Mv ${PerturbComp}_${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${DirOut}/${MemberDir}_${RestartDate}_${generic}_${j4}.nc
671          done
672
673        fi
674        (( j=j+1 ))
675      done
676    else
677      if [ X${Buffered} = Xtrue ] ; then
678        IGCM_sys_GetBuffer ${DirIn}/${FileIn}.nc ${RUN_DIR}/${FileOut}.nc
679
680        cd ${DirOut}
681        for generic in ${OtherGenericList[*]} ; do
682          ln -s ${DirIn}/${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${MemberDir}_${RestartDate}_${generic}.nc
683        done
684        cd -
685
686      elif [ X${Archived} = Xtrue ] ; then
687        IGCM_sys_Get ${DirIn}/${FileIn}.nc ${RUN_DIR}/${FileOut}.nc
688
689        for generic in ${OtherGenericList[*]} ; do
690          IGCM_sys_RshArchive "cd ${DirOut} ; ln -s ${DirIn}/${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${MemberDir}_${RestartDate}_${generic}.nc"
691        done
692
693      elif [ X${Tared} = Xtrue ] ; then
694        IGCM_debug_Print 2 "IGCM_sys_Mv ${PerturbComp}_${FileIn}.nc ${RUN_DIR}/${FileOut}.nc"
695        IGCM_sys_Mv ${PerturbComp}_${FileIn}.nc ${RUN_DIR}/${FileOut}.nc
696
697        for generic in ${OtherGenericList[*]} ; do
698          IGCM_debug_Print 2 "IGCM_sys_Mv ${PerturbComp}_${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${DirOut}/${MemberDir}_${RestartDate}_${generic}.nc"
699          IGCM_sys_Mv ${PerturbComp}_${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${DirOut}/${MemberDir}_${RestartDate}_${generic}.nc
700        done
701
702      fi
703    fi
704
705    ########################
706    # TO BE A FUNCTION END #
707    ########################
708
709# treat the perturbation on different components by looking at the executable name
710
711    case ${PerturbExe} in
712    (AddNoise)
713      IGCM_sys_Chmod 644 ${RUN_DIR}/${FileOut}.nc
714
715      IGCM_debug_Print 1 "${PerturbExe} ${RUN_DIR}/${FileOut}.nc ${PerturbVar} ${PerturbAmp}"
716      echo
717
718      ${PerturbExe} ${RUN_DIR}/${FileOut}.nc ${PerturbVar} ${PerturbAmp}  > /dev/null 2>&1
719      if [ $? -ne 0 ] ; then
720        IGCM_debug_Exit "Error with $( basename ${PerturbExe} )"
721        IGCM_debug_Verif_Exit
722      fi
723      IGCM_sys_Put_Out ${RUN_DIR}/${FileOut}.nc ${DirOut}/ 644
724      ;;
725    (AddPertu3DOCE)
726      # where to find the pattern we apply to the restart
727      PatternFile=${ensemble_Ens_PERTURB_MEMBER_INITPATH}/${ensemble_Ens_PERTURB_MEMBER_INITFROM}/${MemberVec}.nc
728
729      # where to find the land mask for the grid
730      MaskFile=${ensemble_Ens_PERTURB_MASKPATH}/${PerturbMask}
731
732      # if there is multiple restart files rebuild restart file
733      if [ ${nb_restart_file} -gt 1 ] ; then
734        IGCM_debug_Print 1 "rebuild files ${FileOut}_????.nc"
735        IGCM_sys_rebuild ${RUN_DIR}/${FileOut}.nc ${RUN_DIR}/${FileOut}_????.nc
736      fi
737
738      # there is now a single restart file
739      IGCM_sys_Chmod 644 ${RUN_DIR}/${FileOut}.nc
740
741      IGCM_debug_Print 1 "${PerturbExe} ${RUN_DIR}/${FileOut}.nc ${PerturbVar} ${PatternFile} ${MaskFile}"
742      echo
743
744      # add pattern to restart file on variable PerturbVar
745      ${PerturbExe} ${RUN_DIR}/${FileOut}.nc ${PerturbVar} ${PatternFile} ${MaskFile}  > /dev/null 2>&1
746      if [ $? -ne 0 ] ; then
747        IGCM_debug_Exit "Error with $( basename ${PerturbExe} )"
748        IGCM_debug_Verif_Exit
749      fi
750      IGCM_sys_Put_Out ${RUN_DIR}/${FileOut}.nc ${DirOut}/ 644
751     ;;
752    esac
753
754  fi
755
756  #.. Update config.card..
757  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${PerturbComp} Restart "y"
758  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${PerturbComp} RestartDate    ${HumanRestartDate}
759  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${PerturbComp} RestartJobName ${MemberDir}
760  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${PerturbComp} RestartPath    ${RestartDir}/
761  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleType "Ens_PERTURB"
762
763  IGCM_debug_PopStack "IGCM_ensemble_CastPerturbFile"
764}
765
766############### Date ENSEMBLE #################
767function IGCM_ensemble_DateInit
768{
769  IGCM_debug_PushStack "IGCM_ensemble_DateInit"
770
771  IGCM_ensemble_InitRunDir
772
773  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE active
774  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE NAME
775  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE BEGIN_INIT
776  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE BEGIN_RESTART
777  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE END_INIT
778  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE STARTDATE
779  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_DATE NONPERIODIC
780  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_DATE RESTART_NONPERIODIC
781  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE LENGTH
782  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_DATE LENGTH_NONPERIODIC
783  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE INITFROM
784  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE INITFROM_NONPERIODIC
785  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE INITPATH
786  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE INITPATH_NONPERIODIC
787  IGCM_card_DefineVariableFromOption config.card UserChoices JobName
788  IGCM_card_DefineVariableFromOption config.card UserChoices TagName
789  IGCM_card_DefineVariableFromOption config.card UserChoices CalendarType
790  IGCM_card_DefineArrayFromSection   config.card ListOfComponents
791
792  echo
793  IGCM_debug_Print 1 "[Ens_DATE]"
794  IGCM_debug_Print 1 "ACTIVE               = ${ensemble_Ens_DATE_active}"
795  IGCM_debug_Print 1 "NAME                 = ${ensemble_Ens_DATE_NAME}"
796  IGCM_debug_Print 1 "BEGIN_INIT           = ${ensemble_Ens_DATE_BEGIN_INIT}"
797  IGCM_debug_Print 1 "END_INIT             = ${ensemble_Ens_DATE_END_INIT}"
798  IGCM_debug_Print 1 "BEGIN_RESTART        = ${ensemble_Ens_DATE_BEGIN_RESTART}"
799  IGCM_debug_Print 1 "STARTDATE            = ${ensemble_Ens_DATE_STARTDATE}"
800  IGCM_debug_Print 1 "NONPERIODIC          = ${ensemble_Ens_DATE_NONPERIODIC[*]}"
801  IGCM_debug_Print 1 "RESTART_NONPERIODIC  = ${ensemble_Ens_DATE_RESTART_NONPERIODIC[*]}"
802  IGCM_debug_Print 1 "LENGTH               = ${ensemble_Ens_DATE_LENGTH}"
803  IGCM_debug_Print 1 "LENGTH_NONPERIODIC   = ${ensemble_Ens_DATE_LENGTH_NONPERIODIC[*]}"
804  IGCM_debug_Print 1 "INITFROM             = ${ensemble_Ens_DATE_INITFROM}"
805  IGCM_debug_Print 1 "INITFROM_NONPERIODIC = ${ensemble_Ens_DATE_INITFROM_NONPERIODIC[*]}"
806  IGCM_debug_Print 1 "INITPATH             = ${ensemble_Ens_DATE_INITPATH}"
807  IGCM_debug_Print 1 "INITPATH_NONPERIODIC = ${ensemble_Ens_DATE_INITPATH_NONPERIODIC[*]}"
808  IGCM_debug_Print 1 "JobName              = ${config_UserChoices_JobName}"
809  IGCM_debug_Print 1 "TagName              = ${config_UserChoices_TagName}"
810  IGCM_debug_Print 1 "CalendarType         = ${config_UserChoices_CalendarType}"
811  IGCM_debug_Print 1 "ListOfComponents     = ${config_ListOfComponents[*]}"
812  echo ""
813
814  IGCM_debug_Print 1 "Check args..."
815  DateNonPeriodicStart=true
816
817  # ... Check LENGTH ...
818  case ${ensemble_Ens_DATE_LENGTH} in
819  *[Yy]|*[Mm])
820    IGCM_debug_Print 1 "Default simulation duration : ${ensemble_Ens_DATE_LENGTH}" ;;
821  *)
822    IGCM_debug_Exit "IGCM_ensemble_DateInit ${ensemble_Ens_DATE_LENGTH} invalid LENGTH"
823    IGCM_debug_Exit "Choose a value in choose in *Y or *M"
824    IGCM_debug_Verif_Exit ;;
825  esac
826
827  # ***************************************
828  # A few checks for the Non-Periodic case:
829  # ***************************************
830#  if [[ ${#ensemble_Ens_DATE_NONPERIODIC[*]} != ${#ensemble_Ens_DATE_RESTART_NONPERIODIC[*]} ]] ; then
831#    IGCM_debug_Exit "IGCM_ensemble_DateInit: NONPERIODIC and RESTART_NONPERIODIC lists have different sizes"
832#    IGCM_debug_Verif_Exit
833#  fi
834
835  if [[ ${#ensemble_Ens_DATE_RESTART_NONPERIODIC[*]} > 0 ]] && [[ ${ensemble_Ens_DATE_RESTART_NONPERIODIC[*]} != _0_ ]]; then
836    DateNonPeriodicStart=true
837
838    # Use LENGTH if no NONPERIODIC_LENGTH given
839    if [[ ${#ensemble_Ens_DATE_LENGTH_NONPERIODIC[*]} < ${#ensemble_Ens_DATE_NONPERIODIC[*]} ]] ||
840           [[ X"${ensemble_Ens_DATE_LENGTH_NONPERIODIC[0]}" = "XOption" ]] ; then
841        IGCM_debug_Print 1 "WARNING: LENGTH_NONPERIODIC is not fill (or not correctly). "
842        IGCM_debug_Print 1 "Use LENGTH value '${ensemble_Ens_DATE_LENGTH}' for all NONPERIODIC runs"
843      DateNum=0
844      while [ ${DateNum} -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; do
845        ensemble_Ens_DATE_LENGTH_NONPERIODIC[${DateNum}]=${ensemble_Ens_DATE_LENGTH}
846        (( DateNum = DateNum + 1 ))
847      done
848    fi
849   
850    # Use STARTDATE if no NONPERIODIC start date given
851    if [[ ${#ensemble_Ens_DATE_NONPERIODIC[*]} < ${#ensemble_Ens_DATE_RESTART_NONPERIODIC[*]} ]] ||
852           [[ X"${ensemble_Ens_DATE_NONPERIODIC[0]}" = "XOption" ]] ; then
853        IGCM_debug_Print 1 "WARNING: NONPERIODIC start date not fill (or not correctly)."
854        IGCM_debug_Print 1 "Use STARTDATE value '${ensemble_Ens_DATE_STARTDATE}' for all NONPERIODIC runs"
855      DateNum=0
856      while [ ${DateNum} -lt ${#ensemble_Ens_DATE_RESTART_NONPERIODIC[*]} ] ; do
857        ensemble_Ens_DATE_NONPERIODIC[${DateNum}]=${ensemble_Ens_DATE_STARTDATE}
858        (( DateNum = DateNum + 1 ))
859      done
860    fi
861       
862    # Use INITFROM if no INITFROM_NONPERIODIC given
863    if [ ${#ensemble_Ens_DATE_INITFROM_NONPERIODIC[*]} -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; then
864      IGCM_debug_Print 1 "WARNING: INITFROM_NONPERIODIC is not fill (or not correctly). Use INITFROM value '${ensemble_Ens_DATE_INITFROM}' for all NONPERIODIC runs"
865      DateNum=0
866      while [ ${DateNum} -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; do
867        ensemble_Ens_DATE_INITFROM_NONPERIODIC[${DateNum}]=${ensemble_Ens_DATE_INITFROM}
868        (( DateNum = DateNum + 1 ))
869      done
870    fi
871   
872    # Use INITPATH if no INITPATH_NONPERIODIC given
873    if [ ${#ensemble_Ens_DATE_INITPATH_NONPERIODIC[*]} -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; then
874      IGCM_debug_Print 1 "WARNING: INITPATH_NONPERIODIC is not fill (or not correctly). Use INITPATH value '${ensemble_Ens_DATE_INITPATH}' for all NONPERIODIC runs"
875      DateNum=0
876      while [ ${DateNum} -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; do
877        ensemble_Ens_DATE_INITPATH_NONPERIODIC[${DateNum}]=${ensemble_Ens_DATE_INITPATH}
878        (( DateNum = DateNum + 1 ))
879      done
880    fi
881  else
882    IGCM_debug_Print 1 "Non-Periodic start NOT ACTIVE"
883    DateNonPeriodicStart=false
884  fi
885
886  if [[ ${DateNonPeriodicStart} = true ]]; then
887    DateNum=0
888    while [ ${DateNum} -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; do
889      # - Check LENGTH_NONPERIODIC
890      case ${ensemble_Ens_DATE_LENGTH_NONPERIODIC[${DateNum}]} in
891      *[Yy]|*[Mm])
892        IGCM_debug_Print 1 "Non-periodic duration ${DateNum}: ${ensemble_Ens_DATE_LENGTH_NONPERIODIC[${DateNum}]}"
893        ;;
894      *)
895        IGCM_debug_Exit "IGCM_ensemble_DateInit ${ensemble_Ens_DATE_LENGTH_NONPERIODIC[${DateNum}]} : invalid NON PERIODIC LENGTH"
896        IGCM_debug_Exit "choose in *Y or *M"
897        IGCM_debug_Verif_Exit ;;
898      esac
899
900      # - Check RESTART_NONPERIODIC
901      case ${ensemble_Ens_DATE_RESTART_NONPERIODIC[${DateNum}]} in
902      _0_)
903        IGCM_debug_Exit "IGCM_ensemble_DateInit ${ensemble_Ens_DATE_RESTART_NONPERIODIC[${DateNum}]} : invalid NON PERIODIC RESTART"
904        IGCM_debug_Verif_Exit ;;
905      esac
906
907      (( DateNum = DateNum + 1 ))
908    done
909  fi # DateNonPeriodicStart = true
910
911  IGCM_debug_PopStack "IGCM_ensemble_DateInit"
912}
913
914function IGCM_ensemble_DateNonPeriodicStarts
915{
916  IGCM_debug_PushStack "IGCM_ensemble_DateNonPeriodicStarts"
917
918  #.. Manage non periodic starts => Loop over DateBegin ..
919  #   ==========================
920
921  [ ${DateNonPeriodicStart} = false ] && return
922
923  echo
924  IGCM_debug_Print 1 ">>>  MANAGE NON PERIODIC STARTS  <<<"
925
926  # - Build directory name
927  echo ""
928  echo "========================================================================"
929  echo "ensemble_Ens_DATE_NAME = ${ensemble_Ens_DATE_NAME}"
930  StartDir="${ensemble_Ens_DATE_NAME}"
931
932  # -  Does $StartDir already exist ?
933  if [ ! -d ${SUBMIT_DIR}/${StartDir} ] ; then
934    IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}
935    IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}
936    ln -s ../../.resol .
937    ln -s ../../.libmpi .
938    IGCM_sys_Cd ${RUN_DIR}
939  fi
940
941  DateNum=0
942  # ... Loop over ensemble_Ens_DATE_NONPERIODIC ...
943  while [ ${DateNum} -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; do
944    DateBegin=${ensemble_Ens_DATE_NONPERIODIC[${DateNum}]}
945    Duree=${ensemble_Ens_DATE_LENGTH_NONPERIODIC[${DateNum}]}
946    RestartDate=${ensemble_Ens_DATE_RESTART_NONPERIODIC[${DateNum}]}
947    InitFrom=${ensemble_Ens_DATE_INITFROM_NONPERIODIC[${DateNum}]}
948    InitPath=${ensemble_Ens_DATE_INITPATH_NONPERIODIC[${DateNum}]}
949    (( ii=DateNum + 1 ))
950   
951    MemberDir="${ensemble_Ens_DATE_NAME}${ii}"
952    IGCM_debug_Print 3 "${MemberDir}"
953    echo "Create: ${MemberDir}"
954   
955  # - Determine number of day(s) in LENGTH_NONPERIODIC
956    IGCM_date_GetYearMonth ${DateBegin} year month
957    DureeLengthInDays=$(( $( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${Duree} ) - 1 ))
958
959  # - Determine DateEnd
960    (( DateEnd = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${DureeLengthInDays} ) ))
961
962    IGCM_debug_Print 2 "${DateBegin} => ${DateEnd} : ${StartDir}"
963    echo "${DateBegin} ${DateEnd} ${StartDir}" >> ${RUN_DIR}/CreatedDir.txt
964
965    PeriodDateEnd=$( grep -m1 ${StartDir} ${RUN_DIR}/CreatedDir.txt | cut -f2 -d\  )
966
967    JobName="Job_${MemberDir}"
968   
969    # * Create directory if it doesn't exist and copy files
970    if [ ! -d  ${SUBMIT_DIR}/${StartDir}/${MemberDir} ] ; then
971
972        # * Create ${SUBMIT_DIR}/${StartDir}/${MemberDir} directories
973        #   link COMP PARAM POST and DRIVER
974        #   cp config.card, run.card.init, Job_
975        #   and Dump command to be launched
976        IGCM_ensemble_CreateMemberDir
977       
978        # * Update files : config.card, Job_, COMP/comp.card
979        IGCM_ensemble_FilesUpdate "DATE" ${ii} ${DateBegin} ${DateEnd} ${RestartDate} ${InitFrom} ${InitPath}
980    fi
981   
982    # Done. Save ${StartDir} submission text file
983    IGCM_sys_Cp ${RUN_DIR}/Qsub.${StartDir}.sh ${SUBMIT_DIR}
984    IGCM_sys_Cp ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh ${SUBMIT_DIR}
985    IGCM_sys_Cp ${RUN_DIR}/Qclean.latestPackperiod.${StartDir}.sh ${SUBMIT_DIR}
986
987    (( DateNum = DateNum + 1 ))
988  done
989
990  IGCM_debug_PopStack "IGCM_ensemble_DateNonPeriodicStarts"
991}
992
Note: See TracBrowser for help on using the repository browser.