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

Last change on this file since 1623 was 1623, checked in by nillod, 4 months ago

Bug fix for ensemble tools introduce by new functionalities.

  • Property licence set to
    The following licence information concerns ONLY the libIGCM tools
    ==================================================================

    Copyright © Centre National de la Recherche Scientifique CNRS
    Commissariat à l'Énergie Atomique CEA

    libIGCM : Library for Portable Models Computation of IGCM Group.

    IGCM Group is the french IPSL Global Climate Model Group.

    This library is a set of shell scripts and functions whose purpose is
    the management of the initialization, the launch, the transfer of
    output files, the post-processing and the monitoring of datas produce
    by any numerical program on any plateforme.

    This software is governed by the CeCILL license under French law and
    abiding by the rules of distribution of free software. You can use,
    modify and/ or redistribute the software under the terms of the CeCILL
    license as circulated by CEA, CNRS and INRIA at the following URL
    "http://www.cecill.info".

    As a counterpart to the access to the source code and rights to copy,
    modify and redistribute granted by the license, users are provided only
    with a limited warranty and the software's author, the holder of the
    economic rights, and the successive licensors have only limited
    liability.

    In this respect, the user's attention is drawn to the risks associated
    with loading, using, modifying and/or developing or reproducing the
    software by the user in light of its specific status of free software,
    that may mean that it is complicated to manipulate, and that also
    therefore means that it is reserved for developers and experienced
    professionals having in-depth computer knowledge. Users are therefore
    encouraged to load and test the software's suitability as regards their
    requirements in conditions enabling the security of their systems and/or
    data to be ensured and, more generally, to use and operate it in the
    same conditions as regards security.

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