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

Last change on this file since 1607 was 1607, checked in by nillod, 7 months ago

Replace job 'PeriodNb?' with 'NbPeriodsPerJob?' to be more explicit for users.

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