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

Last change on this file since 1475 was 1475, checked in by flavoni, 6 years ago

mv clean.month in clean.PeriodLength? script in ensemble, and use CCCWORKDIR in ins_job -e

  • 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: 57.8 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#**************************************************************
24
25# Read which ensemble type are active
26function IGCM_ensemble_Init
27{
28  IGCM_debug_PushStack "IGCM_ensemble_Init"
29
30  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB active
31  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE active
32  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PARAMETRIC active
33
34  IGCM_debug_Print 1 "Ens_PERTURB ACTIVE     = ${ensemble_Ens_PERTURB_active}"
35  IGCM_debug_Print 1 "Ens_DATE ACTIVE        = ${ensemble_Ens_DATE_active}"
36  IGCM_debug_Print 1 "Ens_PARAMETRIC ACTIVE  = ${ensemble_Ens_PARAMETRIC_active}"
37  echo ""
38
39  #====================================================
40  # Define ARCHIVE : Dedicated to large files
41  # Define STORAGE : Dedicated to small/medium files
42  # Define R_OUT   : Output tree located on ARCHIVE
43  # Define R_FIG   : Output tree located on STORAGE hosting figures (monitoring and atlas, and/or small files)
44  # Define R_BUF   : USELESS and DEPRECATED output tree.
45  IGCM_sys_defineArchives
46
47  IGCM_debug_PopStack "IGCM_ensemble_Init"
48}
49
50# Set Alphanumerical variables ajust to member nb
51function IGCM_ensemble_SetAlpha
52{
53  IGCM_debug_PushStack "IGCM_ensemble_SetAlpha"
54
55  set -A Alpha      A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
56  set -A AlphaMonth a b c d e f g h i j k l
57
58  IGCM_debug_PopStack "IGCM_ensemble_SetAlpha"
59}
60
61############### Perturb ENSEMBLE #################
62function IGCM_ensemble_CastInit
63{
64  IGCM_debug_PushStack "IGCM_ensemble_CastInit"
65
66  IGCM_sys_Mkdir ${RUN_DIR}
67
68  IGCM_sys_Cp ${SUBMIT_DIR}/config.card   ${RUN_DIR}
69  IGCM_sys_Cp ${SUBMIT_DIR}/ensemble.card ${RUN_DIR}
70  IGCM_sys_Cp ${SUBMIT_DIR}/Job_*         ${RUN_DIR}
71  IGCM_sys_Cp ${SUBMIT_DIR}/run.card.init ${RUN_DIR}
72  if [ -f ${SUBMIT_DIR}/Qsub.* ]; then
73    IGCM_sys_Cp ${SUBMIT_DIR}/Qsub.*        ${RUN_DIR}
74  fi
75  if [ -f ${SUBMIT_DIR}/Qclean.* ]; then
76    IGCM_sys_Cp ${SUBMIT_DIR}/Qclean.*      ${RUN_DIR}
77  fi
78 
79  ## Init some variables
80  CastPeriodicStart=false
81  CastNonPeriodicStart=false
82  CastRestartNonPer=false
83  CastLengthNonPer=false
84 
85  # Useful?
86  #if [ -f  ${SUBMIT_DIR}/CreatedDir.txt ] ; then
87  #  IGCM_sys_Cp ${SUBMIT_DIR}/CreatedDir.txt ${RUN_DIR}
88  #fi
89  # Useful?
90  #if [ -f  ${SUBMIT_DIR}/Qsub.sh ] ; then
91  #  IGCM_sys_Cp ${SUBMIT_DIR}/Qsub.sh ${RUN_DIR}
92  #fi
93  echo ${PWD}
94
95  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB active
96  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB NAME
97  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB BEGIN_INIT
98  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB END_INIT
99  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB PERIODICITY
100  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_PERTURB NONPERIODIC
101  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_PERTURB RESTART_NONPERIODIC
102  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB LENGTH
103  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_PERTURB LENGTH_NONPERIODIC
104  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB MEMBER
105  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_PERTURB PERTU_MAP_LIST
106  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_PERTURB MEMBER_NAMESLIST
107  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB MEMBER_INITFROM
108  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB MEMBER_INITPATH
109  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_PERTURB PERTURB_BIN
110  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB INITFROM
111  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB INITPATH
112  IGCM_card_DefineVariableFromOption config.card UserChoices JobName
113  IGCM_card_DefineVariableFromOption config.card UserChoices TagName
114  IGCM_card_DefineVariableFromOption config.card UserChoices CalendarType
115  IGCM_card_DefineArrayFromSection   config.card ListOfComponents
116
117  echo
118  IGCM_debug_Print 1 "[Ens_PERTURB]"
119  IGCM_debug_Print 1 "ACTIVE            = ${ensemble_Ens_PERTURB_active}"
120  IGCM_debug_Print 1 "NAME              = ${ensemble_Ens_PERTURB_NAME}"
121  IGCM_debug_Print 1 "BEGIN_INIT        = ${ensemble_Ens_PERTURB_BEGIN_INIT}"
122  IGCM_debug_Print 1 "END_INIT          = ${ensemble_Ens_PERTURB_END_INIT}"
123  IGCM_debug_Print 1 "PERIODICITY       = ${ensemble_Ens_PERTURB_PERIODICITY}"
124  IGCM_debug_Print 1 "NONPERIODIC       = ${ensemble_Ens_PERTURB_NONPERIODIC[*]}"
125  IGCM_debug_Print 1 "RESTART_NONPERIODIC=${ensemble_Ens_PERTURB_RESTART_NONPERIODIC[*]}"
126  IGCM_debug_Print 1 "LENGTH            = ${ensemble_Ens_PERTURB_LENGTH}"
127  IGCM_debug_Print 1 "LENGTH_NONPERIODIC= ${ensemble_Ens_PERTURB_LENGTH_NONPERIODIC[*]}"
128  IGCM_debug_Print 1 "MEMBER            = ${ensemble_Ens_PERTURB_MEMBER}"
129  IGCM_debug_Print 1 "PERTU_MAP_LIST    = ${ensemble_Ens_PERTURB_PERTU_MAP_LIST[*]}"
130  IGCM_debug_Print 1 "MEMBER_NAMESLIST  = ${ensemble_Ens_PERTURB_MEMBER_NAMESLIST[*]}"
131  IGCM_debug_Print 1 "MEMBER_INITFROM   = ${ensemble_Ens_PERTURB_MEMBER_INITFROM}"
132  IGCM_debug_Print 1 "MEMBER_INITPATH   = ${ensemble_Ens_PERTURB_MEMBER_INITPATH}"
133  IGCM_debug_Print 1 "PERTURB_BIN       = ${ensemble_Ens_PERTURB_PERTURB_BIN[*]}"
134  IGCM_debug_Print 1 "INITFROM          = ${ensemble_Ens_PERTURB_INITFROM}"
135  IGCM_debug_Print 1 "INITPATH          = ${ensemble_Ens_PERTURB_INITPATH}"
136  IGCM_debug_Print 1 "JobName           = ${config_UserChoices_JobName}"
137  IGCM_debug_Print 1 "TagName           = ${config_UserChoices_TagName}"
138  IGCM_debug_Print 1 "CalendarType      = ${config_UserChoices_CalendarType}"
139  IGCM_debug_Print 1 "ListOfComponents  = ${config_ListOfComponents[*]}"
140
141  ### Retro compatibility with former param name ###
142  if [ X"${ensemble_Ens_PERTURB_MEMBER_LIST[0]}" != "XOption" ];
143  then
144      if [ X"${ensemble_Ens_PERTURB_PERTU_MAP_LIST[0]}" = "XOption" ];
145      then
146          ensemble_Ens_PERTURB_PERTU_MAP_LIST=${ensemble_Ens_PERTURB_MEMBER_LIST}
147          IGCM_debug_Print 1 "WARNING: PERTU_MAP_LIST is deprecacated, please use PERTURB_PERTU_MAP_LIST instead."
148      else
149          IGCM_debug_Print 1 "WARNING: both PERTURB_PERTU_MAP_LIST and PERTU_MAP_LIST are specified!"
150          IGCM_debug_Print 1 "Ignore PERTU_MAP_LIST which is deprecated."
151      fi
152  fi
153  ####### End of retro compatibility code #######
154
155  ### Check unset variables and set them to empty
156  # Following var are set because they could be unset in some
157  # use case (ex: non periodic if periodic is active...)
158  if [[ X"${ensemble_Ens_PERTURB_RESTART_NONPERIODIC[0]}" = "XOption" || X"${ensemble_Ens_PERTURB_RESTART_NONPERIODIC[0]}" = "X" ]];
159  then
160      ensemble_Ens_PERTURB_RESTART_NONPERIODIC[0]=_0_
161      CastRestartNonPer=false
162  else
163      CastRestartNonPer=true
164  fi
165  if [[ X"${ensemble_Ens_PERTURB_PERTU_MAP_LIST[0]}" = "XOption" || X"${ensemble_Ens_PERTURB_PERTU_MAP_LIST[0]}" = "X" ]];
166  then
167      ensemble_Ens_PERTURB_PERTU_MAP_LIST[0]=_0_
168  fi
169  if [[ X"${ensemble_Ens_PERTURB_LENGTH_NONPERIODIC[0]}" = "XOption" || X"${ensemble_Ens_PERTURB_LENGTH_NONPERIODIC[0]}" = "X" ]];
170  then
171      CastLengthNonPer=false
172      ensemble_Ens_PERTURB_LENGTH_NONPERIODIC[0]=_0_
173  else
174      CastLengthNonPer=true
175  fi
176  if [ X"${ensemble_Ens_PERTURB_NONPERIODIC[0]}" = "XOption" ];
177  then
178      ensemble_Ens_PERTURB_NONPERIODIC[0]=_0_
179  fi
180  if [[ "${ensemble_Ens_PERTURB_PERIODICITY}" = _0_ || "${ensemble_Ens_PERTURB_PERIODICITY}" = '' ]];
181  then
182      ensemble_Ens_PERTURB_PERIODICITY=NONE
183  fi
184  if [[ "${ensemble_Ens_PERTURB_MEMBER}" = _0_ || "${ensemble_Ens_PERTURB_MEMBER}" = '' ]];
185  then
186      ensemble_Ens_PERTURB_MEMBER=NONE
187  fi
188  if [[ "${ensemble_Ens_PERTURB_END_INIT}" = _0_ || "${ensemble_Ens_PERTURB_END_INIT}" = '' ]];
189  then
190      ensemble_Ens_PERTURB_END_INIT=${ensemble_Ens_PERTURB_BEGIN_INIT}
191  fi
192
193  ### End check unset variables ###
194  PerturbExe=${ensemble_Ens_PERTURB_PERTURB_BIN[0]}
195
196  case ${PerturbExe} in
197  AddNoise)
198    PerturbComp=${ensemble_Ens_PERTURB_PERTURB_BIN[1]}
199    PerturbFile=${ensemble_Ens_PERTURB_PERTURB_BIN[2]}
200    PerturbVar=${ensemble_Ens_PERTURB_PERTURB_BIN[3]}
201    PerturbAmp=${ensemble_Ens_PERTURB_PERTURB_BIN[4]}
202
203    IGCM_debug_Print 1 "PerturbExe  = ${PerturbExe}"
204    IGCM_debug_Print 1 "PerturbFile = ${PerturbFile}"
205    IGCM_debug_Print 1 "PerturbComp = ${PerturbComp}"
206    IGCM_debug_Print 1 "PerturbVar  = ${PerturbVar}"
207    IGCM_debug_Print 1 "PerturbAmp  = ${PerturbAmp}"
208    ;;
209  AddPertu3DOCE)
210    PerturbComp=${ensemble_Ens_PERTURB_PERTURB_BIN[1]}
211    PerturbFile=${ensemble_Ens_PERTURB_PERTURB_BIN[2]}
212    PerturbVar=${ensemble_Ens_PERTURB_PERTURB_BIN[3]}
213    PerturbMask=${ensemble_Ens_PERTURB_PERTURB_BIN[4]}
214
215    IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_PERTURB MASKPATH
216   
217    IGCM_debug_Print 1 "PerturbExe  = ${PerturbExe}"
218    IGCM_debug_Print 1 "PerturbFile = ${PerturbFile}"
219    IGCM_debug_Print 1 "PerturbComp = ${PerturbComp}"
220    IGCM_debug_Print 1 "PerturbVar  = ${PerturbVar}"
221    IGCM_debug_Print 1 "PerturbMask = ${PerturbMask}"
222    IGCM_debug_Print 1 "MASK PATH   = ${ensemble_Ens_PERTURB_MASKPATH}"
223    ;;
224  esac
225  IGCM_ensemble_SetAlpha ${ensemble_Ens_PERTURB_MEMBER}
226
227  # A few checks Period case:
228
229  # ... Check PERIODICITY ...
230  case ${ensemble_Ens_PERTURB_PERIODICITY} in
231  NONE)
232    IGCM_debug_Print 1 "periodic start not active"
233    CastPeriodicStart=false
234    ;;
235  *[Yy]|*[Mm])
236    CastPeriodicStart=true
237    IGCM_debug_Print 1 "Periodic length : ${ensemble_Ens_PERTURB_PERIODICITY}" ;;
238  *)
239    IGCM_debug_Exit "IGCM_ensemble_CastInit ${ensemble_Ens_PERTURB_PERIODICITY} : invalid PERIODICITY"
240    IGCM_debug_Exit "Choose a value in *Y or *M"
241    IGCM_debug_Verif_Exit ;;
242  esac
243  # ... Check LENGTH ...
244  case ${ensemble_Ens_PERTURB_LENGTH} in
245  *[Yy]|*[Mm])
246    IGCM_debug_Print 1 "Periodic duration : ${ensemble_Ens_PERTURB_LENGTH}" ;;
247  *)
248    IGCM_debug_Exit "IGCM_ensemble_CastInit ${ensemble_Ens_PERTURB_LENGTH} invalid LENGTH"
249    IGCM_debug_Exit "Choose a value in choose in *Y or *M"
250    IGCM_debug_Verif_Exit ;;
251  esac
252
253################################
254  if [[ ${#ensemble_Ens_PERTURB_NONPERIODIC[*]} != ${#ensemble_Ens_PERTURB_RESTART_NONPERIODIC[*]} && CastRestartNonPer = "true" ]] ; then
255    IGCM_debug_Exit "IGCM_ensemble_CastInit: NONPERIODIC and RESTART_NONPERIODIC lists have different sizes"
256    IGCM_debug_Verif_Exit
257  fi
258  if [[ ${#ensemble_Ens_PERTURB_NONPERIODIC[*]} > 0 ]] && [[ ${ensemble_Ens_PERTURB_NONPERIODIC[0]} != _0_ ]]; then
259    DateNonPeriodicStart=true
260   
261    # Use LENGTH if no NONPERIODIC_LENGTH given
262    if [[ ${#ensemble_Ens_PERTURB_LENGTH_NONPERIODIC[*]} < ${#ensemble_Ens_PERTURB_NONPERIODIC[*]} || ${ensemble_Ens_PERTURB_LENGTH_NONPERIODIC[0]} = _0_ ]] ; then
263      IGCM_debug_Print 1 "WARNING: LENGTH_NONPERIODIC is not fill (or not correctly). Use LENGTH value '${ensemble_Ens_PERTURB_LENGTH}' for all NONPERIODIC runs"
264      echo "WARNING: LENGTH_NONPERIODIC is not fill (or not correctly). Use LENGTH value '${ensemble_Ens_PERTURB_LENGTH}' for all NONPERIODIC runs"
265      DateNum=0
266      while [ ${DateNum} -lt ${#ensemble_Ens_PERTURB_NONPERIODIC[*]} ] ; do
267        ensemble_Ens_PERTURB_LENGTH_NONPERIODIC[${DateNum}]=${ensemble_Ens_PERTURB_LENGTH}
268        (( DateNum = DateNum + 1 ))
269      done
270    fi
271    # Check lengths
272    DateNum=0
273    while [ ${DateNum} -lt ${#ensemble_Ens_PERTURB_NONPERIODIC[*]} ] ; do
274        # - Check LENGTH_NONPERIODIC
275        case ${ensemble_Ens_PERTURB_LENGTH_NONPERIODIC[${DateNum}]} in
276            _0_)
277                IGCM_debug_Print 1 "non-periodic start not active"
278                CastNonPeriodicStart=false
279                break
280                ;;
281            *[Yy]|*[Mm])
282                IGCM_debug_Print 1 "Non-periodic duration : ${ensemble_Ens_PERTURB_LENGTH_NONPERIODIC[${DateNum}]}"
283                CastNonPeriodicStart=true
284                ;;
285            *)
286                IGCM_debug_Exit "IGCM_ensemble_CastInit ${ensemble_Ens_PERTURB_LENGTH_NONPERIODIC[${DateNum}]} : invalid LENGTH"
287                IGCM_debug_Exit "choose in *Y or *M"
288                IGCM_debug_Verif_Exit ;;
289        esac
290        (( DateNum = DateNum + 1 ))
291       
292        # - Check RESTART_NONPERIODIC
293        if [[ DateNonPeriodicStart ]]; then
294            case ${ensemble_Ens_PERTURB_RESTART_NONPERIODIC[${DateNum}]} in
295                _0_)
296                    IGCM_debug_Exit "IGCM_ensemble_CastInit ${ensemble_Ens_PERTURB_RESTART_NONPERIODIC[${DateNum}]} : invalid NON PERIODIC RESTART"
297                    IGCM_debug_Verif_Exit ;;
298            esac
299        fi
300    done
301   
302    # Use INITFROM if no INITFROM_NONPERIODIC given
303    if [ ${#ensemble_Ens_PERTURB_INITFROM_NONPERIODIC[*]} -lt ${#ensemble_Ens_PERTURB_NONPERIODIC[*]} ] ; then
304      IGCM_debug_Print 1 "WARNING: INITFROM_NONPERIODIC is not fill (or not correctly). Use INITFROM value '${ensemble_Ens_PERTURB_INITFROM}' for all NONPERIODIC runs"
305      DateNum=0
306      while [ ${DateNum} -lt ${#ensemble_Ens_PERTURB_NONPERIODIC[*]} ] ; do
307        ensemble_Ens_PERTURB_INITFROM_NONPERIODIC[${DateNum}]=${ensemble_Ens_PERTURB_INITFROM}
308        (( DateNum = DateNum + 1 ))
309      done
310    fi
311   
312    # Use INITPATH if no INITPATH_NONPERIODIC given
313    if [ ${#ensemble_Ens_PERTURB_INITPATH_NONPERIODIC[*]} -lt ${#ensemble_Ens_PERTURB_NONPERIODIC[*]} ] ; then
314      IGCM_debug_Print 1 "WARNING: INITPATH_NONPERIODIC is not fill (or not correctly). Use INITPATH value '${ensemble_Ens_PERTURB_INITPATH}' for all NONPERIODIC runs"
315      DateNum=0
316      while [ ${DateNum} -lt ${#ensemble_Ens_PERTURB_NONPERIODIC[*]} ] ; do
317        ensemble_Ens_PERTURB_INITPATH_NONPERIODIC[${DateNum}]=${ensemble_Ens_PERTURB_INITPATH}
318        (( DateNum = DateNum + 1 ))
319      done
320    fi
321  else
322    IGCM_debug_Print 1 "Non-Periodic start NOT ACTIVE"
323    DateNonPeriodicStart=false
324  fi
325################################
326
327  # A few checks for the Non-Periodic case:
328 
329  # A few checks for the PERTU_MAP_LIST case:
330  case ${ensemble_Ens_PERTURB_PERTU_MAP_LIST[0]} in
331  _0_)
332    IGCM_debug_Print 1 "list of perturbation maps not active"
333    CastMemberList=false
334    ;;
335  *)
336    if [ ${CastPeriodicStart} = "true" ] ; then
337      IGCM_debug_Exit "list of perturbation maps for periodic start not implemented, will stop execution"
338      IGCM_debug_Verif_Exit
339    elif [ ${CastNonPeriodicStart} = "true" ] ; then
340      IGCM_debug_Exit "list of perturbation maps for non periodic start not implemented, will stop execution"
341      IGCM_debug_Verif_Exit
342    fi
343
344    # test that MEMBER_NAMESLIST and PERTU_MAP_LIST have the same size
345
346    if [ ${#ensemble_Ens_PERTURB_PERTU_MAP_LIST[*]} -ne ${#ensemble_Ens_PERTURB_MEMBER_NAMESLIST[*]} ] ; then
347      IGCM_debug_Exit "number of elements in PERTU_MAP_LIST and MEMBER_NAMESLIST differ"
348      IGCM_debug_Verif_Exit
349    fi
350
351    IGCM_debug_Print 1 "list of perturbation maps : ${ensemble_Ens_PERTURB_PERTU_MAP_LIST[*]}"
352    IGCM_debug_Print 1 "list of members names : ${ensemble_Ens_PERTURB_MEMBER_NAMESLIST[*]}"
353    CastMemberList=true
354    ;;
355  esac
356
357#  IGCM_debug_Exit "fin du test PERTU_MAP_LIST"
358#  IGCM_debug_Verif_Exit
359
360  # Need to know all the restart filename of the component we will apply the noise to
361  IGCM_card_DefineArrayFromOption config.card ListOfComponents ${PerturbComp}
362  eval compname=\${config_ListOfComponents_${PerturbComp}[0]} > /dev/null 2>&1
363
364  # Target the component's card we apply the noise to
365  card=${SUBMIT_DIR}/COMP/${compname}.card
366
367  # Read the restart file list. To be used later
368  IGCM_card_DefineArrayFromOption ${card} RestartFiles List
369  ListFilesName=${compname}_RestartFiles_List
370  eval FileName0=\${${ListFilesName}[0]} > /dev/null 2>&1
371  eval NbFiles=\${#${ListFilesName}[@]} > /dev/null 2>&1
372
373  # Check
374  IGCM_debug_Print 1 "Nb Restart Files  = ${NbFiles}"
375
376  IGCM_debug_PopStack "IGCM_ensemble_CastInit"
377}
378
379function IGCM_ensemble_CastPeriodicStarts
380{
381  IGCM_debug_PushStack "IGCM_ensemble_CastPeriodicStarts"
382
383  [ ${CastPeriodicStart} = false ] && return
384
385  echo
386  IGCM_debug_Print 1 "Manage periodic starts"
387
388#.. Manage periodic starts ..
389#   ======================
390
391# ... Loop over DateBegin ...
392  eval DateBegin=\${ensemble_Ens_PERTURB_BEGIN_INIT}
393
394  while [ ${DateBegin} -le ${ensemble_Ens_PERTURB_END_INIT} ] ; do
395    IGCM_date_GetYearMonth ${DateBegin} year month
396
397  # - Determine number of day(s) in PERIODICITY
398    PeriodLengthInDays=$( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${ensemble_Ens_PERTURB_PERIODICITY} )
399
400  # - Determine number of day(s) in LENGTH
401    DureeLengthInDays=$(( $( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${ensemble_Ens_PERTURB_LENGTH} ) - 1 ))
402
403  # - Determine DateEnd
404    (( DateEnd = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${DureeLengthInDays} ) ))
405
406  # - Build directory name
407    IGCM_ensemble_CastDirectoryName ${ensemble_Ens_PERTURB_NAME} ${ensemble_Ens_PERTURB_PERIODICITY} $year $month $StartDir
408
409  # - Determine RestartDate
410    (( Offset = -1 ))
411    (( RestartDate = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${Offset} ) ))
412
413    IGCM_debug_Print 2 "${DateBegin} => ${DateEnd} : ${StartDir}"
414    echo "${DateBegin} ${DateEnd} ${StartDir}" >> ${RUN_DIR}/CreatedDir.txt
415
416  # - Create directory for current DateBegin
417    if [ ! -d  ${StartDir} ] ; then
418      IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}
419      IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}
420      ln -s ../../.resol .
421      ln -s ../../.libmpi .
422      IGCM_sys_Cd ${RUN_DIR}
423    fi
424
425  # - Create directory to store modified restart files
426    RestartDir=${STORAGE}/IGCM_IN/${config_UserChoices_TagName}/${StartDir}
427    IGCM_sys_MkdirArchive ${RestartDir}
428
429  # - Loop over members
430    i=0
431    while [ $i -lt ${ensemble_Ens_PERTURB_MEMBER} ] ; do
432      MemberDir="${StartDir}${Alpha[$i]}"
433      echo
434      IGCM_debug_Print 3 "${MemberDir}"
435
436      JobName="Job_${MemberDir}"
437
438    # * Create directory if it doesn't exist and copy/link files
439      if [ ! -d  ${SUBMIT_DIR}/${StartDir}/${MemberDir} ] ; then
440        IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}/${MemberDir}
441        IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}/${MemberDir}
442        ln -s ../../COMP
443        ln -s ../../PARAM
444        ln -s ../../POST
445        ln -s ../../DRIVER
446        IGCM_sys_Cd ${RUN_DIR}
447        IGCM_sys_Cp config.card run.card.init ${SUBMIT_DIR}/${StartDir}/${MemberDir}
448        IGCM_sys_Cp Job_${config_UserChoices_JobName} ${SUBMIT_DIR}/${StartDir}/${MemberDir}/${JobName}
449
450        # Dump command to be lauched
451        echo "cd ${StartDir}/${MemberDir}/ ;"    >> ${RUN_DIR}/Qsub.${StartDir}.sh
452        echo "${SUBMIT} ${JobName} ; cd -"       >> ${RUN_DIR}/Qsub.${StartDir}.sh
453
454        echo "cd ${StartDir}/${MemberDir}/ ;"    >> ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh
455        echo "${libIGCM}/clean_PeriodLength.job ; cd -"  >> ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh
456
457        # * Update files : config.card, Job_, COMP/comp.card
458        IGCM_ensemble_CastFilesUpdate ${DateBegin} ${DateEnd} ${RestartDate}
459
460        # * Apply noise on restart file
461        IGCM_ensemble_CastPerturbFile
462      fi
463
464      (( i = i + 1 ))
465    done
466
467    # Done. Save ${StartDir} submission text file
468    IGCM_sys_Cp ${RUN_DIR}/Qsub.${StartDir}.sh ${SUBMIT_DIR}
469    IGCM_sys_Cp ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh ${SUBMIT_DIR}
470
471  # - Next DateBegin
472    echo "$DateBegin  $PeriodLengthInDays"
473    case ${ensemble_Ens_PERTURB_PERIODICITY} in
474    *[Yy]|*[Mm])
475      (( DateBegin = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${PeriodLengthInDays} ) ))
476      ;;
477    esac
478    echo "New DateBegin = $DateBegin"
479    echo "========================================================================"
480  done
481  IGCM_debug_PopStack "IGCM_ensemble_CastPeriodicStarts"
482}
483
484function IGCM_ensemble_CastNonPeriodicStarts
485{
486  IGCM_debug_PushStack "IGCM_ensemble_CastNonPeriodicStarts"
487
488  #.. Manage non periodic starts => Loop over DateBegin ..
489  #   ==========================
490
491  [ ${CastNonPeriodicStart} = false ] && return
492
493  echo
494  IGCM_debug_Print 1 "Manage non periodic starts"
495
496  DateNum=0
497# ... Loop over ensemble_Ens_PERTURB_NONPERIODIC ...
498  echo ">${DateNum}<"
499  echo ">${#ensemble_Ens_PERTURB_NONPERIODIC[*]}<"
500  while [ ${DateNum} -lt ${#ensemble_Ens_PERTURB_NONPERIODIC[*]} ] ; do
501    DateBegin=${ensemble_Ens_PERTURB_NONPERIODIC[${DateNum}]}
502    Duree=${ensemble_Ens_PERTURB_LENGTH_NONPERIODIC[${DateNum}]}
503    echo ">${DateBegin}<"
504    echo ">${Duree}<"
505
506  # - Determine number of day(s) in LENGTH_NONPERIODIC
507    IGCM_date_GetYearMonth ${DateBegin} year month
508    DureeLengthInDays=$(( $( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${Duree} ) - 1 ))
509
510  # - Build directory name
511    echo "========================================================================"
512    echo "ensemble_Ens_PERTURB_NAME = ${ensemble_Ens_PERTURB_NAME}"
513    IGCM_ensemble_CastDirectoryName ${ensemble_Ens_PERTURB_NAME} ${Duree} $year $month $StartDir
514
515  # - Determine DateEnd
516    (( DateEnd = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${DureeLengthInDays} ) ))
517    echo ">${DateEnd}<"
518    echo "tout va bien 1"
519
520  # - Determine RestartDate
521    if [[ ${CastRestartNonPer} == "true" ]]; then
522        RestartDate=${ensemble_Ens_PERTURB_RESTART_NONPERIODIC[${DateNum}]}
523    else
524        (( Offset = -1 ))
525        (( RestartDate = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${Offset} ) ))
526    fi
527   
528    IGCM_debug_Print 2 "${DateBegin} => ${DateEnd} : ${StartDir}"
529
530  # -  Does $StartDir already exist ?
531    #echo "tout va bien 2" ${StartDir}
532    if [ ! -d ${SUBMIT_DIR}/${StartDir} ] ; then
533      echo "create dir"
534      IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}
535      IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}
536      ln -s ../../.resol .
537      ln -s ../../.libmpi .
538      IGCM_sys_Cd ${RUN_DIR}
539      echo "${DateBegin} ${DateEnd} ${StartDir}" >> ${RUN_DIR}/CreatedDir.txt
540    fi
541    PeriodDateEnd=$( grep -m1 ${StartDir} ${RUN_DIR}/CreatedDir.txt | cut -f2 -d\  )
542
543  # - Create directory in which to store new restart files if it does'nt already exist
544    RestartDir=${STORAGE}/IGCM_IN/${config_UserChoices_TagName}/${StartDir}
545    IGCM_sys_MkdirArchive ${RestartDir}
546
547  # - Loop over members
548    i=0
549    while [ $i -lt ${ensemble_Ens_PERTURB_MEMBER} ] ; do
550      MemberDir="${StartDir}${Alpha[$i]}"
551      IGCM_debug_Print 3 "${MemberDir}"
552
553      JobName="Job_${MemberDir}"
554
555    # * Create directory if it doesn't exist and copy files
556      if [ ! -d  ${SUBMIT_DIR}/${StartDir}/${MemberDir} ] ; then
557        IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}/${MemberDir}
558        #IGCM_sys_Cp -r COMP/ PARAM/ ${StartDir}/${MemberDir}
559        IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}/${MemberDir}
560        ln -s ../../COMP
561        ln -s ../../PARAM
562        ln -s ../../POST
563        ln -s ../../DRIVER
564        IGCM_sys_Cd ${RUN_DIR}
565        IGCM_sys_Cp config.card run.card.init ${SUBMIT_DIR}/${StartDir}/${MemberDir}
566        IGCM_sys_Cp Job_${config_UserChoices_JobName} ${SUBMIT_DIR}/${StartDir}/${MemberDir}/Job_${MemberDir}
567
568        # Dump command to be lauched
569        echo "cd ${StartDir}/${MemberDir}/ ;"    >> Qsub.${StartDir}.sh
570        echo "${SUBMIT} ${JobName} ; cd -"       >> Qsub.${StartDir}.sh
571
572        echo "cd ${StartDir}/${MemberDir}/ ;"    >> ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh
573        echo "${libIGCM}/clean_PeriodLength.job ; cd -"  >> ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh
574
575        # * Update files : config.card, Job_, COMP/comp.card
576        echo "${PeriodDateEnd} ? ${DateEnd}"
577        if [ ${PeriodDateEnd} -gt ${DateEnd} ] ; then
578          DateEnd=${PeriodDateEnd}
579        fi
580       
581        IGCM_ensemble_CastFilesUpdate ${DateBegin} ${DateEnd} ${RestartDate}
582
583        # * Apply noise on restart file
584        IGCM_ensemble_CastPerturbFile
585      fi
586
587      (( i = i + 1 ))
588    done
589
590    # Done. Save ${StartDir} submission text file
591    IGCM_sys_Cp ${RUN_DIR}/Qsub.${StartDir}.sh ${SUBMIT_DIR}
592    IGCM_sys_Cp ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh ${SUBMIT_DIR}
593
594    (( DateNum = DateNum + 1 ))
595  done
596  IGCM_debug_PopStack "IGCM_ensemble_CastNonPeriodicStarts"
597}
598
599function IGCM_ensemble_CastMemberList
600{
601  IGCM_debug_PushStack "IGCM_ensemble_CastMemberList"
602
603  if [ ${CastMemberList} = false ] ; then
604    IGCM_debug_PopStack "IGCM_ensemble_CastMemberList"
605    return
606  fi
607
608  echo
609  IGCM_debug_Print 1 "Manage members list"
610
611#.. Manage members list ..
612#   ======================
613
614  # DateBegin
615  eval DateBegin=\${ensemble_Ens_PERTURB_BEGIN_INIT}
616
617  IGCM_date_GetYearMonth ${DateBegin} year month
618
619  # - Determine number of day(s) in LENGTH
620  DureeLengthInDays=$(( $( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${ensemble_Ens_PERTURB_LENGTH} ) - 1 ))
621
622  # - Determine DateEnd
623  DateEnd=$( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${DureeLengthInDays} )
624
625  # bad hack enforce yearly for parent directory name
626  # - Build directory name
627  IGCM_ensemble_CastDirectoryName ${ensemble_Ens_PERTURB_NAME} 1Y $year $month $StartDir
628
629  # - Determine RestartDate
630  (( Offset = -1 ))
631  RestartDate=$( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${Offset} )
632
633  IGCM_debug_Print 2 "${DateBegin} => ${DateEnd} : ${StartDir}"
634  echo "${DateBegin} ${DateEnd} ${StartDir}" >> ${RUN_DIR}/CreatedDir.txt
635
636  # - Create directory for current DateBegin
637  if [ ! -d  ${StartDir} ] ; then
638    IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}
639    IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}
640    ln -s ../../.resol .
641    ln -s ../../.libmpi .
642    IGCM_sys_Cd ${RUN_DIR}
643  fi
644
645  # - Create directory to store modified restart files
646  RestartDir=${STORAGE}/IGCM_IN/${config_UserChoices_TagName}/${StartDir}
647  IGCM_sys_MkdirArchive ${RestartDir}
648
649  # - Loop over members
650  i=0
651  nbmember=${#ensemble_Ens_PERTURB_PERTU_MAP_LIST[*]}
652  while [ $i -lt $nbmember ] ; do
653    MemberDir=${ensemble_Ens_PERTURB_MEMBER_NAMESLIST[${i}]}
654    MemberVec=${ensemble_Ens_PERTURB_PERTU_MAP_LIST[${i}]}
655
656    JobName="Job_${MemberDir}"
657    echo
658    IGCM_debug_Print 3 "${MemberDir}"
659
660    # * Create directory if it doesn't exist and copy/link files
661    if [ ! -d  ${SUBMIT_DIR}/${StartDir}/${MemberDir} ] ; then
662      IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}/${MemberDir}
663      IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}/${MemberDir}
664      ln -s ../../COMP
665      ln -s ../../PARAM
666      ln -s ../../POST
667      ln -s ../../DRIVER
668      IGCM_sys_Cd ${RUN_DIR}
669      IGCM_sys_Cp config.card run.card.init ${SUBMIT_DIR}/${StartDir}/${MemberDir}
670      IGCM_sys_Cp Job_${config_UserChoices_JobName} ${SUBMIT_DIR}/${StartDir}/${MemberDir}/${JobName}
671
672      # Dump command to be lauched
673      echo "cd ${StartDir}/${MemberDir}/ ;"     >> ${RUN_DIR}/Qsub.${StartDir}.sh
674      echo "${SUBMIT} ${JobName} ; cd -"        >> ${RUN_DIR}/Qsub.${StartDir}.sh
675
676      echo "cd ${StartDir}/${MemberDir}/ ;"     >> ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh
677      echo "${libIGCM}/clean_PeriodLength.job ; cd -"   >> ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh
678
679      # * Update files : config.card, Job_, COMP/comp.card
680      IGCM_ensemble_CastFilesUpdate ${DateBegin} ${DateEnd} ${RestartDate}
681
682      # * Apply noise on restart file
683      IGCM_ensemble_CastPerturbFile
684    fi
685
686    (( i = i + 1 ))
687  done
688
689  # Done. Save ${StartDir} submission text file
690  IGCM_sys_Cp ${RUN_DIR}/Qsub.${StartDir}.sh ${SUBMIT_DIR}
691  IGCM_sys_Cp ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh ${SUBMIT_DIR}
692
693  IGCM_debug_PopStack "IGCM_ensemble_CastMemberList"
694}
695
696function IGCM_ensemble_CastFilesUpdate
697{
698  IGCM_debug_PushStack "IGCM_ensemble_CastFilesUpdate"
699
700  # Debug Print :
701  echo
702  IGCM_debug_Print 1 "IGCM_ensemble_CastFilesUpdate :"
703
704  HumanDateBegin=$(   IGCM_date_ConvertFormatToHuman ${1} )
705  HumanDateEnd=$(     IGCM_date_ConvertFormatToHuman ${2} )
706  HumanRestartDate=$( IGCM_date_ConvertFormatToHuman ${3} )
707  # ==> config.card
708  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleRun 'y'
709  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleName ${ensemble_Ens_PERTURB_NAME}
710  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleDate ${StartDir}
711  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleType "Ens_PERTURB"
712
713  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card UserChoices JobName   ${MemberDir}
714  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card UserChoices DateBegin ${HumanDateBegin}
715  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card UserChoices DateEnd   ${HumanDateEnd}
716  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Restarts OverRule "n"
717
718  for comp in ${config_ListOfComponents[*]} ; do
719    IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${comp} Restart "y"
720    IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${comp} RestartDate ${HumanRestartDate}
721    IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${comp} RestartJobName ${ensemble_Ens_PERTURB_INITFROM}
722    IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${comp} RestartPath ${ensemble_Ens_PERTURB_INITPATH}
723  done
724  # Adhoc exception for CMIP6 : exclude XIOS from the restart overrule mechanism.
725  if ( [ X${comp} = XIOS ] && [ X"$( echo ${config_UserChoices_ExpType} | grep CMIP6 )" != "X" ] ) ; then
726      IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${comp} Restart "n"
727  fi
728
729  # ==> Job
730  sed -e "s/\(#.*Script_Output_\)${config_UserChoices_JobName}\(\.*\)/\1${MemberDir}\2/" \
731      -e "s/\(#.*\)${config_UserChoices_JobName}\(\.*\)/\1${MemberDir} \2/"            \
732      -e "s/^PeriodNb=.*/PeriodNb=5/"                                                   \
733      ${SUBMIT_DIR}/${StartDir}/${MemberDir}/Job_${MemberDir} > Job_${MemberDir}.tmp
734  IGCM_sys_Mv Job_${MemberDir}.tmp ${SUBMIT_DIR}/${StartDir}/${MemberDir}/Job_${MemberDir}
735
736  IGCM_debug_PopStack "IGCM_ensemble_CastFilesUpdate"
737}
738
739function IGCM_ensemble_CastDirectoryName
740{
741  IGCM_debug_PushStack "IGCM_ensemble_CastDirectoryName"
742
743  #.. Debug Print ..
744  echo
745  IGCM_debug_Print 1 "IGCM_ensemble_CastDirectoryName :"
746  echo
747
748  Name=$1
749  Duree=$2
750  year=$3
751  month=$4
752
753  # - Build directory name
754  case ${Duree} in
755  *Y|*y)
756    siecle="$( echo $year | cut -c1-2 )"
757    siecle=$( (( $siecle - 18 )) )
758    StartYear="${siecle}$( echo $year | cut -c3-4 )"
759    StartDir="${Name}${StartYear}"
760    ;;
761  *M|*m)
762    echo $month
763    siecle="$( echo $year | cut -c1-2 )"
764    siecle=$( (( $siecle - 18 )) )
765    StartYear="${siecle}$( echo $year | cut -c3-4 )"
766    StartMonth="${AlphaMonth[ (( 10#${month} - 1 )) ]}"
767    StartDir="${Name}${StartYear}${StartMonth}"
768    ;;
769  esac
770
771  IGCM_debug_PopStack "IGCM_ensemble_CastDirectoryName"
772}
773
774function IGCM_ensemble_CastPerturbFile
775{
776  IGCM_debug_PushStack "IGCM_ensemble_CastPerturbFile"
777
778  typeset i i_ j
779  typeset -Z4 j4
780  typeset file_out file_out_
781
782  #.. Debug Print ..
783  echo
784  IGCM_debug_Print 1 "IGCM_ensemble_CastPerturbFile :"
785
786  #.. FileIn ? => RestartDate ..
787  DirIn="${ensemble_Ens_PERTURB_INITPATH}/${ensemble_Ens_PERTURB_INITFROM}/${PerturbComp}/Restart"
788  DirInTar="${ensemble_Ens_PERTURB_INITPATH}/${ensemble_Ens_PERTURB_INITFROM}/RESTART"
789  FileIn="${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${PerturbFile}"
790  DirOut="${RestartDir}/${MemberDir}/${PerturbComp}/Restart"
791
792  # * Create member restart directory
793  IGCM_sys_TestDirArchive ${DirOut}
794  RET=$?
795  if [ $RET -gt 0 ] ; then
796    IGCM_sys_MkdirArchive ${DirOut}
797  fi
798
799  FileOut="${MemberDir}_${RestartDate}_${PerturbFile}"
800  IGCM_debug_Print 1 "FileIn  = ${DirIn}/${FileIn}"
801  IGCM_debug_Print 1 "FileOut = ${DirOut}/${FileOut}.nc"
802
803  IGCM_sys_TestFileArchive ${DirOut}/${FileOut}.nc
804  RET=$?
805  if [ $RET -gt 0 ] ; then
806
807    # * Look for the restart file we apply the noise to
808
809    # restart file list pertaining to the component we apply the noise to
810    # but not being the precise restart file we will apply the noise to
811    unset OtherFileInList
812    # generic restart filename list (like flxat, sstoc, restart, ...)
813    unset OtherGenericList
814
815    if ( [ X${FileName0} != X${NULL_STR} ] && [ X${FileName0} != XNONE ] ) ; then
816      (( i=0 ))
817      until [ $i -ge ${NbFiles} ]; do
818
819        (( i_ = i+1 ))
820        eval file_out_=\${${ListFilesName}[$i_]} > /dev/null 2>&1
821        eval file_out=${file_out_}
822
823        generic_restart_file_name_out=$( basename ${file_out} .nc )
824
825        if [ ! ${generic_restart_file_name_out} = ${PerturbFile} ] ; then
826          set +A OtherFileInList ${OtherFileInList[*]} ${PerturbComp}_${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic_restart_file_name_out}\*.nc
827          set +A OtherGenericList ${OtherGenericList[*]} ${generic_restart_file_name_out}
828        fi
829
830        (( i=i+3 ))
831      done
832    fi
833    # How many restart files other than the one we will apply the noise to
834    NbOtherFiles=${#OtherGenericList[*]}
835
836    ##########################
837    # TO BE A FUNCTION BEGIN #
838    ##########################
839
840    if [ $( IGCM_sys_TestFileBuffer ${DirIn}/${FileIn}*.nc ; echo $? ) = 0 ] ; then
841      IGCM_debug_Print 3 "Buffered restart"
842      Buffered=true
843      Archived=false
844      Tared=false
845      nb_restart_file=$(IGCM_sys_CountFileBuffer ${DirIn}/${FileIn}_????.nc)
846    elif [ $( IGCM_sys_TestFileArchive ${DirIn}/${FileIn}*.nc ; echo $? ) = 0 ] ; then
847      IGCM_debug_Print 3 "Archived restart"
848      Buffered=false
849      Archived=true
850      Tared=false
851      nb_restart_file=$(IGCM_sys_CountFileArchive ${DirIn}/${FileIn}_????.nc)
852    else
853      IGCM_debug_Print 3 "Tared restart"
854      Buffered=false
855      Archived=false
856      Tared=true
857
858      # Look for the tar file we want if we did not found it already
859      for PotentialTarFile in $( find ${ensemble_Ens_PERTURB_INITPATH}/${ensemble_Ens_PERTURB_INITFROM}/RESTART -name "${ensemble_Ens_PERTURB_INITFROM}_*restart*.tar" -print ) ; do
860        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}}' )
861        if [ ! X${IsMatching} = X ] ; then
862          TarFileFound=${PotentialTarFile}
863          break
864        fi
865      done
866
867      # Extract relevant restart files
868      IGCM_debug_Print 1 "tar xvf ${TarFileFound} ${PerturbComp}_${FileIn}*.nc ${OtherFileInList[*]}"
869      tar xvf ${TarFileFound} ${PerturbComp}_${FileIn}*.nc ${OtherFileInList[*]}
870      nb_restart_file=$( IGCM_sys_CountFileBuffer ${PerturbComp}_${FileIn}_????.nc )
871    fi
872
873    # Move around and perturb restart files so as to be able to start hindcast/forecast simulation members
874    if [ ${nb_restart_file} -gt 1 ] ; then
875      j=0
876      until [ $j -ge ${nb_restart_file} ]; do
877        j4=${j}
878        if [ X${Buffered} = Xtrue ] ; then
879          IGCM_sys_GetBuffer ${DirIn}/${FileIn}_${j4}.nc ${RUN_DIR}/${FileOut}_${j4}.nc
880
881          cd ${DirOut}
882          for generic in ${OtherGenericList[*]} ; do
883            ln -s ${DirIn}/${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${MemberDir}_${RestartDate}_${generic}_${j4}.nc
884          done
885          cd -
886
887        elif [ X${Archived} = Xtrue ] ; then
888          IGCM_sys_Get ${DirIn}/${FileIn}_${j4}.nc ${RUN_DIR}/${FileOut}_${j4}.nc
889
890          for generic in ${OtherGenericList[*]} ; do
891            IGCM_sys_RshArchive "cd ${DirOut} ; ln -s ${DirIn}/${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${MemberDir}_${RestartDate}_${generic}_${j4}.nc"
892          done
893
894        elif [ X${Tared} = Xtrue ] ; then
895          IGCM_debug_Print 2 "IGCM_sys_Mv ${PerturbComp}_${FileIn}_${j4}.nc ${RUN_DIR}/${FileOut}_${j4}.nc"
896          IGCM_sys_Mv ${PerturbComp}_${FileIn}_${j4}.nc ${RUN_DIR}/${FileOut}_${j4}.nc
897
898          for generic in ${OtherGenericList[*]} ; do
899            IGCM_sys_Mv ${PerturbComp}_${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${DirOut}/${MemberDir}_${RestartDate}_${generic}_${j4}.nc
900          done
901
902        fi
903        (( j=j+1 ))
904      done
905    else
906      if [ X${Buffered} = Xtrue ] ; then
907        IGCM_sys_GetBuffer ${DirIn}/${FileIn}.nc ${RUN_DIR}/${FileOut}.nc
908
909        cd ${DirOut}
910        for generic in ${OtherGenericList[*]} ; do
911          ln -s ${DirIn}/${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${MemberDir}_${RestartDate}_${generic}.nc
912        done
913        cd -
914
915      elif [ X${Archived} = Xtrue ] ; then
916        IGCM_sys_Get ${DirIn}/${FileIn}.nc ${RUN_DIR}/${FileOut}.nc
917
918        for generic in ${OtherGenericList[*]} ; do
919          IGCM_sys_RshArchive "cd ${DirOut} ; ln -s ${DirIn}/${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${MemberDir}_${RestartDate}_${generic}.nc"
920        done
921
922      elif [ X${Tared} = Xtrue ] ; then
923        IGCM_debug_Print 2 "IGCM_sys_Mv ${PerturbComp}_${FileIn}.nc ${RUN_DIR}/${FileOut}.nc"
924        IGCM_sys_Mv ${PerturbComp}_${FileIn}.nc ${RUN_DIR}/${FileOut}.nc
925
926        for generic in ${OtherGenericList[*]} ; do
927          IGCM_debug_Print 2 "IGCM_sys_Mv ${PerturbComp}_${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${DirOut}/${MemberDir}_${RestartDate}_${generic}.nc"
928          IGCM_sys_Mv ${PerturbComp}_${ensemble_Ens_PERTURB_INITFROM}_${RestartDate}_${generic}.nc ${DirOut}/${MemberDir}_${RestartDate}_${generic}.nc
929        done
930
931      fi
932    fi
933
934    ########################
935    # TO BE A FUNCTION END #
936    ########################
937
938# treat the perturbation on different components by looking at the executable name
939
940    case ${PerturbExe} in
941    (AddNoise)
942      IGCM_sys_Chmod 644 ${RUN_DIR}/${FileOut}.nc
943
944      IGCM_debug_Print 1 "${PerturbExe} ${RUN_DIR}/${FileOut}.nc ${PerturbVar} ${PerturbAmp}"
945      echo
946
947      ${PerturbExe} ${RUN_DIR}/${FileOut}.nc ${PerturbVar} ${PerturbAmp}  > /dev/null 2>&1
948      if [ $? -ne 0 ] ; then
949        IGCM_debug_Exit "Error with $( basename ${PerturbExe} )"
950        IGCM_debug_Verif_Exit
951      fi
952      IGCM_sys_Put_Out ${RUN_DIR}/${FileOut}.nc ${DirOut}/ 644
953      ;;
954    (AddPertu3DOCE)
955      # where to find the pattern we apply to the restart
956      PatternFile=${ensemble_Ens_PERTURB_MEMBER_INITPATH}/${ensemble_Ens_PERTURB_MEMBER_INITFROM}/${MemberVec}.nc
957
958      # where to find the land mask for the grid
959      MaskFile=${ensemble_Ens_PERTURB_MASKPATH}/${PerturbMask}
960
961      # if there is multiple restart files rebuild restart file
962      if [ ${nb_restart_file} -gt 1 ] ; then
963        IGCM_debug_Print 1 "rebuild files ${FileOut}_????.nc"
964        IGCM_sys_rebuild ${RUN_DIR}/${FileOut}.nc ${RUN_DIR}/${FileOut}_????.nc
965      fi
966
967      # there is now a single restart file
968      IGCM_sys_Chmod 644 ${RUN_DIR}/${FileOut}.nc
969
970      IGCM_debug_Print 1 "${PerturbExe} ${RUN_DIR}/${FileOut}.nc ${PerturbVar} ${PatternFile} ${MaskFile}"
971      echo
972
973      # add pattern to restart file on variable PerturbVar
974      ${PerturbExe} ${RUN_DIR}/${FileOut}.nc ${PerturbVar} ${PatternFile} ${MaskFile}  > /dev/null 2>&1
975      if [ $? -ne 0 ] ; then
976        IGCM_debug_Exit "Error with $( basename ${PerturbExe} )"
977        IGCM_debug_Verif_Exit
978      fi
979      IGCM_sys_Put_Out ${RUN_DIR}/${FileOut}.nc ${DirOut}/ 644
980     ;;
981    esac
982
983  fi
984
985  #.. Update config.card..
986  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${PerturbComp} Restart "y"
987  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${PerturbComp} RestartDate    ${HumanRestartDate}
988  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${PerturbComp} RestartJobName ${MemberDir}
989  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${PerturbComp} RestartPath    ${RestartDir}/
990  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleType "Ens_PERTURB"
991
992  IGCM_debug_PopStack "IGCM_ensemble_CastPerturbFile"
993}
994
995############### Date ENSEMBLE #################
996function IGCM_ensemble_DateInit
997{
998  IGCM_debug_PushStack "IGCM_ensemble_DateInit"
999
1000  IGCM_sys_Mkdir ${RUN_DIR}
1001
1002  IGCM_sys_Cp ${SUBMIT_DIR}/config.card   ${RUN_DIR}
1003  IGCM_sys_Cp ${SUBMIT_DIR}/ensemble.card ${RUN_DIR}
1004  IGCM_sys_Cp ${SUBMIT_DIR}/Job_*         ${RUN_DIR}
1005  IGCM_sys_Cp ${SUBMIT_DIR}/run.card.init ${RUN_DIR}
1006  if [ -f ${SUBMIT_DIR}/Qsub.* ]; then
1007    IGCM_sys_Cp ${SUBMIT_DIR}/Qsub.*        ${RUN_DIR}
1008  fi
1009  if [ -f ${SUBMIT_DIR}/Qclean.* ]; then
1010    IGCM_sys_Cp ${SUBMIT_DIR}/Qclean.*      ${RUN_DIR}
1011  fi
1012
1013  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE active
1014  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE NAME
1015  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE BEGIN_INIT
1016  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE BEGIN_RESTART
1017  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE END_INIT
1018  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE PERIODICITY
1019  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_DATE NONPERIODIC
1020  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_DATE RESTART_NONPERIODIC
1021  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE LENGTH
1022  IGCM_card_DefineArrayFromOption    ${F_CFG_ENS} Ens_DATE LENGTH_NONPERIODIC
1023  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE INITFROM
1024  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE INITFROM_NONPERIODIC
1025  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE INITPATH
1026  IGCM_card_DefineVariableFromOption ${F_CFG_ENS} Ens_DATE INITPATH_NONPERIODIC
1027  IGCM_card_DefineVariableFromOption config.card UserChoices JobName
1028  IGCM_card_DefineVariableFromOption config.card UserChoices TagName
1029  IGCM_card_DefineVariableFromOption config.card UserChoices CalendarType
1030  IGCM_card_DefineArrayFromSection   config.card ListOfComponents
1031
1032  echo
1033  IGCM_debug_Print 1 "[Ens_DATE]"
1034  IGCM_debug_Print 1 "ACTIVE               = ${ensemble_Ens_DATE_active}"
1035  IGCM_debug_Print 1 "NAME                 = ${ensemble_Ens_DATE_NAME}"
1036  IGCM_debug_Print 1 "BEGIN_INIT           = ${ensemble_Ens_DATE_BEGIN_INIT}"
1037  IGCM_debug_Print 1 "END_INIT             = ${ensemble_Ens_DATE_END_INIT}"
1038  IGCM_debug_Print 1 "PERIODICITY          = ${ensemble_Ens_DATE_PERIODICITY}"
1039  IGCM_debug_Print 1 "BEGIN_RESTART        = ${ensemble_Ens_DATE_BEGIN_RESTART}"
1040  IGCM_debug_Print 1 "NONPERIODIC          = ${ensemble_Ens_DATE_NONPERIODIC[*]}"
1041  IGCM_debug_Print 1 "RESTART_NONPERIODIC  = ${ensemble_Ens_DATE_RESTART_NONPERIODIC[*]}"
1042  IGCM_debug_Print 1 "LENGTH               = ${ensemble_Ens_DATE_LENGTH}"
1043  IGCM_debug_Print 1 "LENGTH_NONPERIODIC   = ${ensemble_Ens_DATE_LENGTH_NONPERIODIC[*]}"
1044  IGCM_debug_Print 1 "INITFROM             = ${ensemble_Ens_DATE_INITFROM}"
1045  IGCM_debug_Print 1 "INITFROM_NONPERIODIC = ${ensemble_Ens_DATE_INITFROM_NONPERIODIC[*]}"
1046  IGCM_debug_Print 1 "INITPATH             = ${ensemble_Ens_DATE_INITPATH}"
1047  IGCM_debug_Print 1 "INITPATH_NONPERIODIC = ${ensemble_Ens_DATE_INITPATH_NONPERIODIC[*]}"
1048  IGCM_debug_Print 1 "JobName              = ${config_UserChoices_JobName}"
1049  IGCM_debug_Print 1 "TagName              = ${config_UserChoices_TagName}"
1050  IGCM_debug_Print 1 "CalendarType         = ${config_UserChoices_CalendarType}"
1051  IGCM_debug_Print 1 "ListOfComponents     = ${config_ListOfComponents[*]}"
1052  echo ""
1053
1054  ensemble_Ens_DATE_MEMBER=1 # actually use only 1 member
1055  IGCM_ensemble_SetAlpha ${ensemble_Ens_DATE_MEMBER}
1056
1057  IGCM_debug_Print 1 "Check args..."
1058  DatePeriodicStart=false
1059  DateNonPeriodicStart=false
1060
1061  # ... Check LENGTH ...
1062  case ${ensemble_Ens_DATE_LENGTH} in
1063  *[Yy]|*[Mm])
1064    IGCM_debug_Print 1 "Default simulation duration : ${ensemble_Ens_DATE_LENGTH}" ;;
1065  *)
1066    IGCM_debug_Exit "IGCM_ensemble_DateInit ${ensemble_Ens_DATE_LENGTH} invalid LENGTH"
1067    IGCM_debug_Exit "Choose a value in choose in *Y or *M"
1068    IGCM_debug_Verif_Exit ;;
1069  esac
1070
1071  # ***************************************
1072  # A few checks Period case:
1073  # ***************************************
1074  # if all Periodic params are not filled: desactivate Periodic mode
1075  totalPeriodArgs=4
1076  periodFillArgs=0
1077
1078  if [[ X${ensemble_Ens_DATE_BEGIN_RESTART} != "X" ]]; then
1079    (( periodFillArgs = periodFillArgs + 1 ))
1080  fi
1081
1082  if [[ X${ensemble_Ens_DATE_BEGIN_INIT} != "X" ]]; then
1083    (( periodFillArgs = periodFillArgs + 1 ))
1084  fi
1085
1086  if [[ X${ensemble_Ens_DATE_END_INIT} != "X" ]]; then
1087    (( periodFillArgs = periodFillArgs + 1 ))
1088  fi
1089
1090  if [[ X${ensemble_Ens_DATE_PERIODICITY} != "X" ]]; then
1091    (( periodFillArgs = periodFillArgs + 1 ))
1092
1093    # ... Check PERIODICITY ...
1094    case ${ensemble_Ens_DATE_PERIODICITY} in
1095    *[Yy]|*[Mm])
1096      IGCM_debug_Print 1 "Periodic length : ${ensemble_Ens_DATE_PERIODICITY}" ;;
1097    *)
1098      IGCM_debug_Exit "IGCM_ensemble_DateInit ${ensemble_Ens_DATE_PERIODICITY} : invalid PERIODICITY"
1099      IGCM_debug_Exit "Choose a value in *Y or *M"
1100      IGCM_debug_Verif_Exit ;;
1101    esac
1102  fi # if periodicity
1103
1104  if [[ ${periodFillArgs} = ${totalPeriodArgs} ]]; then
1105    DatePeriodicStart=true
1106  else
1107    if [[ ${periodFillArgs} = 0 ]]; then
1108      IGCM_debug_Print 1 "Periodic start NOT ACTIVE"
1109      DatePeriodicStart=false
1110    else
1111      IGCM_debug_Exit "IGCM_ensemble_DateInit missing arguments for Periodic mode!"
1112      IGCM_debug_Exit "Get only ${periodFillArgs} on ${totalPeriodArgs} args. Check ${F_CFG_ENS} file."
1113      IGCM_debug_Verif_Exit
1114    fi
1115  fi
1116
1117  # ***************************************
1118  # A few checks for the Non-Periodic case:
1119  # ***************************************
1120  if [[ ${#ensemble_Ens_DATE_NONPERIODIC[*]} != ${#ensemble_Ens_DATE_RESTART_NONPERIODIC[*]} ]] ; then
1121    IGCM_debug_Exit "IGCM_ensemble_DateInit: NONPERIODIC and RESTART_NONPERIODIC lists have different sizes"
1122    IGCM_debug_Verif_Exit
1123  fi
1124
1125  if [[ ${#ensemble_Ens_DATE_NONPERIODIC[*]} > 0 ]] && [[ ${ensemble_Ens_DATE_NONPERIODIC[*]} != _0_ ]]; then
1126    DateNonPeriodicStart=true
1127
1128    # Use LENGTH if no NONPERIODIC_LENGTH given
1129    if [[ ${#ensemble_Ens_DATE_LENGTH_NONPERIODIC[*]} < ${#ensemble_Ens_DATE_NONPERIODIC[*]} ]] ; then
1130      IGCM_debug_Print 1 "WARNING: LENGTH_NONPERIODIC is not fill (or not correctly). Use LENGTH value '${ensemble_Ens_DATE_LENGTH}' for all NONPERIODIC runs"
1131      DateNum=0
1132      while [ ${DateNum} -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; do
1133        ensemble_Ens_DATE_LENGTH_NONPERIODIC[${DateNum}]=${ensemble_Ens_DATE_LENGTH}
1134        (( DateNum = DateNum + 1 ))
1135      done
1136    fi
1137
1138    # Use INITFROM if no INITFROM_NONPERIODIC given
1139    if [ ${#ensemble_Ens_DATE_INITFROM_NONPERIODIC[*]} -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; then
1140      IGCM_debug_Print 1 "WARNING: INITFROM_NONPERIODIC is not fill (or not correctly). Use INITFROM value '${ensemble_Ens_DATE_INITFROM}' for all NONPERIODIC runs"
1141      DateNum=0
1142      while [ ${DateNum} -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; do
1143        ensemble_Ens_DATE_INITFROM_NONPERIODIC[${DateNum}]=${ensemble_Ens_DATE_INITFROM}
1144        (( DateNum = DateNum + 1 ))
1145      done
1146    fi
1147   
1148    # Use INITPATH if no INITPATH_NONPERIODIC given
1149    if [ ${#ensemble_Ens_DATE_INITPATH_NONPERIODIC[*]} -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; then
1150      IGCM_debug_Print 1 "WARNING: INITPATH_NONPERIODIC is not fill (or not correctly). Use INITPATH value '${ensemble_Ens_DATE_INITPATH}' for all NONPERIODIC runs"
1151      DateNum=0
1152      while [ ${DateNum} -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; do
1153        ensemble_Ens_DATE_INITPATH_NONPERIODIC[${DateNum}]=${ensemble_Ens_DATE_INITPATH}
1154        (( DateNum = DateNum + 1 ))
1155      done
1156    fi
1157  else
1158    IGCM_debug_Print 1 "Non-Periodic start NOT ACTIVE"
1159    DateNonPeriodicStart=false
1160  fi
1161
1162  if [[ ${DateNonPeriodicStart} = true ]]; then
1163    DateNum=0
1164    while [ ${DateNum} -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; do
1165      # - Check LENGTH_NONPERIODIC
1166      case ${ensemble_Ens_DATE_LENGTH_NONPERIODIC[${DateNum}]} in
1167      *[Yy]|*[Mm])
1168        IGCM_debug_Print 1 "Non-periodic duration ${DateNum}: ${ensemble_Ens_DATE_LENGTH_NONPERIODIC[${DateNum}]}"
1169        ;;
1170      *)
1171        IGCM_debug_Exit "IGCM_ensemble_DateInit ${ensemble_Ens_DATE_LENGTH_NONPERIODIC[${DateNum}]} : invalid NON PERIODIC LENGTH"
1172        IGCM_debug_Exit "choose in *Y or *M"
1173        IGCM_debug_Verif_Exit ;;
1174      esac
1175
1176      # - Check RESTART_NONPERIODIC
1177      case ${ensemble_Ens_DATE_RESTART_NONPERIODIC[${DateNum}]} in
1178      _0_)
1179        IGCM_debug_Exit "IGCM_ensemble_DateInit ${ensemble_Ens_DATE_RESTART_NONPERIODIC[${DateNum}]} : invalid NON PERIODIC RESTART"
1180        IGCM_debug_Verif_Exit ;;
1181      esac
1182
1183      (( DateNum = DateNum + 1 ))
1184    done
1185  fi # DateNonPeriodicStart = true
1186
1187  IGCM_debug_PopStack "IGCM_ensemble_DateInit"
1188}
1189
1190function IGCM_ensemble_DatePeriodicStarts
1191{
1192  IGCM_debug_PushStack "IGCM_ensemble_DatePeriodicStarts"
1193
1194  [ ${DatePeriodicStart} = false ] && return
1195
1196  echo
1197  IGCM_debug_Print 1 ">>>  MANAGE PERIODIC STARTS  <<<"
1198
1199#.. Manage periodic starts ..
1200#   ======================
1201
1202  # - Build directory name
1203  StartDir="${ensemble_Ens_DATE_NAME}"
1204
1205  # - Create directory for current DateBegin
1206  if [ ! -d  ${StartDir} ] ; then
1207    IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}
1208    IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}
1209    ln -s ../../.resol .
1210    ln -s ../../.libmpi .
1211    IGCM_sys_Cd ${RUN_DIR}
1212  fi
1213
1214  # ... Loop over DateBegin ...
1215  eval DateBegin=\${ensemble_Ens_DATE_BEGIN_INIT}
1216  eval RestartDate=\${ensemble_Ens_DATE_BEGIN_RESTART}
1217
1218  DateNum=0
1219  while [ ${DateBegin} -le ${ensemble_Ens_DATE_END_INIT} ] ; do
1220    IGCM_date_GetYearMonth ${DateBegin} year month
1221
1222    echo "========================================================================"
1223    echo "New DateBegin = $DateBegin"
1224
1225  # - Determine number of day(s) in PERIODICITY
1226    PeriodLengthInDays=$( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${ensemble_Ens_DATE_PERIODICITY} )
1227
1228  # - Determine number of day(s) in LENGTH
1229    DureeLengthInDays=$(( $( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${ensemble_Ens_DATE_LENGTH} ) - 1 ))
1230
1231  # - Determine DateEnd
1232    (( DateEnd = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${DureeLengthInDays} ) ))
1233
1234    IGCM_debug_Print 2 "${DateBegin} => ${DateEnd} : ${StartDir}"
1235    echo "${DateBegin} ${DateEnd} ${StartDir}" >> ${RUN_DIR}/CreatedDir.txt
1236
1237  # - Loop over members (default =1 no member)
1238    i=0
1239    while [ $i -lt ${ensemble_Ens_DATE_MEMBER} ] ; do
1240      MemberDir="${ensemble_Ens_DATE_NAME}${DateNum}${Alpha[$i]}_per"
1241      echo
1242      IGCM_debug_Print 3 "${MemberDir}"
1243
1244      JobName="Job_${MemberDir}"
1245
1246    # * Create directory if it doesn't exist and copy/link files
1247      if [ ! -d  ${SUBMIT_DIR}/${StartDir}/${MemberDir} ] ; then
1248        IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}/${MemberDir}
1249        IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}/${MemberDir}
1250        ln -s ../../COMP
1251        ln -s ../../PARAM
1252        ln -s ../../POST
1253        ln -s ../../DRIVER
1254        IGCM_sys_Cd ${RUN_DIR}
1255        IGCM_sys_Cp config.card run.card.init ${SUBMIT_DIR}/${StartDir}/${MemberDir}
1256        IGCM_sys_Cp Job_${config_UserChoices_JobName} ${SUBMIT_DIR}/${StartDir}/${MemberDir}/${JobName}
1257
1258        # Dump command to be lauched
1259        echo "cd ${StartDir}/${MemberDir}/ ;"    >> ${RUN_DIR}/Qsub.${StartDir}.sh
1260        echo "${SUBMIT} ${JobName} ; cd -"       >> ${RUN_DIR}/Qsub.${StartDir}.sh
1261
1262        echo "cd ${StartDir}/${MemberDir}/ ;"    >> ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh
1263        echo "${libIGCM}/clean_PeriodLength.job ; cd -"  >> ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh
1264
1265        # * Update files : config.card, Job_, COMP/comp.card
1266        IGCM_ensemble_DateFilesUpdate ${DateBegin} ${DateEnd} ${RestartDate}
1267      fi
1268
1269      (( i = i + 1 ))
1270    done
1271
1272  # - Next DateBegin & RestartDate
1273    echo "$DateBegin  $PeriodLengthInDays"
1274    case ${ensemble_Ens_DATE_PERIODICITY} in
1275    *[Yy]|*[Mm])
1276      (( DateBegin =   $( IGCM_date_AddDaysToGregorianDate ${DateBegin}   ${PeriodLengthInDays} ) ))
1277      (( RestartDate = $( IGCM_date_AddDaysToGregorianDate ${RestartDate} ${PeriodLengthInDays} ) ))
1278      ;;
1279    esac
1280
1281    (( DateNum = DateNum + 1 )) # increment number of restart date
1282  done
1283
1284  # Done. Save ${StartDir} submission text file
1285  IGCM_sys_Cp ${RUN_DIR}/Qsub.${StartDir}.sh ${SUBMIT_DIR}
1286  IGCM_sys_Cp ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh ${SUBMIT_DIR}
1287
1288  IGCM_debug_PopStack "IGCM_ensemble_DatePeriodicStarts"
1289}
1290
1291function IGCM_ensemble_DateNonPeriodicStarts
1292{
1293  IGCM_debug_PushStack "IGCM_ensemble_DateNonPeriodicStarts"
1294
1295  #.. Manage non periodic starts => Loop over DateBegin ..
1296  #   ==========================
1297
1298  [ ${DateNonPeriodicStart} = false ] && return
1299
1300  echo
1301  IGCM_debug_Print 1 ">>>  MANAGE NON PERIODIC STARTS  <<<"
1302
1303  # - Build directory name
1304  echo ""
1305  echo "========================================================================"
1306  echo "ensemble_Ens_DATE_NAME = ${ensemble_Ens_DATE_NAME}"
1307  StartDir="${ensemble_Ens_DATE_NAME}"
1308
1309  # -  Does $StartDir already exist ?
1310  if [ ! -d ${SUBMIT_DIR}/${StartDir} ] ; then
1311    IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}
1312    IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}
1313    ln -s ../../.resol .
1314    ln -s ../../.libmpi .
1315    IGCM_sys_Cd ${RUN_DIR}
1316  fi
1317
1318  DateNum=0
1319  # ... Loop over ensemble_Ens_DATE_NONPERIODIC ...
1320  while [ ${DateNum} -lt ${#ensemble_Ens_DATE_NONPERIODIC[*]} ] ; do
1321    DateBegin=${ensemble_Ens_DATE_NONPERIODIC[${DateNum}]}
1322    Duree=${ensemble_Ens_DATE_LENGTH_NONPERIODIC[${DateNum}]}
1323    RestartDate=${ensemble_Ens_DATE_RESTART_NONPERIODIC[${DateNum}]}
1324    InitFrom=${ensemble_Ens_DATE_INITFROM_NONPERIODIC[${DateNum}]}
1325    InitPath=${ensemble_Ens_DATE_INITPATH_NONPERIODIC[${DateNum}]}
1326
1327  # - Determine number of day(s) in LENGTH_NONPERIODIC
1328    IGCM_date_GetYearMonth ${DateBegin} year month
1329    DureeLengthInDays=$(( $( IGCM_date_DaysInCurrentPeriod ${DateBegin} ${Duree} ) - 1 ))
1330
1331  # - Determine DateEnd
1332    (( DateEnd = $( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${DureeLengthInDays} ) ))
1333
1334    IGCM_debug_Print 2 "${DateBegin} => ${DateEnd} : ${StartDir}"
1335    echo "${DateBegin} ${DateEnd} ${StartDir}" >> ${RUN_DIR}/CreatedDir.txt
1336
1337    PeriodDateEnd=$( grep -m1 ${StartDir} ${RUN_DIR}/CreatedDir.txt | cut -f2 -d\  )
1338
1339  # - Loop over members
1340    i=0
1341    while [ $i -lt ${ensemble_Ens_DATE_MEMBER} ] ; do
1342      MemberDir="${ensemble_Ens_DATE_NAME}${DateNum}${Alpha[$i]}"
1343      IGCM_debug_Print 3 "${MemberDir}"
1344
1345      JobName="Job_${MemberDir}"
1346
1347    # * Create directory if it doesn't exist and copy files
1348      if [ ! -d  ${SUBMIT_DIR}/${StartDir}/${MemberDir} ] ; then
1349        IGCM_sys_Mkdir ${SUBMIT_DIR}/${StartDir}/${MemberDir}
1350        IGCM_sys_Cd ${SUBMIT_DIR}/${StartDir}/${MemberDir}
1351        ln -s ../../COMP
1352        ln -s ../../PARAM
1353        ln -s ../../POST
1354        ln -s ../../DRIVER
1355        IGCM_sys_Cd ${RUN_DIR}
1356        IGCM_sys_Cp config.card run.card.init ${SUBMIT_DIR}/${StartDir}/${MemberDir}
1357        IGCM_sys_Cp Job_${config_UserChoices_JobName} ${SUBMIT_DIR}/${StartDir}/${MemberDir}/Job_${MemberDir}
1358
1359        # Dump command to be lauched
1360        echo "cd ${StartDir}/${MemberDir}/ ;"     >> ${RUN_DIR}/Qsub.${StartDir}.sh
1361        echo "${SUBMIT} ${JobName} ; cd -"        >> ${RUN_DIR}/Qsub.${StartDir}.sh
1362
1363        echo "cd ${StartDir}/${MemberDir}/ ;"     >> ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh
1364        echo "${libIGCM}/clean_PeriodLength.job ; cd -"   >> ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh
1365
1366        # * Update files : config.card, Job_, COMP/comp.card
1367        IGCM_ensemble_DateFilesUpdate ${DateBegin} ${DateEnd} ${RestartDate} ${InitFrom} ${InitPath}
1368      fi
1369
1370      (( i = i + 1 ))
1371    done
1372
1373    # Done. Save ${StartDir} submission text file
1374    IGCM_sys_Cp ${RUN_DIR}/Qsub.${StartDir}.sh ${SUBMIT_DIR}
1375    IGCM_sys_Cp ${RUN_DIR}/Qclean.PeriodLength.${StartDir}.sh ${SUBMIT_DIR}
1376
1377    (( DateNum = DateNum + 1 ))
1378  done
1379
1380  # Done. Save ${StartDir} submission text file
1381  IGCM_sys_Cp ${RUN_DIR}/Qsub.${StartDir}.sh ${SUBMIT_DIR}
1382  IGCM_sys_Cp ${RUN_DIR}/Qclean.month.${StartDir}.sh ${SUBMIT_DIR}
1383  IGCM_sys_Cp ${RUN_DIR}/Qclean.year.${StartDir}.sh ${SUBMIT_DIR}
1384
1385  IGCM_debug_PopStack "IGCM_ensemble_DateNonPeriodicStarts"
1386}
1387
1388function IGCM_ensemble_DateFilesUpdate
1389{
1390  IGCM_debug_PushStack "IGCM_ensemble_DateFilesUpdate"
1391
1392  # Debug Print :
1393  echo
1394  IGCM_debug_Print 1 "IGCM_ensemble_DateFilesUpdate :"
1395
1396  HumanDateBegin=$(   IGCM_date_ConvertFormatToHuman ${1} )
1397  HumanDateEnd=$(     IGCM_date_ConvertFormatToHuman ${2} )
1398  HumanRestartDate=$( IGCM_date_ConvertFormatToHuman ${3} )
1399  if [[ X${4} != "X" ]]; then
1400    initFrom=${4} # non periodic config (INITFROM could be different between members)
1401  else
1402    initFrom=${ensemble_Ens_DATE_INITFROM} # periodic (same INITFROM value)
1403  fi
1404
1405  if [[ X${5} != "X" ]]; then
1406    initPath=${5} # non periodic config (INITPATH could be different between members)
1407  else
1408    initPath=${ensemble_Ens_DATE_INITPATH} # periodic (same INITPATH value)
1409  fi
1410 
1411  # ==> config.card
1412  # [ENSEMBLE]
1413  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleRun 'y'
1414  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleName ${ensemble_Ens_DATE_NAME}
1415  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleDate ${HumanDateBegin}
1416  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Ensemble EnsembleType "Ens_DATE"
1417
1418  # [UserChoices]
1419  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card UserChoices JobName   ${MemberDir}
1420  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card UserChoices DateBegin ${HumanDateBegin}
1421  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card UserChoices DateEnd   ${HumanDateEnd}
1422
1423  # [Restarts]
1424  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Restarts OverRule "y"
1425  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Restarts RestartDate ${HumanRestartDate}
1426  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Restarts RestartJobName ${initFrom}
1427  IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card Restarts RestartPath ${initPath}
1428
1429    # [ATM/OCE/...]
1430  for comp in ${config_ListOfComponents[*]} ; do
1431    IGCM_card_WriteOption ${SUBMIT_DIR}/${StartDir}/${MemberDir}/config.card ${comp} Restart "n"
1432  done
1433  unset initFrom
1434
1435  # ==> Job
1436  sed -e "s/\(#.*Script_Output_\)${config_UserChoices_JobName}\(\.*\)/\1${MemberDir}\2/" \
1437      -e "s/\(#.*\)${config_UserChoices_JobName}\(\.*\)/\1${MemberDir} \2/"            \
1438      -e "s/^PeriodNb=.*/PeriodNb=5/"                                                   \
1439      ${SUBMIT_DIR}/${StartDir}/${MemberDir}/Job_${MemberDir} > Job_${MemberDir}.tmp
1440  IGCM_sys_Mv Job_${MemberDir}.tmp ${SUBMIT_DIR}/${StartDir}/${MemberDir}/Job_${MemberDir}
1441
1442  IGCM_debug_PopStack "IGCM_ensemble_DateFilesUpdate"
1443}
1444
1445############### Parametric ENSEMBLE #################
Note: See TracBrowser for help on using the repository browser.