source: trunk/libIGCM/libIGCM_ensemble/libIGCM_ensemble.ksh @ 1009

Last change on this file since 1009 was 1007, checked in by sdipsl, 10 years ago

add-on for ensemble:

  • generate 2 new files « Qclean.month.XXX.sh » and « Qclean.year.XXX.sh » to clean ensemble members at once.
  • new args INITFROM_NONPERIODIC for ensembleDATE to be able to give a list of simulation where to take restart from (if empty use INITFROM for every members)
  • ensemble merbers from ensembleDATE sre compsoed this way [ENSEMBLENAME][NUMBER]A instead of "simualation we start from"+DateBegin? ==> easier to follow and to determine who's missing.
  • Property svn:keywords set to Revision Author Date
File size: 44.0 KB
Line 
1#!/bin/ksh
2
3#**************************************************************
4# Author: Sebastien Denvil, Sonia Labetoulle, Nicolas Lebas
5# Contact: Nicolas.Lebas__at__locean-ipsl.upmc.fr
6# $Revision::                                          $ Revision of last commit
7# $Author::                                            $ Author of last commit
8# $Date::                                              $ Date of last commit
9# IPSL (2012)
10#  This software is governed by the CeCILL licence see libIGCM/libIGCM_CeCILL.LIC
11#
12#**************************************************************
13
14# Read which ensemble type are active
15function IGCM_ensemble_Init
16{
17  IGCM_debug_PushStack "IGCM_ensemble_Init"
18
19  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB active
20  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE active
21  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PARAMETRIC active
22
23  IGCM_debug_Print 1 "Ens_PERTURB ACTIVE       = ${ensemble_Ens_PERTURB_active}"
24  IGCM_debug_Print 1 "Ens_DATE ACTIVE       = ${ensemble_Ens_DATE_active}"
25  IGCM_debug_Print 1 "Ens_PARAMETRIC ACTIVE  = ${ensemble_Ens_PARAMETRIC_active}"
26  echo ""
27
28  IGCM_debug_PopStack "IGCM_ensemble_Init"
29}
30
31# Set Alphanumerical variables ajust to member nb
32function IGCM_ensemble_SetAlpha
33{
34  IGCM_debug_PushStack "IGCM_ensemble_SetAlpha"
35
36  set -A Alpha      A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
37  set -A AlphaMonth a b c d e f g h i j k l
38
39  IGCM_debug_PopStack "IGCM_ensemble_SetAlpha"
40}
41
42############### Perturb ENSEMBLE #################
43function IGCM_ensemble_CastInit
44{
45  IGCM_debug_PushStack "IGCM_ensemble_CastInit"
46
47  IGCM_sys_Mkdir ${RUN_DIR}
48
49  IGCM_sys_Cp ${SUBMIT_DIR}/config.card   ${RUN_DIR}
50  IGCM_sys_Cp ${SUBMIT_DIR}/ensemble.card ${RUN_DIR}
51  IGCM_sys_Cp ${SUBMIT_DIR}/Job_*         ${RUN_DIR}
52  IGCM_sys_Cp ${SUBMIT_DIR}/run.card.init ${RUN_DIR}
53  if [ -f ${SUBMIT_DIR}/Qsub.* ]; then
54      IGCM_sys_Cp ${SUBMIT_DIR}/Qsub.*        ${RUN_DIR}
55  fi
56  if [ -f ${SUBMIT_DIR}/Qclean.* ]; then
57      IGCM_sys_Cp ${SUBMIT_DIR}/Qclean.*      ${RUN_DIR}
58  fi
59
60  # Useful?
61  #if [ -f  ${SUBMIT_DIR}/CreatedDir.txt ] ; then
62  #  IGCM_sys_Cp ${SUBMIT_DIR}/CreatedDir.txt ${RUN_DIR}
63  #fi
64  # Useful?
65  #if [ -f  ${SUBMIT_DIR}/Qsub.sh ] ; then
66  #  IGCM_sys_Cp ${SUBMIT_DIR}/Qsub.sh ${RUN_DIR}
67  #fi
68  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB NAME
69  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB BEGIN_INIT
70  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB END_INIT
71  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB PERIODICITY
72  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_PERTURB NONPERIODIC
73  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB LENGTH
74  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_PERTURB LENGTH_NONPERIODIC
75  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB MEMBER
76  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_PERTURB PERTURB_BIN
77  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB INITFROM
78  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB INITPATH
79  IGCM_card_DefineVariableFromOption config.card UserChoices JobName
80  IGCM_card_DefineVariableFromOption config.card UserChoices TagName
81  IGCM_card_DefineVariableFromOption config.card UserChoices CalendarType
82  IGCM_card_DefineArrayFromSection   config.card ListOfComponents
83
84  echo
85  IGCM_debug_Print 1 "[Ens_PERTURB]"
86  IGCM_debug_Print 1 "ACTIVE            = ${ensemble_Ens_PERTURB_active}"
87  IGCM_debug_Print 1 "NAME              = ${ensemble_Ens_PERTURB_NAME}"
88  IGCM_debug_Print 1 "BEGIN_INIT        = ${ensemble_Ens_PERTURB_BEGIN_INIT}"
89  IGCM_debug_Print 1 "END_INIT          = ${ensemble_Ens_PERTURB_END_INIT}"
90  IGCM_debug_Print 1 "PERIODICITY       = ${ensemble_Ens_PERTURB_PERIODICITY}"
91  IGCM_debug_Print 1 "NONPERIODIC       = ${ensemble_Ens_PERTURB_NONPERIODIC[*]}"
92  IGCM_debug_Print 1 "LENGTH             = ${ensemble_Ens_PERTURB_LENGTH}"
93  IGCM_debug_Print 1 "LENGTH_NONPERIODIC = ${ensemble_Ens_PERTURB_LENGTH_NONPERIODIC[*]}"
94  IGCM_debug_Print 1 "MEMBER            = ${ensemble_Ens_PERTURB_MEMBER}"
95  IGCM_debug_Print 1 "PERTURB_BIN       = ${ensemble_Ens_PERTURB_PERTURB_BIN[*]}"
96  IGCM_debug_Print 1 "INITFROM          = ${ensemble_Ens_PERTURB_INITFROM}"
97  IGCM_debug_Print 1 "INITPATH          = ${ensemble_Ens_PERTURB_INITPATH}"
98  IGCM_debug_Print 1 "JobName           = ${config_UserChoices_JobName}"
99  IGCM_debug_Print 1 "TagName           = ${config_UserChoices_TagName}"
100  IGCM_debug_Print 1 "CalendarType      = ${config_UserChoices_CalendarType}"
101  IGCM_debug_Print 1 "ListOfComponents  = ${config_ListOfComponents[*]}"
102
103  PerturbExe=${ensemble_Ens_PERTURB_PERTURB_BIN[0]}
104  PerturbComp=${ensemble_Ens_PERTURB_PERTURB_BIN[1]}
105  PerturbFile=${ensemble_Ens_PERTURB_PERTURB_BIN[2]}
106  PerturbVar=${ensemble_Ens_PERTURB_PERTURB_BIN[3]}
107  PerturbAmp=${ensemble_Ens_PERTURB_PERTURB_BIN[4]}
108
109  IGCM_debug_Print 1 "PerturbExe  = ${PerturbExe}"
110  IGCM_debug_Print 1 "PerturbFile = ${PerturbFile}"
111  IGCM_debug_Print 1 "PerturbComp = ${PerturbComp}"
112  IGCM_debug_Print 1 "PerturbVar  = ${PerturbVar}"
113  IGCM_debug_Print 1 "PerturbAmp  = ${PerturbAmp}"
114
115  IGCM_ensemble_SetAlpha ${ensemble_Ens_PERTURB_MEMBER}
116
117  # A few checks Period case:
118
119  # ... Check PERIODICITY ...
120  case ${ensemble_Ens_PERTURB_PERIODICITY} in
121  _0_)
122    IGCM_debug_Print 1 "periodic start not active"
123    CastPeriodicStart=false
124    ;;
125  *[Yy]|*[Mm])
126    CastPeriodicStart=true
127    IGCM_debug_Print 1 "Periodic length : ${ensemble_Ens_PERTURB_PERIODICITY}" ;;
128  *)
129    IGCM_debug_Exit "IGCM_ensemble_CastInit ${ensemble_Ens_PERTURB_PERIODICITY} : invalid PERIODICITY"
130    IGCM_debug_Exit "Choose a value in *Y or *M"
131    IGCM_debug_Verif_Exit ;;
132  esac
133# ... Check LENGTH ...
134  case ${ensemble_Ens_PERTURB_LENGTH} in
135  *[Yy]|*[Mm])
136    IGCM_debug_Print 1 "Periodic duration : ${ensemble_Ens_PERTURB_LENGTH}" ;;
137  *)
138    IGCM_debug_Exit "IGCM_ensemble_CastInit ${ensemble_Ens_PERTURB_LENGTH} invalid LENGTH"
139    IGCM_debug_Exit "Choose a value in choose in *Y or *M"
140    IGCM_debug_Verif_Exit ;;
141  esac
142
143  # A few checks for the Non-Periodic case:
144  DateNum=0
145  while [ $DateNum -lt ${#ensemble_Ens_PERTURB_NONPERIODIC[*]} ] ; do
146
147    # - Check LENGTH_NONPERIODIC
148    case ${ensemble_Ens_PERTURB_LENGTH_NONPERIODIC[$DateNum]} in
149    _0_)
150      IGCM_debug_Print 1 "non-periodic start not active"
151      CastNonPeriodicStart=false
152      ;;
153    *[Yy]|*[Mm])
154      IGCM_debug_Print 1 "Non-periodic duration : ${ensemble_Ens_PERTURB_LENGTH_NONPERIODIC[$DateNum]}"
155      CastNonPeriodicStart=true
156      ;;
157    *)
158      IGCM_debug_Exit "IGCM_ensemble_CastInit ${ensemble_Ens_PERTURB_LENGTH_NONPERIODIC[$DateNum]} : invalid LENGTH"
159      IGCM_debug_Exit "choose in *Y or *M"
160      IGCM_debug_Verif_Exit ;;
161    esac
162    (( DateNum = DateNum + 1 ))
163  done
164
165  # Need to know all the restart filename of the component we will apply the noise to
166  IGCM_card_DefineArrayFromOption config.card ListOfComponents ${PerturbComp}
167  eval compname=\${config_ListOfComponents_${PerturbComp}[0]} > /dev/null 2>&1
168
169  # Target the component's card we apply the noise to
170  card=${SUBMIT_DIR}/COMP/${compname}.card
171
172  # Read the restart file list. To be used later
173  IGCM_card_DefineArrayFromOption ${card} RestartFiles List
174  ListFilesName=${compname}_RestartFiles_List
175  eval FileName0=\${${ListFilesName}[0]} > /dev/null 2>&1
176  eval NbFiles=\${#${ListFilesName}[@]} > /dev/null 2>&1
177
178  # Check
179  IGCM_debug_Print 1 "Nb Restart Files  = ${NbFiles}"
180
181  IGCM_debug_PopStack "IGCM_ensemble_CastInit"
182}
183
184function IGCM_ensemble_CastPeriodicStarts
185{
186  IGCM_debug_PushStack "IGCM_ensemble_CastPeriodicStarts"
187
188  [ ${CastPeriodicStart} = false ] && return
189
190  echo
191  IGCM_debug_Print 1 "Manage periodic starts"
192
193#.. Manage periodic starts ..
194#   ======================
195
196# ... Loop over DateBegin ...
197  eval DateBegin=\${ensemble_Ens_PERTURB_BEGIN_INIT}
198
199  while [ ${DateBegin} -le ${ensemble_Ens_PERTURB_END_INIT} ] ; do
200    IGCM_date_GetYearMonth ${DateBegin} year month
201
202  # - Determine number of day(s) in PERIODICITY
203    PeriodLengthInDays=$( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${ensemble_Ens_PERTURB_PERIODICITY} )
204
205  # - Determine number of day(s) in LENGTH
206    DureeLengthInDays=$(( $( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${ensemble_Ens_PERTURB_LENGTH} ) - 1 ))
207
208  # - Determine DateEnd
209    (( DateEnd = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${DureeLengthInDays} ) ))
210
211  # - Build directory name
212    IGCM_ensemble_CastDirectoryName ${ensemble_Ens_PERTURB_NAME} ${ensemble_Ens_PERTURB_PERIODICITY} $year $month $StartDir
213
214  # - Determine RestartDate
215    (( Offset = -1 ))
216    (( RestartDate = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${Offset} ) ))
217
218    IGCM_debug_Print 2 "${DateBegin} => ${DateEnd} : ${StartDir}"
219    echo "${DateBegin} ${DateEnd} ${StartDir}" >> ${RUN_DIR}/CreatedDir.txt
220
221  # - Create directory for current DateBegin
222    if [ ! -d  ${StartDir} ] ; then
223      IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}
224      IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}
225      ln -s ../../.resol .
226      ln -s ../../.libmpi .
227      IGCM_sys_Cd ${RUN_DIR}
228    fi
229
230  # - Create directory to store modified restart files
231    RestartDir=${STORAGE}/IGCM_IN/${config_UserChoices_TagName}/${StartDir}
232    IGCM_sys_MkdirArchive ${RestartDir}
233
234  # - Loop over members
235    i=0
236    while [ $i -lt ${ensemble_Ens_PERTURB_MEMBER} ] ; do
237      MemberDir="${StartDir}${Alpha[$i]}"
238      echo
239      IGCM_debug_Print 3 "${MemberDir}"
240
241      JobName="Job_${MemberDir}"
242
243    # * Create directory if it doesn't exist and copy/link files
244      if [ ! -d  ${SUBMIT_DIR}/${StartDir}/${MemberDir} ] ; then
245        IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}/${MemberDir}
246        IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}/${MemberDir}
247        ln -s ../../COMP
248        ln -s ../../PARAM
249        ln -s ../../POST
250        ln -s ../../DRIVER
251        IGCM_sys_Cd ${RUN_DIR}
252        IGCM_sys_Cp config.card run.card.init ${SUBMIT_DIR}/${StartDir}/${MemberDir}
253        IGCM_sys_Cp Job_${config_UserChoices_JobName} ${SUBMIT_DIR}/${StartDir}/${MemberDir}/${JobName}
254
255        # Dump command to be lauched
256        echo "cd ${StartDir}/${MemberDir}/ ;"  >> ${RUN_DIR}/Qsub.${StartDir}.sh
257        echo "${SUBMIT} ${JobName} ; cd -"     >> ${RUN_DIR}/Qsub.${StartDir}.sh
258
259        echo "cd ${StartDir}/${MemberDir}/ ;"  >> ${RUN_DIR}/Qclean.month.${StartDir}.sh
260        echo "${libIGCM}/clean_month.job ; cd -"     >> ${RUN_DIR}/Qclean.month.${StartDir}.sh
261
262        echo "cd ${StartDir}/${MemberDir}/ ;"  >> ${RUN_DIR}/Qclean.year.${StartDir}.sh
263        echo "${libIGCM}/clean_year.job ; cd -"     >> ${RUN_DIR}/Qclean.year.${StartDir}.sh
264
265        # * Update files : config.card, Job_, COMP/comp.card
266        IGCM_ensemble_CastFilesUpdate ${DateBegin} ${DateEnd} ${RestartDate}
267
268        # * Apply noise on restart file
269        IGCM_ensemble_CastPerturbFile
270      fi
271
272      (( i = i + 1 ))
273    done
274
275    # Done. Save ${StartDir} submission text file
276    IGCM_sys_Cp ${RUN_DIR}/Qsub.${StartDir}.sh ${SUBMIT_DIR}
277    IGCM_sys_Cp ${RUN_DIR}/Qclean.month.${StartDir}.sh ${SUBMIT_DIR}
278    IGCM_sys_Cp ${RUN_DIR}/Qclean.year.${StartDir}.sh ${SUBMIT_DIR}
279
280  # - Next DateBegin
281    echo "$DateBegin  $PeriodLengthInDays"
282    case ${ensemble_Ens_PERTURB_PERIODICITY} in
283    *[Yy]|*[Mm])
284      (( DateBegin = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${PeriodLengthInDays} ) ))
285      ;;
286    esac
287    echo "New DateBegin = $DateBegin"
288    echo "========================================================================"
289  done
290  IGCM_debug_PopStack "IGCM_ensemble_CastPeriodicStarts"
291}
292
293function IGCM_ensemble_CastNonPeriodicStarts
294{
295  IGCM_debug_PushStack "IGCM_ensemble_CastNonPeriodicStarts"
296
297  #.. Manage non periodic starts => Loop over DateBegin ..
298  #   ==========================
299
300  [ ${CastNonPeriodicStart} = false ] && return
301
302  echo
303  IGCM_debug_Print 1 "Manage non periodic starts"
304
305  DateNum=0
306# ... Loop over ensemble_Ens_PERTURB_NONPERIODIC ...
307  echo ">${DateNum}<"
308  echo ">${#ensemble_Ens_PERTURB_NONPERIODIC[*]}<"
309  while [ $DateNum -lt ${#ensemble_Ens_PERTURB_NONPERIODIC[*]} ] ; do
310    DateBegin=${ensemble_Ens_PERTURB_NONPERIODIC[$DateNum]}
311    Duree=${ensemble_Ens_PERTURB_LENGTH_NONPERIODIC[$DateNum]}
312    echo ">${DateBegin}<"
313    echo ">${Duree}<"
314
315  # - Determine number of day(s) in LENGTH_NONPERIODIC
316    IGCM_date_GetYearMonth ${DateBegin} year month
317    DureeLengthInDays=$(( $( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${Duree} ) - 1 ))
318
319  # - Build directory name
320    echo "========================================================================"
321    echo "ensemble_Ens_PERTURB_NAME = ${ensemble_Ens_PERTURB_NAME}"
322    IGCM_ensemble_CastDirectoryName ${ensemble_Ens_PERTURB_NAME} ${Duree} $year $month $StartDir
323
324  # - Determine DateEnd
325    (( DateEnd = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${DureeLengthInDays} ) ))
326    echo ">${DateEnd}<"
327    echo "tout va bien 1"
328
329  # - Determine RestartDate
330    (( Offset = -1 ))
331    (( RestartDate = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${Offset} ) ))
332
333    IGCM_debug_Print 2 "${DateBegin} => ${DateEnd} : ${StartDir}"
334
335  # -  Does $StartDir already exist ?
336    #echo "tout va bien 2" ${StartDir}
337    if [ ! -d ${SUBMIT_DIR}/${StartDir} ] ; then
338      echo "create dir"
339      IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}
340      IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}
341      ln -s ../../.resol .
342      ln -s ../../.libmpi .
343      IGCM_sys_Cd ${RUN_DIR}
344      echo "${DateBegin} ${DateEnd} ${StartDir}" >> ${RUN_DIR}/CreatedDir.txt
345    fi
346    PeriodDateEnd=$( grep -m1 ${StartDir} ${RUN_DIR}/CreatedDir.txt | cut -f2 -d\  )
347
348  # - Create directory in which to store new restart files if it does'nt already exist
349    RestartDir=${STORAGE}/IGCM_IN/${config_UserChoices_TagName}/${StartDir}
350    IGCM_sys_MkdirArchive ${RestartDir}
351
352  # - Loop over members
353    i=0
354    while [ $i -lt ${ensemble_Ens_PERTURB_MEMBER} ] ; do
355      MemberDir="${StartDir}${Alpha[$i]}"
356      IGCM_debug_Print 3 "${MemberDir}"
357
358      JobName="Job_${MemberDir}"
359
360    # * Create directory if it doesn't exist and copy files
361      if [ ! -d  ${SUBMIT_DIR}/${StartDir}/${MemberDir} ] ; then
362        IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}/${MemberDir}
363        #IGCM_sys_Cp -r COMP/ PARAM/ ${StartDir}/${MemberDir}
364        IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}/${MemberDir}
365        ln -s ../../COMP
366        ln -s ../../PARAM
367        ln -s ../../POST
368        ln -s ../../DRIVER
369        IGCM_sys_Cd ${RUN_DIR}
370        IGCM_sys_Cp config.card run.card.init ${SUBMIT_DIR}/${StartDir}/${MemberDir}
371        IGCM_sys_Cp Job_${config_UserChoices_JobName} ${SUBMIT_DIR}/${StartDir}/${MemberDir}/Job_${MemberDir}
372
373        # Dump command to be lauched
374        echo "cd ${StartDir}/${MemberDir}/ ;"  >> Qsub.${StartDir}.sh
375        echo "${SUBMIT} ${JobName} ; cd -"     >> Qsub.${StartDir}.sh
376
377        echo "cd ${StartDir}/${MemberDir}/ ;"  >> ${RUN_DIR}/Qclean.month.${StartDir}.sh
378        echo "${libIGCM}/clean_month.job ; cd -"     >> ${RUN_DIR}/Qclean.month.${StartDir}.sh
379
380        echo "cd ${StartDir}/${MemberDir}/ ;"  >> ${RUN_DIR}/Qclean.year.${StartDir}.sh
381        echo "${libIGCM}/clean_year.job ; cd -"     >> ${RUN_DIR}/Qclean.year.${StartDir}.sh
382
383        # * Update files : config.card, Job_, COMP/comp.card
384        echo "${PeriodDateEnd} ? ${DateEnd}"
385        if [ ${PeriodDateEnd} -gt ${DateEnd} ] ; then
386            DateEnd=${PeriodDateEnd}
387        fi
388        IGCM_ensemble_CastFilesUpdate ${DateBegin} ${DateEnd} ${RestartDate}
389
390        # * Apply noise on restart file
391        IGCM_ensemble_CastPerturbFile
392      fi
393
394      (( i = i + 1 ))
395    done
396
397    # Done. Save ${StartDir} submission text file
398    IGCM_sys_Cp ${RUN_DIR}/Qsub.${StartDir}.sh ${SUBMIT_DIR}
399    IGCM_sys_Cp ${RUN_DIR}/Qclean.month.${StartDir}.sh ${SUBMIT_DIR}
400    IGCM_sys_Cp ${RUN_DIR}/Qclean.year.${StartDir}.sh ${SUBMIT_DIR}
401
402    (( DateNum = DateNum + 1 ))
403  done
404  IGCM_debug_PopStack "IGCM_ensemble_CastNonPeriodicStarts"
405}
406
407function IGCM_ensemble_CastFilesUpdate
408{
409  IGCM_debug_PushStack "IGCM_ensemble_CastFilesUpdate"
410
411  # Debug Print :
412  echo
413  IGCM_debug_Print 1 "IGCM_ensemble_CastFilesUpdate :"
414
415  HumanDateBegin=$(   IGCM_date_ConvertFormatToHuman ${1} )
416  HumanDateEnd=$(     IGCM_date_ConvertFormatToHuman ${2} )
417  HumanRestartDate=$( IGCM_date_ConvertFormatToHuman ${3} )
418  # ==> config.card
419  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleRun 'y'
420  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleName ${ensemble_Ens_PERTURB_NAME}
421  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleDate ${StartDir}
422
423  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card UserChoices JobName   ${MemberDir}
424  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card UserChoices DateBegin ${HumanDateBegin}
425  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card UserChoices DateEnd   ${HumanDateEnd}
426  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Restarts OverRule "n"
427
428  for comp in ${config_ListOfComponents[*]} ; do
429    IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${comp} Restart "y"
430    IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${comp} RestartDate ${HumanRestartDate}
431    IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${comp} RestartJobName ${ensemble_Ens_PERTURB_INITFROM}
432    IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${comp} RestartPath ${ensemble_Ens_PERTURB_INITPATH}
433  done
434
435  # ==> Job
436  sed -e "s/\(#.*\)${config_UserChoices_JobName}\( *#.*\)/\1${MemberDir} \2/"            \
437      -e "s/\(#.*Script_Output_\)${config_UserChoices_JobName}\(\.*\)/\1${MemberDir}\2/" \
438      -e "s/^PeriodNb=.*/PeriodNb=60/"                                                  \
439      ${SUBMIT_DIR}/${StartDir}/${MemberDir}/Job_${MemberDir} > Job_${MemberDir}.tmp
440  IGCM_sys_Mv Job_${MemberDir}.tmp ${SUBMIT_DIR}/${StartDir}/${MemberDir}/Job_${MemberDir}
441
442  IGCM_debug_PopStack "IGCM_ensemble_CastFilesUpdate"
443}
444
445function IGCM_ensemble_CastDirectoryName
446{
447  IGCM_debug_PushStack "IGCM_ensemble_CastDirectoryName"
448
449  #.. Debug Print ..
450  echo
451  IGCM_debug_Print 1 "IGCM_ensemble_CastDirectoryName :"
452  echo
453
454  Name=$1
455  Duree=$2
456  year=$3
457  month=$4
458
459  # - Build directory name
460  case ${Duree} in
461    *Y|*y)
462      siecle="$( echo $year | cut -c1-2 )"
463      siecle=$( (( $siecle - 18 )) )
464      StartYear="${siecle}$( echo $year | cut -c3-4 )"
465      StartDir="${Name}${StartYear}"
466      ;;
467    *M|*m)
468      echo $month
469      siecle="$( echo $year | cut -c1-2 )"
470      siecle=$( (( $siecle - 18 )) )
471      StartYear="${siecle}$( echo $year | cut -c3-4 )"
472      StartMonth="${AlphaMonth[ (( 10#${month} - 1 )) ]}"
473      StartDir="${Name}${StartYear}${StartMonth}"
474      ;;
475  esac
476
477  IGCM_debug_PopStack "IGCM_ensemble_CastDirectoryName"
478}
479
480function IGCM_ensemble_CastPerturbFile
481{
482  IGCM_debug_PushStack "IGCM_ensemble_CastPerturbFile"
483
484  typeset i i_ j j4 file_out file_out_
485
486  #.. Debug Print ..
487  echo
488  IGCM_debug_Print 1 "IGCM_ensemble_CastPerturbFile :"
489
490  #.. FileIn ? => RestartDate ..
491  DirIn="${ensemble_Ens_PERTURB_INITPATH}/${ensemble_Ens_PERTURB_INITFROM}/${PerturbComp}/Restart"
492  DirInTar="${ensemble_Ens_PERTURB_INITPATH}/${ensemble_Ens_PERTURB_INITFROM}/RESTART"
493  FileIn="${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${PerturbFile}"
494  DirOut="${RestartDir}/${MemberDir}/${PerturbComp}/Restart"
495
496  # * Create member restart directory
497  IGCM_sys_TestDirArchive ${DirOut}
498  RET=$?
499  if [ $RET -gt 0 ] ; then
500    IGCM_sys_MkdirArchive ${DirOut}
501  fi
502
503  FileOut="${MemberDir}_${RestartDate}_${PerturbFile}"
504  IGCM_debug_Print 1 "FileIn  = ${DirIn}/${FileIn}"
505  IGCM_debug_Print 1 "FileOut = ${DirOut}/${FileOut}.nc"
506
507  IGCM_sys_TestFileArchive ${DirOut}/${FileOut}.nc
508  RET=$?
509  if [ $RET -gt 0 ] ; then
510
511    # * Look for the restart file we apply the noise to
512
513    # restart file list pertaining to the component we apply the noise to
514    # but not being the precise restart file we will apply the noise to
515    unset OtherFileInList
516    # generic restart filename list (like flxat, sstoc, restart, ...)
517    unset OtherGenericList
518
519    if ( [ X${FileName0} != X${NULL_STR} ] && [ X${FileName0} != XNONE ] ) ; then
520      (( i=0 ))
521      until [ $i -ge ${NbFiles} ]; do
522
523        (( i_ = i+1 ))
524        eval file_out_=\${${ListFilesName}[$i_]} > /dev/null 2>&1
525        eval file_out=${file_out_}
526
527        generic_restart_file_name_out=$( basename ${file_out} .nc )
528
529        if [ ! ${generic_restart_file_name_out} = ${PerturbFile} ] ; then
530          set +A OtherFileInList ${OtherFileInList[*]} ${PerturbComp}_${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic_restart_file_name_out}\*.nc
531          set +A OtherGenericList ${OtherGenericList[*]} ${generic_restart_file_name_out}
532        fi
533
534        (( i=i+3 ))
535      done
536    fi
537    # How many restart files other than the one we will apply the noise to
538    NbOtherFiles=${#OtherGenericList[*]}
539
540    ##########################
541    # TO BE A FUNCTION BEGIN #
542    ##########################
543
544    if [ $( IGCM_sys_TestFileBuffer ${DirIn}/${FileIn}*.nc ; echo $? ) = 0 ] ; then
545      IGCM_debug_Print 3 "Buffered restart"
546      Buffered=true
547      Archived=false
548      Tared=false
549      nb_restart_file=$(IGCM_sys_CountFileBuffer ${DirIn}/${FileIn}_????.nc)
550    elif [ $( IGCM_sys_TestFileArchive ${DirIn}/${FileIn}*.nc ; echo $? ) = 0 ] ; then
551      IGCM_debug_Print 3 "Archived restart"
552      Buffered=false
553      Archived=true
554      Tared=false
555      nb_restart_file=$(IGCM_sys_CountFileArchive ${DirIn}/${FileIn}_????.nc)
556    else
557      IGCM_debug_Print 3 "Tared restart"
558      Buffered=false
559      Archived=false
560      Tared=true
561
562      # Look for the tar file we want if we did not found it already
563      for PotentialTarFile in $( find ${ensemble_Ens_PERTURB_INITPATH}/${ensemble_Ens_PERTURB_INITFROM}/RESTART -name "${ensemble_Ens_PERTURB_INITFROM}_*restart*.tar" -print ) ; do
564        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}}' )
565        if [ ! X${IsMatching} = X ] ; then
566          TarFileFound=${PotentialTarFile}
567          break
568        fi
569      done
570
571      # Extract relevant restart files
572      IGCM_debug_Print 1 "tar xvf ${TarFileFound} ${PerturbComp}_${FileIn}*.nc ${OtherFileInList[*]}"
573      tar xvf ${TarFileFound} ${PerturbComp}_${FileIn}*.nc ${OtherFileInList[*]}
574      nb_restart_file=$( IGCM_sys_CountFileBuffer ${PerturbComp}_${FileIn}_????.nc )
575    fi
576
577    # Move around and perturb restart files so as to be able to start hindcast/forecast simulation members
578    if [ ${nb_restart_file} -gt 1 ] ; then
579      j=0
580      until [ $j -ge ${nb_restart_file} ]; do
581        j4=${j}
582        if [ X${Buffered} = Xtrue ] ; then
583          IGCM_sys_GetBuffer ${DirIn}/${FileIn}_${j4}.nc ${RUN_DIR}/${FileOut}_${j4}.nc
584
585          cd ${DirOut}
586          for generic in ${OtherGenericList[*]} ; do
587            ln -s ${DirIn}/${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${MemberDir}_${RestartDate}_${generic}_${j4}.nc
588          done
589          cd -
590
591        elif [ X${Archived} = Xtrue ] ; then
592          IGCM_sys_Get ${DirIn}/${FileIn}_${j4}.nc ${RUN_DIR}/${FileOut}_${j4}.nc
593
594          for generic in ${OtherGenericList[*]} ; do
595            IGCM_sys_RshArchive "cd ${DirOut} ; ln -s ${DirIn}/${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${MemberDir}_${RestartDate}_${generic}_${j4}.nc"
596          done
597
598        elif [ X${Tared} = Xtrue ] ; then
599          IGCM_sys_Mv ${PerturbComp}_${FileIn}_${j4}.nc ${RUN_DIR}/${FileOut}_${j4}.nc
600
601          for generic in ${OtherGenericList[*]} ; do
602            IGCM_sys_Mv ${PerturbComp}_${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${DirOut}/${MemberDir}_${RestartDate}_${generic}_${j4}.nc
603          done
604
605        fi
606        (( j=j+1 ))
607      done
608    else
609      if [ X${Buffered} = Xtrue ] ; then
610        IGCM_sys_GetBuffer ${DirIn}/${FileIn}.nc ${RUN_DIR}/${FileOut}.nc
611
612        cd ${DirOut}
613        for generic in ${OtherGenericList[*]} ; do
614          ln -s ${DirIn}/${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${MemberDir}_${RestartDate}_${generic}.nc
615        done
616        cd -
617
618      elif [ X${Archived} = Xtrue ] ; then
619        IGCM_sys_Get ${DirIn}/${FileIn}.nc ${RUN_DIR}/${FileOut}.nc
620
621        for generic in ${OtherGenericList[*]} ; do
622          IGCM_sys_RshArchive "cd ${DirOut} ; ln -s ${DirIn}/${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${MemberDir}_${RestartDate}_${generic}.nc"
623        done
624
625      elif [ X${Tared} = Xtrue ] ; then
626        IGCM_sys_Mv ${PerturbComp}_${FileIn}.nc ${RUN_DIR}/${FileOut}.nc
627
628        for generic in ${OtherGenericList[*]} ; do
629          IGCM_sys_Mv ${PerturbComp}_${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${DirOut}/${MemberDir}_${RestartDate}_${generic}.nc
630        done
631
632      fi
633    fi
634
635    ########################
636    # TO BE A FUNCTION END #
637    ########################
638
639    IGCM_sys_Chmod 644 ${RUN_DIR}/${FileOut}.nc
640    IGCM_debug_Print 1 "${PerturbExe} ${RUN_DIR}/${FileOut}.nc ${PerturbVar} ${PerturbAmp}"
641    echo
642    ${PerturbExe} ${RUN_DIR}/${FileOut}.nc ${PerturbVar} ${PerturbAmp} > /dev/null 2>&1
643
644    if [ $? -ne 0 ] ; then
645      IGCM_debug_Exit "Abend $( basename ${PerturbExe} )"
646      IGCM_debug_Verif_Exit
647    fi
648    IGCM_sys_Put_Out ${RUN_DIR}/${FileOut}.nc ${DirOut}/ 644
649  fi
650
651  #.. Update config.card..
652  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${PerturbComp} Restart "y"
653  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${PerturbComp} RestartDate    ${HumanRestartDate}
654  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${PerturbComp} RestartJobName ${MemberDir}
655  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${PerturbComp} RestartPath    ${RestartDir}/
656  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleType "Ens_PERTURB"
657
658  IGCM_debug_PopStack "IGCM_ensemble_CastPerturbFile"
659}
660
661############### Date ENSEMBLE #################
662function IGCM_ensemble_DateInit
663{
664  IGCM_debug_PushStack "IGCM_ensemble_DateInit"
665
666  IGCM_sys_Mkdir ${RUN_DIR}
667
668  IGCM_sys_Cp ${SUBMIT_DIR}/config.card   ${RUN_DIR}
669  IGCM_sys_Cp ${SUBMIT_DIR}/ensemble.card ${RUN_DIR}
670  IGCM_sys_Cp ${SUBMIT_DIR}/Job_*         ${RUN_DIR}
671  IGCM_sys_Cp ${SUBMIT_DIR}/run.card.init ${RUN_DIR}
672  if [ -f ${SUBMIT_DIR}/Qsub.* ]; then
673        IGCM_sys_Cp ${SUBMIT_DIR}/Qsub.*        ${RUN_DIR}
674  fi
675  if [ -f ${SUBMIT_DIR}/Qclean.* ]; then
676        IGCM_sys_Cp ${SUBMIT_DIR}/Qclean.*      ${RUN_DIR}
677  fi
678
679  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE active
680  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE NAME
681  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE BEGIN_INIT
682  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE BEGIN_RESTART
683  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE END_INIT
684  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE PERIODICITY
685  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_DATE NONPERIODIC
686  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_DATE RESTART_NONPERIODIC
687  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE LENGTH
688  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_DATE LENGTH_NONPERIODIC
689  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE INITFROM
690  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE INITFROM_NONPERIODIC
691  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE INITPATH
692  IGCM_card_DefineVariableFromOption config.card UserChoices JobName
693  IGCM_card_DefineVariableFromOption config.card UserChoices TagName
694  IGCM_card_DefineVariableFromOption config.card UserChoices CalendarType
695  IGCM_card_DefineArrayFromSection   config.card ListOfComponents
696
697  echo
698  IGCM_debug_Print 1 "[Ens_DATE]"
699  IGCM_debug_Print 1 "ACTIVE               = ${ensemble_Ens_DATE_active}"
700  IGCM_debug_Print 1 "NAME                 = ${ensemble_Ens_DATE_NAME}"
701  IGCM_debug_Print 1 "BEGIN_INIT           = ${ensemble_Ens_DATE_BEGIN_INIT}"
702  IGCM_debug_Print 1 "END_INIT             = ${ensemble_Ens_DATE_END_INIT}"
703  IGCM_debug_Print 1 "PERIODICITY          = ${ensemble_Ens_DATE_PERIODICITY}"
704  IGCM_debug_Print 1 "BEGIN_RESTART        = ${ensemble_Ens_DATE_BEGIN_RESTART}"
705  IGCM_debug_Print 1 "NONPERIODIC          = ${ensemble_Ens_DATE_NONPERIODIC[*]}"
706  IGCM_debug_Print 1 "RESTART_NONPERIODIC  = ${ensemble_Ens_DATE_RESTART_NONPERIODIC[*]}"
707  IGCM_debug_Print 1 "LENGTH               = ${ensemble_Ens_DATE_LENGTH}"
708  IGCM_debug_Print 1 "LENGTH_NONPERIODIC   = ${ensemble_Ens_DATE_LENGTH_NONPERIODIC[*]}"
709  IGCM_debug_Print 1 "INITFROM             = ${ensemble_Ens_DATE_INITFROM}"
710  IGCM_debug_Print 1 "INITFROM_NONPERIODIC = ${ensemble_Ens_DATE_INITFROM_NONPERIODIC[*]}"
711  IGCM_debug_Print 1 "INITPATH             = ${ensemble_Ens_DATE_INITPATH}"
712  IGCM_debug_Print 1 "JobName              = ${config_UserChoices_JobName}"
713  IGCM_debug_Print 1 "TagName              = ${config_UserChoices_TagName}"
714  IGCM_debug_Print 1 "CalendarType         = ${config_UserChoices_CalendarType}"
715  IGCM_debug_Print 1 "ListOfComponents     = ${config_ListOfComponents[*]}"
716  echo ""
717
718  ensemble_Ens_DATE_MEMBER=1 # actually use only 1 member
719  IGCM_ensemble_SetAlpha ${ensemble_Ens_DATE_MEMBER}
720
721  IGCM_debug_Print 1 "Check args..."
722  DatePeriodicStart=false
723  DateNonPeriodicStart=false
724
725  # ... Check LENGTH ...
726  case ${ensemble_Ens_DATE_LENGTH} in
727  *[Yy]|*[Mm])
728    IGCM_debug_Print 1 "Default simulation duration : ${ensemble_Ens_DATE_LENGTH}" ;;
729  *)
730    IGCM_debug_Exit "IGCM_ensemble_DateInit ${ensemble_Ens_DATE_LENGTH} invalid LENGTH"
731    IGCM_debug_Exit "Choose a value in choose in *Y or *M"
732    IGCM_debug_Verif_Exit ;;
733  esac
734
735  # ***************************************
736  # A few checks Period case:
737  # ***************************************
738  # if all Periodic params are not filled: desactivate Periodic mode
739  totalPeriodArgs=4
740  periodFillArgs=0
741
742  if [[ X${ensemble_Ens_DATE_BEGIN_RESTART} != "X" ]]; then
743      (( periodFillArgs = periodFillArgs + 1 ))
744  fi
745
746  if [[ X${ensemble_Ens_DATE_BEGIN_INIT} != "X" ]]; then
747      (( periodFillArgs = periodFillArgs + 1 ))
748  fi
749
750  if [[ X${ensemble_Ens_DATE_END_INIT} != "X" ]]; then
751      (( periodFillArgs = periodFillArgs + 1 ))
752  fi
753
754  if [[ X${ensemble_Ens_DATE_PERIODICITY} != "X" ]]; then
755      (( periodFillArgs = periodFillArgs + 1 ))
756
757      # ... Check PERIODICITY ...
758      case ${ensemble_Ens_DATE_PERIODICITY} in
759          *[Yy]|*[Mm])
760              IGCM_debug_Print 1 "Periodic length : ${ensemble_Ens_DATE_PERIODICITY}" ;;
761          *)
762              IGCM_debug_Exit "IGCM_ensemble_DateInit ${ensemble_Ens_DATE_PERIODICITY} : invalid PERIODICITY"
763              IGCM_debug_Exit "Choose a value in *Y or *M"
764              IGCM_debug_Verif_Exit ;;
765      esac
766  fi # if periodicity
767
768  if [[ ${periodFillArgs} = ${totalPeriodArgs} ]]; then
769      DatePeriodicStart=true
770  else
771      if [[ ${periodFillArgs} = 0 ]]; then
772          IGCM_debug_Print 1 "Periodic start NOT ACTIVE"
773          DatePeriodicStart=false
774      else
775          IGCM_debug_Exit "IGCM_ensemble_DateInit missing arguments for Periodic mode!"
776          IGCM_debug_Exit "Get only ${periodFillArgs} on ${totalPeriodArgs} args. Check ${F_CFG_ENS} file."
777          IGCM_debug_Verif_Exit
778      fi
779  fi
780
781  # ***************************************
782  # A few checks for the Non-Periodic case:
783  # ***************************************
784  if [[ ${#ensemble_Ens_DATE_NONPERIODIC[*]} != ${#ensemble_Ens_DATE_RESTART_NONPERIODIC[*]} ]] ; then
785      IGCM_debug_Exit "IGCM_ensemble_DateInit: NONPERIODIC and RESTART_NONPERIODIC lists have different sizes"
786      IGCM_debug_Verif_Exit
787  fi
788
789  if [[ ${#ensemble_Ens_DATE_NONPERIODIC[*]} > 0 ]] && [[ ${ensemble_Ens_DATE_NONPERIODIC[*]} != _0_ ]]; then
790      DateNonPeriodicStart=true
791
792      # Use LENGTH if no NONPERIODIC_LENGTH given
793      if [[ ${#ensemble_Ens_DATE_LENGTH_NONPERIODIC[*]} < ${#ensemble_Ens_DATE_NONPERIODIC[*]} ]] ; then
794          IGCM_debug_Print 1 "WARNING: LENGTH_NONPERIODIC is not fill (or not correctly). Use LENGTH value '${ensemble_Ens_DATE_LENGTH}' for all NONPERIODIC runs"
795          DateNum=0
796          while [ $DateNum -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; do
797              ensemble_Ens_DATE_LENGTH_NONPERIODIC[DateNum]=${ensemble_Ens_DATE_LENGTH}
798              (( DateNum = DateNum + 1 ))
799          done
800      fi
801
802      # Use INITFROM if no NONPERIODIC_INITFROM given
803      if [[ ${#ensemble_Ens_DATE_INITFROM_NONPERIODIC[*]} < ${#ensemble_Ens_DATE_NONPERIODIC[*]} ]] ; then
804          IGCM_debug_Print 1 "WARNING: INITFROM_NONPERIODIC is not fill (or not correctly). Use INITFROM value '${ensemble_Ens_DATE_INITFROM}' for all NONPERIODIC runs"
805          DateNum=0
806          while [ $DateNum -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; do
807              ensemble_Ens_DATE_INITFROM_NONPERIODIC[DateNum]=${ensemble_Ens_DATE_INITFROM}
808              (( DateNum = DateNum + 1 ))
809          done
810      fi
811  else
812      IGCM_debug_Print 1 "Non-Periodic start NOT ACTIVE"
813      DateNonPeriodicStart=false
814  fi
815
816  if [[ ${DateNonPeriodicStart} = true ]]; then
817      DateNum=0
818      while [ $DateNum -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; do
819          # - Check LENGTH_NONPERIODIC
820          case ${ensemble_Ens_DATE_LENGTH_NONPERIODIC[$DateNum]} in
821              *[Yy]|*[Mm])
822                  IGCM_debug_Print 1 "Non-periodic duration $DateNum: ${ensemble_Ens_DATE_LENGTH_NONPERIODIC[$DateNum]}"
823                  ;;
824              *)
825                  IGCM_debug_Exit "IGCM_ensemble_DateInit ${ensemble_Ens_DATE_LENGTH_NONPERIODIC[$DateNum]} : invalid NON PERIODIC LENGTH"
826                  IGCM_debug_Exit "choose in *Y or *M"
827                  IGCM_debug_Verif_Exit ;;
828          esac
829
830          # - Check RESTART_NONPERIODIC
831          case ${ensemble_Ens_DATE_RESTART_NONPERIODIC[$DateNum]} in
832              _0_)
833                  IGCM_debug_Exit "IGCM_ensemble_DateInit ${ensemble_Ens_DATE_RESTART_NONPERIODIC[$DateNum]} : invalid NON PERIODIC RESTART"
834                  IGCM_debug_Verif_Exit ;;
835          esac
836
837          (( DateNum = DateNum + 1 ))
838      done
839  fi # DateNonPeriodicStart = true
840
841  IGCM_debug_PopStack "IGCM_ensemble_DateInit"
842}
843
844function IGCM_ensemble_DatePeriodicStarts
845{
846  IGCM_debug_PushStack "IGCM_ensemble_DatePeriodicStarts"
847
848  [ ${DatePeriodicStart} = false ] && return
849
850  echo
851  IGCM_debug_Print 1 ">>>  MANAGE PERIODIC STARTS  <<<"
852
853#.. Manage periodic starts ..
854#   ======================
855
856  # - Build directory name
857  StartDir="${ensemble_Ens_DATE_NAME}"
858
859  # - Create directory for current DateBegin
860  if [ ! -d  ${StartDir} ] ; then
861      IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}
862      IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}
863      ln -s ../../.resol .
864      ln -s ../../.libmpi .
865      IGCM_sys_Cd ${RUN_DIR}
866  fi
867
868  # ... Loop over DateBegin ...
869  eval DateBegin=\${ensemble_Ens_DATE_BEGIN_INIT}
870  eval RestartDate=\${ensemble_Ens_DATE_BEGIN_RESTART}
871
872  DateNum=0
873  while [ ${DateBegin} -le ${ensemble_Ens_DATE_END_INIT} ] ; do
874    IGCM_date_GetYearMonth ${DateBegin} year month
875
876    echo "========================================================================"
877    echo "New DateBegin = $DateBegin"
878
879  # - Determine number of day(s) in PERIODICITY
880    PeriodLengthInDays=$( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${ensemble_Ens_DATE_PERIODICITY} )
881
882  # - Determine number of day(s) in LENGTH
883    DureeLengthInDays=$(( $( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${ensemble_Ens_DATE_LENGTH} ) - 1 ))
884
885  # - Determine DateEnd
886    (( DateEnd = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${DureeLengthInDays} ) ))
887
888    IGCM_debug_Print 2 "${DateBegin} => ${DateEnd} : ${StartDir}"
889    echo "${DateBegin} ${DateEnd} ${StartDir}" >> ${RUN_DIR}/CreatedDir.txt
890
891  # - Loop over members (default =1 no member)
892    i=0
893    while [ $i -lt ${ensemble_Ens_DATE_MEMBER} ] ; do
894      MemberDir="${ensemble_Ens_DATE_NAME}${DateNum}${Alpha[$i]}_per"
895      echo
896      IGCM_debug_Print 3 "${MemberDir}"
897
898      JobName="Job_${MemberDir}"
899
900    # * Create directory if it doesn't exist and copy/link files
901      if [ ! -d  ${SUBMIT_DIR}/${StartDir}/${MemberDir} ] ; then
902        IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}/${MemberDir}
903        IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}/${MemberDir}
904        ln -s ../../COMP
905        ln -s ../../PARAM
906        ln -s ../../POST
907        ln -s ../../DRIVER
908        IGCM_sys_Cd ${RUN_DIR}
909        IGCM_sys_Cp config.card run.card.init ${SUBMIT_DIR}/${StartDir}/${MemberDir}
910        IGCM_sys_Cp Job_${config_UserChoices_JobName} ${SUBMIT_DIR}/${StartDir}/${MemberDir}/${JobName}
911
912        # Dump command to be lauched
913        echo "cd ${StartDir}/${MemberDir}/ ;"  >> ${RUN_DIR}/Qsub.${StartDir}.sh
914        echo "${SUBMIT} ${JobName} ; cd -"     >> ${RUN_DIR}/Qsub.${StartDir}.sh
915
916        echo "cd ${StartDir}/${MemberDir}/ ;"  >> ${RUN_DIR}/Qclean.month.${StartDir}.sh
917        echo "${libIGCM}/clean_month.job ; cd -"     >> ${RUN_DIR}/Qclean.month.${StartDir}.sh
918
919        echo "cd ${StartDir}/${MemberDir}/ ;"  >> ${RUN_DIR}/Qclean.year.${StartDir}.sh
920        echo "${libIGCM}/clean_year.job ; cd -"     >> ${RUN_DIR}/Qclean.year.${StartDir}.sh
921
922        # * Update files : config.card, Job_, COMP/comp.card
923        IGCM_ensemble_DateFilesUpdate ${DateBegin} ${DateEnd} ${RestartDate}
924      fi
925
926      (( i = i + 1 ))
927    done
928
929  # - Next DateBegin & RestartDate
930    echo "$DateBegin  $PeriodLengthInDays"
931    case ${ensemble_Ens_DATE_PERIODICITY} in
932    *[Yy]|*[Mm])
933      (( DateBegin =   $( IGCM_date_AddDaysToGregorianDate ${DateBegin}   ${PeriodLengthInDays} ) ))
934      (( RestartDate = $( IGCM_date_AddDaysToGregorianDate ${RestartDate} ${PeriodLengthInDays} ) ))
935      ;;
936    esac
937
938    (( DateNum = DateNum + 1 )) # increment number of restart date
939  done
940
941  # Done. Save ${StartDir} submission text file
942  IGCM_sys_Cp ${RUN_DIR}/Qsub.${StartDir}.sh ${SUBMIT_DIR}
943  IGCM_sys_Cp ${RUN_DIR}/Qclean.month.${StartDir}.sh ${SUBMIT_DIR}
944  IGCM_sys_Cp ${RUN_DIR}/Qclean.year.${StartDir}.sh ${SUBMIT_DIR}
945
946  IGCM_debug_PopStack "IGCM_ensemble_DatePeriodicStarts"
947}
948
949function IGCM_ensemble_DateNonPeriodicStarts
950{
951  IGCM_debug_PushStack "IGCM_ensemble_DateNonPeriodicStarts"
952
953  #.. Manage non periodic starts => Loop over DateBegin ..
954  #   ==========================
955
956  [ ${DateNonPeriodicStart} = false ] && return
957
958  echo
959  IGCM_debug_Print 1 ">>>  MANAGE NON PERIODIC STARTS  <<<"
960
961  # - Build directory name
962  echo ""
963  echo "========================================================================"
964  echo "ensemble_Ens_DATE_NAME = ${ensemble_Ens_DATE_NAME}"
965  StartDir="${ensemble_Ens_DATE_NAME}"
966
967  # -  Does $StartDir already exist ?
968  if [ ! -d ${SUBMIT_DIR}/${StartDir} ] ; then
969      IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}
970      IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}
971      ln -s ../../.resol .
972      ln -s ../../.libmpi .
973      IGCM_sys_Cd ${RUN_DIR}
974  fi
975
976  DateNum=0
977  # ... Loop over ensemble_Ens_DATE_NONPERIODIC ...
978  while [ $DateNum -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; do
979    DateBegin=${ensemble_Ens_DATE_NONPERIODIC[$DateNum]}
980    Duree=${ensemble_Ens_DATE_LENGTH_NONPERIODIC[$DateNum]}
981    RestartDate=${ensemble_Ens_DATE_RESTART_NONPERIODIC[$DateNum]}
982    InitFrom=${ensemble_Ens_DATE_INITFROM_NONPERIODIC[$DateNum]}
983
984  # - Determine number of day(s) in LENGTH_NONPERIODIC
985    IGCM_date_GetYearMonth ${DateBegin} year month
986    DureeLengthInDays=$(( $( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${Duree} ) - 1 ))
987
988  # - Determine DateEnd
989    (( DateEnd = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${DureeLengthInDays} ) ))
990
991    IGCM_debug_Print 2 "${DateBegin} => ${DateEnd} : ${StartDir}"
992    echo "${DateBegin} ${DateEnd} ${StartDir}" >> ${RUN_DIR}/CreatedDir.txt
993
994    PeriodDateEnd=$( grep -m1 ${StartDir} ${RUN_DIR}/CreatedDir.txt | cut -f2 -d\  )
995
996  # - Loop over members
997    i=0
998    while [ $i -lt ${ensemble_Ens_DATE_MEMBER} ] ; do
999      MemberDir="${ensemble_Ens_DATE_NAME}${DateNum}${Alpha[$i]}"
1000      IGCM_debug_Print 3 "${MemberDir}"
1001
1002      JobName="Job_${MemberDir}"
1003
1004    # * Create directory if it doesn't exist and copy files
1005      if [ ! -d  ${SUBMIT_DIR}/${StartDir}/${MemberDir} ] ; then
1006        IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}/${MemberDir}
1007        IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}/${MemberDir}
1008        ln -s ../../COMP
1009        ln -s ../../PARAM
1010        ln -s ../../POST
1011        ln -s ../../DRIVER
1012        IGCM_sys_Cd ${RUN_DIR}
1013        IGCM_sys_Cp config.card run.card.init ${SUBMIT_DIR}/${StartDir}/${MemberDir}
1014        IGCM_sys_Cp Job_${config_UserChoices_JobName} ${SUBMIT_DIR}/${StartDir}/${MemberDir}/Job_${MemberDir}
1015
1016        # Dump command to be lauched
1017        echo "cd ${StartDir}/${MemberDir}/ ;"  >> ${RUN_DIR}/Qsub.${StartDir}.sh
1018        echo "${SUBMIT} ${JobName} ; cd -"     >> ${RUN_DIR}/Qsub.${StartDir}.sh
1019
1020        echo "cd ${StartDir}/${MemberDir}/ ;"  >> ${RUN_DIR}/Qclean.month.${StartDir}.sh
1021        echo "${libIGCM}/clean_month.job ; cd -"     >> ${RUN_DIR}/Qclean.month.${StartDir}.sh
1022
1023        echo "cd ${StartDir}/${MemberDir}/ ;"  >> ${RUN_DIR}/Qclean.year.${StartDir}.sh
1024        echo "${libIGCM}/clean_year.job ; cd -"     >> ${RUN_DIR}/Qclean.year.${StartDir}.sh
1025
1026        # * Update files : config.card, Job_, COMP/comp.card
1027        IGCM_ensemble_DateFilesUpdate ${DateBegin} ${DateEnd} ${RestartDate} ${InitFrom}
1028      fi
1029
1030      (( i = i + 1 ))
1031    done
1032
1033    # Done. Save ${StartDir} submission text file
1034    IGCM_sys_Cp ${RUN_DIR}/Qsub.${StartDir}.sh ${SUBMIT_DIR}
1035    IGCM_sys_Cp ${RUN_DIR}/Qclean.month.${StartDir}.sh ${SUBMIT_DIR}
1036    IGCM_sys_Cp ${RUN_DIR}/Qclean.year.${StartDir}.sh ${SUBMIT_DIR}
1037
1038    (( DateNum = DateNum + 1 ))
1039  done
1040
1041  # Done. Save ${StartDir} submission text file
1042  IGCM_sys_Cp ${RUN_DIR}/Qsub.${StartDir}.sh ${SUBMIT_DIR}
1043  IGCM_sys_Cp ${RUN_DIR}/Qclean.month.${StartDir}.sh ${SUBMIT_DIR}
1044  IGCM_sys_Cp ${RUN_DIR}/Qclean.year.${StartDir}.sh ${SUBMIT_DIR}
1045
1046  IGCM_debug_PopStack "IGCM_ensemble_DateNonPeriodicStarts"
1047}
1048
1049function IGCM_ensemble_DateFilesUpdate
1050{
1051  IGCM_debug_PushStack "IGCM_ensemble_DateFilesUpdate"
1052
1053  # Debug Print :
1054  echo
1055  IGCM_debug_Print 1 "IGCM_ensemble_DateFilesUpdate :"
1056
1057  HumanDateBegin=$(   IGCM_date_ConvertFormatToHuman ${1} )
1058  HumanDateEnd=$(     IGCM_date_ConvertFormatToHuman ${2} )
1059  HumanRestartDate=$( IGCM_date_ConvertFormatToHuman ${3} )
1060  if [[ X${4} != "X" ]]; then
1061      initFrom=${4} # non periodic config (INITFROM could be different between members)
1062  else
1063      initFrom=${ensemble_Ens_DATE_INITFROM} # periodic (same INITFROM value)
1064  fi
1065
1066  # ==> config.card
1067  # [ENSEMBLE]
1068  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleRun 'y'
1069  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleName ${ensemble_Ens_DATE_NAME}
1070  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleDate ${HumanDateBegin}
1071  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleType "Ens_DATE"
1072
1073  # [UserChoices]
1074  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card UserChoices JobName   ${MemberDir}
1075  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card UserChoices DateBegin ${HumanDateBegin}
1076  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card UserChoices DateEnd   ${HumanDateEnd}
1077
1078  # [Restarts]
1079  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Restarts OverRule "y"
1080  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Restarts RestartDate ${HumanRestartDate}
1081  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Restarts RestartJobName ${initFrom}
1082  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Restarts RestartPath ${ensemble_Ens_DATE_INITPATH}
1083
1084    # [ATM/OCE/...]
1085  for comp in ${config_ListOfComponents[*]} ; do
1086    IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${comp} Restart "n"
1087  done
1088  unset initFrom
1089
1090  # ==> Job
1091  sed -e "s/\(#.*\)${config_UserChoices_JobName}\( *#.*\)/\1${MemberDir} \2/"            \
1092      -e "s/\(#.*Script_Output_\)${config_UserChoices_JobName}\(\.*\)/\1${MemberDir}\2/" \
1093      -e "s/^PeriodNb=.*/PeriodNb=60/"                                                  \
1094      ${SUBMIT_DIR}/${StartDir}/${MemberDir}/Job_${MemberDir} > Job_${MemberDir}.tmp
1095  IGCM_sys_Mv Job_${MemberDir}.tmp ${SUBMIT_DIR}/${StartDir}/${MemberDir}/Job_${MemberDir}
1096
1097  IGCM_debug_PopStack "IGCM_ensemble_DateFilesUpdate"
1098}
1099
1100############### Parametric ENSEMBLE #################
Note: See TracBrowser for help on using the repository browser.