Ignore:
Timestamp:
Apr 5, 2022, 3:44:30 PM (2 years ago)
Author:
dcugnet
Message:
  • New water names: H2Ov, H2Ol, H2Oi, H2Or -> H2O_g, H2O_l, H2O_s, H2O_r.
  • Corrections for the lOldCode=.FALSE., not activated yet.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • LMDZ6/trunk/libf/misc/readTracFiles_mod.f90

    r4075 r4120  
    11MODULE readTracFiles_mod
    22
    3   USE strings_mod,    ONLY: msg, testFile,  strFind, strStack, strReduce,  strHead, strCount,   find, maxlen, fmsg, &
    4              removeComment, cat, checkList, strIdx,  strParse, strReplace, strTail, reduceExpr, test, get_in, dispTable
     3  USE strings_mod,    ONLY: msg, testFile,  strFind, strStack, strReduce,  strHead, strCount, find, fmsg, reduceExpr, &
     4             removeComment, cat, checkList, str2int, strParse, strReplace, strTail, strIdx, maxlen, test, dispTable, get_in
    55  USE trac_types_mod, ONLY: trac_type, isot_type, keys_type
    66
     
    1212  PUBLIC :: readTracersFiles, indexUpdate, setGeneration             !--- TOOLS ASSOCIATED TO TRACERS  DESCRIPTORS
    1313  PUBLIC :: readIsotopesFile                                         !--- TOOLS ASSOCIATED TO ISOTOPES DESCRIPTORS
    14   PUBLIC :: getKey_init, getKey, setDirectKeys                       !--- GET/SET KEYS FROM/TO tracers & isotopes
    15 
    16   PUBLIC :: known_phases, old_phases, nphases, phases_names, &       !--- VARIABLES RELATED TO THE PHASES
    17             phases_sep, delPhase, addPhase, &                        !--- + ROUTINES TO ADD/REMOVE PHASE TO/FROM A NAME
    18             old2newPhase, new2oldPhase
     14  PUBLIC :: getKey_init, getKey, fGetKey, setDirectKeys              !--- GET/SET KEYS FROM/TO tracers & isotopes
     15
     16  PUBLIC :: addPhase, new2oldName,  getPhase, &                      !--- FUNCTIONS RELATED TO THE PHASES
     17            delPhase, old2newName, getiPhase, &                      !--- + ASSOCIATED VARIABLES
     18            known_phases, old_phases, phases_sep, phases_names, nphases
     19
     20  PUBLIC :: oldH2OIso, newH2OIso                                     !--- NEEDED FOR BACKWARD COMPATIBILITY (OLD traceur.def)
    1921
    2022  PUBLIC :: tran0, idxAncestor, ancestor                             !--- GENERATION 0 TRACER + TOOLS FOR GENERATIONS
    21 
    2223!------------------------------------------------------------------------------------------------------------------------------
    2324  TYPE :: dataBase_type                                              !=== TYPE FOR TRACERS SECTION
     
    3031  END INTERFACE getKey
    3132!------------------------------------------------------------------------------------------------------------------------------
     33  INTERFACE fGetKey;       MODULE PROCEDURE fgetKeyByIndex_s1, fgetKeyByName_s1; END INTERFACE fGetKey
    3234  INTERFACE tracersSubset; MODULE PROCEDURE trSubset_Indx, trSubset_Name, trSubset_gen0Name; END INTERFACE tracersSubset
    3335  INTERFACE idxAncestor;   MODULE PROCEDURE idxAncestor_1, idxAncestor_m; END INTERFACE idxAncestor
    3436  INTERFACE    ancestor;   MODULE PROCEDURE    ancestor_1,    ancestor_m; END INTERFACE    ancestor
    35   INTERFACE    addPhase;   MODULE PROCEDURE    addPhase_1,    addPhase_m; END INTERFACE    addPhase
     37  INTERFACE    addPhase;   MODULE PROCEDURE   addPhase_s1,   addPhase_sm,   addPhase_i1,   addPhase_im; END INTERFACE addPhase
     38  INTERFACE old2newName;   MODULE PROCEDURE old2newName_1, old2newName_m; END INTERFACE old2newName
     39  INTERFACE new2oldName;   MODULE PROCEDURE new2oldName_1, new2oldName_m; END INTERFACE new2oldName
    3640!------------------------------------------------------------------------------------------------------------------------------
    3741
     
    4953  LOGICAL,          SAVE :: tracs_merge = .TRUE.                     !--- Merge/stack tracers lists
    5054  LOGICAL,          SAVE :: lSortByGen  = .TRUE.                     !--- Sort by growing generation
     55
     56  !--- KEPT JUST TO MANAGE OLD WATER ISOTOPES NAMES
     57  !--- Apart from that context, on limitaion on isotopes names (as long as they have a corresponding line in isotopes_params.def)
     58  CHARACTER(LEN=maxlen), SAVE :: oldH2OIso(5) = ['eau',     'HDO',     'O18',     'O17',     'HTO'    ]
     59  CHARACTER(LEN=maxlen), SAVE :: newH2OIso(5) = ['H2[16]O', 'H[2]HO ', 'H2[18]O', 'H2[17]O', 'H[3]HO ']
     60
    5161
    5262  !=== LOCAL COPIES OF THE TRACERS AND ISOTOPES DESCRIPTORS, USED BY getKey (INITIALIZED IN getKey_init)
     
    8797  INTEGER,                      INTENT(OUT) :: fType                  !--- Type of input file found
    8898  TYPE(trac_type), ALLOCATABLE, INTENT(OUT) :: tracs(:)
    89   CHARACTER(LEN=maxlen),  ALLOCATABLE ::  s(:), sections(:), trac_files(:)
    90   CHARACTER(LEN=maxlen) :: str, fname, mesg, oldH2O, newH2O
     99  CHARACTER(LEN=maxlen),  ALLOCATABLE :: s(:), sections(:), trac_files(:)
     100  CHARACTER(LEN=maxlen) :: str, fname, mesg
    91101  INTEGER               :: is, nsec, ierr, it, ntrac, ns, ip, ix
    92102  LOGICAL, ALLOCATABLE  :: ll(:), lGen3(:)
     
    142152        CALL msg('This file is for air tracers only',           modname, ns == 3 .AND. it == 1)
    143153        CALL msg('This files specifies the transporting fluid', modname, ns == 4 .AND. it == 1)
    144         tracs(it)%name = TRIM(s(3))                                  !--- Set %name:   name of the tracer
    145         tracs(it)%parent = tran0                                     !--- Set %parent: transporting fluid
    146         IF(ns == 4) tracs(it)%parent = s(4)                          !---     default: 'air' or defined in the file
    147         tracs(it)%phase = known_phases(1:1)                          !--- Set %phase:  tracer phase (default: "g"azeous)
     154        tracs(it)%name   = old2newName(s(3), ip)                     !--- Set %name:   name  of the tracer
     155        tracs(it)%parent = tran0                                     !--- Default transporting fluid name
     156        IF(ns == 4) tracs(it)%parent = old2newName(s(4))             !--- Set %parent: parent of the tracer
     157        tracs(it)%phase = known_phases(ip:ip)                        !--- Set %phase:  tracer phase (default: "g"azeous)
    148158        tracs(it)%component = TRIM(type_trac)                        !--- Set %component: model component name
    149159        tracs(it)%keys%key = ['hadv', 'vadv']                        !--- Set %keys%key
     
    151161      END DO
    152162      CLOSE(90)
    153       DO ip = 1, nphases                                             !--- Deal with old water names
    154         oldH2O = 'H2O'//old_phases(ip:ip)
    155         newH2O = 'H2O'//phases_sep//known_phases(ip:ip)
    156         ix = strIdx(tracs(:)%name, oldH2O)
    157         IF(ix == 0) CYCLE
    158         tracs(ix)%name  = newH2O                                     !--- Set %name:   name of the tracer
    159         WHERE(tracs(:)%parent == oldH2O) tracs(:)%parent = newH2O    !--- Set %parent: transporting fluid
    160         tracs(ix)%phase = known_phases(ip:ip)                        !--- Set %phase:  tracer phase
    161       END DO
    162163      CALL setGeneration(tracs)                                      !--- Set %iGeneration and %gen0Name
    163       WHERE(tracs%iGeneration == 3) tracs%type = 'tag'               !--- Set %type:        'tracer' or 'tag'
     164      WHERE(tracs%iGeneration == 2) tracs%type = 'tag'               !--- Set %type:        'tracer' or 'tag'
    164165      IF(test(checkTracers(tracs, fname, fname), lerr)) RETURN       !--- Detect orphans and check phases
    165166      IF(test(checkUnique (tracs, fname, fname), lerr)) RETURN       !--- Detect repeated tracers
     
    167168      tracs(:)%keys%name = tracs(:)%name                             !--- Copy tracers names in keys components
    168169    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    169     CASE(2); IF(test(feedDBase(["tracer.def"],[type_trac]), lerr)) RETURN  !=== SINGLE FILE, COMA-SEPARATED SECTIONS LIST
     170    CASE(2); IF(test(feedDBase(["tracer.def"], [type_trac], modname), lerr)) RETURN !=== SINGLE   FILE, MULTIPLE SECTIONS
    170171    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    171     CASE(3); IF(test(feedDBase(  trac_files  , sections  ), lerr)) RETURN  !=== MULTIPLE FILES, ONE SECTION EACH FILE
     172    CASE(3); IF(test(feedDBase(  trac_files  ,  sections,   modname), lerr)) RETURN !=== MULTIPLE FILES, SINGLE  SECTION
    172173  !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    173174  END SELECT
    174175  !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    175176
    176   IF(ANY([2,3] == fType) .AND. nsec > 1) THEN
    177     IF(tracs_merge) THEN
    178       CALL msg('The multiple required sections will be MERGED.',    modname)
    179       IF(test(mergeTracers(dBase, tracs), lerr)) RETURN
    180     ELSE
    181       CALL msg('The multiple required sections will be CUMULATED.', modname)
    182       IF(test(cumulTracers(dBase, tracs), lerr)) RETURN
    183     END IF
    184     WHERE(tracs%gen0Name(1:3) /= 'H2O') tracs%isInPhysics=.TRUE.     !--- Set %isInPhysics: passed to physics
    185     CALL setDirectKeys(tracs)                                        !--- Set %iqParent, %iqDescen, %nqDescen, %nqChilds
     177  IF(ALL([2,3] /= fType)) RETURN
     178
     179  IF(nsec  == 1) THEN;
     180    tracs = dBase(1)%trac
     181  ELSE IF(tracs_merge) THEN
     182    CALL msg('The multiple required sections will be MERGED.',    modname)
     183    IF(test(mergeTracers(dBase, tracs), lerr)) RETURN
     184  ELSE
     185    CALL msg('The multiple required sections will be CUMULATED.', modname)
     186    IF(test(cumulTracers(dBase, tracs), lerr)) RETURN
    186187  END IF
    187 
     188  WHERE(tracs%gen0Name(1:3) /= 'H2O') tracs%isInPhysics=.TRUE.       !--- Set %isInPhysics: passed to physics
     189  CALL setDirectKeys(tracs)                                          !--- Set %iqParent, %iqDescen, %nqDescen, %nqChilds
    188190END FUNCTION readTracersFiles
    189191!==============================================================================================================================
    190192
    191193!==============================================================================================================================
    192 LOGICAL FUNCTION feedDBase(fnames, snames) RESULT(lerr)
     194LOGICAL FUNCTION feedDBase(fnames, snames, modname) RESULT(lerr)
    193195! Purpose: Read the sections "snames(is)" (coma-separated list) from each "fnames(is)"
    194196!   file and create the corresponding tracers set descriptors in the database "dBase":
     
    200202  CHARACTER(LEN=*), INTENT(IN)  :: fnames(:)                         !--- Files names
    201203  CHARACTER(LEN=*), INTENT(IN)  :: snames(:)                         !--- Coma-deparated list of sections (one list each file)
    202   INTEGER,  ALLOCATABLE :: ndb(:)                                    !--- Nuber of sections for each file
     204  CHARACTER(LEN=*), INTENT(IN)  :: modname                           !--- Calling routine name
     205  INTEGER,  ALLOCATABLE :: ndb(:)                                    !--- Number of sections for each file
    203206  INTEGER,  ALLOCATABLE :: ixf(:)                                    !--- File index for each section of the expanded list
    204207  LOGICAL,  ALLOCATABLE :: lTg(:)                                    !--- Tagging tracers mask
    205   CHARACTER(LEN=maxlen) :: fnm, snm, modname
     208  CHARACTER(LEN=maxlen) :: fnm, snm
    206209  INTEGER               :: idb, i
    207210  LOGICAL :: ll
    208211!------------------------------------------------------------------------------------------------------------------------------
    209   modname = 'feedDBase'
    210212  !=== READ THE REQUIRED SECTIONS
    211213  ll = strCount(snames, ',', ndb)                                    !--- Number of sections for each file
     
    219221  !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    220222    fnm = fnames(ixf(idb)); snm = dBase(idb)%name                    !--- FILE AND SECTION NAMES
     223    lerr = ANY([(dispTraSection('RAW CONTENT OF SECTION "'//TRIM(snm)//'"', snm, modname), idb=1, SIZE(dBase))])
    221224    IF(test(expandSection(dBase(idb)%trac, snm, fnm), lerr)) RETURN  !--- EXPAND NAMES ;  set %parent, %type, %component
    222225    CALL setGeneration   (dBase(idb)%trac)                           !---                 set %iGeneration,   %genOName
     
    225228    CALL expandPhases    (dBase(idb)%trac)                           !--- EXPAND PHASES ; set %phase
    226229    CALL sortTracers     (dBase(idb)%trac)                           !--- SORT TRACERS
     230    lerr = ANY([(dispTraSection('EXPANDED CONTENT OF SECTION "'//TRIM(snm)//'"', snm, modname), idb=1, SIZE(dBase))])
    227231  !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    228232  END DO
    229233  !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    230 
    231   !=== DISPLAY BASIC INFORMATION
    232   lerr = ANY([( dispTraSection('Expanded list for section "'//TRIM(dBase(idb)%name)//'"', dBase(idb)%name, modname), &
    233                 idb=1, SIZE(dBase) )])
    234234END FUNCTION feedDBase
    235235!------------------------------------------------------------------------------------------------------------------------------
     
    406406  DO it = 1, nt                                                      !=== EXPAND TRACERS AND PARENTS NAMES LISTS
    407407  !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    408     ll = strParse(tr(it)%name, ',', ta, n=ntr)                       !--- Number of tracers
     408    ll = strParse(tr(it)%name,   ',', ta, n=ntr)                     !--- Number of tracers
    409409    ll = strParse(tr(it)%parent, ',', pa, n=npr)                     !--- Number of parents
    410410    DO ipr=1,npr                                                     !--- Loop on parents list elts
    411411      DO itr=1,ntr                                                   !--- Loop on tracers list elts
    412412        i = iq+itr-1+(ipr-1)*ntr
    413         ttr(i)%name = TRIM(ta(itr)); ttr(i)%parent = pa(ipr)
    414         ttr(i)%keys = keys_type(ta(itr), tr(it)%keys%key, tr(it)%keys%val)
     413        ttr(i)%name   = TRIM(ta(itr))
     414        ttr(i)%parent = TRIM(pa(ipr))
     415        ttr(i)%keys   = keys_type(ta(itr), tr(it)%keys%key, tr(it)%keys%val)
    415416      END DO
    416417    END DO
    417     ttr(iq:iq+ntr*npr-1)%type = tr(it)%type                          !--- Duplicating type
     418    ttr(iq:iq+ntr*npr-1)%type      = tr(it)%type                     !--- Duplicating type
     419    ttr(iq:iq+ntr*npr-1)%component = tr(it)%component                !--- Duplicating type
    418420    iq = iq + ntr*npr
    419421  !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     
    440442  tr(:)%iGeneration = -1                                             !--- error if -1
    441443  nq = SIZE(tr, DIM=1)                                               !--- Number of tracers lines
    442   lg = tr(:)%parent == tran0                                         !--- First generation tracers flag
    443   WHERE(lg) tr(:)%iGeneration = 0                                    !--- First generation tracers
     444  lg = tr(:)%parent == tran0                                         !--- Flag for generation 0 tracers
     445  WHERE(lg) tr(:)%iGeneration = 0                                    !--- Generation 0 tracers
    444446
    445447  !=== Determine generation for each tracer
     
    511513    ll = tr(:)%name==TRIM(tnam)                                      !--- Mask for current tracer name
    512514    IF(COUNT(ll)==1 ) CYCLE                                          !--- Tracer is not repeated
    513     IF(tr(iq)%iGeneration>1) THEN
    514       tdup(iq) = tnam                                                !--- gen>1: MUST be unique
     515    IF(tr(iq)%iGeneration>0) THEN
     516      tdup(iq) = tnam                                                !--- gen>0: MUST be unique
    515517    ELSE
    516518      DO ip=1,nphases; p=known_phases(ip:ip)                         !--- Loop on known phases
     
    531533SUBROUTINE expandPhases(tr)
    532534!------------------------------------------------------------------------------------------------------------------------------
    533 ! Purpose: Expand the phases in the tracers descriptor "tr".
     535! Purpose: Expand the phases in the tracers descriptor "tr". Phases are not repeated for a tracer, thanks to "checkUnique".
    534536!------------------------------------------------------------------------------------------------------------------------------
    535537  TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: tr(:)               !--- Tracer derived type vector
     
    538540  INTEGER,   ALLOCATABLE ::  i0(:)
    539541  CHARACTER(LEN=maxlen)  :: nam, pha, trn
     542  CHARACTER(LEN=1) :: p
    540543  INTEGER :: ip, np, iq, jq, nq, it, nt, nc, i, n
    541544  LOGICAL :: lTg, lEx
     
    544547  nt = 0
    545548  DO iq = 1, nq                                                      !--- GET THE NUMBER OF TRACERS
    546     IF(tr(iq)%iGeneration /= 1) CYCLE
    547     nc = COUNT(tr(:)%gen0Name==tr(iq)%name .AND. tr%iGeneration/=1)  !--- Number of childs of tr(iq)
     549    IF(tr(iq)%iGeneration /= 0) CYCLE                                !--- Only deal with generation 0 tracers
     550    nc = COUNT(tr(:)%gen0Name==tr(iq)%name .AND. tr%iGeneration/=0)  !--- Number of childs of tr(iq)
    548551    tr(iq)%phase = fgetKey(iq, 'phases', tr(:)%keys)                 !--- Phases list      of tr(iq)
    549552    np = LEN_TRIM(tr(iq)%phase)                                      !--- Number of phases of tr(iq)
    550553    nt = nt + (1+nc) * np                                            !--- Number of tracers after expansion
    551554  END DO
    552   ALLOCATE(ttr(nt))
     555  ALLOCATE(ttr(nt))                                                  !--- Version  of "tr" after phases expansion
    553556  it = 1                                                             !--- Current "ttr(:)" index
    554557  DO iq = 1, nq                                                      !--- Loop on "tr(:)" indexes
    555558    lTg = tr(iq)%type=='tag'                                         !--- Current tracer is a tag
    556559    i0 = strFind(tr(:)%name, TRIM(tr(iq)%gen0Name), n)               !--- Indexes of first generation ancestor copies
    557     np = SUM( [( LEN_TRIM(tr(i0(i))%phase),i=1,n )],1)               !--- Number of phases for current tracer tr(iq)
    558     lEx = np>1                                                       !--- Need of a phase suffix
    559     IF(lTg) lEx=lEx.AND.tr(iq)%iGeneration>1                         !--- No phase suffix for first generation tags
    560     DO i=1,n                                                         !=== LOOP ON FIRST GENERATION ANCESTORS
    561       jq=i0(i)                                                       !--- tr(jq): ith copy of 1st gen. ancestor of tr(iq)
    562       IF(tr(iq)%iGeneration==1) jq=iq                                !--- Generation 1: current tracer phases only
     560    np = SUM([( LEN_TRIM(tr(i0(i))%phase),i=1,n )], 1)               !--- Number of phases for current tracer tr(iq)
     561    lEx = np>1                                                       !--- Phase suffix only required if phases number is > 1
     562    IF(lTg) lEx = lEx .AND. tr(iq)%iGeneration>0                     !--- No phase suffix for generation 0 tags
     563    DO i=1,n                                                         !=== LOOP ON GENERATION 0 ANCESTORS
     564      jq = i0(i)                                                     !--- tr(jq): ith tracer with same gen 0 ancestor as tr(iq)
     565      IF(tr(iq)%iGeneration==0) jq=iq                                !--- Generation 0: count the current tracer phases only
    563566      pha = tr(jq)%phase                                             !--- Phases list for tr(jq)
    564       DO ip=1,LEN_TRIM(pha)                                          !=== LOOP ON PHASES LISTS
    565         trn=TRIM(tr(iq)%name); nam=trn                               !--- Tracer name (regular case)
     567      DO ip = 1, LEN_TRIM(pha)                                       !=== LOOP ON PHASES LISTS
     568        p = pha(ip:ip)
     569        trn = TRIM(tr(iq)%name); nam = trn                           !--- Tracer name (regular case)
    566570        IF(lTg) nam = TRIM(tr(iq)%parent)                            !--- Parent name (tagging case)
    567         IF(lEx) nam = TRIM(nam)//phases_sep//pha(ip:ip)              !--- Phase extension needed
     571        IF(lEx) nam = addPhase(nam, p )                              !--- Phase extension needed
    568572        IF(lTg) nam = TRIM(nam)//'_'//TRIM(trn)                      !--- <parent>_<name> for tags
    569573        ttr(it) = tr(iq)                                             !--- Same <key>=<val> pairs
    570         ttr(it)%name = TRIM(nam)                                     !--- Name with possibly phase suffix
     574        ttr(it)%name      = TRIM(nam)                                !--- Name with possibly phase suffix
    571575        ttr(it)%keys%name = TRIM(nam)                                !--- Name inside the keys decriptor
    572         ttr(it)%phase = pha(ip:ip)                                   !--- Single phase entry
    573         IF(lEx.AND.tr(iq)%iGeneration>1) THEN
    574           ttr(it)%parent   = TRIM(ttr(it)%parent)//phases_sep//pha(ip:ip)
    575           ttr(it)%gen0Name = TRIM(ttr(it)%gen0Name)//phases_sep//pha(ip:ip)
     576        ttr(it)%phase     = p                                        !--- Single phase entry
     577        IF(lEx .AND. tr(iq)%iGeneration>0) THEN
     578          ttr(it)%parent   = addPhase(ttr(it)%parent,   p)
     579          ttr(it)%gen0Name = addPhase(ttr(it)%gen0Name, p)
    576580        END IF
    577         it=it+1
     581        it = it+1
    578582      END DO
    579       IF(tr(iq)%iGeneration==1) EXIT                                 !--- Break phase loop for gen 1
     583      IF(tr(iq)%iGeneration==0) EXIT                                 !--- Break phase loop for gen 0
    580584    END DO
    581585  END DO
     
    590594!------------------------------------------------------------------------------------------------------------------------------
    591595! Purpose: Sort tracers:
    592 !  * Put water at first places, in the "known_phases" order.
     596!  * Put water at the beginning of the vector, in the "known_phases" order.
    593597!  * lGrowGen == T: in ascending generations numbers.
    594598!  * lGrowGen == F: tracer + its childs sorted by growing generation, one after the other.
    595599!   TO BE ADDED IF NECESSARY: HIGHER MOMENTS AT THE END
    596600!------------------------------------------------------------------------------------------------------------------------------
    597   TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: tr(:)               !--- Tracer derived type vector
     601  TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: tr(:)         !--- Tracer derived type vector
     602!  TYPE(trac_type), ALLOCATABLE :: ttr(:)
     603  INTEGER,         ALLOCATABLE :: iy(:), iz(:)
    598604  INTEGER :: ig, ng, iq, jq, ip, nq, n, ix(SIZE(tr)), k
    599   INTEGER, ALLOCATABLE :: iy(:), iz(:)
    600605!------------------------------------------------------------------------------------------------------------------------------
    601606  nq = SIZE(tr)
    602   iy = [(k, k=1, nq)]
    603607  DO ip = nphases, 1, -1
    604     iq = strIdx(tracers(:)%name, 'H2O'//phases_sep//known_phases(ip:ip))
    605     IF(iq/=0) iy = [iq, iy(1:iq-1), iy(iq:nq)]
    606   END DO
    607   tr = tr(iy)                                                        !--- Water displaces at first positions
    608   iq = 1
     608    iq = strIdx(tr(:)%name, addPhase('H2O', ip))
     609    IF(iq == 0) CYCLE
     610    tr = tr([iq, 1:iq-1, iq+1:nq])
     611!    tr(:)%name = nam
     612  END DO
    609613  IF(lSortByGen) THEN
     614    iq = 1
    610615    ng = MAXVAL(tr(:)%iGeneration, MASK=.TRUE., DIM=1)               !--- Number of generations
    611616    DO ig = 0, ng                                                    !--- Loop on generations
     
    616621    END DO
    617622  ELSE
    618     DO jq = 1, nq                                                    !--- Loop on first generation tracers
    619       IF(tr(jq)%iGeneration /= 1) CYCLE                              !--- Skip generations >= 1
    620       ix(iq) = jq                                                    !--- First generation ancestor index first
    621       iq = iq + 1
     623    iq = 1
     624    DO jq = 1, nq                                                    !--- Loop on generation 0 tracers
     625      IF(tr(jq)%iGeneration /= 0) CYCLE                              !--- Skip generations /= 0
     626      ix(iq) = jq                                                    !--- Generation 0 ancestor index first
     627      iq = iq + 1                                                    !--- Next "iq" for next generations tracers
    622628      iy = strFind(tr(:)%gen0Name, TRIM(tr(jq)%name))                !--- Indexes of "tr(jq)" childs in "tr(:)"
    623       ng = MAXVAL(tr(iy)%iGeneration, MASK=.TRUE., DIM=1)            !--- Generations number of the "tr(jq)" family
    624       DO ig = 2, ng                                                  !--- Loop   on generations for the tr(jq) family
     629      ng = MAXVAL(tr(iy)%iGeneration, MASK=.TRUE., DIM=1)            !--- Number of generations of the "tr(jq)" family
     630      DO ig = 1, ng                                                  !--- Loop   on generations of the "tr(jq)" family
    625631        iz = find(tr(iy)%iGeneration, ig, n)                         !--- Indexes of the tracers "tr(iy(:))" of generation "ig"
    626632        ix(iq:iq+n-1) = iy(iz)                                       !--- Same indexes in "tr(:)"
     
    724730      tnam = TRIM(t1(iq)%name)                                       !--- Original name
    725731      IF(COUNT(t1%name == tnam) == 1) CYCLE                          !--- Current tracer is not duplicated: finished
    726       tnam_new = TRIM(tnam)//phases_sep//TRIM(sections(is)%name)     !--- Same with section extension
     732      tnam_new = TRIM(tnam)//'_'//TRIM(sections(is)%name)            !--- Same with section extension
    727733      nq = SUM(nt(1:is-1))                                           !--- Number of tracers in previous sections
    728734      ns = nt(is)                                                    !--- Number of tracers in the current section
     
    757763  INTEGER :: idb, iq, nq
    758764  INTEGER, ALLOCATABLE :: hadv(:), vadv(:)
     765  CHARACTER(LEN=maxlen), ALLOCATABLE :: phas(:)
    759766  TYPE(trac_type), POINTER :: tm(:)
    760767  lerr = .FALSE.
     
    762769  tm => dBase(idb)%trac
    763770  nq = SIZE(tm)
    764   IF(test(getKeyByName_im('hadv', hadv, tm(:)%name, tm(:)%keys),lerr)) RETURN
    765   IF(test(getKeyByName_im('vadv', vadv, tm(:)%name, tm(:)%keys),lerr)) RETURN
     771  !--- BEWARE ! Can't use the "getKeyByName" functions yet.
     772  !             Names must first include the phases for tracers defined on multiple lines.
     773  hadv = str2int([(fgetKey(iq, 'hadv',  tm(:)%keys, '10'), iq=1, nq)])
     774  vadv = str2int([(fgetKey(iq, 'vadv',  tm(:)%keys, '10'), iq=1, nq)])
     775  phas =         [(fgetKey(iq, 'phases',tm(:)%keys, 'g' ), iq=1, nq)]
    766776  CALL msg(TRIM(message)//':', modname)
    767   IF(test(dispTable('iiissis', ['iq        ','hadv      ','vadv      ','short name','parent    ','igen      ','phase     '], &
    768     cat(tm(:)%name,  tm(:)%parent, tm(:)%phase), cat([(iq, iq=1, nq)],  hadv,  vadv, tm(:)%iGeneration)), lerr)) RETURN
     777  IF(tm(1)%parent == '') THEN
     778    IF(test(dispTable('iiiss',   ['iq    ','hadv  ','vadv  ','name  ','phase '], cat(tm%name, phas), cat([(iq, iq=1, nq)], &
     779                                            hadv,    vadv),                 sub=modname), lerr)) RETURN
     780  ELSE
     781    IF(test(dispTable('iiissis', ['iq    ','hadv  ','vadv  ','name  ','parent','igen  ','phase '], cat(tm%name, tm%parent, &
     782           tm%phase), cat([(iq, iq=1, nq)], hadv,    vadv, tm%iGeneration), sub=modname), lerr)) RETURN
     783  END IF
    769784END FUNCTION dispTraSection
    770785!==============================================================================================================================
     
    825840SUBROUTINE indexUpdate(tr)
    826841  TYPE(trac_type), INTENT(INOUT) :: tr(:)
    827   INTEGER :: iq, ig, ng, ngen
     842  INTEGER :: iq, ig, ng, igen, ngen
    828843  INTEGER, ALLOCATABLE :: ix(:)
    829844  tr(:)%iqParent = strIdx( tr(:)%name, tr(:)%parent )                !--- Parent index
    830845  ngen = MAXVAL(tr(:)%iGeneration, MASK=.TRUE.)
    831846  DO iq = 1, SIZE(tr)
    832     ng = tr(iq)%iGeneration                                          !--- Generation of the current tracer
    833     ix = idxAncestor(tr, igen = ng); ix = PACK(ix, ix/=0)            !--- Indexes of the tracers with ancestor tr(iq)
    834     !--- Childs indexes in growing generation order
    835     tr(iq)%iqDescen = [( PACK(ix, MASK = tr(ix)%iGeneration == ig), ig = ng+1, ngen)]
    836     tr(iq)%nqDescen =     SUM(  [( COUNT(tr(ix)%iGeneration == ig), ig = ng+1, ngen)] )
    837     tr(iq)%nqChilds =              COUNT(tr(ix)%iGeneration == ng+1)
     847    ig = tr(iq)%iGeneration
     848    IF(ALLOCATED(tr(iq)%iqDescen)) DEALLOCATE(tr(iq)%iqDescen)
     849    ALLOCATE(tr(iq)%iqDescen(0))
     850    ix = idxAncestor(tr, igen=ig)                                    !--- Ancestor of generation "ng" for each tr
     851    DO igen = ig+1, ngen
     852      tr(iq)%iqDescen = [tr(iq)%iqDescen, find(ix==iq .AND. tr%iGeneration==igen)]
     853      tr(iq)%nqDescen = SIZE(tr(iq)%iqDescen)
     854      IF(igen == ig+1) tr(iq)%nqChilds=tr(iq)%nqDescen
     855    END DO
    838856  END DO
    839857END SUBROUTINE indexUpdate
     
    847865!=== NOTES:                                                                                                                ====
    848866!===  * Most of the "isot" components have been defined in the calling routine (initIsotopes):                             ====
    849 !===      parent,  nzone, zone(:),  niso, keys(:)%name,  ntiso, trac(:),  nphas, phas,  iTraPha(:,:),  iZonPhi(:,:)        ====
     867!===      parent,  nzone, zone(:),  niso, keys(:)%name,  ntiso, trac(:),  nphas, phas,  iqTraPha(:,:),  itZonPhi(:,:)      ====
    850868!===  * Same syntax for isotopes file and "tracer.def": a tracers section contains one line for each of its isotopes       ====
    851869!===  * Each tracers section can contain a "params" virtual isotope line of isotopes parameters default values             ====
     
    909927    ALLOCATE(tdb(nb0-1)); tdb(1:nb0-1)=dBase(1:nb0-1); CALL MOVE_ALLOC(FROM=tdb, TO=dBase)
    910928  END IF
     929
     930  !--- GET THE isoCheck ENTRY FROM THE *.DEF FILES (MIGHT BE CHANGED TO A CLASS-DEPENDANT KEYWORD)
     931  CALL get_in('ok_iso_verif', isot(strIdx(isot%parent, 'H2O'))%check, .FALSE.)
     932
    911933  lerr = dispIsotopes(isot, 'Isotopes parameters read from file', modname)
    912934
     
    930952  LOGICAL, ALLOCATABLE :: ll(:)                                      !--- Mask
    931953  TYPE(trac_type), POINTER   ::  t(:), t1
    932   TYPE(isot_type), POINTER   ::  s
     954  TYPE(isot_type), POINTER   ::  i
    933955
    934956  t => trac
    935957
    936   p = PACK(delPhase(t%parent), MASK = t%type=='tracer' .AND. t%iGeneration==2) !--- Parents of 2nd generation isotopes
     958  p = PACK(delPhase(t%parent), MASK = t%type=='tracer' .AND. t%iGeneration==1) !--- Parents of generation 1 isotopes
    937959  CALL strReduce(p, nbIso)
    938960  ALLOCATE(isot(nbIso))
     
    943965  isot(:)%parent = p
    944966  DO ic = 1, SIZE(p)                                                 !--- Loop on isotopes classes
    945     s => isot(ic)
    946     iname = s%parent                                                 !--- Current isotopes class name (parent tracer name)
     967    i => isot(ic)
     968    iname = i%parent                                                 !--- Current isotopes class name (parent tracer name)
    947969
    948970    !=== Isotopes childs of tracer "iname": mask, names, number (same for each phase of "iname")
    949971    ll = t(:)%type=='tracer' .AND. delPhase(t(:)%parent) == iname .AND. t(:)%phase == 'g'
    950972    str = PACK(delPhase(t(:)%name), MASK = ll)                       !--- Effectively found isotopes of "iname"
    951     s%niso = SIZE(str)                                               !--- Number of "effectively found isotopes of "iname"
    952     ALLOCATE(s%keys(s%niso))
    953     FORALL(it = 1:s%niso) s%keys(it)%name = str(it)
     973    i%niso = SIZE(str)                                               !--- Number of "effectively found isotopes of "iname"
     974    ALLOCATE(i%keys(i%niso))
     975    FORALL(it = 1:i%niso) i%keys(it)%name = str(it)
    954976
    955977    !=== Geographic tagging tracers descending on tracer "iname": mask, names, number
    956     ll = t(:)%type=='tag'    .AND. delPhase(t(:)%gen0Name) == iname .AND. t(:)%iGeneration == 3
    957     s%zone = PACK(strTail(t(:)%name,'_',lFirst=.TRUE.), MASK = ll)   !--- Tagging zones names  for isotopes category "iname"
    958     CALL strReduce(s%zone)
    959     s%nzone = SIZE(s%zone)                                           !--- Tagging zones number for isotopes category "iname"
     978    ll = t(:)%type=='tag'    .AND. delPhase(t(:)%gen0Name) == iname .AND. t(:)%iGeneration == 2
     979    i%zone = PACK(strTail(t(:)%name,'_'), MASK = ll)                 !--- Tagging zones names  for isotopes category "iname"
     980    CALL strReduce(i%zone)
     981    i%nzone = SIZE(i%zone)                                           !--- Tagging zones number for isotopes category "iname"
    960982
    961983    !=== Geographic tracers of the isotopes childs of tracer "iname" (same for each phase of "iname")
     
    963985    str = PACK(delPhase(t(:)%name), MASK=ll)
    964986    CALL strReduce(str)
    965     s%ntiso = s%niso + SIZE(str)                                     !--- Number of isotopes + their geographic tracers [ntraciso]
    966     ALLOCATE(s%trac(s%ntiso))
    967     FORALL(it = 1:s%niso) s%trac(it) = s%keys(it)%name
    968     FORALL(it = s%niso+1:s%ntiso) s%trac(it) = str(it-s%niso)
     987    i%ntiso = i%niso + SIZE(str)                                     !--- Number of isotopes + their geographic tracers [ntraciso]
     988    ALLOCATE(i%trac(i%ntiso))
     989    FORALL(it = 1:i%niso) i%trac(it) = i%keys(it)%name
     990    FORALL(it = i%niso+1:i%ntiso) i%trac(it) = str(it-i%niso)
    969991
    970992    !=== Phases for tracer "iname"
    971     s%phase = ''
    972     DO ip = 1, nphases; ph = known_phases(ip:ip); IF(strIdx(t%name,addPhase(iname, ph)) /= 0) s%phase = TRIM(s%phase)//ph; END DO
    973     s%nphas = LEN_TRIM(s%phase)                                       !--- Equal to "nqo" for water
     993    i%phase = ''
     994    DO ip = 1, nphases; ph = known_phases(ip:ip); IF(strIdx(t%name,addPhase(iname, ph)) /= 0) i%phase = TRIM(i%phase)//ph; END DO
     995    i%nphas = LEN_TRIM(i%phase)                                       !--- Equal to "nqo" for water
    974996
    975997    !=== Tables giving the index in a table of effectively found items for each dynamical tracer (1<=iq<=nqtot)
    976998    DO iq = 1, SIZE(t)
    977999      t1 => trac(iq)
    978       IF(delPhase(t1%gen0Name) /= iname) CYCLE                       !--- Only deal with tracers descending on "iname"
     1000      IF(delPhase(t1%gen0Name)/=iname .OR. t1%iGeneration==0) CYCLE  !--- Only deal with tracers descending on "iname"
    9791001      t1%iso_iGroup = ic                                             !--- Isotopes family       idx in list "isotopes(:)%parent"
    980       t1%iso_iName  = strIdx(s%trac, delPhase(strHead(t1%name,'_'))) !--- Current isotope       idx in effective isotopes list
    981       t1%iso_iZone  = strIdx(s%zone,          strTail(t1%name,'_') ) !--- Current isotope zone  idx in effective zones    list
    982       t1%iso_iPhase =  INDEX(s%phase,TRIM(t1%phase))                 !--- Current isotope phase idx in effective phases   list
    983       IF(t1%iGeneration /= 3) t1%iso_iZone = 0                       !--- Skip possible generation 2 tagging tracers
     1002      t1%iso_iName  = strIdx(i%trac, delPhase(strHead(t1%name,'_'))) !--- Current isotope       idx in effective isotopes list
     1003      t1%iso_iZone  = strIdx(i%zone,          strTail(t1%name,'_') ) !--- Current isotope zone  idx in effective zones    list
     1004      t1%iso_iPhase =  INDEX(i%phase,TRIM(t1%phase))                 !--- Current isotope phase idx in effective phases   list
     1005      IF(t1%iGeneration /= 2) t1%iso_iZone = 0                       !--- Skip possible generation 1 tagging tracers
    9841006    END DO
    9851007
    9861008    !=== Table used to get iq (index in dyn array, size nqtot) from the isotope and phase indexes ; the full isotopes list
    9871009    !    (including tagging tracers) is sorted this way:  iso1, iso2, ..., iso1_zone1, iso2_zone1, ..., iso1_zoneN, iso2_zoneN
    988     s%iTraPha = RESHAPE( [( (strIdx(t(:)%name,  addPhase(s%trac(it),s%phase(ip:ip))),    it=1, s%ntiso), ip=1, s%nphas)], &
    989                          [s%ntiso, s%nphas] )
    990 
     1010    i%iqTraPha = RESHAPE( [( (strIdx(t%name,  addPhase(i%trac(it),i%phase(ip:ip))),    it=1, i%ntiso), ip=1, i%nphas)], &
     1011                         [i%ntiso, i%nphas] )
    9911012    !=== Table used to get ix (index in tagging tracers isotopes list, size ntiso) from the zone and isotope indexes
    992     s%iZonIso = RESHAPE( [( (strIdx(s%trac(:), TRIM(s%trac(it))//'_'//TRIM(s%zone(iz))), iz=1, s%nzone), it=1, s%niso )], &
    993                          [s%nzone, s%niso] )
     1013    i%itZonIso = RESHAPE( [( (strIdx(i%trac(:), TRIM(i%trac(it))//'_'//TRIM(i%zone(iz))), iz=1, i%nzone), it=1, i%niso )], &
     1014                         [i%nzone, i%niso] )
    9941015  END DO
    9951016
     
    10231044      END DO
    10241045    END DO
    1025     IF(test(fmsg('Problem with the table content', modname, dispTable(prf, ttl, val, cat([(it,it=1,nt)]), rFmt='(EN8.4)')), &
    1026        lerr)) RETURN
     1046    IF(test(fmsg('Problem with the table content', modname, dispTable(prf, ttl, val, cat([(it,it=1,nt)]), rFmt='(EN8.4)',    &
     1047       sub=modname)), lerr)) RETURN
    10271048    DEALLOCATE(ttl, val)
    10281049  END DO       
     
    10781099  IF(jd == 0) RETURN
    10791100  DO ik = 1, SIZE(t(jd)%keys%key)
    1080     CALL get_in(t(jd)%keys%key(ik), val, 'zzzz')
    1081     IF(val /= 'zzzz') CALL addKey_1(t(jd)%keys%key(ik), val, t(jd)%keys, .TRUE.)
     1101    CALL get_in(t(jd)%keys%key(ik), val, '*none*')
     1102    IF(val /= '*none*') CALL addKey_1(t(jd)%keys%key(ik), val, t(jd)%keys, .TRUE.)
    10821103  END DO
    10831104END SUBROUTINE addKeysFromDef
     
    11271148END SUBROUTINE getKey_init
    11281149!==============================================================================================================================
    1129 CHARACTER(LEN=maxlen) FUNCTION fgetKey(itr, keyn, ky, def_val) RESULT(out)
    1130 !------------------------------------------------------------------------------------------------------------------------------
    1131 ! Purpose: Internal function ; get a key value in string format (this is the returned argument).
     1150CHARACTER(LEN=maxlen) FUNCTION fgetKeyByIndex_s1(itr, keyn, ky, def_val) RESULT(val)
     1151!------------------------------------------------------------------------------------------------------------------------------
     1152! Purpose: Internal function ; get a string formatted key value (returned argument) from its name and the tracer index.
    11321153!------------------------------------------------------------------------------------------------------------------------------
    11331154  INTEGER,                    INTENT(IN) :: itr
     
    11361157  CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: def_val
    11371158!------------------------------------------------------------------------------------------------------------------------------
    1138   INTEGER :: ik
    1139   ik = 0; IF(itr>0 .AND. itr<=SIZE(ky)) ik = strIdx(ky(itr)%key(:), keyn)
    1140   out = '';              IF(ik /= 0) out = ky(itr)%val(ik)           !--- Key was found
    1141   IF(PRESENT(def_val) .AND. ik == 0) out = def_val                   !--- Default value from arguments
    1142 END FUNCTION fgetKey
     1159  INTEGER :: iky
     1160  iky = 0;  IF(itr >  0 .AND. itr <= SIZE(ky)) iky = strIdx(ky(itr)%key(:), keyn)
     1161  val = ''; IF(iky /= 0) val = ky(itr)%val(iky)                      !--- Key was found
     1162  IF(PRESENT(def_val) .AND. iky == 0) val = def_val                  !--- Default value from arguments
     1163END FUNCTION fgetKeyByIndex_s1
     1164!==============================================================================================================================
     1165CHARACTER(LEN=maxlen) FUNCTION fgetKeyByName_s1(tname, keyn, ky, def_val, lerr) RESULT(val)
     1166!------------------------------------------------------------------------------------------------------------------------------
     1167! Purpose: Internal function ; get a string formatted key value (returned argument) from its name and the tracer name.
     1168!------------------------------------------------------------------------------------------------------------------------------
     1169  CHARACTER(LEN=*),           INTENT(IN)  :: tname, keyn
     1170  TYPE(keys_type),            INTENT(IN)  :: ky(:)
     1171  CHARACTER(LEN=*), OPTIONAL, INTENT(IN)  :: def_val
     1172  LOGICAL,          OPTIONAL, INTENT(OUT) :: lerr
     1173!------------------------------------------------------------------------------------------------------------------------------
     1174  INTEGER :: iky, itr
     1175  val = ''; iky = 0
     1176  itr = strIdx(ky(:)%name, tname)                                    !--- Get the index of the wanted tracer
     1177  IF(PRESENT(lerr)) lerr = itr==0; IF(itr == 0) RETURN
     1178  IF(itr >  0 .AND. itr <= SIZE(ky)) iky = strIdx(ky(itr)%key(:), keyn)
     1179  IF(iky /= 0) val = ky(itr)%val(iky)                                !--- Key was found
     1180  IF(PRESENT(def_val) .AND. iky == 0) val = def_val                  !--- Default value from arguments
     1181END FUNCTION fgetKeyByName_s1
    11431182!==============================================================================================================================
    11441183LOGICAL FUNCTION getKeyByName_s1(keyn, val, tname, ky) RESULT(lerr)
     
    11511190  CHARACTER(LEN=*),          INTENT(IN)  :: tname
    11521191  TYPE(keys_type), OPTIONAL, INTENT(IN)  :: ky(:)
    1153   INTEGER :: is
    1154   lerr = .FALSE.
     1192  CHARACTER(LEN=maxlen) :: tnam
     1193  INTEGER, ALLOCATABLE  :: is(:)
     1194  INTEGER :: i, itr
     1195  tnam = delPhase(strHead(tname,'_',.FALSE.))                        !--- Remove tag and phase
    11551196  IF(PRESENT(ky)) THEN
    1156     val = getKeyByName_prv(keyn, tname , ky);    IF(val /= '') RETURN          !--- "ky" and "tnam"
    1157     val = getKeyByName_prv(keyn, delPhase(strHead(tname,'_')), ky)             !--- "ky" and "tnam" without phase
     1197    val = fgetKeyByName_s1(tname, keyn, ky, lerr=lerr)               !--- "ky" and "tname"
     1198    IF(val /= '' .OR. lerr)      RETURN
     1199    val = fgetKeyByName_s1(tnam,  keyn, ky, lerr=lerr)               !--- "ky" and "tnam"
    11581200  ELSE
    11591201    IF(.NOT.ALLOCATED(tracers))  RETURN
    1160     val = getKeyByName_prv(keyn, tname, tracers(:)%keys); IF(val /= '') RETURN !--- "tracers" and "tnam"
     1202    val = fgetKeyByName_s1(tname, keyn, tracers(:)%keys, lerr=lerr)  !--- "tracers" and "tname"
     1203    IF(val /= ''.AND..NOT.lerr)  RETURN
    11611204    IF(.NOT.ALLOCATED(isotopes)) RETURN
    11621205    IF(SIZE(isotopes) == 0)      RETURN
    1163     DO is = 1, SIZE(isotopes); IF(strIdx(isotopes(is)%keys(:)%name, delPhase(strHead(tname,'_'))) /= 0) EXIT; END DO
    1164     IF(is /= 0) val = getKeyByName_prv(keyn, tname, isotopes(is)%keys(:))      !--- "isotopes" and "tnam" without phase
     1206    !--- Search the "is" isotopes class index of the isotope named "tnam"
     1207    is = find([(ANY(isotopes(i)%keys(:)%name == tnam), i=1, SIZE(isotopes))])
     1208    IF(test(SIZE(is) == 0,lerr)) RETURN
     1209    val = fgetKeyByName_s1(tname, keyn, isotopes(is(1))%keys(:),lerr=lerr)!--- "isotopes" and "tnam"
    11651210  END IF
    1166 
    1167 CONTAINS
    1168 
    1169 FUNCTION getKeyByName_prv(keyn, tname, ky) RESULT(val)
    1170   CHARACTER(LEN=maxlen)         :: val
    1171   CHARACTER(LEN=*), INTENT(IN)  :: keyn
    1172   CHARACTER(LEN=*), INTENT(IN)  :: tname
    1173   TYPE(keys_type),  INTENT(IN)  :: ky(:)
    1174   INTEGER :: itr, iky
    1175   val = ''; iky = 0
    1176   itr = strIdx(ky(:)%name, tname);                 IF(itr==0) RETURN           !--- Get the index of the wanted tracer
    1177   IF(itr /= 0) iky = strIdx(ky(itr)%key(:), keyn); IF(iky==0) RETURN           !--- Wanted key    index
    1178   val = ky(itr)%val(iky)
    1179 END FUNCTION getKeyByName_prv
    1180 
    11811211END FUNCTION getKeyByName_s1
    11821212!==============================================================================================================================
    1183 LOGICAL FUNCTION getKeyByName_sm(keyn, val, tnam, ky) RESULT(lerr)
     1213LOGICAL FUNCTION getKeyByName_sm(keyn, val, tname, ky) RESULT(lerr)
    11841214  CHARACTER(LEN=*),                   INTENT(IN)  :: keyn
    1185   CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) ::  val(:)
    1186   CHARACTER(LEN=*), TARGET, OPTIONAL, INTENT(IN)  :: tnam(:)
    1187   TYPE(keys_type),  TARGET, OPTIONAL, INTENT(IN)  ::   ky(:)
    1188   CHARACTER(LEN=maxlen),    POINTER :: n(:)
    1189   INTEGER :: iq
    1190   n => tracers(:)%keys%name; IF(PRESENT(tnam)) n => tnam(:)
    1191   ALLOCATE(val(SIZE(n)))
    1192   IF(     PRESENT(ky)) lerr = ANY([(getKeyByName_s1(keyn, val(iq), n(iq), ky), iq=1, SIZE(n))])
    1193   IF(.NOT.PRESENT(ky)) lerr = ANY([(getKeyByName_s1(keyn, val(iq), n(iq)),     iq=1, SIZE(n))])
     1215  CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) ::   val(:)
     1216  CHARACTER(LEN=*), TARGET, OPTIONAL, INTENT(IN)  :: tname(:)
     1217  TYPE(keys_type),  TARGET, OPTIONAL, INTENT(IN)  ::    ky(:)
     1218  TYPE(keys_type),           POINTER :: k(:)
     1219  CHARACTER(LEN=maxlen), ALLOCATABLE :: n(:)
     1220  INTEGER :: iq, nq
     1221  IF(test(.NOT.(PRESENT(tname).OR.PRESENT(ky)), lerr)) RETURN
     1222  IF(PRESENT(ky   )) nq = SIZE(ky%name)
     1223  IF(PRESENT(tname)) nq = SIZE(  tname)
     1224  ALLOCATE(val(nq))
     1225  IF(PRESENT(tname)) THEN
     1226    IF(     PRESENT(ky)) lerr = ANY([(getKeyByName_s1(keyn, val(iq), tname(iq),   ky), iq=1, nq)])
     1227    IF(.NOT.PRESENT(ky)) lerr = ANY([(getKeyByName_s1(keyn, val(iq), tname(iq)      ), iq=1, nq)])
     1228  ELSE;                  lerr = ANY([(getKeyByName_s1(keyn, val(iq), ky(iq)%name, ky), iq=1, nq)])
     1229  END IF
    11941230END FUNCTION getKeyByName_sm
    11951231!==============================================================================================================================
    1196 LOGICAL FUNCTION getKeyByName_i1(keyn, val, tnam, ky) RESULT(lerr)
     1232LOGICAL FUNCTION getKeyByName_i1(keyn, val, tname, ky) RESULT(lerr)
    11971233  CHARACTER(LEN=*),          INTENT(IN)  :: keyn
    11981234  INTEGER,                   INTENT(OUT) :: val
    1199   CHARACTER(LEN=*),          INTENT(IN)  :: tnam
     1235  CHARACTER(LEN=*),          INTENT(IN)  :: tname
    12001236  TYPE(keys_type), OPTIONAL, INTENT(IN)  :: ky(:)
    12011237  CHARACTER(LEN=maxlen) :: sval
    12021238  INTEGER :: ierr
    1203   IF(     PRESENT(ky)) lerr = getKeyByName_s1(keyn, sval, tnam, ky)
    1204   IF(.NOT.PRESENT(ky)) lerr = getKeyByName_s1(keyn, sval, tnam)
    1205   IF(test(fmsg('key "'//TRIM(keyn)//'" or tracer "'//TRIM(tnam)//'" is missing',        modname, lerr), lerr)) RETURN
     1239  IF(     PRESENT(ky)) lerr = getKeyByName_s1(keyn, sval, tname, ky)
     1240  IF(.NOT.PRESENT(ky)) lerr = getKeyByName_s1(keyn, sval, tname)
     1241  IF(test(fmsg('key "'//TRIM(keyn)//'" or tracer "'//TRIM(tname)//'" is missing',        modname, lerr), lerr)) RETURN
    12061242  READ(sval, *, IOSTAT=ierr) val
    1207   IF(test(fmsg('key "'//TRIM(keyn)//'" of tracer "'//TRIM(tnam)//'" is not an integer', modname, lerr), lerr)) RETURN
     1243  IF(test(fmsg('key "'//TRIM(keyn)//'" of tracer "'//TRIM(tname)//'" is not an integer', modname, lerr), lerr)) RETURN
    12081244END FUNCTION getKeyByName_i1
    12091245!==============================================================================================================================
    1210 LOGICAL FUNCTION getKeyByName_im(keyn, val, tnam, ky) RESULT(lerr)
     1246LOGICAL FUNCTION getKeyByName_im(keyn, val, tname, ky) RESULT(lerr)
    12111247  CHARACTER(LEN=*),                   INTENT(IN)  :: keyn
    1212   INTEGER,               ALLOCATABLE, INTENT(OUT) ::  val(:)
    1213   CHARACTER(LEN=*), TARGET, OPTIONAL, INTENT(IN)  :: tnam(:)
    1214   TYPE(keys_type),  TARGET, OPTIONAL, INTENT(IN)  ::   ky(:)
    1215   CHARACTER(LEN=maxlen), POINTER :: n(:)
    1216   INTEGER :: iq
    1217   n => tracers(:)%name; IF(PRESENT(tnam)) n => tnam(:)
    1218   ALLOCATE(val(SIZE(n)))
    1219   IF(     PRESENT(ky)) lerr = ANY([(getKeyByName_i1(keyn, val(iq), n(iq), ky), iq=1, SIZE(n))])
    1220   IF(.NOT.PRESENT(ky)) lerr = ANY([(getKeyByName_i1(keyn, val(iq), n(iq)),     iq=1, SIZE(n))])
     1248  INTEGER,               ALLOCATABLE, INTENT(OUT) ::   val(:)
     1249  CHARACTER(LEN=*), TARGET, OPTIONAL, INTENT(IN)  :: tname(:)
     1250  TYPE(keys_type),  TARGET, OPTIONAL, INTENT(IN)  ::    ky(:)
     1251  TYPE(keys_type),           POINTER :: k(:)
     1252  CHARACTER(LEN=maxlen), ALLOCATABLE :: n(:)
     1253  INTEGER :: iq, nq
     1254  IF(test(.NOT.(PRESENT(tname).OR.PRESENT(ky)), lerr)) RETURN
     1255  IF(PRESENT(ky   )) nq = SIZE(ky%name)
     1256  IF(PRESENT(tname)) nq = SIZE(  tname)
     1257  ALLOCATE(val(nq))
     1258  IF(PRESENT(tname)) THEN
     1259    IF(     PRESENT(ky)) lerr = ANY([(getKeyByName_i1(keyn, val(iq), tname(iq),   ky), iq=1, nq)])
     1260    IF(.NOT.PRESENT(ky)) lerr = ANY([(getKeyByName_i1(keyn, val(iq), tname(iq)      ), iq=1, nq)])
     1261  ELSE;                  lerr = ANY([(getKeyByName_i1(keyn, val(iq), ky(iq)%name, ky), iq=1, nq)])
     1262  END IF
    12211263END FUNCTION getKeyByName_im
    12221264!==============================================================================================================================
    1223 LOGICAL FUNCTION getKeyByName_r1(keyn, val, tnam, ky) RESULT(lerr)
     1265LOGICAL FUNCTION getKeyByName_r1(keyn, val, tname, ky) RESULT(lerr)
    12241266  CHARACTER(LEN=*),          INTENT(IN)  :: keyn
    12251267  REAL,                      INTENT(OUT) :: val
    1226   CHARACTER(LEN=*),          INTENT(IN)  :: tnam
     1268  CHARACTER(LEN=*),          INTENT(IN)  :: tname
    12271269  TYPE(keys_type), OPTIONAL, INTENT(IN)  :: ky(:)
    12281270  CHARACTER(LEN=maxlen) :: sval
    12291271  INTEGER :: ierr
    1230   IF(     PRESENT(ky)) lerr = getKeyByName_s1(keyn, sval, tnam, ky)
    1231   IF(.NOT.PRESENT(ky)) lerr = getKeyByName_s1(keyn, sval, tnam)
    1232   IF(test(fmsg('key "'//TRIM(keyn)//'" or tracer "'//TRIM(tnam)//'" is missing',    modname, lerr), lerr)) RETURN
     1272  IF(     PRESENT(ky)) lerr = getKeyByName_s1(keyn, sval, tname, ky)
     1273  IF(.NOT.PRESENT(ky)) lerr = getKeyByName_s1(keyn, sval, tname)
     1274  IF(test(fmsg('key "'//TRIM(keyn)//'" or tracer "'//TRIM(tname)//'" is missing',    modname, lerr), lerr)) RETURN
    12331275  READ(sval, *, IOSTAT=ierr) val
    1234   IF(test(fmsg('key "'//TRIM(keyn)//'" of tracer "'//TRIM(tnam)//'" is not a real', modname, lerr), lerr)) RETURN
     1276  IF(test(fmsg('key "'//TRIM(keyn)//'" of tracer "'//TRIM(tname)//'" is not a real', modname, lerr), lerr)) RETURN
    12351277END FUNCTION getKeyByName_r1
    12361278!==============================================================================================================================
    1237 LOGICAL FUNCTION getKeyByName_rm(keyn, val, tnam, ky) RESULT(lerr)
     1279LOGICAL FUNCTION getKeyByName_rm(keyn, val, tname, ky) RESULT(lerr)
    12381280  CHARACTER(LEN=*),                   INTENT(IN)  :: keyn
    1239   REAL,                  ALLOCATABLE, INTENT(OUT) ::  val(:)
    1240   CHARACTER(LEN=*), TARGET, OPTIONAL, INTENT(IN)  :: tnam(:)
    1241   TYPE(keys_type),  TARGET, OPTIONAL, INTENT(IN)  ::   ky(:)
    1242   CHARACTER(LEN=maxlen), POINTER :: n(:)
    1243   INTEGER :: iq
    1244   n => tracers(:)%name;  IF(PRESENT(tnam)) n => tnam(:)
    1245   ALLOCATE(val(SIZE(n)))
    1246   IF(     PRESENT(ky)) lerr = ANY([(getKeyByName_r1(keyn, val(iq), n(iq), ky), iq=1, SIZE(n))])
    1247   IF(.NOT.PRESENT(ky)) lerr = ANY([(getKeyByName_r1(keyn, val(iq), n(iq)),     iq=1, SIZE(n))])
     1281  REAL,                  ALLOCATABLE, INTENT(OUT) ::   val(:)
     1282  CHARACTER(LEN=*), TARGET, OPTIONAL, INTENT(IN)  :: tname(:)
     1283  TYPE(keys_type),  TARGET, OPTIONAL, INTENT(IN)  ::    ky(:)
     1284  TYPE(keys_type),           POINTER :: k(:)
     1285  CHARACTER(LEN=maxlen), ALLOCATABLE :: n(:)
     1286  INTEGER :: iq, nq
     1287  IF(test(.NOT.(PRESENT(tname).OR.PRESENT(ky)), lerr)) RETURN
     1288  IF(PRESENT(ky   )) nq = SIZE(ky%name)
     1289  IF(PRESENT(tname)) nq = SIZE(  tname)
     1290  ALLOCATE(val(nq))
     1291  IF(PRESENT(tname)) THEN
     1292    IF(     PRESENT(ky)) lerr = ANY([(getKeyByName_r1(keyn, val(iq), tname(iq),   ky), iq=1, nq)])
     1293    IF(.NOT.PRESENT(ky)) lerr = ANY([(getKeyByName_r1(keyn, val(iq), tname(iq)      ), iq=1, nq)])
     1294  ELSE;                  lerr = ANY([(getKeyByName_r1(keyn, val(iq), ky(iq)%name, ky), iq=1, nq)])
     1295  END IF
    12481296END FUNCTION getKeyByName_rm
    12491297!==============================================================================================================================
     
    12761324END FUNCTION delPhase
    12771325!------------------------------------------------------------------------------------------------------------------------------
    1278 CHARACTER(LEN=maxlen) FUNCTION addPhase_1(s,pha,ph_sep) RESULT(out)
     1326CHARACTER(LEN=maxlen) FUNCTION addPhase_s1(s,pha) RESULT(out)
    12791327  CHARACTER(LEN=*),           INTENT(IN) :: s
    12801328  CHARACTER(LEN=1),           INTENT(IN) :: pha
    1281   CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: ph_sep
    1282   CHARACTER(LEN=1) :: psep
    12831329  INTEGER :: l, i
    12841330  out = s
    12851331  IF(s == '') RETURN                                                           !--- Empty string: nothing to do
    1286   psep = phases_sep; IF(PRESENT(ph_sep)) psep = ph_sep
    12871332  i = INDEX(s, '_')                                                            !--- /=0 for <var>_<tag> tracers names
    12881333  l = LEN_TRIM(s)
    1289   IF(i == 0) out =  TRIM(s)//TRIM(psep)//pha                                   !--- <var>       => return <var><sep><pha>
    1290   IF(i /= 0) out = s(1:i-1)//TRIM(psep)//pha//'_'//s(i+1:l)                    !--- <var>_<tag> => return <var><sep><pha>_<tag>
    1291 END FUNCTION addPhase_1
    1292 !------------------------------------------------------------------------------------------------------------------------------
    1293 FUNCTION addPhase_m(s,pha,ph_sep) RESULT(out)
     1334  IF(i == 0) out =  TRIM(s)//phases_sep//pha                                   !--- <var>       => return <var><sep><pha>
     1335  IF(i /= 0) out = s(1:i-1)//phases_sep//pha//'_'//s(i+1:l)                    !--- <var>_<tag> => return <var><sep><pha>_<tag>
     1336END FUNCTION addPhase_s1
     1337!------------------------------------------------------------------------------------------------------------------------------
     1338FUNCTION addPhase_sm(s,pha) RESULT(out)
    12941339  CHARACTER(LEN=*),           INTENT(IN) :: s(:)
    12951340  CHARACTER(LEN=1),           INTENT(IN) :: pha
    1296   CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: ph_sep
    12971341  CHARACTER(LEN=maxlen),     ALLOCATABLE :: out(:)
    1298   CHARACTER(LEN=1) :: psep
    12991342  INTEGER :: k
    1300   psep = phases_sep; IF(PRESENT(ph_sep)) psep = ph_sep
    1301   out = [( addPhase_1(s(k), pha, psep), k=1, SIZE(s) )]
    1302 END FUNCTION addPhase_m
    1303 !------------------------------------------------------------------------------------------------------------------------------
    1304 
    1305 CHARACTER(LEN=1) FUNCTION old2newPhase(op) RESULT(np)
    1306   CHARACTER(LEN=1), INTENT(IN) :: op
    1307   np = known_phases(INDEX(old_phases,op):INDEX(old_phases,op))
    1308 END FUNCTION old2newPhase
    1309 
    1310 CHARACTER(LEN=1) FUNCTION new2oldPhase(np) RESULT(op)
    1311   CHARACTER(LEN=1), INTENT(IN) :: np
    1312   op = old_phases(INDEX(known_phases,np):INDEX(known_phases,np))
    1313 END FUNCTION new2oldPhase
     1343  out = [( addPhase_s1(s(k), pha), k=1, SIZE(s) )]
     1344END FUNCTION addPhase_sm
     1345!------------------------------------------------------------------------------------------------------------------------------
     1346CHARACTER(LEN=maxlen) FUNCTION addPhase_i1(s,ipha,phases) RESULT(out)
     1347  CHARACTER(LEN=*),           INTENT(IN) :: s
     1348  INTEGER,                    INTENT(IN) :: ipha
     1349  CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: phases
     1350  out = s
     1351  IF(s == '') RETURN                                                           !--- Empty string: nothing to do
     1352  IF(ipha==0) RETURN                                                           !--- Null index: no phase to add
     1353  IF(     PRESENT(phases)) out = addPhase_s1(s,       phases(ipha:ipha))
     1354  IF(.NOT.PRESENT(phases)) out = addPhase_s1(s, known_phases(ipha:ipha))
     1355END FUNCTION addPhase_i1
     1356!------------------------------------------------------------------------------------------------------------------------------
     1357FUNCTION addPhase_im(s,ipha,phases) RESULT(out)
     1358  CHARACTER(LEN=*),           INTENT(IN) :: s(:)
     1359  INTEGER,                    INTENT(IN) :: ipha
     1360  CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: phases
     1361  CHARACTER(LEN=maxlen),     ALLOCATABLE :: out(:)
     1362  INTEGER :: k
     1363  IF(     PRESENT(phases)) out = [( addPhase_i1(s(k), ipha,       phases), k=1, SIZE(s) )]
     1364  IF(.NOT.PRESENT(phases)) out = [( addPhase_i1(s(k), ipha, known_phases), k=1, SIZE(s) )]
     1365END FUNCTION addPhase_im
     1366!------------------------------------------------------------------------------------------------------------------------------
     1367
     1368
     1369!==============================================================================================================================
     1370!=== GET PHASE INDEX IN THE POSSIBLE PHASES LIST OR IN A SPECIFIED LIST ("phases") ============================================
     1371!==============================================================================================================================
     1372INTEGER FUNCTION getiPhase(tname, phases) RESULT(iPhase)
     1373  CHARACTER(LEN=*),           INTENT(IN)  :: tname
     1374  CHARACTER(LEN=*), OPTIONAL, INTENT(IN)  :: phases
     1375  CHARACTER(LEN=maxlen) :: phase
     1376  IF(     PRESENT(phases)) phase = getPhase(tname,       phases, iPhase)
     1377  IF(.NOT.PRESENT(phases)) phase = getPhase(tname, known_phases, iPhase)
     1378END FUNCTION getiPhase
     1379!------------------------------------------------------------------------------------------------------------------------------
     1380CHARACTER(LEN=1) FUNCTION getPhase(tname, phases, iPhase) RESULT(phase)
     1381  CHARACTER(LEN=*),           INTENT(IN)  :: tname
     1382  CHARACTER(LEN=*), OPTIONAL, INTENT(IN)  :: phases
     1383  INTEGER,          OPTIONAL, INTENT(OUT) :: iPhase
     1384  INTEGER :: ip
     1385  phase = TRIM(strHead(strTail(tname, phases_sep, .TRUE.), '_', .TRUE.))
     1386  IF(     PRESENT(phases)) ip = INDEX(      phases, phase)
     1387  IF(.NOT.PRESENT(phases)) ip = INDEX(known_phases, phase)
     1388  IF(ip == 0) phase = 'g'
     1389  IF(PRESENT(iPhase)) iPhase = ip
     1390END FUNCTION getPhase
     1391!------------------------------------------------------------------------------------------------------------------------------
     1392
     1393
     1394!------------------------------------------------------------------------------------------------------------------------------
     1395CHARACTER(LEN=maxlen) FUNCTION old2newName_1(oldName, iPhase) RESULT(newName)
     1396  !--- Convert an old style name into a new one.
     1397  !    Only usable with old style "traceur.def" files, in which only water isotopes are allowed.
     1398  !    In these files, H2O descendants names are: H2O<phase>[_<isotope>][_<tag>], with:
     1399  !    phase = v, l or i ; isotope = eau, HDO, O18, O17 or HTO.
     1400  CHARACTER(LEN=*),  INTENT(IN)  :: oldName
     1401  INTEGER, OPTIONAL, INTENT(OUT) :: iPhase
     1402  CHARACTER(LEN=maxlen), ALLOCATABLE :: tmp(:)
     1403  INTEGER :: ix, ip, it, nt
     1404  LOGICAL :: lerr
     1405  newName = oldName
     1406  IF(PRESENT(iPhase)) iPhase = 1                                               !--- Default: gaseous phase
     1407  IF(oldName(1:MIN(3,LEN_TRIM(oldName))) /= 'H2O') RETURN                      !--- Not a water descendant
     1408  lerr = strParse(oldName, '_', tmp, n=nt)
     1409  ip = strIdx([('H2O'//old_phases(ip:ip), ip=1, nphases)], tmp(1))             !--- Phase index (/=0 if any)
     1410  IF(PRESENT(iPhase)) iPhase = ip
     1411  newName = addPhase('H2O', ip)                                                !--- Water
     1412  IF(nt == 1) RETURN                                                           !--- Water: finished
     1413  ix = strIdx(oldH2OIso, tmp(2))                                               !--- Index in the known isotopes list
     1414  IF(ix == 0) newName = addPhase(tmp(2),        ip)                            !--- Not an isotope
     1415  IF(ix /= 0) newName = addPhase(newH2OIso(ix), ip)                            !--- Isotope
     1416  IF(nt == 3) newName = TRIM(newName)//'_'//TRIM(tmp(3))                       !--- Tagging tracer
     1417END FUNCTION old2newName_1
     1418!------------------------------------------------------------------------------------------------------------------------------
     1419FUNCTION old2newName_m(oldName, iPhase) RESULT(newName)
     1420  CHARACTER(LEN=*),  INTENT(IN)  :: oldName(:)
     1421  INTEGER, OPTIONAL, INTENT(OUT) :: iPhase
     1422  CHARACTER(LEN=maxlen)          :: newName(SIZE(oldName))
     1423  INTEGER :: i
     1424  newName = [(old2newName_1(oldName(i), iPhase), i=1, SIZE(oldName))]
     1425END FUNCTION old2newName_m
     1426!------------------------------------------------------------------------------------------------------------------------------
     1427
     1428!------------------------------------------------------------------------------------------------------------------------------
     1429CHARACTER(LEN=maxlen) FUNCTION new2oldName_1(newName, iPhase) RESULT(oldName)
     1430  !--- Convert a new style name into an old one.
     1431  !    Only convertable names are water descendants names H2O_<phase>, <isotope>_<phase>, <isotope>_<phase>_<tag>, with:
     1432  !    phase = g, l or s ; isotope = H2[16]O, H[2]O, H2<[18]O, H2[17]O or H[3]O.
     1433  CHARACTER(LEN=*),  INTENT(IN)    :: newName
     1434  INTEGER, OPTIONAL, INTENT(OUT)   :: iPhase
     1435  INTEGER :: ix, ip, it, nt
     1436  LOGICAL :: lH2O
     1437  CHARACTER(LEN=maxlen) :: tag
     1438  ix = strIdx([(addPhase('H2O',ip), ip=1, nphases)], newName)                  !--- Phase index for H2O_<phase>
     1439  IF(ix /= 0) THEN; oldName = 'H2O'//old_phases(ix:ix); RETURN; END IF         !--- H2O_<phase> case
     1440  ix = strIdx(newH2OIso, strHead(newName, phases_sep, .TRUE.))                 !--- Isotope index
     1441  IF(ix == 0) THEN; oldName = newName;                  RETURN; END IF         !--- Not a water descendant
     1442  ip = getiPhase(newName)                                                      !--- Phase index
     1443  oldName = TRIM(oldH2OIso(ix))//old_phases(ip:ip)                             !--- <isotope>_<phase>
     1444  tag = strTail(delPhase(newName), TRIM(newH2OIso(ix)))                        !--- Get "_<tag>" if any
     1445  IF(tag /= delPhase(newName) .AND. tag /= '') oldName = TRIM(oldName)//tag    !--- Tagging tracer
     1446END FUNCTION new2oldName_1
     1447!------------------------------------------------------------------------------------------------------------------------------
     1448FUNCTION new2oldName_m(newName, iPhase) RESULT(oldName)
     1449  CHARACTER(LEN=*),  INTENT(IN)  :: newName(:)
     1450  INTEGER, OPTIONAL, INTENT(OUT) :: iPhase
     1451  CHARACTER(LEN=maxlen)          :: oldName(SIZE(newName))
     1452  INTEGER :: i
     1453  oldName = [(new2oldName_1(newName(i), iPhase), i=1, SIZE(newName))]
     1454END FUNCTION new2oldName_m
     1455!------------------------------------------------------------------------------------------------------------------------------
     1456
    13141457
    13151458!==============================================================================================================================
Note: See TracChangeset for help on using the changeset viewer.