Changeset 5190 for LMDZ6/trunk/libf


Ignore:
Timestamp:
Sep 15, 2024, 10:38:32 AM (10 months ago)
Author:
dcugnet
Message:

Revert to r5182 because r5183 still craches with gfortran for unclear reasons.
r5188 and r5189 have been included.

Location:
LMDZ6/trunk/libf
Files:
1 deleted
21 edited

Legend:

Unmodified
Added
Removed
  • LMDZ6/trunk/libf/dyn3d/check_isotopes.F90

    r5183 r5190  
    22   USE strings_mod, ONLY: maxlen, msg, strIdx, strStack, int2str, real2str
    33   USE infotrac,    ONLY: nqtot, niso, nphas, isotope, isoCheck, iqIsoPha, isoSelect, &
    4                           ntiso, iH2O, nzone, tracers, isoName,  itZonIso
    5    USE iso_params_mod,  ONLY: tnat_H216O, tnat_H217O, tnat_H218O, tnat_HDO, tnat_HTO
    6    USE ioipsl_getincom, ONLY: getin
     4                          ntiso, iH2O, nzone, tracers, isoName,  itZonIso, getKey
    75   IMPLICIT NONE
    86   include "dimensions.h"
     
    2220                      deltaDmin =-999.0, &
    2321                      ridicule  = 1e-12
    24    INTEGER, SAVE :: iso_eau, iso_O17, iso_O18, iso_HDO, iso_HTO
    25    LOGICAL, SAVE :: ltnat1, first=.TRUE.
     22   INTEGER, SAVE :: iso_eau, iso_HDO, iso_O18, &
     23                             iso_O17, iso_HTO
     24   LOGICAL, SAVE :: first=.TRUE.
     25   LOGICAL, PARAMETER :: tnat1=.TRUE.
    2626
    2727   modname='check_isotopes'
     
    3030   IF(niso == 0)        RETURN                   !--- No isotopes => finished
    3131   IF(first) THEN
    32       ltnat1 = .TRUE.; CALL getin('tnateq1', ltnat1)
    33       ALLOCATE(tnat(niso))
    34       iso_eau = strIdx(isoName,'H216O'); IF(iso_eau /= 0) tnat(iso_eau) = tnat_H216O
    35       iso_O17 = strIdx(isoName,'H217O'); IF(iso_O17 /= 0) tnat(iso_O17) = tnat_H217O
    36       iso_O18 = strIdx(isoName,'H218O'); IF(iso_O18 /= 0) tnat(iso_O18) = tnat_H218O
    37       iso_HDO = strIdx(isoName,'HDO');   IF(iso_HDO /= 0) tnat(iso_HDO) = tnat_HDO
    38       iso_HTO = strIdx(isoName,'HTO');   IF(iso_HTO /= 0) tnat(iso_HTO) = tnat_HTO
    39       IF(ltnat1) tnat(:) = 1.
     32      iso_eau = strIdx(isoName,'H216O')
     33      iso_HDO = strIdx(isoName,'HDO')
     34      iso_O18 = strIdx(isoName,'H218O')
     35      iso_O17 = strIdx(isoName,'H217O')
     36      iso_HTO = strIdx(isoName,'HTO')
     37      if (tnat1) then
     38              tnat(:)=1.0
     39      else
     40         IF(getKey('tnat', tnat)) CALL abort_gcm(modname, 'missing isotopic parameter', 1)
     41      endif
    4042      first = .FALSE.
    4143   END IF
  • LMDZ6/trunk/libf/dyn3d/dynetat0.F90

    r5183 r5190  
    66! Purpose: Initial state reading.
    77!-------------------------------------------------------------------------------
    8   USE infotrac,    ONLY: nqtot, tracers, niso, iqIsoPha, iH2O, isoName, &
    9                          new2oldH2O, newHNO3, oldHNO3
     8  USE infotrac,    ONLY: nqtot, tracers, niso, iqIsoPha, iH2O, isoName
    109  USE strings_mod, ONLY: maxlen, msg, strStack, real2str, int2str
    1110  USE netcdf,      ONLY: NF90_OPEN,  NF90_NOWRITE, NF90_INQ_VARID, &
    1211                         NF90_CLOSE, NF90_GET_VAR, NF90_NoErr
     12  USE readTracFiles_mod, ONLY: new2oldH2O, newHNO3, oldHNO3, getKey
    1313  USE control_mod, ONLY: planet_type
    1414  USE assert_eq_m, ONLY: assert_eq
     
    1919  USE temps_mod, ONLY: annee_ref, day_ini, day_ref, itau_dyn, start_time
    2020  USE ener_mod, ONLY: etot0,ptot0,ztot0,stot0,ang0
    21 #ifdef CPP_IOIPSL
    22   USE IOIPSL,   ONLY: getin
    23 #else
    24   USE ioipsl_getincom, ONLY: getin
    25 #endif
    26   USE iso_params_mod   ! tnat_* and alpha_ideal_*
    2721
    2822  IMPLICIT NONE
     
    4842  INTEGER :: iq, fID, vID, idecal, iqParent, iName, iZone, iPhase
    4943  REAL    :: time, tnat, alpha_ideal, tab_cntrl(length)    !--- RUN PARAMS TABLE
    50   LOGICAL :: lSkip, ll, ltnat1
     44  LOGICAL :: lSkip, ll
     45  LOGICAL,PARAMETER :: tnat1=.TRUE.
    5146!-------------------------------------------------------------------------------
    5247  modname="dynetat0"
     
    121116  var="temps"
    122117  IF(NF90_INQ_VARID(fID,var,vID)/=NF90_NoErr) THEN
    123     CALL msg('Missing field <temps> ; trying with <Time>', modname)
     118    CALL msg('missing field <temps> ; trying with <Time>', modname)
    124119    var="Time"
    125120    CALL err(NF90_INQ_VARID(fID,var,vID),"inq",var)
     
    138133  ll = NF90_INQ_VARID(fID, 'HNO3tot', vID) /= NF90_NoErr                                 !--- DETECT OLD REPRO start.nc FILE
    139134#endif
    140   ltnat1 = .TRUE.; CALL getin('tnateq1', ltnat1)
    141135  DO iq=1,nqtot
    142136    var = tracers(iq)%name
     
    154148    !--------------------------------------------------------------------------------------------------------------------------
    155149    ELSE IF(NF90_INQ_VARID(fID, oldVar, vID) == NF90_NoErr) THEN                         !=== TRY WITH ALTERNATE NAME
    156       CALL msg('Missing tracer <'//TRIM(var)//'> => initialized to <'//TRIM(oldVar)//'>', modname)
     150      CALL msg('Tracer <'//TRIM(var)//'> is missing => initialized to <'//TRIM(oldVar)//'>', modname)
    157151      CALL err(NF90_GET_VAR(fID,vID,q(:,:,:,iq)),"get",oldVar)
    158152    !--------------------------------------------------------------------------------------------------------------------------
     
    162156      iqParent = tracers(iq)%iqParent
    163157      IF(tracers(iq)%iso_iZone == 0) THEN
    164          IF(ltnat1) THEN
    165             tnat = 1.0
    166             alpha_ideal = 1.0
    167             CALL msg(' !!!  Beware: alpha_ideal put to 1  !!!', modname)
    168          ELSE
    169             SELECT CASE(isoName(iName))
    170               CASE('H216O'); tnat = tnat_H216O; alpha_ideal = alpha_ideal_H216O
    171               CASE('H217O'); tnat = tnat_H217O; alpha_ideal = alpha_ideal_H217O
    172               CASE('H218O'); tnat = tnat_H218O; alpha_ideal = alpha_ideal_H218O
    173               CASE('HDO');   tnat = tnat_HDO;   alpha_ideal = alpha_ideal_HDO
    174               CASE('HTO');   tnat = tnat_HTO;   alpha_ideal = alpha_ideal_HTO
    175               CASE DEFAULT; CALL abort_gcm(TRIM(modname),'unknown isotope "'//TRIM(isoName(iName))//'" ; check tracer.def file',1)
    176             END SELECT
    177          END IF
    178          CALL msg('Missing tracer <'//TRIM(var)//'> => initialized with a simplified Rayleigh distillation law.', modname)
     158         if (tnat1) then
     159                 tnat=1.0
     160                 alpha_ideal=1.0
     161                 write(*,*) 'attention dans dynetat0: les alpha_ideal sont a 1'
     162         else
     163          IF(getKey('tnat', tnat, isoName(iName)) .OR. getKey('alpha', alpha_ideal, isoName(iName))) &
     164            CALL abort_gcm(TRIM(modname), 'missing isotopic parameters', 1)
     165         endif
     166         CALL msg('Tracer <'//TRIM(var)//'> is missing => initialized with a simplified Rayleigh distillation law.', modname)
    179167         q(:,:,:,iq) = q(:,:,:,iqParent)*tnat*(q(:,:,:,iqParent)/30.e-3)**(alpha_ideal-1.)
    180168      ELSE
    181          CALL msg('Missing tracer <'//TRIM(var)//'> => initialized to its parent isotope concentration.', modname)
     169         CALL msg('Tracer <'//TRIM(var)//'> is missing => initialized to its parent isotope concentration.', modname)
    182170         ! Camille 9 mars 2023: attention!! seuls les tags qui correspondent à
    183171         ! izone=izone_init (définie dans isotrac_mod) sont initialisés comme
     
    193181    !--------------------------------------------------------------------------------------------------------------------------
    194182    ELSE                                                                                 !=== MISSING: SET TO 0
    195       CALL msg('Missing tracer <'//TRIM(var)//'> => initialized to zero', modname)
     183      CALL msg('Tracer <'//TRIM(var)//'> is missing => initialized to zero', modname)
    196184      q(:,:,:,iq)=0.
    197185    !--------------------------------------------------------------------------------------------------------------------------
  • LMDZ6/trunk/libf/dyn3d/iniacademic.F90

    r5183 r5190  
    55
    66  USE filtreg_mod, ONLY: inifilr
    7   USE infotrac,    ONLY: nqtot, niso, iqIsoPha, tracers, getKey, isoName, addPhase
     7  USE infotrac,    ONLY: nqtot, niso, iqIsoPha, tracers, getKey, isoName
    88  USE control_mod, ONLY: day_step,planet_type
    99  use exner_hyb_m, only: exner_hyb
     
    2121  USE temps_mod, ONLY: annee_ref, day_ini, day_ref
    2222  USE ener_mod, ONLY: etot0,ptot0,ztot0,stot0,ang0
     23  USE readTracFiles_mod, ONLY: addPhase
    2324  use netcdf, only : NF90_NOWRITE,NF90_OPEN,NF90_NOERR,NF90_INQ_VARID
    2425  use netcdf, only : NF90_CLOSE, NF90_GET_VAR
    25   USE iso_params_mod   ! tnat_* and alpha_ideal_*
    2626
    2727
     
    8080
    8181  REAL zdtvr, tnat, alpha_ideal
    82   LOGICAL :: ltnat1
     82  LOGICAL,PARAMETER :: tnat1=.true.
    8383 
    8484  character(len=*),parameter :: modname="iniacademic"
     
    309309        ! bulk initialization of tracers
    310310        if (planet_type=="earth") then
    311            ltnat1 = .TRUE.; CALL getin('tnateq1', ltnat1)
    312311           ! Earth: first two tracers will be water
    313312           do iq=1,nqtot
     
    323322              iqParent = tracers(iq)%iqParent
    324323              IF(tracers(iq)%iso_iZone == 0) THEN
    325                  IF(ltnat1) THEN
    326                     tnat = 1.0
    327                     alpha_ideal = 1.0
    328                     WRITE(lunout, *)'In '//TRIM(modname)//': !!!  Beware: alpha_ideal put to 1  !!!'
    329                  ELSE
    330                     SELECT CASE(isoName(iName))
    331                       CASE('H216O'); tnat = tnat_H216O; alpha_ideal = alpha_ideal_H216O
    332                       CASE('H217O'); tnat = tnat_H217O; alpha_ideal = alpha_ideal_H217O
    333                       CASE('H218O'); tnat = tnat_H218O; alpha_ideal = alpha_ideal_H218O
    334                       CASE('HDO');   tnat = tnat_HDO;   alpha_ideal = alpha_ideal_HDO
    335                       CASE('HTO');   tnat = tnat_HTO;   alpha_ideal = alpha_ideal_HTO
    336                       CASE DEFAULT
    337                          CALL abort_gcm(TRIM(modname),'unknown isotope "'//TRIM(isoName(iName))//'" ; check tracer.def file',1)
    338                     END SELECT
    339                  END IF
     324                 if (tnat1) then
     325                         tnat=1.0
     326                         alpha_ideal=1.0
     327                         write(*,*) 'Attention dans iniacademic: alpha_ideal=1'
     328                 else
     329                    IF(getKey('tnat', tnat, isoName(iName)) .OR. getKey('alpha', alpha_ideal, isoName(iName))) &
     330                    CALL abort_gcm(TRIM(modname), 'missing isotopic parameters', 1)
     331                 endif
    340332                 q(:,:,iq) = q(:,:,iqParent)*tnat*(q(:,:,iqParent)/30.e-3)**(alpha_ideal-1.)
    341333              ELSE !IF(tracers(iq)%iso_iZone == 0) THEN
  • LMDZ6/trunk/libf/dyn3d/qminimum.F

    r5183 r5190  
    44      SUBROUTINE qminimum( q,nqtot,deltap )
    55
    6       USE infotrac, ONLY: niso, ntiso, iqIsoPha, tracers, addPhase
     6      USE infotrac, ONLY: niso, ntiso,iqIsoPha, tracers
    77      USE strings_mod, ONLY: strIdx
     8      USE readTracFiles_mod, ONLY: addPhase
    89      IMPLICIT none
    910c
  • LMDZ6/trunk/libf/dyn3d_common/infotrac.F90

    r5183 r5190  
    33MODULE infotrac
    44
    5    USE       strings_mod, ONLY: msg, maxlen, cat, dispTable, int2str, bool2str, strStack, strParse, strCount, strIdx
    6    USE readTracFiles_mod, ONLY: readTracersFiles, maxTableWidth,  tisot=>isot_type, addPhase, addKey, iH2O, &
    7         indexUpdate, keys_type, testTracersFiles, processIsotopes, trac=>tracers,   delPhase, getKey, tran0
    8    USE readTracFiles_mod, ONLY: new2oldH2O, newHNO3, oldHNO3
    9 
     5   USE       strings_mod, ONLY: msg, fmsg, maxlen, cat, dispTable, int2str, bool2str, strStack, strParse
     6   USE readTracFiles_mod, ONLY: trac_type, readTracersFiles, tracers, setGeneration, itZonIso, nzone, tran0, isoZone, &
     7        delPhase, niso, getKey, isot_type, processIsotopes,  isotope, maxTableWidth, iqIsoPha, nphas, ixIso, isoPhas, &
     8        addPhase, iH2O, addKey, isoSelect, testTracersFiles, isoKeys, indexUpdate,  iqWIsoPha, nbIso, ntiso, isoName, isoCheck
    109   IMPLICIT NONE
    1110
     
    1716   PUBLIC :: nqtot,   nbtr,   nqo,   nqCO2,   nqtottr      !--- Main dimensions
    1817   PUBLIC :: conv_flg, pbl_flg                             !--- Convection & boundary layer activation keys
    19    PUBLIC :: new2oldH2O, newHNO3, oldHNO3                  !--- For backwards compatibility in dynetat0
    20    PUBLIC :: addPhase, delPhase                            !--- Add/remove the phase from the name of a tracer
    2118
    2219   !=== FOR ISOTOPES: General
    2320   PUBLIC :: isot_type, nbIso                              !--- Derived type, full isotopes families database + nb of families
    24    PUBLIC :: isoSelect, ixIso, isoFamilies                 !--- Isotopes families selection tool + selected index + list
     21   PUBLIC :: isoSelect, ixIso                              !--- Isotopes family selection tool + selected family index
    2522   !=== FOR ISOTOPES: Specific to water
    26    PUBLIC :: iH2O                                          !--- Value of "ixIso" for "H2O" isotopes class
     23   PUBLIC :: iH2O                                          !--- H2O isotopes class index
    2724   PUBLIC :: min_qParent, min_qMass, min_ratio             !--- Min. values for various isotopic quantities
    2825   !=== FOR ISOTOPES: Depending on the selected isotopes family
    29    PUBLIC :: isotope                                       !--- Selected isotopes database (argument of getKey)
    30    PUBLIC :: isoKeys, isoName, isoZone, isoPhas            !--- Isotopes keys & names, tagging zones names, phases
    31    PUBLIC ::    niso,   ntiso,   nzone,   nphas            !--- Number of   "   "
    32    PUBLIC :: itZonIso                                      !--- index "it" in "isoName(1:niso)" = f(tagging idx, isotope idx)
    33    PUBLIC :: iqIsoPha                                      !--- index "iq" in "qx"              = f(isotope idx,   phase idx)
     26   PUBLIC :: isotope, isoKeys                              !--- Selected isotopes database + associated keys (cf. getKey)
     27   PUBLIC :: isoName, isoZone, isoPhas                     !--- Isotopes and tagging zones names, phases
     28   PUBLIC :: niso,    nzone,   nphas,   ntiso              !---  " " numbers + isotopes & tagging tracers number
     29   PUBLIC :: itZonIso                                      !--- idx "it" (in "isoName(1:niso)") = function(tagging idx, isotope idx)
     30   PUBLIC :: iqIsoPha                                      !--- idx "iq" (in "qx") = function(isotope idx, phase idx) + aliases
    3431   PUBLIC :: isoCheck                                      !--- Run isotopes checking routines
    3532   !=== FOR BOTH TRACERS AND ISOTOPES
     
    3936!  |--------------------+-----------------------+-----------------+---------------+----------------------------|
    4037!  | water in different |    water tagging      |  water isotopes | other tracers | additional tracers moments |
    41 !  | phases: H2O_[glsrb]|      isotopes         |                 |               |  for higher order schemes  |
     38!  | phases: H2O_[gls|      isotopes         |                 |               |  for higher order schemes  |
    4239!  |--------------------+-----------------------+-----------------+---------------+----------------------------|
    4340!  |                    |                       |                 |               |                            |
     
    5350!  |-----------------------------------------------------------------------------------------------------------|
    5451!  NOTES FOR THIS TABLE:
    55 !  * Used "niso", "nzone" and "ntiso" are components of "isotopes(ip)" for water (isotopes(ip)%name == 'H2O'),
     52!  * Used "niso", "nzone" and "ntiso" are components of "isotopes(ip)" for water (isotopes(ip)%parent == 'H2O'),
    5653!    since water is so far the sole tracers family, except passive CO2, removed from the main tracers table.
    5754!  * For water, "nqo" is equal to the more general field "isotopes(ip)%nphas".
    5855!  * "niso", "nzone", "ntiso", "nphas" are defined for other isotopic tracers families, if any.
    59 !  * If you deal with an isotopes family other than "H2O" ("Sulf" in the example), a good practice is to keep
    60 !    track of the isotopes class (of its index) before switching to it at the beginning of the dedicated code:
    61 !  - first time (use selection by name and compute the corresponding index iSulf) :
    62 !  i0=ixIso; IF(.NOT.isoSelect('Sulf')) CALL abort_gcm("Can't select isotopes class", modname, 1); iS=ixIso
    63 !  - next times (use selection by index - "iS" has been computed at first call):
    64 !  i0=ixIso; IF(.NOT.isoSelect(iS))     CALL abort_gcm("Can't select isotopes class", modname, 1)
    65 !    and to switch back to the original category when you're done with "Sulf":
    66 !            IF(.NOT.isoSelect(i0))     CALL abort_gcm("Can't select isotopes class", modname, 1)
    67 !    to restore the original isotopes category (before dealing with "Sulf" (most of the time "H2O").
    68 !
    69 !=== LOCAL DERIVED TYPE "trac_type" EMBEDDING MOST OF THE TRACERS-RELATED QUANTITIES (LENGTH: nqtot)
     56!
     57!=== DERIVED TYPE EMBEDDING MOST OF THE TRACERS-RELATED QUANTITIES (LENGTH: nqtot)
    7058!    Each entry is accessible using "%" sign.
    7159!  |-------------+------------------------------------------------------+-------------+------------------------+
     
    7361!  |-------------+------------------------------------------------------+-------------+------------------------+
    7462!  | name        | Name (short)                                         | tname       |                        |
    75 !  | keys        | key/val pairs accessible with "getKey" routine       | /           |                        |
    7663!  | gen0Name    | Name of the 1st generation ancestor                  | /           |                        |
    7764!  | parent      | Name of the parent                                   | /           |                        |
    7865!  | longName    | Long name (with adv. scheme suffix) for outputs      | ttext       |                        |
    7966!  | type        | Type (so far: tracer or tag)                         | /           | tracer,tag             |
    80 !  | phase       | Phases list ("g"as / "l"iquid / "s"olid              |             | [g|l|s|r|b]            |
    81 !  |             |              "r"(cloud) / "b"lowing)                 | /           |                        |
     67!  | phase       | Phases list ("g"as / "l"iquid / "s"olid)             | /           | [g][l][s]              |
    8268!  | component   | Name(s) of the merged/cumulated section(s)           | /           | coma-separated names   |
    8369!  | iGeneration | Generation (>=1)                                     | /           |                        |
     
    8672!  | nqDescen    | Number of the descendants   (all generations)        | nqdesc      | 1:nqtot                |
    8773!  | nqChildren  | Number of childs            (1st generation only)    | nqfils      | 1:nqtot                |
     74!  | keys        | key/val pairs accessible with "getKey" routine       | /           |                        |
    8875!  | iadv        | Advection scheme number                              | iadv        | 1,2,10-20(exc.15,19),30|
     76!  | isAdvected  | advected tracers flag (.TRUE. if iadv >= 0)          | /           | nqtrue  .TRUE. values  |
     77!  | isInPhysics | tracers not extracted from the main table in physics | /           | nqtottr .TRUE. values  |
    8978!  | iso_iGroup  | Isotopes group index in isotopes(:)                  | /           | 1:nbIso                |
    9079!  | iso_iName   | Isotope  name  index in isotopes(iso_iGroup)%trac(:) | iso_indnum  | 1:niso                 |
     
    9887!  |  entry | length | Meaning                                          |    Former name     | Possible values |
    9988!  |-----------------+--------------------------------------------------+--------------------+-----------------+
    100 !  | name            | Name of the isotopes class (family)              |                    |                 |
     89!  | parent          | Parent tracer (isotopes family name)             |                    |                 |
    10190!  | keys   | niso   | Isotopes keys/values pairs list + number         |                    |                 |
    10291!  | trac   | ntiso  | Isotopes + tagging tracers list + number         | / | ntraciso       |                 |
    10392!  | zone   | nzone  | Geographic tagging zones   list + number         | / | ntraceurs_zone |                 |
    104 !  | phase  | nphas  | Phases                     list + number         |                    | [g|l|s|r|b] 1:5 |
     93!  | phase  | nphas  | Phases                     list + number         |                    | [g][l][s], 1:3 |
    10594!  | iqIsoPha        | Index in "qx"           = f(name(1:ntiso)),phas) | iqiso              | 1:nqtot         |
    10695!  | itZonIso        | Index in "trac(1:ntiso)"= f(zone, name(1:niso))  | index_trac         | 1:ntiso         |
    10796!  +-----------------+--------------------------------------------------+--------------------+-----------------+
    10897
    109 !------------------------------------------------------------------------------------------------------------------------------
    110    TYPE :: trac_type                                            !=== TYPE FOR A SINGLE TRACER NAMED "name"
    111      CHARACTER(LEN=maxlen) :: name        = ''                  !--- Name of the tracer
    112      TYPE(keys_type)       :: keys                              !--- <key>=<val> pairs vector (general container)
    113      CHARACTER(LEN=maxlen) :: gen0Name    = ''                  !--- First generation ancestor name
    114      CHARACTER(LEN=maxlen) :: parent      = ''                  !--- Parent name
    115      CHARACTER(LEN=maxlen) :: longName    = ''                  !--- Long name (with advection scheme suffix)
    116      CHARACTER(LEN=maxlen) :: type        = 'tracer'            !--- Type  (so far: 'tracer' / 'tag')
    117      CHARACTER(LEN=maxlen) :: phase       = 'g'                 !--- Phase ('g'as / 'l'iquid / 's'olid)
    118      CHARACTER(LEN=maxlen) :: component   = ''                  !--- Coma-separated list of components (Ex: lmdz,inca)
    119      INTEGER               :: iGeneration = -1                  !--- Generation number (>=0)
    120      INTEGER               :: iqParent    = 0                   !--- Parent index
    121      INTEGER,  ALLOCATABLE :: iqDescen(:)                       !--- Descendants index (in growing generation order)
    122      INTEGER               :: nqDescen    = 0                   !--- Number of descendants (all generations)
    123      INTEGER               :: nqChildren  = 0                   !--- Number of children  (first generation)
    124      INTEGER               :: iadv        = 10                  !--- Advection scheme used
    125      INTEGER               :: iso_iGroup  = 0                   !--- Isotopes group index in isotopes(:)
    126      INTEGER               :: iso_iName   = 0                   !--- Isotope  name  index in isotopes(iso_iGroup)%trac(:)
    127      INTEGER               :: iso_iZone   = 0                   !--- Isotope  zone  index in isotopes(iso_iGroup)%zone(:)
    128      INTEGER               :: iso_iPhase  = 0                   !--- Isotope  phase index in isotopes(iso_iGroup)%phase
    129    END TYPE trac_type
    130 !------------------------------------------------------------------------------------------------------------------------------
    131   TYPE :: isot_type                                             !=== TYPE FOR THE ISOTOPES FAMILY DESCENDING ON TRACER "name"
    132     CHARACTER(LEN=maxlen)              :: name                  !--- Isotopes family name (ex: H2O)
    133     TYPE(keys_type),       ALLOCATABLE :: keys(:)               !--- Isotopes keys/values pairs list     (length: niso)
    134     LOGICAL                            :: check=.FALSE.         !--- Flag for checking routines triggering
    135     CHARACTER(LEN=maxlen), ALLOCATABLE :: trac(:)               !--- Isotopes + tagging tracers list     (length: ntiso)
    136     CHARACTER(LEN=maxlen), ALLOCATABLE :: zone(:)               !--- Geographic tagging zones names list (length: nzone)
    137     CHARACTER(LEN=maxlen)              :: phase = 'g'           !--- Phases list: [g|l|s|r|b]            (length: nphas)
    138     INTEGER                            :: niso  = 0             !--- Number of isotopes, excluding tagging tracers
    139     INTEGER                            :: ntiso = 0             !--- Number of isotopes, including tagging tracers
    140     INTEGER                            :: nzone = 0             !--- Number of geographic tagging zones
    141     INTEGER                            :: nphas = 0             !--- Number of phases
    142     INTEGER,               ALLOCATABLE :: iqIsoPha(:,:)         !--- Idx in "tracers(1:nqtot)" = f(     name(1:ntiso) ,phas)
    143     INTEGER,               ALLOCATABLE :: itZonIso(:,:)         !--- Idx in "trac(1:ntiso)"    = f(zone,name(1:niso))
    144   END TYPE isot_type
    145 !------------------------------------------------------------------------------------------------------------------------------
    146   INTERFACE isoSelect; MODULE PROCEDURE isoSelectByIndex, isoSelectByName; END INTERFACE isoSelect
    147 !------------------------------------------------------------------------------------------------------------------------------
    148 
    149    !=== THRESHOLDS FOR WATER
    15098   REAL, PARAMETER :: min_qParent = 1.e-30, min_qMass = 1.e-18, min_ratio = 1.e-16 ! MVals et CRisi
    15199
    152100   !=== DIMENSIONS OF THE TRACERS TABLES AND OTHER SCALAR VARIABLES
    153    INTEGER,               SAVE :: nqtot,   &                    !--- Tracers nb in dynamics (incl. higher moments + H2O)
    154                                   nbtr,    &                    !--- Tracers nb in physics  (excl. higher moments + H2O)
    155                                   nqo,     &                    !--- Number of water phases
     101   INTEGER,               SAVE :: nqtot,  &                     !--- Tracers nb in dynamics (incl. higher moments + H2O)
     102                                  nbtr,   &                     !--- Tracers nb in physics  (excl. higher moments + H2O)
     103                                  nqo,    &                     !--- Number of water phases
    156104                                  nqtottr, &                    !--- Number of tracers passed to phytrac (TO BE DELETED ?)
    157105                                  nqCO2                         !--- Number of tracers of CO2  (ThL)
    158    CHARACTER(LEN=maxlen), SAVE :: type_trac                     !--- Keyword for tracers type(s)
    159 
    160    !=== NUMBER AND LIST OF DEFINED ISOTOPES FAMILIES
    161    INTEGER,               SAVE              :: nbIso            !--- Number of defined isotopes classes
    162    CHARACTER(LEN=maxlen), SAVE, ALLOCATABLE :: isoFamilies(:)   !--- Generation 0 tracer name for each isotopes family (nbIso)
    163 
    164    !=== QUANTITIES RELATED TO THE CURRENTLY SELECTED ISOTOPES CLASS (USUALLY H2O)
    165    TYPE(isot_type),       SAVE, POINTER :: isotope              !--- Selected isotopes database (=isotopes(ixIso))
    166    TYPE(keys_type),       SAVE, POINTER :: isoKeys(:)           !--- Database to get isotopes keys using "getKey"       (niso)
    167    CHARACTER(LEN=maxlen), SAVE, POINTER :: isoName(:),      &   !--- Isotopes list including tagging tracers, no phase (ntiso)
    168                                            isoZone(:),      &   !--- Geographic tagging zones list                     (nzone)
    169                                            isoPhas              !--- Used phases names ([g|l|s|r|b])                   (nphas)
    170    INTEGER,               SAVE, POINTER :: itZonIso(:,:),   &   !--- Idx "it" in isoName(1:niso) = f(tagging idx, isotope idx)
    171                                            iqIsoPha(:,:)        !--- Idx "iq" in qx              = f(isotope idx,   phase idx)
    172    INTEGER,               SAVE          :: ixIso,           &   !--- Idx in "isoFamilies" of currently selectd class
    173                                            niso,            &   !--- Number of isotopes
    174                                            ntiso,           &   !--- Number of isotopes + tagging tracers
    175                                            nzone,           &   !--- Number of tagging zones
    176                                            nphas                !--- Number of phases
    177    LOGICAL,               SAVE          :: isoCheck             !--- Isotopes checking routines triggering flag
     106   CHARACTER(LEN=maxlen), SAVE :: type_trac                     !--- Keyword for tracers type
    178107
    179108   !=== VARIABLES FOR INCA
    180    INTEGER, DIMENSION(:), SAVE, ALLOCATABLE :: &
    181                     conv_flg, pbl_flg                           !--- Convection / boundary layer activation (nbtr)
    182 
    183    !=== TRACERS/ISOTOPES DESCRIPTORS: EFFECTIVE STORAGE (LOCAL DERIVED TYPES)
    184    TYPE(trac_type), SAVE, ALLOCATABLE, TARGET ::  tracers(:)
    185    TYPE(isot_type), SAVE, ALLOCATABLE, TARGET :: isotopes(:)
     109   INTEGER,               SAVE, ALLOCATABLE :: conv_flg(:), &   !--- Convection     activation ; needed for INCA        (nbtr)
     110                                                pbl_flg(:)      !--- Boundary layer activation ; needed for INCA        (nbtr)
    186111
    187112CONTAINS
     
    189114SUBROUTINE init_infotrac
    190115   USE control_mod, ONLY: planet_type
    191 #ifdef CPP_IOIPSL
    192     USE IOIPSL, ONLY: getin
    193 #else
    194     USE ioipsl_getincom, only: getin
    195 #endif
    196 #ifdef CPP_PARA
    197    USE parallel_lmdz, ONLY: is_master
    198 #endif
    199116#ifdef REPROBUS
    200    USE CHEM_REP, ONLY: Init_chem_rep_trac
     117   USE CHEM_REP,    ONLY: Init_chem_rep_trac
    201118#endif
    202119   IMPLICIT NONE
     
    225142!------------------------------------------------------------------------------------------------------------------------------
    226143! Local variables
    227    INTEGER, ALLOCATABLE :: hadv(:), vadv(:), itmp(:)                 !--- Horizontal/vertical transport scheme number
     144   INTEGER, ALLOCATABLE :: hadv(:), vadv(:)                          !--- Horizontal/vertical transport scheme number
    228145#ifdef INCA
    229146   INTEGER, ALLOCATABLE :: had (:), hadv_inca(:), conv_flg_inca(:), &!--- Variables specific to INCA
     
    232149   INTEGER :: nqINCA
    233150#endif
    234 #ifndef CPP_PARA
    235    LOGICAL               :: is_master=.TRUE.
    236 #endif
    237151   CHARACTER(LEN=2)      ::   suff(9)                                !--- Suffixes for schemes of order 3 or 4 (Prather)
    238152   CHARACTER(LEN=3)      :: descrq(30)                               !--- Advection scheme description tags
    239    CHARACTER(LEN=maxlen) :: msg1, texp, ttp, ky, nam, val            !--- Strings for messages and expanded tracers type
     153   CHARACTER(LEN=maxlen) :: msg1, texp, ttp                          !--- Strings for messages and expanded tracers type
    240154   INTEGER :: fType                                                  !--- Tracers description file type ; 0: none
    241155                                                                     !--- 1/2/3: "traceur.def"/"tracer.def"/"tracer_*.def"
    242156   INTEGER :: nqtrue                                                 !--- Tracers nb from tracer.def (no higher order moments)
    243157   INTEGER :: iad                                                    !--- Advection scheme number
    244    INTEGER :: iq, jq, it, nt, im, nm, ig                             !--- Indexes and temporary variables
    245    LOGICAL :: lerr, lInit
    246    TYPE(keys_type), ALLOCATABLE, TARGET :: tra(:)                    !--- Tracers  descriptor as in readTracFiles_mod
    247    TYPE(tisot),     ALLOCATABLE         :: iso(:)                    !--- Isotopes descriptor as in readTracFiles_mod
     158   INTEGER :: iq, jq, nt, im, nm                                     !--- Indexes and temporary variables
     159   LOGICAL :: lerr, ll
    248160   TYPE(trac_type), ALLOCATABLE, TARGET :: ttr(:)
    249    TYPE(trac_type), POINTER             :: t(:), t1
    250    TYPE(keys_type), POINTER             :: k(:)
    251    CHARACTER(LEN=maxlen),   ALLOCATABLE :: types_trac(:)             !--- Keywords for tracers type(s), parsed version
     161   TYPE(trac_type), POINTER             :: t1, t(:)
     162   CHARACTER(LEN=maxlen),   ALLOCATABLE :: types_trac(:)  !--- Keyword for tracers type(s), parsed version
     163
    252164   CHARACTER(LEN=*), PARAMETER :: modname="init_infotrac"
    253165!------------------------------------------------------------------------------------------------------------------------------
     
    259171   descrq(10:20) = ['VL1','VLP','FH1','FH2','VLH','   ','PPM','PPS','PPP','   ','SLP']
    260172   descrq(30)    =  'PRA'
    261 
    262    CALL msg('type_trac = "'//TRIM(type_trac)//'"', modname, is_master)
    263    IF(strCount(type_trac, '|', nt)) CALL abort_gcm(modname, 'Could''nt parse the "type_trac" string with delimiter "|"', 1)
    264    IF(nt >= 3) CALL abort_gcm(modname, 'you need to modify type_trac, this version is not supported by lmdz', 1)
    265    IF(strParse(type_trac, '|', types_trac, n=nt)) CALL abort_gcm(modname, "couldn't parse "//'"type_trac"', 1)
    266    IF(nt == 2) type_trac = types_trac(2) ! TO BE DELETED SOON
    267 
    268    lInit = .NOT.ALLOCATED(trac)
    269 
    270 !##############################################################################################################################
    271    IF(lInit .AND. is_master) THEN                                    !=== SKIPED IF ALREADY DONE
    272 !##############################################################################################################################
     173   
     174   CALL msg('type_trac = "'//TRIM(type_trac)//'"', modname)
     175
     176   lerr=strParse(type_trac, '|', types_trac, n=nt)
     177   IF (nt .GT. 1) THEN
     178      IF (nt .GT. 2) CALL abort_gcm(modname, 'you need to modify type_trac, this version is not supported by lmdz', 1)
     179      if (nt .EQ. 2) type_trac=types_trac(2)
     180   ENDIF
     181
     182
     183   
    273184   !--- MESSAGE ABOUT THE CHOSEN CONFIGURATION
    274185   msg1 = 'For type_trac = "'//TRIM(type_trac)//'":'
     
    298209#endif
    299210   END SELECT
    300 !##############################################################################################################################
    301    END IF
    302 !##############################################################################################################################
    303 
    304 !==============================================================================================================================
    305 ! 0) DETERMINE THE TYPE OF THE INPUT TRACERS DESCRIPTION FILE AND READ IT ; TRANSFER THE NEEDED QUANTITIES TO LOCAL "tracers".
    306 !==============================================================================================================================
    307    texp = type_trac                                                            !=== EXPANDED (WITH "|" SEPARATOR) "type_trac"
     211
     212   nqCO2 = COUNT( [type_trac == 'inco', type_trac == 'co2i'] )
     213
     214!==============================================================================================================================
     215! 1) Get the numbers of: true (first order only) tracers "nqtrue", water tracers "nqo" (vapor/liquid/solid)
     216!==============================================================================================================================
     217   texp = type_trac                                                  !=== EXPANDED VERSION OF "type_trac", WITH "|" SEPARATOR
    308218   IF(texp == 'inco') texp = 'co2i|inca'
    309219   IF(texp /= 'lmdz') texp = 'lmdz|'//TRIM(texp)
    310    IF(testTracersFiles(modname, texp, fType, lInit.AND.is_master)) CALL abort_gcm(modname, 'problem with tracers file(s)',1)
     220
     221   !=== DETERMINE THE TYPE OF THE INPUT TRACERS DESCRIPTION FILE
     222   IF(testTracersFiles(modname, texp, fType, .TRUE.)) CALL abort_gcm(modname, 'problem with tracers file(s)',1)
    311223   ttp = type_trac; IF(fType /= 1) ttp = texp
    312    !---------------------------------------------------------------------------------------------------------------------------
    313    IF(fType == 0) CALL abort_gcm(modname, 'Missing "traceur.def", "tracer.def" or "tracer_<keyword>.def tracers file.',1)
    314    !---------------------------------------------------------------------------------------------------------------------------
    315    IF(fType == 1 .AND. ANY(['inca', 'inco'] == type_trac) .AND. lInit) &       !=== FOUND OLD STYLE INCA "traceur.def"
    316       CALL abort_gcm(modname, 'retro-compatibility with old-style INCA traceur.def files has been disabled.', 1)
    317    !---------------------------------------------------------------------------------------------------------------------------
    318 
    319 !##############################################################################################################################
    320    IF(lInit) THEN
    321       IF(readTracersFiles(ttp, tra, type_trac == 'repr')) CALL abort_gcm(modname, 'problem with tracers file(s)',1)
    322    ELSE
    323       tra = trac
     224
     225   IF(readTracersFiles(ttp, lRepr=type_trac=='repr')) CALL abort_gcm(modname, 'problem with tracers file(s)',1)
     226   !---------------------------------------------------------------------------------------------------------------------------
     227   IF(fType == 0) CALL abort_gcm(modname, 'Missing tracers file: "traceur.def", "tracer.def" or "tracer_<keyword>.def file.',1)
     228   !---------------------------------------------------------------------------------------------------------------------------
     229   IF(fType == 1 .AND. ANY(['inca','inco']==type_trac)) THEN         !=== FOUND OLD STYLE INCA "traceur.def"
     230   !---------------------------------------------------------------------------------------------------------------------------
     231#ifdef INCA
     232      nqo = SIZE(tracers) - nqCO2
     233      CALL Init_chem_inca_trac(nqINCA)                               !--- Get nqINCA from INCA
     234      nbtr = nqINCA + nqCO2                                          !--- Number of tracers passed to phytrac
     235      nqtrue = nbtr + nqo                                            !--- Total number of "true" tracers
     236      IF(ALL([2,3] /= nqo)) CALL abort_gcm(modname, 'Only 2 or 3 water phases allowed ; found nqo='//TRIM(int2str(nqo)), 1)
     237      ALLOCATE(hadv(nqtrue), hadv_inca(nqINCA), conv_flg_inca(nqINCA), solsym_inca(nqINCA))
     238      ALLOCATE(vadv(nqtrue), vadv_inca(nqINCA),  pbl_flg_inca(nqINCA))
     239      CALL init_transport(solsym_inca, conv_flg_inca, pbl_flg_inca, hadv_inca, vadv_inca)
     240      ALLOCATE(ttr(nqtrue))
     241      ttr(1:nqo+nqCO2)                  = tracers
     242      ttr(1    :      nqo   )%component = 'lmdz'
     243      ttr(1+nqo:nqCO2+nqo   )%component = 'co2i'
     244      ttr(1+nqo+nqCO2:nqtrue)%component = 'inca'
     245      ttr(1+nqo      :nqtrue)%name      = [('CO2     ', iq=1, nqCO2), solsym_inca]
     246      ttr(1+nqo+nqCO2:nqtrue)%parent    = tran0
     247      ttr(1+nqo+nqCO2:nqtrue)%phase     = 'g'
     248      lerr = getKey('hadv', had, ky=tracers(:)%keys)
     249      lerr = getKey('vadv', vad, ky=tracers(:)%keys)
     250      hadv(1:nqo+nqCO2) = had(:); hadv(1+nqo+nqCO2:nqtrue) = hadv_inca
     251      vadv(1:nqo+nqCO2) = vad(:); vadv(1+nqo+nqCO2:nqtrue) = vadv_inca
     252      CALL MOVE_ALLOC(FROM=ttr, TO=tracers)
     253      DO iq = 1, nqtrue
     254         t1 => tracers(iq)
     255         CALL addKey('name',      t1%name,      t1%keys)
     256         CALL addKey('component', t1%component, t1%keys)
     257         CALL addKey('parent',    t1%parent,    t1%keys)
     258         CALL addKey('phase',     t1%phase,     t1%keys)
     259      END DO
     260      IF(setGeneration(tracers)) CALL abort_gcm(modname,'See above',1) !- SET FIELDS %iGeneration, %gen0Name
     261      DEALLOCATE(had, hadv_inca, vad, vadv_inca, conv_flg_inca, pbl_flg_inca, solsym_inca)
     262#endif
     263   !---------------------------------------------------------------------------------------------------------------------------
     264   ELSE                                                              !=== OTHER CASES (OLD OR NEW FORMAT, NO INCA MODULE)
     265   !---------------------------------------------------------------------------------------------------------------------------
     266      nqo    =        COUNT(delPhase(tracers(:)%name)     == 'H2O' &
     267                               .AND. tracers(:)%component == 'lmdz') !--- Number of water phases
     268      nqtrue = SIZE(tracers)                                         !--- Total number of "true" tracers
     269      nbtr   = nqtrue-COUNT(delPhase(tracers(:)%gen0Name) == 'H2O' &
     270                               .AND. tracers(:)%component == 'lmdz') !--- Number of tracers passed to phytrac
     271#ifdef INCA
     272      nqINCA = COUNT(tracers(:)%component == 'inca')
     273#endif
     274      lerr = getKey('hadv', hadv, ky=tracers(:)%keys)
     275      lerr = getKey('vadv', vadv, ky=tracers(:)%keys)
     276   !---------------------------------------------------------------------------------------------------------------------------
    324277   END IF
    325    CALL msg('No tracers description file(s) reading needed: already done', modname, .NOT.lInit.AND.is_master)
    326 !##############################################################################################################################
    327 
    328    !--- POPULATE SOME EXPLICIT (ACCESSIBLE THROUGH "%") KEYS OF THE LOCAL TRACERS DESCRIPTION DERIVED TYPE
    329    !    To be defined: iqParent, iq/nqDescen, nqChildren (in indexUpdate), longName, iso_i*, iadv (later)
    330    ALLOCATE(tracers(SIZE(tra)))
    331    DO iq = 1, SIZE(tra); t1 => tracers(iq)
    332       t1%keys = tra(iq)
    333       msg1 = '" for tracer nr. '//TRIM(int2str(iq))
    334       ky='name       '; IF(getKey(ky, t1%name,        iq, tra)) CALL abort_gcm(modname, 'No key "'//TRIM(ky)//TRIM(msg1), 1)
    335       msg1 = '" for "'//TRIM(t1%name)//'"'
    336       ky='gen0Name   '; IF(getKey(ky, t1%gen0Name,    iq, tra)) CALL abort_gcm(modname, 'No key "'//TRIM(ky)//TRIM(msg1), 1)
    337       ky='parent     '; IF(getKey(ky, t1%parent,      iq, tra)) CALL abort_gcm(modname, 'No key "'//TRIM(ky)//TRIM(msg1), 1)
    338       ky='type       '; IF(getKey(ky, t1%type,        iq, tra)) CALL abort_gcm(modname, 'No key "'//TRIM(ky)//TRIM(msg1), 1)
    339       ky='phase      '; IF(getKey(ky, t1%phase,       iq, tra)) CALL abort_gcm(modname, 'No key "'//TRIM(ky)//TRIM(msg1), 1)
    340       ky='component  '; IF(getKey(ky, t1%component,   iq, tra)) CALL abort_gcm(modname, 'No key "'//TRIM(ky)//TRIM(msg1), 1)
    341       ky='iGeneration'; IF(getKey(ky, t1%iGeneration, iq, tra)) CALL abort_gcm(modname, 'No key "'//TRIM(ky)//TRIM(msg1), 1)
    342    END DO
    343 
    344 !==============================================================================================================================
    345 ! 1) Get various numbers: "nqtrue" (first order only tracers), "nqo" (water phases), 'nbtr' (tracers passed to physics), etc.
    346 !==============================================================================================================================
    347    nqtrue = SIZE(tracers)                                                                               !--- "true" tracers
    348    nqo    =      COUNT(tracers(:)%component == 'lmdz' .AND. delPhase(tracers(:)%name)     == 'H2O')     !--- Water phases
    349    nbtr = nqtrue-COUNT(tracers(:)%component == 'lmdz' .AND. delPhase(tracers(:)%gen0Name) == 'H2O')     !--- Passed to phytrac
    350    nqCO2  =      COUNT( [type_trac == 'inco', type_trac == 'co2i'] )
    351 #ifdef INCA
    352    nqINCA =      COUNT(tracers(:)%component == 'inca')
    353 #endif
     278   !---------------------------------------------------------------------------------------------------------------------------
     279
    354280#ifdef REPROBUS
    355    CALL Init_chem_rep_trac(nbtr, nqo, tracers(:)%name)                         !--- Transfert the number of tracers to Reprobus
    356 #endif
    357 
     281   !--- Transfert the number of tracers to Reprobus
     282   CALL Init_chem_rep_trac(nbtr, nqo, tracers(:)%name)
     283
     284#endif
    358285!==============================================================================================================================
    359286! 2) Calculate nqtot, number of tracers needed (greater if advection schemes 20 or 30 have been chosen).
    360287!==============================================================================================================================
    361    IF(getKey('hadv', hadv, ky=tra)) CALL abort_gcm(modname, 'missing key "hadv"', 1)
    362    IF(getKey('vadv', vadv, ky=tra)) CALL abort_gcm(modname, 'missing key "vadv"', 1)
    363288   DO iq = 1, nqtrue
    364289      IF( hadv(iq)<20 .OR. (ANY(hadv(iq)==[20,30]) .AND. hadv(iq)==vadv(iq)) ) CYCLE
     
    378303
    379304!==============================================================================================================================
    380 ! 3) Determine the advection scheme choice for water and tracers "iadv" and the fields long name.
     305! 3) Determine the advection scheme choice for water and tracers "iadv" and the fields long name, isAdvected.
    381306!     iadv = 1    "LMDZ-specific humidity transport" (for H2O vapour)          LMV
    382307!     iadv = 2    backward                           (for H2O liquid)          BAK
     
    396321!==============================================================================================================================
    397322   ALLOCATE(ttr(nqtot))
    398    jq = nqtrue+1
     323   jq = nqtrue+1; tracers(:)%iadv = -1
    399324   DO iq = 1, nqtrue
    400325      t1 => tracers(iq)
     
    407332      IF(iad == -1) CALL abort_gcm(modname, msg1, 1)
    408333
    409       !--- SET FIELDS longName, iadv
     334      !--- SET FIELDS %longName, %iadv, %isAdvected, %isInPhysics
     335      t1%longName   = t1%name; IF(iad > 0) t1%longName=TRIM(t1%name)//descrq(iad)
    410336      t1%iadv       = iad
    411       t1%longName   = t1%name; IF(iad > 0) t1%longName=TRIM(t1%name)//descrq(iad)
     337      t1%isAdvected = iad >= 0
     338      t1%isInPhysics= delPhase(t1%gen0Name) /= 'H2O' &
     339                          .OR. t1%component /= 'lmdz' !=== OTHER EXCEPTIONS TO BE ADDED: CO2i, SURSATURATED WATER CLOUD...
    412340      ttr(iq)       = t1
    413341
     
    419347      ttr(jq+1:jq+nm)             = t1
    420348      ttr(jq+1:jq+nm)%name        = [ (TRIM(t1%name)    //'-'//TRIM(suff(im)), im=1, nm) ]
    421       ttr(jq+1:jq+nm)%gen0Name    = [ (TRIM(t1%name)    //'-'//TRIM(suff(im)), im=1, nm) ]
    422349      ttr(jq+1:jq+nm)%parent      = [ (TRIM(t1%parent)  //'-'//TRIM(suff(im)), im=1, nm) ]
    423350      ttr(jq+1:jq+nm)%longName    = [ (TRIM(t1%longName)//'-'//TRIM(suff(im)), im=1, nm) ]
    424351      ttr(jq+1:jq+nm)%iadv        = [ (-iad,    im=1, nm) ]
     352      ttr(jq+1:jq+nm)%isAdvected  = [ (.FALSE., im=1, nm) ]
    425353      jq = jq + nm
    426354   END DO
     
    428356   CALL MOVE_ALLOC(FROM=ttr, TO=tracers)
    429357
    430    !--- SET FIELDS iqParent, iqDescen, nqDescen, nqChildren
    431    IF(indexUpdate(tracers%keys)) CALL abort_gcm(modname, 'problem with tracers indices update', 1)
    432    k => tracers(:)%keys
    433    DO iq = 1, SIZE(tracers); t1 => tracers(iq); msg1 = '" for "'//TRIM(t1%name)//'"'
    434       ky='iqParent  '; IF(getKey(ky, t1%iqParent,   iq, k)) CALL abort_gcm(modname, 'missing key "'//TRIM(ky)//TRIM(msg1), 1)
    435       ky='iqDescen  '; IF(getKey(ky, t1%iqDescen,   iq, k)) CALL abort_gcm(modname, 'missing key "'//TRIM(ky)//TRIM(msg1), 1)
    436       ky='nqDescen  '; IF(getKey(ky, t1%nqDescen,   iq, k)) CALL abort_gcm(modname, 'missing key "'//TRIM(ky)//TRIM(msg1), 1)
    437       ky='nqChildren'; IF(getKey(ky, t1%nqChildren, iq, k)) CALL abort_gcm(modname, 'missing key "'//TRIM(ky)//TRIM(msg1), 1)
     358   !--- SET FIELDS %iqParent, %nqChildren, %iGeneration, %iqDescen, %nqDescen
     359   IF(indexUpdate(tracers)) CALL abort_gcm(modname, 'problem with tracers indices update', 1)
     360
     361   !=== TEST ADVECTION SCHEME
     362   DO iq=1,nqtot ; t1 => tracers(iq); iad = t1%iadv
     363
     364      !--- ONLY TESTED VALUES FOR TRACERS FOR NOW:               iadv = 14, 10 (and 0 for non-transported tracers)
     365      IF(ALL([10,14,0] /= iad)) &
     366         CALL abort_gcm(modname, 'Not tested for iadv='//TRIM(int2str(iad))//' ; 10 or 14 only are allowed !', 1)
     367
     368      !--- ONLY TESTED VALUES FOR PARENTS HAVING CHILDS FOR NOW: iadv = 14, 10 (PARENTS: TRACERS OF GENERATION 1)
     369      IF(ALL([10,14] /= iad) .AND. t1%iGeneration == 1 .AND. ANY(tracers(:)%iGeneration > 1)) &
     370         CALL abort_gcm(modname, 'iadv='//TRIM(int2str(iad))//' not implemented for parents ; 10 or 14 only are allowed !', 1)
     371
     372      !--- ONLY TESTED VALUES FOR CHILDS FOR NOW:                iadv = 10     (CHILDS:  TRACERS OF GENERATION GREATER THAN 1)
     373      IF(fmsg('WARNING ! iadv='//TRIM(int2str(iad))//' not implemented for childs. Setting iadv=10 for "'//TRIM(t1%name)//'"',&
     374         modname, iad /= 10 .AND. t1%iGeneration > 1)) t1%iadv = 10
     375
     376      !--- ONLY VALID SCHEME NUMBER FOR WATER VAPOUR:            iadv = 14
     377      ll = t1%name /= addPhase('H2O','g')
     378      IF(fmsg('WARNING ! iadv=14 is valid for water vapour only. Setting iadv=10 for "'//TRIM(t1%name)//'".', &
     379         modname, iad == 14 .AND. ll))                 t1%iadv = 10
    438380   END DO
    439381
    440    !=== TEST ADVECTION SCHEME
    441    DO iq = 1, nqtot ; t1 => tracers(iq)
    442       iad = t1%iadv
    443       ig  = t1%iGeneration
    444       nam = t1%name
    445       val = 'iadv='//TRIM(int2str(iad))
    446 
    447       !--- ONLY TESTED VALUES FOR TRACERS FOR NOW:               iadv = 14, 10 (and 0 for non-transported tracers)
    448       IF(ALL([10,14,0] /= iad)) CALL abort_gcm(modname, TRIM(val)//' has not been tested yet ; 10 or 14 only are allowed !', 1)
    449 
    450       !--- ONLY TESTED VALUES SO FAR FOR PARENTS HAVING CHILDREN: iadv = 14, 10 (PARENTS: TRACERS OF GENERATION 0)
    451       IF(ALL([10,14] /= iad) .AND. ig == 0 .AND. ANY(tracers(:)%parent==nam)) &
    452          CALL abort_gcm(modname, TRIM(val)//' is not implemented for parents ; 10 or 14 only are allowed !', 1)
    453 
    454       !--- ONLY TESTED VALUES SO FAR FOR DESCENDANTS (TRACERS OF GENERATION > 0): iadv = 10 ; WATER VAPOUR: iadv = 14
    455       lerr = iad /= 10 .AND. ig > 0;                     IF(lerr) tracers(iq)%iadv = 10
    456       CALL msg('WARNING! '//TRIM(val)//  ' not implemented for children. Setting iadv=10 for "'//TRIM(nam)//'"', modname, lerr)
    457       lerr = iad == 14 .AND. nam /= addPhase('H2O','g'); IF(lerr) tracers(iq)%iadv = 10
    458       CALL msg('WARNING! '//TRIM(val)//' is valid for water vapour only. Setting iadv=10 for "'//TRIM(nam)//'"', modname, lerr)
    459    END DO
    460 
    461    !=== DETERMINE ISOTOPES RELATED PARAMETERS ; DEFINE THE EXPLICIT KEYS iso_i*
    462    IF(processIsotopes(tracers%keys, iso)) CALL abort_gcm(modname, 'problem while processing isotopes parameters', 1)
    463 
    464    !--- POPULATE SOME EXPLICIT (ACCESSIBLE THROUGH "%") KEYS OF THE LOCAL ISOTOPES DESCRIPTION DERIVED TYPE
    465    nbIso = SIZE(iso)
    466    ALLOCATE(isotopes(nbIso))
    467    IF(nbIso /= 0) THEN
    468       k => tracers(:)%keys
    469       IF(getKey('iso_iGroup', itmp, ky=k)) CALL abort_gcm(modname, 'missing key "iso_iGroup"', 1); tracers%iso_iGroup=itmp
    470       IF(getKey('iso_iName',  itmp, ky=k)) CALL abort_gcm(modname, 'missing key "iso_iName"',  1); tracers%iso_iName =itmp
    471       IF(getKey('iso_iZone',  itmp, ky=k)) CALL abort_gcm(modname, 'missing key "iso_iZone"',  1); tracers%iso_iZone =itmp
    472       IF(getKey('iso_iPhas',  itmp, ky=k)) CALL abort_gcm(modname, 'missing key "iso_iPhas"',  1); tracers%iso_iPhase=itmp
    473       isotopes(:)%name  = iso(:)%name                           !--- Isotopes family name (ex: H2O)
    474       isotopes(:)%phase = iso(:)%phase                          !--- Phases list: [g][l][s]              (length: nphas)
    475       isotopes(:)%niso  = iso(:)%niso                           !--- Number of isotopes, excluding tagging tracers
    476       isotopes(:)%ntiso = iso(:)%ntiso                          !--- Number of isotopes, including tagging tracers
    477       isotopes(:)%nzone = iso(:)%nzone                          !--- Number of geographic tagging zones
    478       isotopes(:)%nphas = iso(:)%nphas                          !--- Number of phases
    479       isotopes(:)%check = .FALSE.                               !--- Flag for checking routines triggering
    480       CALL getin('ok_iso_verif', isotopes(:)%check)
    481       DO it = 1, nbIso
    482          isotopes(it)%keys     = iso(it)%keys                   !--- Isotopes keys/values pairs list     (length: niso)
    483          isotopes(it)%trac     = iso(it)%trac                   !--- Isotopes + tagging tracers list     (length: ntiso)
    484          isotopes(it)%zone     = iso(it)%zone                   !--- Geographic tagging zones names list (length: nzone)
    485          isotopes(it)%iqIsoPha = iso(it)%iqIsoPha(:,:)          !--- Idx in "tracers(1:nqtot)" = f(name(1:ntiso)),phas)
    486          isotopes(it)%itZonIso = iso(it)%itZonIso(:,:)          !--- Idx in "tracers(1:ntiso)" = f(  zone,name(1:niso))
    487       END DO
    488       IF(isoSelect(1, .TRUE.)) CALL abort_gcm(modname, "Can't select the first isotopes family", 1)
    489       IF(.NOT.isoSelect('H2O', .TRUE.)) iH2O = ixIso
    490    END IF
    491    isoFamilies = isotopes(:)%name
     382   !=== READ PHYSICAL PARAMETERS FOR ISOTOPES ; DONE HERE BECAUSE dynetat0 AND iniacademic NEED "tnat" AND "alpha_ideal"
     383   niso = 0; nzone = 0; nphas = nqo; ntiso = 0; isoCheck = .FALSE.
     384   IF(processIsotopes()) CALL abort_gcm(modname, 'problem when processing isotopes parameters', 1)
    492385
    493386   !--- Convection / boundary layer activation for all tracers
    494    IF(.NOT.ALLOCATED(conv_flg)) ALLOCATE(conv_flg(nbtr)); conv_flg(1:nbtr) = 1
    495    IF(.NOT.ALLOCATED( pbl_flg)) ALLOCATE( pbl_flg(nbtr));  pbl_flg(1:nbtr) = 1
     387   ALLOCATE(conv_flg(nbtr)); conv_flg(1:nbtr) = 1
     388   ALLOCATE( pbl_flg(nbtr));  pbl_flg(1:nbtr) = 1
    496389
    497390   !--- Note: nqtottr can differ from nbtr when nmom/=0
     
    501394
    502395   !=== DISPLAY THE RESULTS
    503    IF(.NOT.is_master) RETURN
    504396   CALL msg('nqo    = '//TRIM(int2str(nqo)),    modname)
    505397   CALL msg('nbtr   = '//TRIM(int2str(nbtr)),   modname)
     
    513405#endif
    514406   t => tracers
    515    CALL msg('Information stored in '//TRIM(modname)//': ', modname)
    516    IF(dispTable('isssssssiiiiiiiii', ['iq  ', 'name', 'lNam', 'g0Nm', 'prnt', 'type', 'phas', 'comp',      &
    517                               'iAdv', 'iGen', 'iqPr', 'nqDe', 'nqCh', 'iGrp', 'iNam', 'iZon', 'iPha'],     &
    518       cat(t%name, t%longName, t%gen0Name, t%parent, t%type, t%phase, t%component),                         &
     407   CALL msg('Information stored in infotrac :', modname)
     408
     409   IF(dispTable('isssssssssiiiiiiiii', ['iq  ', 'name', 'lNam', 'g0Nm', 'prnt', 'type', 'phas', 'comp',    &
     410                'isPh', 'isAd', 'iadv', 'iGen', 'iqPr', 'nqDe', 'nqCh', 'iGrp', 'iNam', 'iZon', 'iPha'],   &
     411      cat(t%name, t%longName, t%gen0Name, t%parent, t%type, t%phase, t%component, bool2str(t%isInPhysics), &
     412                                                                                  bool2str(t%isAdvected)), &
    519413      cat([(iq, iq=1, nqtot)], t%iadv, t%iGeneration, t%iqParent, t%nqDescen, t%nqChildren, t%iso_iGroup,  &
    520414                  t%iso_iName, t%iso_iZone, t%iso_iPhase), nColMax=maxTableWidth, nHead=2, sub=modname))   &
    521415      CALL abort_gcm(modname, "problem with the tracers table content", 1)
    522    CALL msg('No isotopes identified.', modname, nbIso == 0)
    523    IF(nbIso == 0) RETURN
    524    DO it = 1, nbIso
    525       IF(isoSelect(it, .TRUE.)) CALL abort_gcm(modname, 'Problem when selecting isotopes class', 1)
    526       CALL msg('For isotopes family "'//TRIM(isoFamilies(it))//'":', modname)
    527       CALL msg('  isoName = '//strStack(isotope%trac),  modname)
    528       CALL msg('  isoZone = '//strStack(isotope%zone),  modname)
    529       CALL msg('  isoPhas = '//    TRIM(isotope%phase), modname)
    530    END DO
    531    IF(isoSelect('H2O', .TRUE.)) THEN
    532       IF(isoSelect(1,  .TRUE.)) CALL abort_gcm(modname, 'Problem when selecting isotopes class', 1)
     416   IF(niso > 0) THEN
     417      CALL msg('Where, for isotopes family "'//TRIM(isotope%parent)//'":', modname)
     418      CALL msg('  isoKeys%name = '//strStack(isoKeys%name), modname)
     419      CALL msg('  isoName = '//strStack(isoName),      modname)
     420      CALL msg('  isoZone = '//strStack(isoZone),      modname)
     421      CALL msg('  isoPhas = '//TRIM(isoPhas),          modname)
    533422   ELSE
    534       iH2O = ixIso
     423      CALL msg('No isotopes identified.', modname)
    535424   END IF
    536    IF(ALLOCATED(isotope%keys(ixIso)%key)) &
    537      CALL msg('  isoKeys('//TRIM(int2str(ixIso))//') = '//TRIM(strStack(isotope%keys(ixIso)%key)), modname)
     425   CALL msg('end', modname)
    538426
    539427END SUBROUTINE init_infotrac
    540428
    541 !==============================================================================================================================
    542 LOGICAL FUNCTION isoSelectByName(iClass, lVerbose) RESULT(lerr)
    543    IMPLICIT NONE
    544    CHARACTER(LEN=*),  INTENT(IN) :: iClass
    545    LOGICAL, OPTIONAL, INTENT(IN) :: lVerbose
    546    INTEGER :: iIso
    547    LOGICAL :: lV
    548    lV = .FALSE.; IF(PRESENT(lVerbose)) lV = lVerbose
    549    iIso = strIdx(isotopes(:)%name, iClass)
    550    lerr = iIso == 0
    551    IF(lerr) THEN
    552       niso = 0; ntiso = 0; nzone = 0; nphas = 0; isoCheck=.FALSE.
    553       CALL msg('no isotope family named "'//TRIM(iClass)//'"', ll=lV)
    554       RETURN
    555    END IF
    556    lerr = isoSelectByIndex(iIso, lV)
    557 END FUNCTION isoSelectByName
    558 !==============================================================================================================================
    559 LOGICAL FUNCTION isoSelectByIndex(iIso, lVerbose) RESULT(lerr)
    560    IMPLICIT NONE
    561    INTEGER,           INTENT(IN) :: iIso
    562    LOGICAL, OPTIONAL, INTENT(IN) :: lVerbose
    563    LOGICAL :: lV
    564    lV = .FALSE.;  IF(PRESENT(lVerbose)) lV = lVerbose
    565    lerr = .FALSE.
    566    IF(iIso == ixIso) RETURN                                          !--- Nothing to do if the index is already OK
    567    lerr = iIso<=0 .OR. iIso>SIZE(isotopes)
    568    CALL msg('Inconsistent isotopes family index '//TRIM(int2str(iIso))//': should be > 0 and <= '&
    569           //TRIM(int2str(SIZE(isotopes)))//'"', ll = lerr .AND. lV)
    570    IF(lerr) RETURN
    571    ixIso = iIso                                                      !--- Update currently selected family index
    572    isotope  => isotopes(ixIso)                                       !--- Select corresponding component
    573    isoKeys  => isotope%keys;     niso     = isotope%niso
    574    isoName  => isotope%trac;     ntiso    = isotope%ntiso
    575    isoZone  => isotope%zone;     nzone    = isotope%nzone
    576    isoPhas  => isotope%phase;    nphas    = isotope%nphas
    577    itZonIso => isotope%itZonIso; isoCheck = isotope%check
    578    iqIsoPha => isotope%iqIsoPha
    579 END FUNCTION isoSelectByIndex
    580 !==============================================================================================================================
    581 
    582429END MODULE infotrac
  • LMDZ6/trunk/libf/dyn3d_common/iso_verif_dyn.F

    r5183 r5190  
    6464        function iso_verif_aberrant_nostop
    6565     :           (x,iso,q,err_msg)
    66 #ifdef CPP_IOIPSL
    67         USE IOIPSL, ONLY: getin
    68 #else
    69         USE ioipsl_getincom, ONLY: getin
    70 #endif
    71         USE iso_params_mod, ONLY: tnat_HDO
     66        USE infotrac, ONLY: isoName, getKey
    7267        implicit none
    7368       
     
    7974        ! locals
    8075        real qmin,deltaD
    81         real deltaDmax,deltaDmin
     76        real deltaDmax,deltaDmin,tnat
    8277        parameter (qmin=1e-11)
    8378        parameter (deltaDmax=200.0,deltaDmin=-999.9)
    84         LOGICAL       :: ltnat1
    85         LOGICAL, SAVE :: lFirst=.TRUE.
    86         REAL,    SAVE :: tnat
    8779
    8880        ! output
    8981        integer iso_verif_aberrant_nostop
    9082
    91         IF(lFirst) THEN
    92            ltnat1 = .TRUE.; CALL getin('tnateq1', ltnat1)
    93            tnat = tnat_HDO; IF(ltnat1) tnat = 1.0
    94            lFirst = .FALSE.
    95         END IF
    9683        iso_verif_aberrant_nostop=0
    9784
    9885        ! verifier que HDO est raisonable
    9986         if (q.gt.qmin) then
     87             IF(getKey('tnat', tnat, isoName(iso))) THEN
     88                  err_msg = 'Missing isotopic parameter "tnat"'
     89                  iso_verif_aberrant_nostop=1
     90                  RETURN
     91             END IF
    10092             deltaD=(x/q/tnat-1)*1000
    10193             if ((deltaD.gt.deltaDmax).or.(deltaD.lt.deltaDmin)) then
  • LMDZ6/trunk/libf/dyn3dmem/check_isotopes_loc.F90

    r5183 r5190  
    33   USE strings_mod, ONLY: maxlen, msg, strIdx, strStack, int2str, real2str
    44   USE infotrac,    ONLY: nqtot, niso, nphas, isotope, isoCheck, iqIsoPha, isoSelect, &
    5                           ntiso, iH2O, nzone, tracers, isoName,  itZonIso
    6    USE iso_params_mod, ONLY: tnat_H216O, tnat_H217O, tnat_H218O, tnat_HDO, tnat_HTO
    7 #ifdef CPP_IOIPSL
    8    USE ioipsl,          ONLY: getin
    9 #else
    10    USE ioipsl_getincom, ONLY: getin
    11 #endif
     5                          ntiso, iH2O, nzone, tracers, isoName,  itZonIso, getKey
    126   IMPLICIT NONE
    137   include "dimensions.h"
     
    2721                      deltaDmin =-999.0, &
    2822                      ridicule  = 1e-12
    29    INTEGER, SAVE :: iso_eau, iso_HDO, iso_O18, iso_O17, iso_HTO
    30 !$OMP THREADPRIVATE(iso_eau, iso_HDO, iso_O18, iso_O17, iso_HTO)
    31    LOGICAL       :: ltnat1
     23   INTEGER, SAVE :: iso_eau, iso_HDO, iso_O18, & !--- OpenMP shared variables
     24                             iso_O17, iso_HTO
    3225   LOGICAL, SAVE :: first=.TRUE.
     26   LOGICAL, PARAMETER :: tnat1=.TRUE.
    3327!$OMP THREADPRIVATE(first)
    3428
     
    3832   IF(niso == 0)        RETURN                   !--- No isotopes => finished
    3933   IF(first) THEN
    40       ltnat1 = .TRUE.; CALL getin('tnateq1', ltnat1)
    41       iso_eau = strIdx(isoName,'H216O'); IF(iso_eau /= 0) tnat(iso_eau) = tnat_H216O
    42       iso_O17 = strIdx(isoName,'H217O'); IF(iso_O17 /= 0) tnat(iso_O17) = tnat_H217O
    43       iso_O18 = strIdx(isoName,'H218O'); IF(iso_O18 /= 0) tnat(iso_O18) = tnat_H218O
    44       iso_HDO = strIdx(isoName,'HDO');   IF(iso_HDO /= 0) tnat(iso_HDO) = tnat_HDO
    45       iso_HTO = strIdx(isoName,'HTO');   IF(iso_HTO /= 0) tnat(iso_HTO) = tnat_HTO
    46       IF(ltnat1) tnat(:) = 1.0
     34!$OMP MASTER
     35      iso_eau = strIdx(isoName,'H216O')
     36      iso_HDO = strIdx(isoName,'HDO')
     37      iso_O18 = strIdx(isoName,'H218O')
     38      iso_O17 = strIdx(isoName,'H217O')
     39      iso_HTO = strIdx(isoName,'HTO')
     40      if (tnat1) then
     41              tnat(:)=1.0
     42      else
     43         IF(getKey('tnat', tnat)) CALL abort_gcm(modname, 'missing isotopic parameter', 1)
     44      endif
     45!$OMP END MASTER
     46!$OMP BARRIER
    4747      first = .FALSE.
    4848   END IF
  • LMDZ6/trunk/libf/dyn3dmem/dynetat0_loc.F90

    r5183 r5190  
    77!-------------------------------------------------------------------------------
    88  USE parallel_lmdz
    9   USE infotrac,    ONLY: nqtot, tracers, niso, iqIsoPha, iH2O, isoName, &
    10                          new2oldH2O, newHNO3, oldHNO3
     9  USE infotrac,    ONLY: nqtot, tracers, niso, iqIsoPha, iH2O, isoName
    1110  USE strings_mod, ONLY: maxlen, msg, strStack, real2str, int2str, strIdx
    1211  USE netcdf,      ONLY: NF90_OPEN,  NF90_NOWRITE, NF90_INQUIRE_DIMENSION, NF90_INQ_VARID, &
    1312                         NF90_CLOSE, NF90_GET_VAR, NF90_INQUIRE_VARIABLE,  NF90_NoErr
     13  USE readTracFiles_mod, ONLY: new2oldH2O, newHNO3, oldHNO3, getKey
    1414  USE control_mod, ONLY: planet_type
    1515  USE assert_eq_m, ONLY: assert_eq
     
    2020  USE temps_mod, ONLY: annee_ref, day_ini, day_ref, itau_dyn, start_time
    2121  USE ener_mod, ONLY: etot0,ptot0,ztot0,stot0,ang0
    22 #ifdef CPP_IOIPSL
    23   USE IOIPSL,   ONLY: getin
    24 #else
    25   USE ioipsl_getincom, ONLY: getin
    26 #endif
    27   USE iso_params_mod   ! tnat_* and alpha_ideal_*
    2822
    2923  IMPLICIT NONE
     
    5347  REAL,             ALLOCATABLE :: ucov_glo(:,:),    q_glo(:,:), phis_glo(:)
    5448  REAL,             ALLOCATABLE :: teta_glo(:,:)
    55   LOGICAL :: lSkip, ll, ltnat1
     49  LOGICAL :: lSkip, ll
     50  LOGICAL,PARAMETER :: tnat1=.TRUE.
    5651!-------------------------------------------------------------------------------
    5752  modname="dynetat0_loc"
     
    163158  ll = NF90_INQ_VARID(fID, 'HNO3tot', vID) /= NF90_NoErr                                 !--- DETECT OLD REPRO start.nc FILE
    164159#endif
    165   ltnat1 = .TRUE.; CALL getin('tnateq1', ltnat1)
    166160  DO iq=1,nqtot
    167161    var = tracers(iq)%name
     
    179173    !--------------------------------------------------------------------------------------------------------------------------
    180174    ELSE IF(NF90_INQ_VARID(fID, oldVar, vID) == NF90_NoErr) THEN                         !=== TRY WITH ALTERNATE NAME
    181       CALL msg('Missing tracer <'//TRIM(var)//'> => initialized to <'//TRIM(oldVar)//'>', modname)
     175      CALL msg('Tracer <'//TRIM(var)//'> is missing => initialized to <'//TRIM(oldVar)//'>', modname)
    182176      CALL get_var2(oldVar, q_glo); q(ijb_u:ije_u,:,iq)=q_glo(ijb_u:ije_u,:)
    183177    !--------------------------------------------------------------------------------------------------------------------------
     
    187181      iqParent = tracers(iq)%iqParent
    188182      IF(tracers(iq)%iso_iZone == 0) THEN
    189          IF(ltnat1) THEN
    190             tnat = 1.0
    191             alpha_ideal = 1.0
    192             CALL msg(' !!!  Beware: alpha_ideal put to 1  !!!', modname)
    193          ELSE
    194             SELECT CASE(isoName(iName))
    195               CASE('H216O'); tnat = tnat_H216O; alpha_ideal = alpha_ideal_H216O
    196               CASE('H217O'); tnat = tnat_H217O; alpha_ideal = alpha_ideal_H217O
    197               CASE('H218O'); tnat = tnat_H218O; alpha_ideal = alpha_ideal_H218O
    198               CASE('HDO');   tnat = tnat_HDO;   alpha_ideal = alpha_ideal_HDO
    199               CASE('HTO');   tnat = tnat_HTO;   alpha_ideal = alpha_ideal_HTO
    200               CASE DEFAULT; CALL abort_gcm(TRIM(modname),'unknown isotope "'//TRIM(isoName(iName))//'" ; check tracer.def file',1)
    201             END SELECT
    202          END IF
    203          CALL msg('Missing tracer <'//TRIM(var)//'> => initialized with a simplified Rayleigh distillation law.', modname)
     183         if (tnat1) then
     184                 tnat=1.0
     185                 alpha_ideal=1.0
     186                 write(*,*) 'attention dans dynetat0: les alpha_ideal sont a 1'
     187         else
     188          IF(getKey('tnat', tnat, isoName(iName)) .OR. getKey('alpha', alpha_ideal, isoName(iName))) &
     189            CALL abort_gcm(TRIM(modname), 'missing isotopic parameters', 1)
     190         endif
     191         CALL msg('Tracer <'//TRIM(var)//'> is missing => initialized with a simplified Rayleigh distillation law.', modname)
    204192         q(ijb_u:ije_u,:,iq) = q(ijb_u:ije_u,:,iqParent)*tnat*(q(ijb_u:ije_u,:,iqParent)/30.e-3)**(alpha_ideal-1.)
    205193         ! Camille 9 mars 2023: point de vigilence: initialisation incohérente
    206194         ! avec celle de xt_ancien dans la physiq.
    207195      ELSE
    208          CALL msg('Missing tracer <'//TRIM(var)//'> => initialized to its parent isotope concentration.', modname)
     196         CALL msg('Tracer <'//TRIM(var)//'> is missing => initialized to its parent isotope concentration.', modname)
    209197         ! Camille 9 mars 2023: attention!! seuls les tags qui correspondent à
    210198         ! izone=izone_init (définie dans isotrac_mod) sont initialisés comme
     
    220208    !--------------------------------------------------------------------------------------------------------------------------
    221209    ELSE                                                                                 !=== MISSING: SET TO 0
    222       CALL msg('missing tracer <'//TRIM(var)//'> => initialized to zero', modname)
     210      CALL msg('Tracer <'//TRIM(var)//'> is missing => initialized to zero', modname)
    223211      q(ijb_u:ije_u,:,iq)=0.
    224212    !--------------------------------------------------------------------------------------------------------------------------
  • LMDZ6/trunk/libf/dyn3dmem/iniacademic_loc.F90

    r5183 r5190  
    55
    66  USE filtreg_mod, ONLY: inifilr
    7   USE infotrac,    ONLY: nqtot, niso, iqIsoPha, tracers, addPhase, isoName
     7  USE infotrac,    ONLY: nqtot, niso, iqIsoPha, tracers, getKey, isoName
    88  USE control_mod, ONLY: day_step,planet_type
    99  use exner_hyb_m, only: exner_hyb
     
    2222  USE temps_mod, ONLY: annee_ref, day_ini, day_ref
    2323  USE ener_mod, ONLY: etot0,ptot0,ztot0,stot0,ang0
     24  USE readTracFiles_mod, ONLY: addPhase
    2425  use netcdf, only : NF90_NOWRITE,NF90_OPEN,NF90_NOERR,NF90_INQ_VARID
    2526  use netcdf, only : NF90_CLOSE, NF90_GET_VAR
    26   USE iso_params_mod   ! tnat_* and alpha_ideal_*
    2727
    2828
     
    8585
    8686  REAL zdtvr, tnat, alpha_ideal
    87   LOGICAL :: ltnat1
     87  LOGICAL,PARAMETER :: tnat1=.true.
    8888 
    8989  character(len=*),parameter :: modname="iniacademic"
     
    311311        ! bulk initialization of tracers
    312312        if (planet_type=="earth") then
    313            ltnat1 = .TRUE.; CALL getin('tnateq1', ltnat1)
    314313           ! Earth: first two tracers will be water
    315314           do iq=1,nqtot
     
    325324              iqParent = tracers(iq)%iqParent
    326325              IF(tracers(iq)%iso_iZone == 0) THEN
    327                  IF(ltnat1) THEN
    328                     tnat = 1.0
    329                     alpha_ideal = 1.0
    330                     WRITE(lunout, *) 'In '//TRIM(modname)//': !!!  Beware: alpha_ideal put to 1  !!!'
    331                  ELSE
    332                     SELECT CASE(isoName(iName))
    333                       CASE('H216O'); tnat = tnat_H216O; alpha_ideal = alpha_ideal_H216O
    334                       CASE('H217O'); tnat = tnat_H217O; alpha_ideal = alpha_ideal_H217O
    335                       CASE('H218O'); tnat = tnat_H218O; alpha_ideal = alpha_ideal_H218O
    336                       CASE('HDO');   tnat = tnat_HDO;   alpha_ideal = alpha_ideal_HDO
    337                       CASE('HTO');   tnat = tnat_HTO;   alpha_ideal = alpha_ideal_HTO
    338                       CASE DEFAULT
    339                          CALL abort_gcm(TRIM(modname),'unknown isotope "'//TRIM(isoName(iName))//'" ; check tracer.def file',1)
    340                     END SELECT
    341                  END IF
     326                 if (tnat1) then
     327                         tnat=1.0
     328                         alpha_ideal=1.0
     329                         write(*,*) 'Attention dans iniacademic: alpha_ideal=1'
     330                 else
     331                    IF(getKey('tnat', tnat, isoName(iName)) .OR. getKey('alpha', alpha_ideal, isoName(iName))) &
     332                    CALL abort_gcm(TRIM(modname), 'missing isotopic parameters', 1)
     333                 endif
    342334                 q(ijb_u:ije_u,:,iq) = q(ijb_u:ije_u,:,iqParent)*tnat*(q(ijb_u:ije_u,:,iqParent)/30.e-3)**(alpha_ideal-1.)
    343335              ELSE !IF(tracers(iq)%iso_iZone == 0) THEN
  • LMDZ6/trunk/libf/dyn3dmem/qminimum_loc.F

    r5183 r5190  
    44      SUBROUTINE qminimum_loc( q,nqtot,deltap )
    55      USE parallel_lmdz
    6       USE infotrac, ONLY: niso, ntiso, iqIsoPha, tracers, addPhase,
     6      USE infotrac, ONLY: niso, ntiso, iqIsoPha, tracers,
    77     &                    isoCheck, min_qParent
    88      USE strings_mod, ONLY: strIdx
     9      USE readTracFiles_mod, ONLY: addPhase
    910      IMPLICIT none
    1011c
  • LMDZ6/trunk/libf/dynphy_lonlat/calfis.F

    r5183 r5190  
    2929c    Auteur :  P. Le Van, F. Hourdin
    3030c   .........
    31       USE infotrac_phy, ONLY: nqtot, tracers
     31      USE infotrac, ONLY: nqtot, tracers
    3232      USE control_mod, ONLY: planet_type, nsplit_phys
    3333#ifdef CPP_PHYS
  • LMDZ6/trunk/libf/dynphy_lonlat/calfis_loc.F

    r5183 r5190  
    4747      USE Times
    4848#endif
    49       USE infotrac_phy, ONLY: nqtot, tracers
     49      USE infotrac, ONLY: nqtot, tracers
    5050      USE control_mod, ONLY: planet_type, nsplit_phys
    5151#ifdef CPP_PHYS
  • LMDZ6/trunk/libf/misc/readTracFiles_mod.f90

    r5184 r5190  
    1010
    1111  PUBLIC :: maxlen                                              !--- PARAMETER FOR CASUAL STRING LENGTH
    12   PUBLIC :: keys_type, tracers, setGeneration, indexUpdate      !--- TRACERS  DESCRIPTION DATABASE + ASSOCIATED TOOLS
     12  PUBLIC :: trac_type, tracers, setGeneration, indexUpdate      !--- TRACERS  DESCRIPTION DATABASE + ASSOCIATED TOOLS
    1313  PUBLIC :: testTracersFiles, readTracersFiles                  !--- TRACERS FILES READING ROUTINES
    1414  PUBLIC :: getKeysDBase, setKeysDBase                          !--- TOOLS TO GET/SET THE DATABASE (tracers & isotopes)
    1515  PUBLIC :: addTracer, delTracer                                !--- ADD/REMOVE A TRACER FROM
    16   PUBLIC :: addKey,    delKey,    getKey                        !--- TOOLS TO SET/DEL/GET KEYS FROM/TO  tracers & isotopes
     16  PUBLIC :: addKey,    delKey,    getKey,    keys_type          !--- TOOLS TO SET/DEL/GET KEYS FROM/TO  tracers & isotopes
    1717  PUBLIC :: addPhase,  delPhase,  getPhase,  getiPhase,  &      !--- FUNCTIONS RELATED TO THE PHASES
    1818   nphases, old_phases, phases_sep, known_phases, phases_names  !--- + ASSOCIATED VARIABLES
     
    3535  PUBLIC :: itZonIso                                            !--- Idx IN isoName(1:niso) = f(tagging idx, isotope idx)
    3636  PUBLIC :: iqIsoPha                                            !--- Idx IN qx(1:nqtot)     = f(isotope idx,   phase idx)
    37   PUBLIC :: iqWIsoPha                                           !--- SAME AS iqIsoPha BUT ISOTOPES LIST STARTS WITH PARENT TRAC
     37  PUBLIC :: iqWIsoPha                                           !--- Idx IN qx(1:nqtot)     = f(isotope idx,   phase idx) but with normal water first
    3838  PUBLIC :: isoCheck                                            !--- FLAG TO RUN ISOTOPES CHECKING ROUTINES
    3939
     
    4141!------------------------------------------------------------------------------------------------------------------------------
    4242  TYPE :: keys_type                                             !=== TYPE FOR A SET OF KEYS ASSOCIATED TO AN ELEMENT
     43    CHARACTER(LEN=maxlen)              :: name                  !--- Tracer name
    4344    CHARACTER(LEN=maxlen), ALLOCATABLE :: key(:)                !--- Keys string list
    4445    CHARACTER(LEN=maxlen), ALLOCATABLE :: val(:)                !--- Corresponding values string list
    4546  END TYPE keys_type
    4647!------------------------------------------------------------------------------------------------------------------------------
    47   TYPE :: isot_type                                             !=== TYPE FOR AN ISOTOPES FAMILY DESCENDING ON TRACER "name"
    48     CHARACTER(LEN=maxlen)              :: name                  !--- Isotopes family name (example: H2O)
     48  TYPE :: trac_type                                             !=== TYPE FOR A SINGLE TRACER NAMED "name"
     49    CHARACTER(LEN=maxlen) :: name        = ''                   !--- Name of the tracer
     50    TYPE(keys_type)       :: keys                               !--- <key>=<val> pairs vector
     51    CHARACTER(LEN=maxlen) :: gen0Name    = ''                   !--- First generation ancestor name
     52    CHARACTER(LEN=maxlen) :: parent      = ''                   !--- Parent name
     53    CHARACTER(LEN=maxlen) :: longName    = ''                   !--- Long name (with advection scheme suffix)
     54    CHARACTER(LEN=maxlen) :: type        = 'tracer'             !--- Type  (so far: 'tracer' / 'tag')
     55    CHARACTER(LEN=maxlen) :: phase       = 'g'                  !--- Phase ('g'as / 'l'iquid / 's'olid)
     56    CHARACTER(LEN=maxlen) :: component   = ''                   !--- Coma-separated list of components (Ex: lmdz,inca)
     57    INTEGER               :: iGeneration = -1                   !--- Generation number (>=0)
     58    INTEGER               :: iqParent    = 0                    !--- Parent index
     59    INTEGER,  ALLOCATABLE :: iqDescen(:)                        !--- Descendants index (in growing generation order)
     60    INTEGER               :: nqDescen    = 0                    !--- Number of descendants (all generations)
     61    INTEGER               :: nqChildren  = 0                    !--- Number of children  (first generation)
     62    INTEGER               :: iadv        = 10                   !--- Advection scheme used
     63    LOGICAL               :: isAdvected  = .FALSE.              !--- "true" tracers: iadv > 0.   COUNT(isAdvected )=nqtrue
     64    LOGICAL               :: isInPhysics = .TRUE.               !--- "true" tracers: in tr_seri. COUNT(isInPhysics)=nqtottr
     65    INTEGER               :: iso_iGroup  = 0                    !--- Isotopes group index in isotopes(:)
     66    INTEGER               :: iso_iName   = 0                    !--- Isotope  name  index in isotopes(iso_iGroup)%trac(:)
     67    INTEGER               :: iso_iZone   = 0                    !--- Isotope  zone  index in isotopes(iso_iGroup)%zone(:)
     68    INTEGER               :: iso_iPhase  = 0                    !--- Isotope  phase index in isotopes(iso_iGroup)%phase
     69  END TYPE trac_type
     70!------------------------------------------------------------------------------------------------------------------------------
     71  TYPE :: isot_type                                             !=== TYPE FOR AN ISOTOPES FAMILY DESCENDING ON TRACER "parent"
     72    CHARACTER(LEN=maxlen)              :: parent                !--- Isotopes family name (parent tracer name ; ex: H2O)
    4973    TYPE(keys_type),       ALLOCATABLE :: keys(:)               !--- Isotopes keys/values pairs list     (length: niso)
    5074    LOGICAL                            :: check=.FALSE.         !--- Flag for checking routines triggering
     
    6488  TYPE :: dataBase_type                                         !=== TYPE FOR TRACERS SECTION
    6589    CHARACTER(LEN=maxlen) :: name                               !--- Section name
    66     TYPE(keys_type), ALLOCATABLE :: trac(:)                     !--- Tracers descriptors
     90    TYPE(trac_type), ALLOCATABLE :: trac(:)                     !--- Tracers descriptors
    6791  END TYPE dataBase_type
    6892!------------------------------------------------------------------------------------------------------------------------------
     
    115139
    116140  !=== TRACERS AND ISOTOPES DESCRIPTORS, USED BY getKey
    117   TYPE(keys_type), ALLOCATABLE, TARGET, SAVE ::  tracers(:)
     141  TYPE(trac_type), ALLOCATABLE, TARGET, SAVE ::  tracers(:)
    118142  TYPE(isot_type), ALLOCATABLE, TARGET, SAVE :: isotopes(:)
    119143
     
    169193!------------------------------------------------------------------------------------------------------------------------------
    170194  CHARACTER(LEN=*),                               INTENT(IN)  :: type_trac     !--- List of components used
    171   TYPE(keys_type), ALLOCATABLE, TARGET, OPTIONAL, INTENT(OUT) :: tracs(:)      !--- Tracers descriptor for external storage
     195  TYPE(trac_type), ALLOCATABLE, TARGET, OPTIONAL, INTENT(OUT) :: tracs(:)      !--- Tracers descriptor for external storage
    172196  LOGICAL,                              OPTIONAL, INTENT(IN)  :: lRepr         !--- Activate the HNO3 exceptions for REPROBUS
    173197  CHARACTER(LEN=maxlen),  ALLOCATABLE :: s(:), sections(:), trac_files(:)
    174   CHARACTER(LEN=maxlen) :: str, fname, tname, pname, cname, ttype
     198  CHARACTER(LEN=maxlen) :: str, fname, tname, pname, cname
    175199  INTEGER               :: nsec, ierr, it, ntrac, ns, ip, ix, fType
    176200  INTEGER, ALLOCATABLE  :: iGen(:)
     
    208232        CALL msg('This file is for air tracers only',           modname, ns == 3 .AND. it == 1)
    209233        CALL msg('This files specifies the transporting fluid', modname, ns == 4 .AND. it == 1)
    210         k => tracers(it)
     234        k => tracers(it)%keys
    211235
    212236        !=== NAME OF THE TRACER
     
    214238        ix = strIdx(oldHNO3, s(3))
    215239        IF(ix /= 0 .AND. lRep) tname = newHNO3(ix)                   !--- Exception for HNO3 (REPROBUS ONLY)
    216         CALL addKey('name', tname, tracers)                          !--- Set the name of the tracer
    217 !        tracers(it)%name = tname                                     !--- Copy tracers names in keys components
     240        tracers(it)%name = tname                                     !--- Set the name of the tracer
     241        CALL addKey('name', tname, k)                                !--- Set the name of the tracer
     242        tracers(it)%keys%name = tname                                !--- Copy tracers names in keys components
    218243
    219244        !=== NAME OF THE COMPONENT
    220245        cname = type_trac                                            !--- Name of the model component
    221246        IF(ANY([(addPhase('H2O', ip), ip = 1, nphases)] == tname)) cname = 'lmdz'
    222         CALL addKey('component', cname, tracers)                     !--- Set the name of the model component
     247        tracers(it)%component = cname                                !--- Set component
     248        CALL addKey('component', cname, k)                           !--- Set the name of the model component
    223249
    224250        !=== NAME OF THE PARENT
     
    229255          IF(ix /= 0 .AND. lRep) pname = newHNO3(ix)                 !--- Exception for HNO3 (REPROBUS ONLY)
    230256        END IF
    231         CALL addKey('parent', pname, tracers)                        !--- Set the parent name
     257        tracers(it)%parent = pname                                   !--- Set the parent name
     258        CALL addKey('parent', pname, k)
    232259
    233260        !=== PHASE AND ADVECTION SCHEMES NUMBERS
    234         CALL addKey('phase', known_phases(ip:ip), tracers)           !--- Set the phase of the tracer (default: "g"azeous)
     261        tracers(it)%phase = known_phases(ip:ip)                      !--- Set the phase of the tracer (default: "g"azeous)
     262        CALL addKey('phase', known_phases(ip:ip), k)                 !--- Set the phase of the tracer (default: "g"azeous)
    235263        CALL addKey('hadv', s(1),  k)                                !--- Set the horizontal advection schemes number
    236264        CALL addKey('vadv', s(2),  k)                                !--- Set the vertical   advection schemes number
     
    238266      CLOSE(90)
    239267      lerr = setGeneration(tracers); IF(lerr) RETURN                 !--- Set iGeneration and gen0Name
    240       lerr = getKey('iGeneration', iGen, tracers(:))                 !--- Generation number
     268      lerr = getKey('iGeneration', iGen, tracers(:)%keys)            !--- Generation number
     269      WHERE(iGen == 2) tracers(:)%type = 'tag'                       !--- Set type:      'tracer' or 'tag'
    241270      DO it = 1, ntrac
    242         ttype = 'tracer'; IF(iGen(it) == 2) ttype = 'tag'
    243         CALL addKey('type', ttype, tracers(it))                 !--- Set the type of tracer
     271        CALL addKey('type', tracers(it)%type, tracers(it)%keys)      !--- Set the type of tracer
    244272      END DO
    245273      lerr = checkTracers(tracers, fname, fname); IF(lerr) RETURN    !--- Detect orphans and check phases
     
    263291  END IF
    264292  lerr = indexUpdate(tracers); IF(lerr) RETURN                       !--- Set iqParent, iqDescen, nqDescen, nqChildren
    265   IF(PRESENT(tracs)) tracs = tracers
     293  IF(PRESENT(tracs)) CALL MOVE_ALLOC(FROM=tracers, TO=tracs)
    266294END FUNCTION readTracersFiles
    267295!==============================================================================================================================
     
    311339! Purpose: Read the sections "snames(is)" (pipe-separated list) from each "fnames(is)"
    312340!   file and create the corresponding tracers set descriptors in the database "dBase":
    313 ! * dBase(id)%name           : section name
    314 ! * dBase(id)%trac(:)        : tracers descriptor (the key "name" of tracers(i) is the name of the ith tracer)
    315 ! * dBase(id)%trac(it)%key(:): names  of keys associated to tracer dBase(id)%trac(it)%name
    316 ! * dBase(id)%trac(it)%val(:): values of keys associated to tracer dBase(id)%trac(it)%name
     341! * dBase(id)%name                : section name
     342! * dBase(id)%trac(:)%name        : tracers names
     343! * dBase(id)%trac(it)%keys%key(:): names  of keys associated to tracer dBase(id)%trac(it)%name
     344! * dBase(id)%trac(it)%keys%val(:): values of keys associated to tracer dBase(id)%trac(it)%name
    317345!------------------------------------------------------------------------------------------------------------------------------
    318346  CHARACTER(LEN=*), INTENT(IN)  :: fnames(:)                         !--- Files names
     
    367395  ndb= SIZE(dBase)                                                   !--- Current number of sections in the database
    368396  IF(PRESENT(defName)) THEN                                          !--- Add default values to all the tracers
    369     DO idb=n0,ndb                                                    !--- and remove the virtual tracer "defName"
    370        lerr = addDefault(dBase(idb)%trac, defName); IF(lerr) RETURN
    371     END DO
     397    DO idb=n0,ndb; CALL addDefault(dBase(idb)%trac, defName); END DO !--- and remove the virtual tracer "defName"
    372398  END IF
    373399  ll = strParse(snam, '|', keys = sec)                               !--- Requested sections names
     
    382408!------------------------------------------------------------------------------------------------------------------------------
    383409  CHARACTER(LEN=maxlen), ALLOCATABLE ::  s(:), v(:)
    384   TYPE(keys_type),       ALLOCATABLE :: tt(:)
     410  TYPE(trac_type),       ALLOCATABLE :: tt(:)
     411  TYPE(trac_type)       :: tmp
    385412  CHARACTER(LEN=1024)   :: str, str2
    386413  CHARACTER(LEN=maxlen) :: secn
     
    418445      tt = dBase(ndb)%trac(:)
    419446      v(1) = s(1); s(1) = 'name'                                     !--- Convert "name" into a regular key
    420       dBase(ndb)%trac = [tt(:), keys_type(s(:), v(:))]
    421       DEALLOCATE(tt)
     447      tmp%name = v(1); tmp%keys = keys_type(v(1), s(:), v(:))        !--- Set %name and %keys
     448      dBase(ndb)%trac = [tt(:), tmp]
     449      DEALLOCATE(tt, tmp%keys%key, tmp%keys%val)
    422450    END IF
    423451  END DO
     
    432460
    433461!==============================================================================================================================
    434 LOGICAL FUNCTION addDefault(t, defName) RESULT(lerr)
     462SUBROUTINE addDefault(t, defName)
    435463!------------------------------------------------------------------------------------------------------------------------------
    436464! Purpose: Add the keys from virtual tracer named "defName" (if any) and remove this virtual tracer.
    437465!------------------------------------------------------------------------------------------------------------------------------
    438   TYPE(keys_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: t(:)
     466  TYPE(trac_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: t(:)
    439467  CHARACTER(LEN=*),                     INTENT(IN)    :: defName
    440468  INTEGER :: jd, it, k
    441   CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:)
    442   TYPE(keys_type),       ALLOCATABLE :: tt(:)
    443   lerr = getKey('name', tname, t(:)); IF(lerr) RETURN
    444   jd = strIdx(tname(:), defName)
     469  TYPE(keys_type), POINTER :: ky
     470  TYPE(trac_type), ALLOCATABLE :: tt(:)
     471  jd = strIdx(t(:)%name, defName)
    445472  IF(jd == 0) RETURN
    446   DO k = 1, SIZE(t(jd)%key)                                          !--- Loop on the keys of the tracer named "defName"
    447 !   CALL addKey(t(jd)%key(k), t(jd)%val(k), t(:), .FALSE.)           !--- Add key to all the tracers (no overwriting)
    448     DO it = 1, SIZE(t); CALL addKey(t(jd)%key(k), t(jd)%val(k), t(it), .FALSE.); END DO
     473  ky => t(jd)%keys
     474  DO k = 1, SIZE(ky%key)                                             !--- Loop on the keys of the tracer named "defName"
     475!   CALL addKey(ky%key(k), ky%val(k), t(:)%keys, .FALSE.)            !--- Add key to all the tracers (no overwriting)
     476    DO it = 1, SIZE(t); CALL addKey(ky%key(k), ky%val(k), t(it)%keys, .FALSE.); END DO
    449477  END DO
    450478  tt = [t(1:jd-1),t(jd+1:SIZE(t))]; CALL MOVE_ALLOC(FROM=tt, TO=t)   !--- Remove the virtual tracer named "defName"
    451 END FUNCTION addDefault
    452 !==============================================================================================================================
    453 
    454 !==============================================================================================================================
    455 LOGICAL FUNCTION subDefault(t, defName, lSubLocal) RESULT(lerr)
     479END SUBROUTINE addDefault
     480!==============================================================================================================================
     481
     482!==============================================================================================================================
     483SUBROUTINE subDefault(t, defName, lSubLocal)
    456484!------------------------------------------------------------------------------------------------------------------------------
    457485! Purpose: Substitute the keys from virtual tracer named "defName" (if any) and remove this virtual tracer.
    458486!          Substitute the keys locally (for the current tracer) if the flag "lSubLocal" is .TRUE.
    459487!------------------------------------------------------------------------------------------------------------------------------
    460   TYPE(keys_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: t(:)
     488  TYPE(trac_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: t(:)
    461489  CHARACTER(LEN=*),                     INTENT(IN)    :: defName
    462490  LOGICAL,                              INTENT(IN)    :: lSubLocal
    463491  INTEGER :: i0, it, ik
    464   TYPE(keys_type),       ALLOCATABLE :: tt(:)
    465   CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:)
    466   lerr = getKey('name', tname, t(:)); IF(lerr) RETURN
    467   i0 = strIdx(tname(:), defName)
     492  TYPE(keys_type), POINTER     :: k0, ky
     493  TYPE(trac_type), ALLOCATABLE :: tt(:)
     494  i0 = strIdx(t(:)%name, defName)
    468495  IF(i0 == 0) RETURN
     496  k0 => t(i0)%keys
    469497  DO it = 1, SIZE(t); IF(it == i0) CYCLE                             !--- Loop on the tracers
     498    ky => t(it)%keys
    470499
    471500    !--- Substitute in the values of <key>=<val> pairs the keys defined in the virtual tracer "defName"
    472     DO ik = 1, SIZE(t(i0)%key); CALL strReplace(t(it)%val, t(i0)%key(ik), t(i0)%val(ik), .TRUE.); END DO
     501    DO ik = 1, SIZE(k0%key); CALL strReplace(ky%val, k0%key(ik), k0%val(ik), .TRUE.); END DO
    473502
    474503    IF(.NOT.lSubLocal) CYCLE
    475504    !--- Substitute in the values of <key>=<val> pairs the keys defined locally (in the current tracer)
    476     DO ik = 1, SIZE(t(it)%key); CALL strReplace(t(it)%val, t(it)%key(ik), t(it)%val(ik), .TRUE.); END DO
     505    DO ik = 1, SIZE(ky%key); CALL strReplace(ky%val, ky%key(ik), ky%val(ik), .TRUE.); END DO
    477506  END DO
    478507  tt = [t(1:i0-1),t(i0+1:SIZE(t))]; CALL MOVE_ALLOC(FROM=tt, TO=t)   !--- Remove the virtual tracer named "defName"
    479508
    480 END FUNCTION subDefault
     509END SUBROUTINE subDefault
    481510!==============================================================================================================================
    482511
     
    489518!        * Default values are provided for these keys because they are necessary.
    490519!------------------------------------------------------------------------------------------------------------------------------
    491   TYPE(keys_type), ALLOCATABLE, INTENT(INOUT) :: tr(:)                 !--- Tracer derived type vector
     520  TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: tr(:)                 !--- Tracer derived type vector
    492521  CHARACTER(LEN=*),             INTENT(IN)    :: sname                 !--- Current section name
    493522  CHARACTER(LEN=*), OPTIONAL,   INTENT(IN)    :: fname                 !--- Tracers description file name
    494   TYPE(keys_type),       ALLOCATABLE :: ttr(:)
     523  TYPE(trac_type),       ALLOCATABLE :: ttr(:)
    495524  CHARACTER(LEN=maxlen), ALLOCATABLE :: ta(:), pa(:), tname(:), parent(:), dType(:)
    496525  CHARACTER(LEN=maxlen) :: msg1, modname
     
    500529  lerr = .FALSE.
    501530  nt = SIZE(tr)
    502   lerr = getKey('name',   tname,  tr(:));                 IF(lerr) RETURN
    503   lerr = getKey('parent', parent, tr(:), def = tran0);    IF(lerr) RETURN
    504   lerr = getKey('type',   dType,  tr(:), def = 'tracer'); IF(lerr) RETURN
     531  lerr = getKey('name',   tname,  tr(:)%keys);                 IF(lerr) RETURN
     532  lerr = getKey('parent', parent, tr(:)%keys, def = tran0);    IF(lerr) RETURN
     533  lerr = getKey('type',   dType,  tr(:)%keys, def = 'tracer'); IF(lerr) RETURN
    505534  nq = 0
    506535  !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     
    508537  !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    509538    !--- Extract useful keys: parent name, type, component name
    510     CALL addKey('component', sname,  tr(it))
     539    tr(it)%component = sname
     540    CALL addKey('component', sname,  tr(it)%keys)
    511541
    512542    !--- Determine the number of tracers and parents ; coherence checking
     
    535565    DO ipr = 1, npr                                                  !--- Loop on parents list elts
    536566      DO itr = 1, ntr                                                !--- Loop on tracers list elts
    537         ttr(iq)%key  = tr(it)%key
    538         ttr(iq)%val  = tr(it)%val
    539         CALL addKey('name',    ta(itr), ttr(iq))
    540         CALL addKey('parent',  pa(ipr), ttr(iq))
    541         CALL addKey('type',  dType(it), ttr(iq))
    542         CALL addKey('component', sname, ttr(iq))
     567        ttr(iq)%keys%name = TRIM(ta(itr))
     568        ttr(iq)%keys%key  = tr(it)%keys%key
     569        ttr(iq)%keys%val  = tr(it)%keys%val
     570        ttr(iq)%name      = TRIM(ta(itr))
     571        ttr(iq)%parent    = TRIM(pa(ipr))
     572        ttr(iq)%type      = dType(it)
     573        ttr(iq)%component = sname
     574        CALL addKey('name',      ta(itr),   ttr(iq)%keys)
     575        CALL addKey('parent',    pa(ipr),   ttr(iq)%keys)
     576        CALL addKey('type',      dType(it), ttr(iq)%keys)
     577        CALL addKey('component', sname,     ttr(iq)%keys)
    543578        iq = iq + 1
    544579      END DO
     
    562597!          Check also for orphan tracers (tracers without parent).
    563598!------------------------------------------------------------------------------------------------------------------------------
    564   TYPE(keys_type),     INTENT(INOUT) :: tr(:)                        !--- Tracer derived type vector
     599  TYPE(trac_type),     INTENT(INOUT) :: tr(:)                        !--- Tracer derived type vector
    565600  INTEGER                            :: iq, jq, ig
    566601  CHARACTER(LEN=maxlen), ALLOCATABLE :: parent(:), tname(:)
     
    568603  CHARACTER(LEN=maxlen) :: modname
    569604  modname = 'setGeneration'
    570   lerr = getKey('name',   tname,  ky=tr(:)); IF(lerr) RETURN
    571   lerr = getKey('parent', parent, ky=tr(:)); IF(lerr) RETURN
     605  lerr = getKey('name',   tname,  ky=tr(:)%keys); IF(lerr) RETURN
     606  lerr = getKey('parent', parent, ky=tr(:)%keys); IF(lerr) RETURN
    572607  DO iq = 1, SIZE(tr)
    573608    jq = iq; ig = 0
     
    578613      ig = ig + 1
    579614    END DO
    580     CALL addKey('iGeneration',    ig,  tr(iq))
    581     CALL addKey('gen0Name', tname(jq), tr(iq))
     615    tr(iq)%gen0Name = tname(jq)
     616    tr(iq)%iGeneration = ig
     617    CALL addKey('iGeneration',   ig,  tr(iq)%keys)
     618    CALL addKey('gen0Name', tname(jq), tr(iq)%keys)
    582619  END DO
    583620END FUNCTION setGeneration
     
    592629!   * check wether the phases are known or not (elements of "known_phases")
    593630!------------------------------------------------------------------------------------------------------------------------------
    594   TYPE(keys_type),            INTENT(IN) :: tr(:)                    !--- Tracers description vector
     631  TYPE(trac_type),            INTENT(IN) :: tr(:)                    !--- Tracer derived type vector
    595632  CHARACTER(LEN=*),           INTENT(IN) :: sname                    !--- Section name
    596633  CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: fname                    !--- File name
     
    607644  mesg = 'Check section "'//TRIM(sname)//'"'
    608645  IF(PRESENT(fname)) mesg=TRIM(mesg)//' in file "'//TRIM(fname)//'"'
    609   lerr = getKey('iGeneration', iGen, tr(:));                    IF(lerr) RETURN
    610   lerr = getKey('name',       tname, tr(:));                    IF(lerr) RETURN
     646  lerr = getKey('iGeneration', iGen, tr(:)%keys);               IF(lerr) RETURN
     647  lerr = getKey('name',       tname, tr(:)%keys);               IF(lerr) RETURN
    611648
    612649  !=== CHECK FOR ORPHAN TRACERS
     
    615652  !=== CHECK PHASES
    616653  DO iq = 1, nq; IF(iGen(iq) /= 0) CYCLE                             !--- Generation O only is checked
    617     IF(getKey(['phases','phase '], pha, iq, tr(:), lDisp=.FALSE.)) pha = 'g'   !--- Phase
     654    IF(getKey(['phases','phase '], pha, iq, tr(:)%keys, lDisp=.FALSE.)) pha = 'g'   !--- Phase
    618655    np = LEN_TRIM(pha); bp(iq)=' '
    619656    DO ip = 1, np; p = pha(ip:ip); IF(INDEX(known_phases, p) == 0) bp(iq) = TRIM(bp(iq))//p; END DO
     
    630667! Purpose: Make sure that tracers are not repeated.
    631668!------------------------------------------------------------------------------------------------------------------------------
    632   TYPE(keys_type),            INTENT(IN) :: tr(:)                    !--- Tracers description vector
     669  TYPE(trac_type),            INTENT(IN) :: tr(:)                    !--- Tracer derived type vector
    633670  CHARACTER(LEN=*),           INTENT(IN) :: sname                    !--- Section name
    634671  CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: fname                    !--- File name
     
    647684  nq=SIZE(tr,DIM=1); lerr=.FALSE.                                    !--- Number of lines ; error flag
    648685  tdup(:) = ''
    649   lerr = getKey('name',       tname, tr); IF(lerr) RETURN
    650   lerr = getKey('type',       dType, tr); IF(lerr) RETURN
    651   lerr = getKey('iGeneration', iGen, tr); IF(lerr) RETURN
     686  lerr = getKey('name',       tname, tr%keys); IF(lerr) RETURN
     687  lerr = getKey('type',       dType, tr%keys); IF(lerr) RETURN
     688  lerr = getKey('iGeneration', iGen, tr%keys); IF(lerr) RETURN
    652689  DO iq = 1, nq
    653690    IF(dType(iq) == 'tag') CYCLE                                     !--- Tags can be repeated
     
    661698        DO k = 1, nq
    662699          IF(.NOT.ll(k)) CYCLE                                       !--- Skip tracers different from current one
    663           IF(getKey(['phases','phase '], phase, k, tr, lDisp=.FALSE.)) phase='g'!--- Get current phases
     700          IF(getKey(['phases','phase '], phase, k, tr%keys, lDisp=.FALSE.)) phase='g'!--- Get current phases
    664701          IF(INDEX(phase, p) /= 0) np = np + 1                       !--- One more appearance of current tracer with phase "p"
    665702        END DO
     
    681718! Purpose: Expand the phases in the tracers descriptor "tr". Phases are not repeated for a tracer, thanks to "checkUnique".
    682719!------------------------------------------------------------------------------------------------------------------------------
    683   TYPE(keys_type), ALLOCATABLE, INTENT(INOUT) :: tr(:)               !--- Tracers description vector
    684 !------------------------------------------------------------------------------------------------------------------------------
    685   TYPE(keys_type),       ALLOCATABLE :: ttr(:)
     720  TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: tr(:)               !--- Tracer derived type vector
     721!------------------------------------------------------------------------------------------------------------------------------
     722  TYPE(trac_type),       ALLOCATABLE :: ttr(:)
    686723  INTEGER,               ALLOCATABLE ::  i0(:), iGen(:)
    687724  CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:), gen0N(:), phase(:), parents(:), dType(:)
     
    695732  nq = SIZE(tr, DIM=1)
    696733  nt = 0
    697   lerr = getKey('name',       tname, tr); IF(lerr) RETURN            !--- Names of the tracers
    698   lerr = getKey('gen0Name',   gen0N, tr); IF(lerr) RETURN            !--- Names of the tracers of first generation
    699   lerr = getKey('iGeneration', iGen, tr); IF(lerr) RETURN            !--- Generation number
    700   lerr = getKey('phases',     phase, tr); IF(lerr) RETURN            !--- Phases names
    701   lerr = getKey('parent',   parents, tr); IF(lerr) RETURN            !--- Parents names
    702   lerr = getKey('type',       dType, tr); IF(lerr) RETURN            !--- Tracers types ('tracer' or 'tag')
     734  lerr = getKey('name',       tname, tr%keys); IF(lerr) RETURN       !--- Names of the tracers
     735  lerr = getKey('gen0Name',   gen0N, tr%keys); IF(lerr) RETURN       !--- Names of the tracers of first generation
     736  lerr = getKey('iGeneration', iGen, tr%keys); IF(lerr) RETURN       !--- Generation number
     737  lerr = getKey('phases',     phase, tr%keys); IF(lerr) RETURN       !--- Phases names
     738  lerr = getKey('parent',   parents, tr%keys); IF(lerr) RETURN       !--- Parents names
     739  lerr = getKey('type',       dType, tr%keys); IF(lerr) RETURN       !--- Tracers types ('tracer' or 'tag')
    703740  DO iq = 1, nq                                                      !--- GET THE NUMBER OF TRACERS
    704741    IF(iGen(iq) /= 0) CYCLE                                          !--- Only deal with generation 0 tracers
     
    726763        IF(lTag) nam = TRIM(nam)//'_'//TRIM(tname(iq))               !--- <parent>_<name> for tags
    727764        ttr(it) = tr(iq)                                             !--- Same <key>=<val> pairs
    728         CALL addKey('name', nam, ttr(it))                            !--- Name with possibly phase suffix
    729         CALL addKey('phase', p,  ttr(it))                            !--- Single phase entry
     765        ttr(it)%name      = TRIM(nam)                                !--- Name with possibly phase suffix
     766        ttr(it)%keys%name = TRIM(nam)                                !--- Name inside the keys decriptor
     767        ttr(it)%phase     = p                                        !--- Single phase entry
     768        CALL addKey('name', nam, ttr(it)%keys)
     769        CALL addKey('phase', p,  ttr(it)%keys)
    730770        IF(lExt) THEN
    731771          parent = parents(iq); IF(iGen(iq) > 0) parent = addPhase(parent, p)
    732772          gen0Nm =   gen0N(iq); IF(iGen(iq) > 0) gen0Nm = addPhase(gen0Nm, p)
    733           CALL addKey('parent',   parent, ttr(it))
    734           CALL addKey('gen0Name', gen0Nm, ttr(it))
     773          ttr(it)%parent   = parent
     774          ttr(it)%gen0Name = gen0Nm
     775          CALL addKey('parent',   parent, ttr(it)%keys)
     776          CALL addKey('gen0Name', gen0Nm, ttr(it)%keys)
    735777        END IF
    736778        it = it+1
     
    740782  END DO
    741783  CALL MOVE_ALLOC(FROM=ttr, TO=tr)
    742   CALL delKey(['phases'], tr)                                        !--- Remove "phases" key, useless since "phase" is defined
     784  CALL delKey(['phases'],tr)                                         !--- Remove few keys entries
    743785
    744786END FUNCTION expandPhases
     
    755797!   TO BE ADDED IF NECESSARY: HIGHER MOMENTS AT THE END
    756798!------------------------------------------------------------------------------------------------------------------------------
    757   TYPE(keys_type), INTENT(INOUT) :: tr(:)                            !--- Tracers description vector
    758 !------------------------------------------------------------------------------------------------------------------------------
    759   TYPE(keys_type),       ALLOCATABLE :: tr2(:)
    760   INTEGER,               ALLOCATABLE :: iy(:), iz(:), iGen(:)
     799  TYPE(trac_type), INTENT(INOUT) :: tr(:)                            !--- Tracer derived type vector
     800!------------------------------------------------------------------------------------------------------------------------------
     801  TYPE(trac_type),       ALLOCATABLE :: tr2(:)
     802  INTEGER,               ALLOCATABLE :: iy(:), iz(:)
     803  INTEGER,               ALLOCATABLE ::  iGen(:)
    761804  CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:), gen0N(:)
    762805  INTEGER :: ig, ng, iq, jq, ip, nq, n, ix(SIZE(tr)), k
     
    764807!  tr2 is introduced in order to cope with a bug in gfortran 4.8.5 compiler
    765808!------------------------------------------------------------------------------------------------------------------------------
    766   lerr = getKey('iGeneration', iGen, tr); IF(lerr) RETURN            !--- Generation number
     809  lerr = getKey('iGeneration', iGen, tr%keys); IF(lerr) RETURN       !--- Generation number
    767810  nq = SIZE(tr)
    768811  DO ip = nphases, 1, -1
    769     lerr = getKey('name',     tname, tr); IF(lerr) RETURN            !--- Names of the tracers of first generation
     812    lerr = getKey('name',     tname, tr%keys); IF(lerr) RETURN       !--- Names of the tracers of first generation
    770813    iq = strIdx(tname, addPhase('H2O', ip))
    771814    IF(iq == 0) CYCLE
     
    783826    END DO
    784827  ELSE
    785     lerr = getKey('gen0Name', gen0N, tr); IF(lerr) RETURN            !--- Names of the tracers    iq = 1
     828    lerr = getKey('gen0Name',   gen0N, tr%keys); IF(lerr) RETURN     !--- Names of the tracers    iq = 1
    786829    DO jq = 1, nq                                                    !--- Loop on generation 0 tracers
    787830      IF(iGen(jq) /= 0) CYCLE                                        !--- Skip generations /= 0
     
    805848LOGICAL FUNCTION mergeTracers(sections, tr) RESULT(lerr)
    806849  TYPE(dataBase_type),  TARGET, INTENT(IN)  :: sections(:)
    807   TYPE(keys_type), ALLOCATABLE, INTENT(OUT) ::       tr(:)
    808   TYPE(keys_type), POINTER ::   t1(:),   t2(:)
     850  TYPE(trac_type), ALLOCATABLE, INTENT(OUT) ::       tr(:)
     851  TYPE(trac_type), POINTER ::   t1(:),   t2(:)
     852  TYPE(keys_type), POINTER ::   k1(:),   k2(:)
    809853  INTEGER,     ALLOCATABLE :: ixct(:), ixck(:)
    810854  INTEGER :: is, ik, ik1, ik2, nk2, i1, i2, nt2
     
    814858  lerr = .FALSE.
    815859  keys = ['parent     ', 'type       ', 'iGeneration']               !--- Mandatory keys
    816   t1 => sections(1)%trac(:)                                          !--- Alias: first tracers section
    817   lerr = getKey('name', n1, t1); IF(lerr) RETURN                     !--- Names of the tracers
     860  t1 => sections(1)%trac(:); k1 => t1(:)%keys                        !--- Alias: first tracers section, corresponding keys
     861  lerr = getKey('name', n1, k1); IF(lerr) RETURN                     !--- Names of the tracers
    818862  tr = t1
    819863  !----------------------------------------------------------------------------------------------------------------------------
     
    821865  !----------------------------------------------------------------------------------------------------------------------------
    822866    t2  => sections(is)%trac(:)                                      !--- Alias: current tracers section
    823     lerr = getKey('name', n2, t2); IF(lerr) RETURN                   !--- Names of the tracers
     867    k2  => t2(:)%keys
     868    lerr = getKey('name', n2, k2); IF(lerr) RETURN                   !--- Names of the tracers
    824869    nt2  = SIZE(t2(:), DIM=1)                                        !--- Number of tracers in section
    825870    ixct = strIdx(n1(:), n2(:))                                      !--- Indexes of common tracers
     
    829874    CALL msg(n1(PACK(ixct, MASK = ixct/=0)), modname, nmax=128)      !--- Display duplicates (the 128 first at most)
    830875    !--------------------------------------------------------------------------------------------------------------------------
    831     DO i2=1,nt2; tnam = TRIM(n2(i2))                                 !=== LOOP ON COMMON TRACERS
     876    DO i2=1,nt2; tnam = TRIM(t2(i2)%name)                            !=== LOOP ON COMMON TRACERS
    832877    !--------------------------------------------------------------------------------------------------------------------------
    833878      i1 = ixct(i2); IF(i1 == 0) CYCLE                               !--- Idx in t1(:) ; skip new tracers
     
    836881      s1=' of "'//TRIM(tnam)//'" in "'//TRIM(sections(is)%name)//'" not matching previous value'
    837882      DO ik = 1, SIZE(keys)
    838         lerr = getKey(keys(ik), v1, i1, t1)
    839         lerr = getKey(keys(ik), v2, i2, t2)
     883        lerr = getKey(keys(ik), v1, i1, k1)
     884        lerr = getKey(keys(ik), v2, i2, k2)
    840885        lerr = v1 /= v2; IF(fmsg(TRIM(keys(ik))//TRIM(s1), modname, lerr)) RETURN
    841886      END DO
    842887
    843       !=== GET THE INDICES IN tr(i2)%key(:) OF THE KEYS ALSO PRESENT IN tr(i1)%key(:)
    844       nk2  =   SIZE(t2(i2)%key(:))                                   !--- Keys number in current section
    845       ixck = strIdx(t1(i1)%key(:), t2(i2)%key(:))                    !--- Common keys indexes
    846       !--- APPEND THE NEW KEYS PAIRS IN tr(i1)%key(:)
    847       tr(i1)%key = [ tr(i1)%key, PACK(tr(i2)%key, MASK = ixck==0)]
    848       tr(i1)%val = [ tr(i1)%val, PACK(tr(i2)%val, MASK = ixck==0)]
     888      !=== GET THE INDICES IN tr(i2)%keys%key(:) OF THE KEYS ALSO PRESENT IN tr(i1)%keys%key(:)
     889      nk2  =   SIZE(k2(i2)%key(:))                                   !--- Keys number in current section
     890      ixck = strIdx(k1(i1)%key(:), k2(i2)%key(:))                    !--- Common keys indexes
     891      !--- APPEND THE NEW KEYS PAIRS IN tr(i1)%keys%key(:)
     892      tr(i1)%keys%key = [ tr(i1)%keys%key, PACK(tr(i2)%keys%key, MASK = ixck==0)]
     893      tr(i1)%keys%val = [ tr(i1)%keys%val, PACK(tr(i2)%keys%val, MASK = ixck==0)]
    849894
    850895      !=== KEEP TRACK OF THE COMPONENTS NAMES: COMA-SEPARATED LIST
    851       lerr = getKey('component', v1, i1, t1)
    852       lerr = getKey('component', v2, i2, t2)
    853       CALL addKey('component', TRIM(v1)//','//TRIM(v2), tr(i1))
     896      lerr = getKey('component', v1, i1, k1)
     897      lerr = getKey('component', v2, i2, k2)
     898      tr(i1)%component = TRIM(v1)//','//TRIM(v2)
     899      CALL addKey('component', TRIM(v1)//','//TRIM(v2), tr(i1)%keys)
    854900
    855901      !=== FOR TRACERS COMMON TO PREVIOUS AND CURRENT SECTIONS: CHECK WETHER SOME KEYS HAVE DIFFERENT VALUES ; KEEP OLD ONE
    856902      DO ik2 = 1, nk2                                                !--- Collect the corresponding indices
    857903        ik1 = ixck(ik2); IF(ik1 == 0) CYCLE
    858         IF(t1(i1)%val(ik1) == t2(i2)%val(ik2)) ixck(ik2)=0
     904        IF(k1(i1)%val(ik1) == k2(i2)%val(ik2)) ixck(ik2)=0
    859905      END DO
    860906      IF(ALL(ixck==0)) CYCLE                                         !--- No identical keys with /=values => nothing to display
    861907      CALL msg('Key(s)'//TRIM(s1), modname)                          !--- Display the  keys with /=values (names list)
    862908      DO ik2 = 1, nk2                                                !--- Loop on keys found in both t1(:) and t2(:)
    863         knam = t2(i2)%key(ik2)                                       !--- Name of the current key
     909        knam = k2(i2)%key(ik2)                                       !--- Name of the current key
    864910        ik1 = ixck(ik2)                                              !--- Corresponding index in t1(:)
    865911        IF(ik1 == 0) CYCLE                                           !--- New keys are skipped
    866         v1 = t1(i1)%val(ik1); v2 = t2(i2)%val(ik2)                   !--- Key values in t1(:) and t2(:)
     912        v1 = k1(i1)%val(ik1); v2 = k2(i2)%val(ik2)                   !--- Key values in t1(:) and t2(:)
    867913        CALL msg(' * '//TRIM(knam)//'='//TRIM(v2)//' ; previous value kept:'//TRIM(v1), modname)
    868914      END DO
     
    879925LOGICAL FUNCTION cumulTracers(sections, tr, lRename) RESULT(lerr)
    880926  TYPE(dataBase_type),  TARGET, INTENT(IN)  :: sections(:)
    881   TYPE(keys_type), ALLOCATABLE, INTENT(OUT) ::       tr(:)
     927  TYPE(trac_type), ALLOCATABLE, INTENT(OUT) ::       tr(:)
    882928  LOGICAL,            OPTIONAL, INTENT(IN)  :: lRename               !--- .TRUE.: add a section suffix to identical names
    883929  CHARACTER(LEN=maxlen)  :: tnam_new, modname
     
    888934  tr = [( sections(is)%trac(:), is = 1, SIZE(sections) )]            !--- Concatenated tracers vector
    889935  IF(PRESENT(lRename)) THEN; IF(lRename) RETURN; END IF              !--- No renaming: finished
    890   lerr = getKey('name',     tname, tr); IF(lerr) RETURN              !--- Names
    891   lerr = getKey('parent',  parent, tr); IF(lerr) RETURN              !--- Parents
    892   lerr = getKey('component', comp, tr); IF(lerr) RETURN              !--- Component name
     936  lerr = getKey('name',     tname, tr%keys); IF(lerr) RETURN         !--- Names
     937  lerr = getKey('parent',  parent, tr%keys); IF(lerr) RETURN         !--- Parents
     938  lerr = getKey('component', comp, tr%keys); IF(lerr) RETURN         !--- Component name
    893939  !----------------------------------------------------------------------------------------------------------------------------
    894940  DO iq = 1, SIZE(tr); IF(COUNT(tname == tname(iq)) == 1) CYCLE      !=== LOOP ON TRACERS
    895941  !----------------------------------------------------------------------------------------------------------------------------
    896942    tnam_new = TRIM(tname(iq))//'_'//TRIM(comp(iq))                  !--- Same with section extension
    897     CALL addKey('name', tnam_new, tr(iq))                            !--- Modify tracer name
     943    CALL addKey('name', tnam_new, tr(iq)%keys)                       !--- Modify tracer name
     944    tr(iq)%name = TRIM(tnam_new)                                     !--- Modify tracer name
    898945    !--------------------------------------------------------------------------------------------------------------------------
    899946    DO jq = 1, SIZE(tr); IF(parent(jq) /= tname(iq)) CYCLE           !=== LOOP ON TRACERS PARENTS
    900947    !--------------------------------------------------------------------------------------------------------------------------
    901       CALL addKey('parent', tnam_new, tr(jq))                        !--- Modify tracer name
     948      CALL addKey('parent', tnam_new, tr(jq)%keys)                   !--- Modify tracer name
     949      tr(jq)%parent = TRIM(tnam_new)                                 !--- Modify tracer name
    902950    !--------------------------------------------------------------------------------------------------------------------------
    903951    END DO
     
    946994    tmp = int2str([(iq, iq=1, nq)])
    947995  ELSE
    948     lerr = getKey(nam, tmp, dBase(idb)%trac(:), lDisp=lMandatory)
     996    lerr = getKey(nam, tmp, dBase(idb)%trac(:)%keys, lDisp=lMandatory)
    949997  END IF
    950998  IF(lerr) THEN; lerr = lMandatory; RETURN; END IF
     
    9651013LOGICAL FUNCTION aliasTracer(tname, trac, alias) RESULT(lerr)                  !=== TRACER NAMED "tname" - SCALAR
    9661014  CHARACTER(LEN=*),         INTENT(IN)  :: tname
    967   TYPE(keys_type), TARGET,  INTENT(IN)  :: trac(:)
    968   TYPE(keys_type), POINTER, INTENT(OUT) :: alias
     1015  TYPE(trac_type), TARGET,  INTENT(IN)  :: trac(:)
     1016  TYPE(trac_type), POINTER, INTENT(OUT) :: alias
    9691017  INTEGER :: it
    9701018  CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:)
    9711019  alias => NULL()
    972   lerr = getKey('name', tnames, trac(:))
     1020  lerr = getKey('name', tnames, trac(:)%keys)
    9731021  it = strIdx(tnames, tname)
    9741022  lerr = it /= 0; IF(.NOT.lerr) alias => trac(it)
     
    9761024!==============================================================================================================================
    9771025LOGICAL FUNCTION trSubset_Indx(trac, idx, alias) RESULT(lerr)                  !=== TRACERS WITH INDICES "idx(:)" - VECTOR
    978   TYPE(keys_type), ALLOCATABLE, INTENT(IN)  ::  trac(:)
     1026  TYPE(trac_type), ALLOCATABLE, INTENT(IN)  ::  trac(:)
    9791027  INTEGER,                      INTENT(IN)  ::   idx(:)
    980   TYPE(keys_type), ALLOCATABLE, INTENT(OUT) :: alias(:)
     1028  TYPE(trac_type), ALLOCATABLE, INTENT(OUT) :: alias(:)
    9811029  alias = trac(idx)
    9821030  lerr = indexUpdate(alias)
     
    9841032!------------------------------------------------------------------------------------------------------------------------------
    9851033LOGICAL FUNCTION trSubset_Name(trac, tname, alias) RESULT(lerr)                !=== TRACERS NAMED "tname(:)" - VECTOR
    986   TYPE(keys_type), ALLOCATABLE, INTENT(IN)  ::  trac(:)
     1034  TYPE(trac_type), ALLOCATABLE, INTENT(IN)  ::  trac(:)
    9871035  CHARACTER(LEN=*),             INTENT(IN)  :: tname(:)
    988   TYPE(keys_type), ALLOCATABLE, INTENT(OUT) :: alias(:)
     1036  TYPE(trac_type), ALLOCATABLE, INTENT(OUT) :: alias(:)
    9891037  CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:)
    990   lerr = getKey('name', tnames, trac(:))
     1038  lerr = getKey('name', tnames, trac(:)%keys)
    9911039  alias = trac(strIdx(tnames, tname))
    9921040  lerr = indexUpdate(alias)
     
    9941042!==============================================================================================================================
    9951043LOGICAL FUNCTION trSubset_gen0Name(trac, gen0Nm, alias) RESULT(lerr)           !=== TRACERS OF COMMON 1st GENERATION ANCESTOR
    996   TYPE(keys_type), ALLOCATABLE, INTENT(IN)  :: trac(:)
     1044  TYPE(trac_type), ALLOCATABLE, INTENT(IN)  :: trac(:)
    9971045  CHARACTER(LEN=*),             INTENT(IN)  :: gen0Nm
    998   TYPE(keys_type), ALLOCATABLE, INTENT(OUT) :: alias(:)
     1046  TYPE(trac_type), ALLOCATABLE, INTENT(OUT) :: alias(:)
    9991047  CHARACTER(LEN=maxlen), ALLOCATABLE :: gen0N(:)
    1000   lerr = getKey('gen0Name', gen0N, trac(:))
     1048  lerr = getKey('gen0Name', gen0N, trac(:)%keys)
    10011049  alias = trac(strFind(delPhase(gen0N), gen0Nm))
    10021050  lerr = indexUpdate(alias)
     
    10061054
    10071055!==============================================================================================================================
    1008 !=== UPDATE THE INDEXES iqParent, iqDescen, nqDescen, nqChildren IN THE TRACERS DESCRIPTOR LIST "tr" ==========================
     1056!=== UPDATE THE INDEXES iqParent, iqDescend AND iGeneration IN THE TRACERS DESCRIPTOR LIST "tr" (USEFULL FOR SUBSETS) =========
    10091057!==============================================================================================================================
    10101058LOGICAL FUNCTION indexUpdate(tr) RESULT(lerr)
    1011   TYPE(keys_type), INTENT(INOUT) :: tr(:)
     1059  TYPE(trac_type), INTENT(INOUT) :: tr(:)
    10121060  INTEGER :: iq, jq, nq, ig, nGen
    10131061  INTEGER,               ALLOCATABLE :: iqDescen(:), ix(:), iy(:)
    10141062  CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:), parent(:)
    10151063  INTEGER,       DIMENSION(SIZE(tr)) :: iqParent, iGen
    1016   lerr = getKey('name',   tnames, tr); IF(lerr) RETURN               !--- Names
    1017   lerr = getKey('parent', parent, tr); IF(lerr) RETURN               !--- Parents
     1064  lerr = getKey('name',   tnames, tr%keys); IF(lerr) RETURN          !--- Names
     1065  lerr = getKey('parent', parent, tr%keys); IF(lerr) RETURN          !--- Parents
    10181066  nq = SIZE(tr)
    10191067
    1020   !=== iqParent
     1068  !=== iqParent, iGeneration
    10211069  DO iq = 1, nq; iGen(iq) = 0; jq = iq
    10221070    iqParent(iq) = strIdx(tnames, parent(iq))
    10231071    DO; jq = strIdx(tnames, parent(jq)); IF(jq == 0) EXIT; iGen(iq) = iGen(iq) + 1; END DO
    1024     CALL addKey('iqParent', iqParent(iq), tr(iq))
     1072    CALL addKey('iqParent',   parent(iq), tr(iq)%keys)
     1073    CALL addKey('iqGeneration', iGen(iq), tr(iq)%keys)
    10251074  END DO
    10261075
     
    10291078  DO iq = 1, nq
    10301079    ix = [iq]; ALLOCATE(iqDescen(0))
    1031     CALL addKey('nqChildren', 0, tr(iq))
    10321080    DO ig = iGen(iq)+1, nGen
    10331081      iy = find(iqParent, ix); iqDescen = [iqDescen, iy]; ix = iy
    10341082      IF(ig /= iGen(iq)+1) CYCLE
    1035       CALL addKey('nqChildren', SIZE(iqDescen), tr(iq))
     1083      CALL addKey('nqChildren', SIZE(iqDescen), tr(iq)%keys)
     1084      tr(iq)%nqChildren = SIZE(iqDescen)
    10361085    END DO
    1037     CALL addKey('iqDescen', strStack(int2str(iqDescen)), tr(iq))
    1038     CALL addKey('nqDescen',             SIZE(iqDescen),  tr(iq))
     1086    CALL addKey('iqDescen', strStack(int2str(iqDescen)), tr(iq)%keys)
     1087    CALL addKey('nqDescen',             SIZE(iqDescen),  tr(iq)%keys)
     1088    tr(iq)%iqDescen =      iqDescen
     1089    tr(iq)%nqDescen = SIZE(iqDescen)
    10391090    DEALLOCATE(iqDescen)
    10401091  END DO
     
    10441095 
    10451096!==============================================================================================================================
    1046 !=== READ FILE "fnam" TO APPEND THE "dBase" TRACERS DATABASE WITH AS MUCH SECTIONS AS ISOTOPES CLASSES IN "isot(:)%name":  ====
    1047 !===  * Each section dBase(i)%name contains the isotopes "dBase(i)%trac(:)" descending on "dBase(i)%name"="iso(i)%name"    ====
     1097!=== READ FILE "fnam" TO APPEND THE "dBase" TRACERS DATABASE WITH AS MUCH SECTIONS AS PARENTS NAMES IN "isot(:)%parent":   ====
     1098!===  * Each section dBase(i)%name contains the isotopes "dBase(i)%trac(:)" descending on "dBase(i)%name"="iso(i)%parent"  ====
    10481099!===  * For each isotopes class, the <key>=<val> vector of each tracer is moved into the isotopes descriptor "isot"        ====
    10491100!=== NOTES:                                                                                                                ====
    10501101!===  * Most of the "isot" components have been defined in the calling routine (processIsotopes):                          ====
    1051 !===      name,  nzone, zone(:),  niso, keys(:)%name,  ntiso, trac(:),  nphas, phas,  iqIsoPha(:,:),  itZonPhi(:,:)        ====
     1102!===      parent,  nzone, zone(:),  niso, keys(:)%name,  ntiso, trac(:),  nphas, phas,  iqIsoPha(:,:),  itZonPhi(:,:)      ====
    10521103!===  * Same syntax for isotopes file and "tracer.def": a tracers section contains one line for each of its isotopes       ====
    10531104!===  * Each tracers section can contain a "params" virtual isotope line of isotopes parameters default values             ====
     
    10581109LOGICAL FUNCTION readIsotopesFile(fnam, isot) RESULT(lerr)
    10591110  CHARACTER(LEN=*),        INTENT(IN)    :: fnam                     !--- Input file name
    1060   TYPE(isot_type), TARGET, INTENT(INOUT) :: isot(:)                  !--- Isotopes descriptors (field %name must be defined!)
     1111  TYPE(isot_type), TARGET, INTENT(INOUT) :: isot(:)                  !--- Isotopes descriptors (field %parent must be defined!)
    10611112  LOGICAL :: lFound
    10621113  INTEGER :: is, iis, it, idb, ndb, nb0
    1063   CHARACTER(LEN=maxlen), ALLOCATABLE :: vals(:), tname(:), iname(:)
     1114  CHARACTER(LEN=maxlen), ALLOCATABLE :: vals(:)
    10641115  CHARACTER(LEN=maxlen)              :: modname
    1065   TYPE(keys_type),           POINTER ::  t
     1116  TYPE(trac_type),           POINTER ::   tt(:), t
    10661117  TYPE(dataBase_type),   ALLOCATABLE ::  tdb(:)
    10671118  modname = 'readIsotopesFile'
    10681119
    10691120  !--- THE INPUT FILE MUST BE PRESENT
    1070   INQUIRE(FILE=TRIM(fnam), EXIST=lFound)
    1071   lerr = .NOT.lFound
    1072   CALL msg('Missing isotopes parameters file "'//TRIM(fnam)//'"', modname, lerr)
    1073   IF(lerr) RETURN
    1074 
    1075   !--- READ THE FILE SECTIONS, ONE EACH ISOTOPES CLASS (FIEDL %name)
     1121  INQUIRE(FILE=TRIM(fnam), EXIST=lFound); lerr = .NOT.lFound
     1122  IF(fmsg('Missing isotopes parameters file "'//TRIM(fnam)//'"', modname, lerr)) RETURN
     1123
     1124  !--- READ THE FILE SECTIONS, ONE EACH PARENT TRACER
    10761125  nb0 = SIZE(dBase, DIM=1)+1                                         !--- Next database element index
    1077   lerr = readSections(fnam,strStack(isot(:)%name,'|')); IF(lerr) RETURN !--- Read sections, one each isotopes class %name
     1126  lerr = readSections(fnam,strStack(isot(:)%parent,'|')); IF(lerr) RETURN !--- Read sections, one each parent tracer
    10781127  ndb = SIZE(dBase, DIM=1)                                           !--- Current database size
    10791128  DO idb = nb0, ndb
     
    10811130
    10821131    !--- GET FEW GLOBAL KEYS FROM "def" FILES AND ADD THEM TO THE 'params' SECTION
    1083 !    lerr = addKeysFromDef(dBase(idb)%trac, 'params');     IF(lerr) RETURN
     1132    CALL addKeysFromDef(dBase(idb)%trac, 'params')
    10841133
    10851134    !--- SUBSTITUTE THE KEYS DEFINED IN THE 'params' VIRTUAL TRACER ; SUBSTITUTE LOCAL KEYS ; REMOVE 'params' VIRTUAL TRACER
    1086     lerr = subDefault(dBase(idb)%trac, 'params', .TRUE.); IF(lerr) RETURN
     1135    CALL subDefault(dBase(idb)%trac, 'params', .TRUE.)
     1136
     1137    tt => dBase(idb)%trac
    10871138
    10881139    !--- REDUCE THE EXPRESSIONS TO OBTAIN SCALARS AND TRANSFER THEM TO THE "isot" ISOTOPES DESCRIPTORS VECTOR
    1089     lerr = getKey('name', tname, dBase(idb)%trac);        IF(lerr) RETURN
    1090     lerr = getKey('name', iname, isot(iis)%keys);         IF(lerr) RETURN
    10911140    DO it = 1, SIZE(dBase(idb)%trac)
    10921141      t => dBase(idb)%trac(it)
    1093       is = strIdx(iname, tname(it))                                  !--- Index in "iname(:)" of isotope "tname(it)"
     1142      is = strIdx(isot(iis)%keys(:)%name, t%name)                    !--- Index in "isot(iis)%keys(:)%name" of isotope "t%name"
    10941143      IF(is == 0) CYCLE
    1095       lerr = ANY(reduceExpr(t%val, vals)); IF(lerr) RETURN           !--- Reduce expressions ; detect non-numerical elements
    1096       isot(iis)%keys(is)%key = t%key
     1144      lerr = ANY(reduceExpr(t%keys%val, vals)); IF(lerr) RETURN      !--- Reduce expressions ; detect non-numerical elements
     1145      isot(iis)%keys(is)%key = t%keys%key
    10971146      isot(iis)%keys(is)%val = vals
    10981147    END DO
    10991148
    11001149    !--- CHECK FOR MISSING ISOTOPES (NO KEYS ALLOCATED)
    1101     lerr = checkList(iname, .NOT.[( ALLOCATED(isot(iis)%keys(is)%key), is=1, SIZE(isot(iis)%keys) )], &
     1150    lerr = checkList(isot(iis)%keys(:)%name, .NOT.[( ALLOCATED(isot(iis)%keys(is)%key), is=1, SIZE(isot(iis)%keys) )], &
    11021151                     'Check file "'//TRIM(fnam)//'" in section "'//TRIM(dBase(idb)%name)//'"', 'isotopes', 'missing')
    11031152    IF(lerr) RETURN
     
    11121161
    11131162  !--- GET THE isoCheck ENTRY FROM THE *.DEF FILES (MIGHT BE CHANGED TO A CLASS-DEPENDANT KEYWORD)
    1114   CALL get_in('ok_iso_verif', isot(strIdx(iname, 'H2O'))%check, .FALSE.)
     1163  CALL get_in('ok_iso_verif', isot(strIdx(isot%parent, 'H2O'))%check, .FALSE.)
    11151164
    11161165  lerr = dispIsotopes()
     
    11221171  INTEGER :: ik, nk, ip, it, nt
    11231172  CHARACTER(LEN=maxlen) :: prf
    1124   CHARACTER(LEN=maxlen), ALLOCATABLE :: ttl(:), val(:,:), tname(:)
     1173  CHARACTER(LEN=maxlen), ALLOCATABLE :: ttl(:), val(:,:)
    11251174  CALL msg('Isotopes parameters read from file "'//TRIM(fnam)//'":', modname)
    1126   DO ip = 1, SIZE(isot)                                              !--- Loop on isotopes classes
    1127     IF(SIZE(isot(ip)%keys) == 0) CYCLE
     1175  DO ip = 1, SIZE(isot)                                              !--- Loop on parents tracers
    11281176    nk = SIZE(isot(ip)%keys(1)%key)                                  !--- Same keys for each isotope
    11291177    nt = SIZE(isot(ip)%keys)                                         !--- Number of isotopes
     
    11311179    ALLOCATE(ttl(nk+2), val(nt,nk+1))
    11321180    ttl(1:2) = ['it  ','name']; ttl(3:nk+2) = isot(ip)%keys(1)%key(:)!--- Titles line with keys names
    1133     lerr = getKey('name', tname, isot(ip)%keys); IF(lerr) RETURN
    1134     val(:,1) = tname                                                 !--- Values table 1st column: isotopes names
     1181    val(:,1) = isot(ip)%keys(:)%name                                 !--- Values table 1st column: isotopes names 
    11351182    DO ik = 1, nk
    11361183      DO it = 1, nt
     
    11521199!=== IF ISOTOPES (2ND GENERATION TRACERS) ARE DETECTED:                                                                     ===
    11531200!===    * COMPUTE MOST OF THE RELATED QUANTITIES ("isot" COMPONENTS).                                                       ===
    1154 !===    * COMPUTE FEW ISOTOPES-DEDICATED "trac" COMPONENTS (defined by "keys(:)")                                           ===
    1155 !===    * CALL readIsotopesFile TO GET PHYSICAL QUANTITIES (<key>=<val> PAIRS)     /!\ DISABLED FUNCTION /!\                ===
    1156 !==============================================================================================================================
    1157 LOGICAL FUNCTION processIsotopes(keys, isot, iClasses) RESULT(lerr)
    1158   TYPE(keys_type),  TARGET,              OPTIONAL, INTENT(INOUT) ::   keys(:)
    1159   TYPE(isot_type),  TARGET, ALLOCATABLE, OPTIONAL, INTENT(OUT)   ::   isot(:)
    1160   CHARACTER(LEN=*), TARGET,              OPTIONAL, INTENT(IN)    :: iClasses(:)
    1161   CHARACTER(LEN=maxlen), ALLOCATABLE :: str1(:), str2(:)             !--- Temporary storage
    1162   CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:), parent(:), dType(:), phase(:), gen0N(:), iCla(:)
    1163   CHARACTER(LEN=maxlen) :: iClass, modname
    1164   CHARACTER(LEN=1)      :: ph                                        !--- Phase
    1165   LOGICAL,  ALLOCATABLE :: ll(:)                                     !--- Mask
    1166   INTEGER,  ALLOCATABLE :: iGen(:)
    1167   INTEGER :: ic, ip, iq, ii, it, iz
    1168   TYPE(isot_type), POINTER :: i1
    1169   TYPE(keys_type), POINTER :: k(:)
     1201!===    * COMPUTE FEW ISOTOPES-DEDICATED "trac" COMPONENTS                                                                  ===
     1202!===    * CALL readIsotopesFile TO GET PHYSICAL QUANTITIES (<key>=<val> PAIRS)                                              ===
     1203!===      NOTE: THIS IS DONE HERE (IN A ROUTINE CALLED BY THE DYNAMIC), BECAUSE THE DYNAMIC NEEDS FEW PHYSICAL PARAMETERS.  ===
     1204!==============================================================================================================================
     1205LOGICAL FUNCTION processIsotopes(iNames) RESULT(lerr)
     1206  CHARACTER(LEN=maxlen), TARGET, OPTIONAL, INTENT(IN)  :: iNames(:)
     1207  CHARACTER(LEN=maxlen), ALLOCATABLE :: p(:), str(:)                 !--- Temporary storage
     1208  CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:), parent(:), dType(:), phase(:), gen0N(:)
     1209  CHARACTER(LEN=maxlen) :: iName, modname
     1210  CHARACTER(LEN=1)   :: ph                                           !--- Phase
     1211  INTEGER, ALLOCATABLE ::  iGen(:)
     1212  INTEGER :: ic, ip, iq, it, iz
     1213  LOGICAL, ALLOCATABLE :: ll(:)                                      !--- Mask
     1214  TYPE(trac_type), POINTER   ::  t(:), t1
     1215  TYPE(isot_type), POINTER   ::  i
    11701216
    11711217  lerr = .FALSE.
    11721218  modname = 'readIsotopesFile'
    1173   k => tracers; IF(PRESENT(keys )) k => keys
    1174   lerr = getKey('name',       tname, k); IF(lerr) RETURN             !--- Names
    1175   lerr = getKey('parent',    parent, k); IF(lerr) RETURN             !--- Parents
    1176   lerr = getKey('type',       dType, k); IF(lerr) RETURN             !--- Tracer type
    1177   lerr = getKey('phase',      phase, k); IF(lerr) RETURN             !--- Phase
    1178   lerr = getKey('gen0Name',   gen0N, k); IF(lerr) RETURN             !--- 1st generation ancestor name
    1179   lerr = getKey('iGeneration', iGen, k); IF(lerr) RETURN             !--- Generation number
    1180 
    1181   !--- INITIALIZATION IF ISOTOPES-SPECIFIC KEYS (MUST BE DEFINED EVEN WITHOUT ISOTOPES)
    1182   DO iq = 1, SIZE(k)
    1183     CALL addKey('iso_iGroup',0, k(iq))                               !--- Family       idx in list "isotopes(:)%parent"
    1184     CALL addKey('iso_iName', 0, k(iq))                               !--- Isotope      idx in effective isotopes list
    1185     CALL addKey('iso_iZone', 0, k(iq))                               !--- Tagging zone idx in effective zones    list
    1186     CALL addKey('iso_iPhas', 0, k(iq))                               !--- Phase        idx in effective phases   list
    1187   END DO
     1219
     1220  t => tracers
     1221
     1222  lerr = getKey('name',       tname, t%keys); IF(lerr) RETURN       !--- Names
     1223  lerr = getKey('parent',    parent, t%keys); IF(lerr) RETURN       !--- Parents
     1224  lerr = getKey('type',       dType, t%keys); IF(lerr) RETURN       !--- Tracer type
     1225  lerr = getKey('phase',      phase, t%keys); IF(lerr) RETURN       !--- Phase
     1226  lerr = getKey('gen0Name',   gen0N, t%keys); IF(lerr) RETURN       !--- 1st generation ancestor name
     1227  lerr = getKey('iGeneration', iGen, t%keys); IF(lerr) RETURN       !--- Generation number
    11881228
    11891229  !--- GET FROM "tracers" THE FULL LIST OF AVAILABLE ISOTOPES CLASSES
    1190   iCla = PACK(delPhase(parent), MASK = dType=='tracer' .AND. iGen==1)
    1191   CALL strReduce(iCla)
    1192 
    1193   !--- CHECK WHETHER NEEDED ISOTOPES CLASSES "iClasses" ARE AVAILABLE OR NOT
    1194   IF(PRESENT(iClasses)) THEN
    1195     DO it = 1, SIZE(iClasses)
    1196       lerr = ALL(iCla /= iClasses(it))
    1197       IF(fmsg('No isotopes class "'//TRIM(iClasses(it))//'" found among tracers', modname, lerr)) RETURN
     1230  p = PACK(delPhase(parent), MASK = dType=='tracer' .AND. iGen==1)
     1231  CALL strReduce(p, nbIso)
     1232
     1233  !--- CHECK WHETHER NEEDED ISOTOPES CLASSES "iNames" ARE AVAILABLE OR NOT
     1234  IF(PRESENT(iNames)) THEN
     1235    DO it = 1, SIZE(iNames)
     1236      lerr = ALL(p /= iNames(it))
     1237      IF(fmsg('No isotopes class "'//TRIM(iNames(it))//'" found among tracers', modname, lerr)) RETURN
    11981238    END DO
    1199     iCla = iClasses
     1239    p = iNames; nbIso = SIZE(p)
    12001240  END IF
    1201   nbIso = SIZE(iCla)
    1202 
    1203   !--- USE THE ARGUMENT "isot" TO STORE THE ISOTOPIC DATABASE OR THE LOCAL VECTOR "isotopes"
    1204   IF(PRESENT(isot)) THEN
    1205     ALLOCATE(    isot(nbIso))
    1206   ELSE
    1207     IF(ALLOCATED(isotopes)) DEALLOCATE(isotopes)
    1208     ALLOCATE(isotopes(nbIso))
    1209   END IF
     1241  IF(ALLOCATED(isotopes)) DEALLOCATE(isotopes)
     1242  ALLOCATE(isotopes(nbIso))
     1243
    12101244  IF(nbIso==0) RETURN                                                !=== NO ISOTOPES: FINISHED
    12111245
    12121246  !--- ISOTOPES RELATED VARIABLES ; NULL OR EMPTY IF NO ISOTOPES
    1213   DO ic = 1, nbIso                                                   !--- Loop on isotopes classes
    1214     IF(     PRESENT(isot)) i1 => isot    (ic)
    1215     IF(.NOT.PRESENT(isot)) i1 => isotopes(ic)
    1216     iClass = iCla(ic)                                                !--- Current isotopes class name (parent tracer name)
    1217     i1%name = iClass
    1218 
    1219     !=== Isotopes children of tracer "iClass": mask, names, number (same for each phase of "iClass")
    1220     ll = dType=='tracer' .AND. delPhase(parent) == iClass .AND. phase == 'g'
    1221     str1 = PACK(delPhase(tname), MASK = ll)                          !--- Effectively found isotopes of "iClass"
    1222     i1%niso = SIZE(str1)                                             !--- Number of "effectively found isotopes of "iname"
    1223     ALLOCATE(i1%keys(i1%niso))
    1224     DO it = 1, i1%niso; CALL addKey('name', str1(it), i1%keys(it)); END DO
    1225 
    1226     !=== Geographic tagging tracers descending on tracer "iClass": mask, names, number
    1227     ll = dType=='tag'    .AND. delPhase(gen0N) == iClass .AND. iGen == 2
    1228     i1%zone = PACK(strTail(tname, '_', .TRUE.), MASK = ll)           !--- Tagging zones names  for isotopes category "iname"
    1229     CALL strReduce(i1%zone)
    1230     i1%nzone = SIZE(i1%zone)                                         !--- Tagging zones number for isotopes category "iClass"
    1231 
    1232     !=== Geographic tracers of the isotopes children of tracer "iClass" (same for each phase of "iClass")
     1247  isotopes(:)%parent = p
     1248  DO ic = 1, SIZE(p)                                                 !--- Loop on isotopes classes
     1249    i => isotopes(ic)
     1250    iname = i%parent                                                 !--- Current isotopes class name (parent tracer name)
     1251
     1252    !=== Isotopes children of tracer "iname": mask, names, number (same for each phase of "iname")
     1253    ll = dType=='tracer' .AND. delPhase(parent) == iname .AND. phase == 'g'
     1254    str = PACK(delPhase(tname), MASK = ll)                           !--- Effectively found isotopes of "iname"
     1255    i%niso = SIZE(str)                                               !--- Number of "effectively found isotopes of "iname"
     1256    ALLOCATE(i%keys(i%niso))
     1257    FORALL(it = 1:i%niso) i%keys(it)%name = str(it)
     1258
     1259    !=== Geographic tagging tracers descending on tracer "iname": mask, names, number
     1260    ll = dType=='tag'    .AND. delPhase(gen0N) == iname .AND. iGen == 2
     1261    i%zone = PACK(strTail(tname,'_',.TRUE.), MASK = ll)              !--- Tagging zones names  for isotopes category "iname"
     1262    CALL strReduce(i%zone)
     1263    i%nzone = SIZE(i%zone)                                           !--- Tagging zones number for isotopes category "iname"
     1264
     1265    !=== Geographic tracers of the isotopes children of tracer "iname" (same for each phase of "iname")
    12331266    !    NOTE: One might like to create a similar variable for 2nd generation tagging tracers (tagging the gen1 tracers)
    1234     str2 = PACK(delPhase(tname), MASK=ll)
    1235     CALL strReduce(str2)
    1236     i1%ntiso = i1%niso + SIZE(str2)                                  !--- Number of isotopes + their geographic tracers [ntiso]
    1237     ALLOCATE(i1%trac(i1%ntiso))
    1238     DO it =         1, i1%niso;  i1%trac(it) = str1(it);         END DO
    1239     DO it = i1%niso+1, i1%ntiso; i1%trac(it) = str2(it-i1%niso); END DO
    1240 
    1241     !=== Phases for tracer "iClass"
    1242     i1%phase = ''
    1243     DO ip = 1, nphases; ph = known_phases(ip:ip); IF(ANY(tname == addPhase(iClass, ph))) i1%phase = TRIM(i1%phase)//ph; END DO
    1244     i1%nphas = LEN_TRIM(i1%phase)                                       !--- Equal to "nqo" for water
     1267    str = PACK(delPhase(tname), MASK=ll)
     1268    CALL strReduce(str)
     1269    i%ntiso = i%niso + SIZE(str)                                     !--- Number of isotopes + their geographic tracers [ntiso]
     1270    ALLOCATE(i%trac(i%ntiso))
     1271    FORALL(it = 1:i%niso) i%trac(it) = i%keys(it)%name
     1272    FORALL(it = i%niso+1:i%ntiso) i%trac(it) = str(it-i%niso)
     1273
     1274    !=== Phases for tracer "iname"
     1275    i%phase = ''
     1276    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
     1277    i%nphas = LEN_TRIM(i%phase)                                       !--- Equal to "nqo" for water
    12451278
    12461279    !=== Tables giving the index in a table of effectively found items for each dynamical tracer (1<=iq<=nqtot)
    1247     DO iq = 1, SIZE(tracers)
    1248       ii = strIdx(i1%trac, strHead(delPhase(tname(iq)), '_', .TRUE.))
    1249       iz = strIdx(i1%zone, strTail(         tname(iq),  '_', .TRUE.))
    1250       ip =  INDEX(i1%phase,            TRIM(phase(iq)              ))
    1251       IF(delPhase(gen0N(iq)) /= iClass .OR. iGen(iq) == 0) CYCLE     !--- Only deal with tracers descending on "iClass"
    1252       CALL addKey('iso_iGroup',ic, k(iq))                            !--- Family       idx in list "isotopes(:)%name"
    1253       CALL addKey('iso_iName', ii, k(iq))                            !--- Isotope      idx in effective isotopes list
    1254       CALL addKey('iso_iZone', iz, k(iq))                            !--- Tagging zone idx in effective zones    list
    1255       CALL addKey('iso_iPhas', ip, k(iq))                            !--- Phase        idx in effective phases   list
    1256       IF(iGen(iq) /= 2) CALL addKey('iso_iZone', 0, k(iq))           !--- Skip possible generation 1 tagging tracers
     1280    DO iq = 1, SIZE(t)
     1281      t1 => tracers(iq)
     1282      IF(delPhase(t1%gen0Name)/=iname .OR. t1%iGeneration==0) CYCLE  !--- Only deal with tracers descending on "iname"
     1283      t1%iso_iGroup = ic                                             !--- Isotopes family       idx in list "isotopes(:)%parent"
     1284      t1%iso_iName  = strIdx(i%trac, strHead(delPhase(t1%name),'_',.TRUE.)) !--- Current isotope       idx in effective isotopes list
     1285      t1%iso_iZone  = strIdx(i%zone,          strTail(t1%name, '_',.TRUE.)) !--- Current isotope zone  idx in effective zones    list
     1286      t1%iso_iPhase =  INDEX(i%phase,TRIM(t1%phase))                 !--- Current isotope phase idx in effective phases   list
     1287      IF(t1%iGeneration /= 2) t1%iso_iZone = 0                       !--- Skip possible generation 1 tagging tracers
    12571288    END DO
    12581289
    12591290    !=== Table used to get iq (index in dyn array, size nqtot) from the isotope and phase indexes ; the full isotopes list
    12601291    !    (including tagging tracers) is sorted this way:  iso1, iso2, ..., iso1_zone1, iso2_zone1, ..., iso1_zoneN, iso2_zoneN
    1261     i1%iqIsoPha = RESHAPE( [( (strIdx(tname,  addPhase(i1%trac(it),i1%phase(ip:ip))),         it=1, i1%ntiso), ip=1, i1%nphas)], &
    1262                          [i1%ntiso, i1%nphas] )
     1292    i%iqIsoPha = RESHAPE( [( (strIdx(t%name,  addPhase(i%trac(it),i%phase(ip:ip))),       it=1, i%ntiso), ip=1, i%nphas)], &
     1293                         [i%ntiso, i%nphas] )
    12631294    !=== Table used to get iq (index in dyn array, size nqtot) from the water and isotope and phase indexes ; the full isotopes list
    12641295    !    (including tagging tracers) is sorted this way:  iso1, iso2, ..., iso1_zone1, iso2_zone1, ..., iso1_zoneN, iso2_zoneN
    1265     i1%iqWIsoPha = RESHAPE( [( [strIdx(tname, addPhase('H2O',      i1%phase(ip:ip))), i1%iqIsoPha(:,ip)],      ip=1, i1%nphas)], &
    1266                          [1+i1%ntiso, i1%nphas] )
     1296    i%iqWIsoPha = RESHAPE( [( [strIdx(t%name,   addPhase('H2O',i%phase(ip:ip))), i%iqIsoPha(:,ip)], ip=1,i%nphas)], &
     1297                         [1+i%ntiso, i%nphas] )
    12671298    !=== Table used to get ix (index in tagging tracers isotopes list, size ntiso) from the zone and isotope indexes
    1268     i1%itZonIso = RESHAPE( [( (strIdx(i1%trac(:), TRIM(i1%trac(it))//'_'//TRIM(i1%zone(iz))), iz=1, i1%nzone), it=1, i1%niso )], &
    1269                          [i1%nzone, i1%niso] )
     1299    i%itZonIso = RESHAPE( [( (strIdx(i%trac(:), TRIM(i%trac(it))//'_'//TRIM(i%zone(iz))), iz=1, i%nzone), it=1, i%niso )], &
     1300                         [i%nzone, i%niso] )
    12701301  END DO
    12711302
    1272   !=== READ PHYSICAL PARAMETERS FROM isoFile FILE (COMMENTED => DISABLED)
    1273 !  IF(     PRESENT(isot)) lerr = readIsotopesFile(isoFile, isot)
    1274 !  IF(.NOT.PRESENT(isot)) lerr = readIsotopesFile(isoFile, isotopes)
    1275 !  IF(lerr) RETURN
     1303  !=== READ PHYSICAL PARAMETERS FROM isoFile FILE
     1304!  lerr = readIsotopesFile(isoFile, isotopes); IF(lerr) RETURN! on commente pour ne pas chercher isotopes_params.def
    12761305
    12771306  !--- GET THE isoCheck ENTRY FROM THE *.DEF FILES (MIGHT BE CHANGED TO A CLASS-DEPENDANT KEYWORD)
     
    12821311
    12831312  !=== SELECT WATER ISOTOPES CLASS OR, IF UNFOUND, THE FIRST ISOTOPES CLASS
    1284   IF(isoSelect('H2O', lVerbose=.TRUE.)) THEN
    1285     iH2O = ixIso
    1286   ELSE
    1287     lerr = isoSelect(1, lVerbose=.TRUE.)
    1288   END IF
     1313  IF(isoSelect('H2O', .TRUE.)) THEN; iH2O = ixIso; ELSE; lerr = isoSelect(1, .TRUE.); END IF
    12891314
    12901315CONTAINS
     
    12941319!------------------------------------------------------------------------------------------------------------------------------
    12951320  INTEGER :: ix, it, ip, np, iz, nz, npha, nzon
     1321  TYPE(isot_type), POINTER :: i
    12961322  DO ix = 1, nbIso
    1297     IF(     PRESENT(isot)) i1 => isot    (ix)
    1298     IF(.NOT.PRESENT(isot)) i1 => isotopes(ix)
     1323    i => isotopes(ix)
    12991324    !--- Check whether each isotope and tagging isotopic tracer is present in the same number of phases
    1300     DO it = 1, i1%ntiso; npha = i1%nphas
    1301       np = SUM([(COUNT(tname(:) == addPhase(i1%trac(it), i1%phase(ip:ip))), ip=1, npha)])
     1325    DO it = 1, i%ntiso; npha = i%nphas
     1326      np = SUM([(COUNT(tracers(:)%name == addPhase(i%trac(it), i%phase(ip:ip))), ip=1, npha)])
    13021327      lerr = np /= npha
    1303       CALL msg(TRIM(int2str(np))//       ' phases instead of '//TRIM(int2str(npha))//' for '//TRIM(i1%trac(it)), modname, lerr)
     1328      CALL msg(TRIM(int2str(np))//' phases instead of '//TRIM(int2str(npha))//' for '//TRIM(i%trac(it)), modname, lerr)
    13041329      IF(lerr) RETURN
    13051330    END DO
    1306     DO it = 1, i1%niso; nzon = i1%nzone
    1307       nz = SUM([(COUNT(i1%trac == TRIM(i1%trac(it))//'_'//i1%zone(iz)), iz=1, nzon)])
     1331    DO it = 1, i%niso; nzon = i%nzone
     1332      nz = SUM([(COUNT(i%trac == TRIM(i%trac(it))//'_'//i%zone(iz)), iz=1, nzon)])
    13081333      lerr = nz /= nzon
    1309       CALL msg(TRIM(int2str(nz))//' tagging zones instead of '//TRIM(int2str(nzon))//' for '//TRIM(i1%trac(it)), modname, lerr)
     1334      CALL msg(TRIM(int2str(nz))//' tagging zones instead of '//TRIM(int2str(nzon))//' for '//TRIM(i%trac(it)), modname, lerr)
    13101335      IF(lerr) RETURN
    13111336    END DO
     
    13201345!==============================================================================================================================
    13211346!=== THE ROUTINE isoSelect IS USED TO SWITCH FROM AN ISOTOPE FAMILY TO ANOTHER: ISOTOPES DEPENDENT PARAMETERS ARE UPDATED
    1322 !     Single generic "isoSelect" routine, using the predefined index of the class (fast version) or its name (first call).
    1323 !==============================================================================================================================
    1324 LOGICAL FUNCTION isoSelectByName(iClass, isot, lVerbose) RESULT(lerr)
     1347!     Single generic "isoSelect" routine, using the predefined index of the parent (fast version) or its name (first call).
     1348!==============================================================================================================================
     1349LOGICAL FUNCTION isoSelectByName(iName, lVerbose) RESULT(lerr)
    13251350   IMPLICIT NONE
    1326    CHARACTER(LEN=*),                  INTENT(IN) :: iClass
    1327    TYPE(isot_type), OPTIONAL, TARGET, INTENT(IN) :: isot(:)
    1328    LOGICAL,         OPTIONAL,         INTENT(IN) :: lVerbose
    1329    TYPE(isot_type), POINTER :: iso(:)
     1351   CHARACTER(LEN=*),  INTENT(IN) :: iName
     1352   LOGICAL, OPTIONAL, INTENT(IN) :: lVerbose
    13301353   INTEGER :: iIso
    13311354   LOGICAL :: lV
    1332    lV = .FALSE.;    IF(PRESENT(lVerbose)) lV = lVerbose
    1333    iso => isotopes; IF(PRESENT(isot))    iso => isot
    1334    iIso = strIdx(iso(:)%name, iClass)
     1355   lV = .FALSE.; IF(PRESENT(lVerbose)) lV = lVerbose
     1356   iIso = strIdx(isotopes(:)%parent, iName)
    13351357   lerr = iIso == 0
    13361358   IF(lerr) THEN
    13371359      niso = 0; ntiso = 0; nzone = 0; nphas = 0; isoCheck=.FALSE.
    1338       CALL msg('no isotope family named "'//TRIM(iClass)//'"', ll=lV)
     1360      CALL msg('no isotope family named "'//TRIM(iName)//'"', ll=lV)
    13391361      RETURN
    13401362   END IF
    1341    lerr = isoSelectByIndex(iIso, iso, lV)
     1363   lerr = isoSelectByIndex(iIso, lV)
    13421364END FUNCTION isoSelectByName
    13431365!==============================================================================================================================
    1344 LOGICAL FUNCTION isoSelectByIndex(iIso, isot, lVerbose) RESULT(lerr)
     1366LOGICAL FUNCTION isoSelectByIndex(iIso, lVerbose) RESULT(lerr)
    13451367   IMPLICIT NONE
    1346    INTEGER,                           INTENT(IN)    :: iIso
    1347    TYPE(isot_type), TARGET, OPTIONAL, INTENT(INOUT) :: isot(:)
    1348    LOGICAL,                 OPTIONAL, INTENT(IN)    :: lVerbose
    1349    TYPE(isot_type), POINTER :: i(:)
     1368   INTEGER,           INTENT(IN) :: iIso
     1369   LOGICAL, OPTIONAL, INTENT(IN) :: lVerbose
    13501370   LOGICAL :: lV
    1351    lV = .FALSE.;  IF(PRESENT(lVerbose)) lV = lVerbose
    1352    i => isotopes; IF(PRESENT(isot))      i => isot
     1371   lv = .FALSE.; IF(PRESENT(lVerbose)) lv = lVerbose
    13531372   lerr = .FALSE.
    13541373   IF(iIso == ixIso) RETURN                                          !--- Nothing to do if the index is already OK
    1355    lerr = iIso<=0 .OR. iIso>SIZE(i)
     1374   lerr = iIso<=0 .OR. iIso>SIZE(isotopes)
    13561375   CALL msg('Inconsistent isotopes family index '//TRIM(int2str(iIso))//': should be > 0 and <= '&
    1357           //TRIM(int2str(SIZE(i)))//'"', ll = lerr .AND. lV)
     1376          //TRIM(int2str(SIZE(isotopes)))//'"', ll = lerr .AND. lV)
    13581377   IF(lerr) RETURN
    13591378   ixIso = iIso                                                      !--- Update currently selected family index
    1360    isotope  => i(ixIso)                                              !--- Select corresponding component
     1379   isotope  => isotopes(ixIso)                                       !--- Select corresponding component
    13611380   isoKeys  => isotope%keys;     niso     = isotope%niso
    13621381   isoName  => isotope%trac;     ntiso    = isotope%ntiso
     
    13651384   itZonIso => isotope%itZonIso; isoCheck = isotope%check
    13661385   iqIsoPha => isotope%iqIsoPha
    1367    iqWIsoPha=> isotope%iqWIsoPha
     1386   iqWIsoPha => isotope%iqWIsoPha
    13681387END FUNCTION isoSelectByIndex
    13691388!==============================================================================================================================
     
    15091528!=== OVERWRITE THE KEYS OF THE TRACER NAMED "tr0" WITH THE VALUES FOUND IN THE *.def FILES, IF ANY. ===========================
    15101529!==============================================================================================================================
    1511 LOGICAL FUNCTION addKeysFromDef(t, tr0) RESULT(lerr)
    1512   TYPE(keys_type), ALLOCATABLE, INTENT(INOUT) :: t(:)
     1530SUBROUTINE addKeysFromDef(t, tr0)
     1531  TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: t(:)
    15131532  CHARACTER(LEN=*),             INTENT(IN)    :: tr0
    15141533!------------------------------------------------------------------------------------------------------------------------------
    1515   CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:)
    15161534  CHARACTER(LEN=maxlen) :: val
    15171535  INTEGER               :: ik, jd
    1518   lerr = getKey('name', tname, t); IF(lerr) RETURN
    1519   jd = strIdx(tname(:), tr0)
     1536  jd = strIdx(t%name, tr0)
    15201537  IF(jd == 0) RETURN
    1521   DO ik = 1, SIZE(t(jd)%key)
    1522     CALL get_in(t(jd)%key(ik), val, '*none*')
    1523     IF(val /= '*none*') CALL addKey(t(jd)%key(ik), val, t(jd), .TRUE.)
     1538  DO ik = 1, SIZE(t(jd)%keys%key)
     1539    CALL get_in(t(jd)%keys%key(ik), val, '*none*')
     1540    IF(val /= '*none*') CALL addKey(t(jd)%keys%key(ik), val, t(jd)%keys, .TRUE.)
    15241541  END DO
    1525 END FUNCTION addKeysFromDef
     1542END SUBROUTINE addKeysFromDef
    15261543!==============================================================================================================================
    15271544
     
    15331550  INTEGER,          INTENT(IN)    :: itr
    15341551  CHARACTER(LEN=*), INTENT(IN)    :: keyn(:)
    1535   TYPE(keys_type),  INTENT(INOUT) :: ky(:)
     1552  TYPE(trac_type),  INTENT(INOUT) :: ky(:)
    15361553!------------------------------------------------------------------------------------------------------------------------------
    15371554  CHARACTER(LEN=maxlen), ALLOCATABLE :: k(:), v(:)
     
    15391556  INTEGER :: iky
    15401557  IF(itr<=0 .OR. itr>SIZE(ky, DIM=1)) RETURN                          !--- Index is out of range
    1541   ll = [( ALL(keyn/=ky(itr)%key(iky)), iky=1, SIZE(ky(itr)%key) )]
    1542   k = PACK(ky(itr)%key, MASK=ll); CALL MOVE_ALLOC(FROM=k, TO=ky(itr)%key)
    1543   v = PACK(ky(itr)%val, MASK=ll); CALL MOVE_ALLOC(FROM=v, TO=ky(itr)%val)
     1558  ll = [( ALL(keyn/=ky(itr)%keys%key(iky)), iky=1, SIZE(ky(itr)%keys%key) )]
     1559  k = PACK(ky(itr)%keys%key, MASK=ll); CALL MOVE_ALLOC(FROM=k, TO=ky(itr)%keys%key)
     1560  v = PACK(ky(itr)%keys%val, MASK=ll); CALL MOVE_ALLOC(FROM=v, TO=ky(itr)%keys%val)
    15441561END SUBROUTINE delKey_1
    15451562!==============================================================================================================================
    15461563SUBROUTINE delKey(keyn, ky)
    15471564  CHARACTER(LEN=*), INTENT(IN)    :: keyn(:)
    1548   TYPE(keys_type),  INTENT(INOUT) :: ky(:)
     1565  TYPE(trac_type),  INTENT(INOUT) :: ky(:)
    15491566!------------------------------------------------------------------------------------------------------------------------------
    15501567  INTEGER :: iky
     
    15941611!=== TRY TO GET THE KEY NAMED "key" FOR THE "itr"th TRACER IN:                                                              ===
    15951612!===  * ARGUMENT "ky" DATABASE IF SPECIFIED ; OTHERWISE:                                                                    ===
    1596 !===  * IN INTERNAL TRACERS DATABASE "tracers(:)" (IF UNFOUND, IN INTERNAL ISOTOPES DATABASE "isotope%keys(:)")             ===
     1613!===  * IN INTERNAL TRACERS DATABASE "tracers(:)%keys" (IF UNFOUND, IN INTERNAL ISOTOPES DATABASE "isotope%keys(:)")        ===
    15971614!=== THE RETURNED VALUE (STRING, AN INTEGER, A REAL OR A LOGICAL) CAN BE EITHER:                                            ===
    15981615!===  * A SCALAR                                                                                                            ===
     
    16601677  lerr = .TRUE.
    16611678  IF(lerr .AND. PRESENT(ky))         val = fgetKey(ky)                                   !--- "ky"
    1662   IF(lerr .AND. ALLOCATED (tracers)) val = fgetKey(tracers(:))                           !--- "tracers"
     1679  IF(lerr .AND. ALLOCATED (tracers)) val = fgetKey(tracers(:)%keys)                      !--- "tracers"
    16631680  IF(lerr .AND. ASSOCIATED(isotope)) val = fgetKey(isotope%keys(:))                      !--- "isotope"
    16641681  IF(lerr .AND. PRESENT(def)) THEN
     
    17651782  IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
    17661783  val = str2int(svals)
    1767   lerr = ANY(val == -HUGE(1)) .AND. sval /= ''
     1784  lerr = ANY(val == -HUGE(1))
    17681785  s = 'key "'//TRIM(keyn)//'" of tracer nr. '//TRIM(int2str(itr))//' is not'
    17691786  CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr)
     
    17851802  IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
    17861803  val = str2real(svals)
    1787   lerr = ANY(val == -HUGE(1.)) .AND. sval /= ''
     1804  lerr = ANY(val == -HUGE(1.))
    17881805  s = 'key "'//TRIM(keyn)//'" of tracer nr. '//TRIM(int2str(itr))//' is not'
    17891806  CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr)
     
    18061823  IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
    18071824  ivals = str2bool(svals)
    1808   lerr = ANY(ivals == -1) .AND. sval /= ''
     1825  lerr = ANY(ivals == -1)
    18091826  s = 'key "'//TRIM(keyn)//'" of tracer nr. '//TRIM(int2str(itr))//' is not'
    18101827  CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr)
     
    18431860  IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
    18441861  val = str2int(svals)
    1845   lerr = ANY(val == -HUGE(1)) .AND. sval /= ''
     1862  lerr = ANY(val == -HUGE(1))
    18461863  s = 'key "'//TRIM(strStack(keyn, '/'))//'" of tracer nr. '//TRIM(int2str(itr))//' is not'
    18471864  CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr)
     
    18641881  IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
    18651882  val = str2real(svals)
    1866   lerr = ANY(val == -HUGE(1.)) .AND. sval /= ''
     1883  lerr = ANY(val == -HUGE(1.))
    18671884  s = 'key "'//TRIM(strStack(keyn, '/'))//'" of tracer nr. '//TRIM(int2str(itr))//' is not'
    18681885  CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr)
     
    18861903  IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
    18871904  ivals = str2bool(svals)
    1888   lerr = ANY(ivals == -1) .AND. sval /= ''
     1905  lerr = ANY(ivals == -1)
    18891906  s = 'key "'//TRIM(strStack(keyn, '/'))//'" of tracer nr. '//TRIM(int2str(itr))//' is not'
    18901907  CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr)
     
    18931910!==============================================================================================================================
    18941911!==============================================================================================================================
    1895 LOGICAL FUNCTION getKeyByIndex_s1mm(keyn, val, ky, def, lDisp) RESULT(lerr)
    1896   CHARACTER(LEN=*),                   INTENT(IN)  :: keyn
    1897   CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: val(:)
    1898   TYPE(keys_type),       OPTIONAL,    INTENT(IN)  ::  ky(:)
    1899   CHARACTER(LEN=*),      OPTIONAL,    INTENT(IN)  :: def
    1900   LOGICAL,               OPTIONAL,    INTENT(IN)  :: lDisp
    1901   lerr = getKeyByIndex_smmm([keyn], val, ky, def, lDisp)
     1912LOGICAL FUNCTION getKeyByIndex_s1mm(keyn, val, ky, nam, def, lDisp) RESULT(lerr)
     1913  CHARACTER(LEN=*),                             INTENT(IN)  :: keyn
     1914  CHARACTER(LEN=maxlen),           ALLOCATABLE, INTENT(OUT) :: val(:)
     1915  TYPE(keys_type),       OPTIONAL,              INTENT(IN)  ::  ky(:)
     1916  CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:)
     1917  CHARACTER(LEN=*),      OPTIONAL,              INTENT(IN)  :: def
     1918  LOGICAL,               OPTIONAL,              INTENT(IN)  :: lDisp
     1919  lerr = getKeyByIndex_smmm([keyn], val, ky, nam, def, lDisp)
    19021920END FUNCTION getKeyByIndex_s1mm
    19031921!==============================================================================================================================
    1904 LOGICAL FUNCTION getKeyByIndex_i1mm(keyn, val, ky, def, lDisp) RESULT(lerr)
    1905   CHARACTER(LEN=*),                   INTENT(IN)  :: keyn
    1906   INTEGER,               ALLOCATABLE, INTENT(OUT) :: val(:)
    1907   TYPE(keys_type),       OPTIONAL,    INTENT(IN)  ::  ky(:)
    1908   INTEGER,               OPTIONAL,    INTENT(IN)  :: def
    1909   LOGICAL,               OPTIONAL,    INTENT(IN)  :: lDisp
    1910   lerr = getKeyByIndex_immm([keyn], val, ky, def, lDisp)
     1922LOGICAL FUNCTION getKeyByIndex_i1mm(keyn, val, ky, nam, def, lDisp) RESULT(lerr)
     1923  CHARACTER(LEN=*),                             INTENT(IN)  :: keyn
     1924  INTEGER,                         ALLOCATABLE, INTENT(OUT) :: val(:)
     1925  TYPE(keys_type),       OPTIONAL,              INTENT(IN)  ::  ky(:)
     1926  CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:)
     1927  INTEGER,               OPTIONAL,              INTENT(IN)  :: def
     1928  LOGICAL,               OPTIONAL,              INTENT(IN)  :: lDisp
     1929  lerr = getKeyByIndex_immm([keyn], val, ky, nam, def, lDisp)
    19111930END FUNCTION getKeyByIndex_i1mm
    19121931!==============================================================================================================================
    1913 LOGICAL FUNCTION getKeyByIndex_r1mm(keyn, val, ky, def, lDisp) RESULT(lerr)
    1914   CHARACTER(LEN=*),                   INTENT(IN)  :: keyn
    1915   REAL,                  ALLOCATABLE, INTENT(OUT) :: val(:)
    1916   TYPE(keys_type),       OPTIONAL,    INTENT(IN)  ::  ky(:)
    1917   REAL,                  OPTIONAL,    INTENT(IN)  :: def
    1918   LOGICAL,               OPTIONAL,    INTENT(IN)  :: lDisp
    1919   lerr = getKeyByIndex_rmmm([keyn], val, ky, def, lDisp)
     1932LOGICAL FUNCTION getKeyByIndex_r1mm(keyn, val, ky, nam, def, lDisp) RESULT(lerr)
     1933  CHARACTER(LEN=*),                             INTENT(IN)  :: keyn
     1934  REAL,                            ALLOCATABLE, INTENT(OUT) :: val(:)
     1935  TYPE(keys_type),       OPTIONAL,              INTENT(IN)  ::  ky(:)
     1936  CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:)
     1937  REAL,                  OPTIONAL,              INTENT(IN)  :: def
     1938  LOGICAL,               OPTIONAL,              INTENT(IN)  :: lDisp
     1939  lerr = getKeyByIndex_rmmm([keyn], val, ky, nam, def, lDisp)
    19201940END FUNCTION getKeyByIndex_r1mm
    19211941!==============================================================================================================================
    1922 LOGICAL FUNCTION getKeyByIndex_l1mm(keyn, val, ky, def, lDisp) RESULT(lerr)
    1923   CHARACTER(LEN=*),                   INTENT(IN)  :: keyn
    1924   LOGICAL,               ALLOCATABLE, INTENT(OUT) :: val(:)
    1925   TYPE(keys_type),       OPTIONAL,    INTENT(IN)  ::  ky(:)
    1926   LOGICAL,               OPTIONAL,    INTENT(IN)  :: def
    1927   LOGICAL,               OPTIONAL,    INTENT(IN)  :: lDisp
    1928   lerr = getKeyByIndex_lmmm([keyn], val, ky, def, lDisp)
     1942LOGICAL FUNCTION getKeyByIndex_l1mm(keyn, val, ky, nam, def, lDisp) RESULT(lerr)
     1943  CHARACTER(LEN=*),                             INTENT(IN)  :: keyn
     1944  LOGICAL,                         ALLOCATABLE, INTENT(OUT) :: val(:)
     1945  TYPE(keys_type),       OPTIONAL,              INTENT(IN)  ::  ky(:)
     1946  CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:)
     1947  LOGICAL,               OPTIONAL,              INTENT(IN)  :: def
     1948  LOGICAL,               OPTIONAL,              INTENT(IN)  :: lDisp
     1949  lerr = getKeyByIndex_lmmm([keyn], val, ky, nam, def, lDisp)
    19291950END FUNCTION getKeyByIndex_l1mm
    19301951!==============================================================================================================================
    19311952!==============================================================================================================================
    1932 LOGICAL FUNCTION getKeyByIndex_smmm(keyn, val, ky, def, lDisp) RESULT(lerr)
    1933   CHARACTER(LEN=*),                   INTENT(IN)  :: keyn(:)
    1934   CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) ::  val(:)
    1935   TYPE(keys_type),       OPTIONAL,    INTENT(IN)  ::   ky(:)
    1936   CHARACTER(LEN=*),      OPTIONAL,    INTENT(IN)  ::  def
    1937   LOGICAL,               OPTIONAL,    INTENT(IN)  :: lDisp
     1953LOGICAL FUNCTION getKeyByIndex_smmm(keyn, val, ky, nam, def, lDisp) RESULT(lerr)
     1954  CHARACTER(LEN=*),                             INTENT(IN)  :: keyn(:)
     1955  CHARACTER(LEN=maxlen),           ALLOCATABLE, INTENT(OUT) ::  val(:)
     1956  TYPE(keys_type),       OPTIONAL,              INTENT(IN)  ::   ky(:)
     1957  CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) ::  nam(:)
     1958  CHARACTER(LEN=*),      OPTIONAL,              INTENT(IN)  ::  def
     1959  LOGICAL,               OPTIONAL,              INTENT(IN)  :: lDisp
    19381960!------------------------------------------------------------------------------------------------------------------------------
    19391961  CHARACTER(LEN=maxlen) :: s
     1962  CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:)
    19401963  INTEGER :: iq, nq(3), k
    19411964  LOGICAL :: lD, l(3)
     
    19441967  lerr = .TRUE.
    19451968  IF(PRESENT(ky)) THEN;                 val = fgetKey(ky)                                !--- "ky"
    1946   ELSE IF(ALLOCATED(tracers)) THEN;     val = fgetKey(tracers(:))                        !--- "tracers"
     1969  ELSE IF(ALLOCATED(tracers)) THEN;     val = fgetKey(tracers(:)%keys)                   !--- "tracers"
    19471970     IF(lerr .AND. ASSOCIATED(isotope)) val = fgetKey(isotope%keys(:))                   !--- "isotope"
    19481971  END IF
    1949   IF(.NOT.lerr) RETURN
     1972  IF(.NOT.lerr) THEN; IF(PRESENT(nam)) nam = tname; RETURN; END IF
    19501973  IF(.NOT.PRESENT(def)) THEN; CALL msg('No '//TRIM(s)//' found', modname, lD); RETURN; END IF
    19511974
     
    19681991  INTEGER :: iq
    19691992  lerr = SIZE(ky) == 0; IF(lerr) RETURN
     1993  tname = ky%name
    19701994  val = [(fgetKeyIdx(iq, keyn(:), ky, ler(iq)), iq = 1, SIZE(ky))]
    19711995  lerr = ANY(ler)
     
    19741998END FUNCTION getKeyByIndex_smmm
    19751999!==============================================================================================================================
    1976 LOGICAL FUNCTION getKeyByIndex_immm(keyn, val, ky, def, lDisp) RESULT(lerr)
    1977   CHARACTER(LEN=*),          INTENT(IN)  :: keyn(:)
    1978   INTEGER,      ALLOCATABLE, INTENT(OUT) ::  val(:)
    1979   TYPE(keys_type), OPTIONAL, INTENT(IN)  ::   ky(:)
    1980   INTEGER,         OPTIONAL, INTENT(IN)  ::  def
    1981   LOGICAL,         OPTIONAL, INTENT(IN)  :: lDisp
     2000LOGICAL FUNCTION getKeyByIndex_immm(keyn, val, ky, nam, def, lDisp) RESULT(lerr)
     2001  CHARACTER(LEN=*),                             INTENT(IN)  :: keyn(:)
     2002  INTEGER,                         ALLOCATABLE, INTENT(OUT) ::  val(:)
     2003  TYPE(keys_type),       OPTIONAL,              INTENT(IN)  ::   ky(:)
     2004  CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) ::  nam(:)
     2005  INTEGER,               OPTIONAL,              INTENT(IN)  ::  def
     2006  LOGICAL,               OPTIONAL,              INTENT(IN)  :: lDisp
    19822007!------------------------------------------------------------------------------------------------------------------------------
    19832008  CHARACTER(LEN=maxlen) :: s
    19842009  CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:), tname(:)
    19852010  LOGICAL,               ALLOCATABLE ::    ll(:)
    1986   IF(     PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, int2str(def), lDisp)
    1987   IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, lDisp=lDisp)
     2011  IF(     PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, int2str(def), lDisp)
     2012  IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, lDisp=lDisp)
    19882013  IF(lerr) RETURN
    19892014  val = str2int(svals)
    1990   ll = val == -HUGE(1) .AND. (SIZE(svals) /=1 .OR. svals(1) /= '')
    1991   lerr = ANY(ll); IF(.NOT.lerr) RETURN
    1992   IF(getKeyByIndex_smmm(['name'], tname, ky)) RETURN
     2015  ll = val == -HUGE(1)
     2016  lerr = ANY(ll); IF(.NOT.lerr) THEN; IF(PRESENT(nam)) nam = tname; RETURN; END IF
    19932017  s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(PACK(tname, MASK=ll)))//' is not'
    19942018  CALL msg(TRIM(s)//' an integer: '//TRIM(strStack(svals, MASK=ll)), modname, lerr)
     2019  IF(.NOT.lerr .AND. PRESENT(nam)) nam = tname
    19952020END FUNCTION getKeyByIndex_immm
    19962021!==============================================================================================================================
    1997 LOGICAL FUNCTION getKeyByIndex_rmmm(keyn, val, ky, def, lDisp) RESULT(lerr)
    1998   CHARACTER(LEN=*),          INTENT(IN)  :: keyn(:)
    1999   REAL,         ALLOCATABLE, INTENT(OUT) ::  val(:)
    2000   TYPE(keys_type), OPTIONAL, INTENT(IN)  ::   ky(:)
    2001   REAL,            OPTIONAL, INTENT(IN)  ::  def
    2002   LOGICAL,         OPTIONAL, INTENT(IN)  :: lDisp
     2022LOGICAL FUNCTION getKeyByIndex_rmmm(keyn, val, ky, nam, def, lDisp) RESULT(lerr)
     2023  CHARACTER(LEN=*),                             INTENT(IN)  :: keyn(:)
     2024  REAL,                            ALLOCATABLE, INTENT(OUT) ::  val(:)
     2025  TYPE(keys_type),       OPTIONAL,              INTENT(IN)  ::   ky(:)
     2026  CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) ::  nam(:)
     2027  REAL,                  OPTIONAL,              INTENT(IN)  ::  def
     2028  LOGICAL,               OPTIONAL,              INTENT(IN)  :: lDisp
    20032029!------------------------------------------------------------------------------------------------------------------------------
    20042030  CHARACTER(LEN=maxlen) :: s
    20052031  CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:), tname(:)
    20062032  LOGICAL,               ALLOCATABLE ::    ll(:)
    2007   IF(     PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, real2str(def), lDisp)
    2008   IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, lDisp=lDisp)
     2033  IF(     PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, real2str(def), lDisp)
     2034  IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, lDisp=lDisp)
    20092035  IF(lerr) RETURN
    20102036  val = str2real(svals)
    2011   ll = val == -HUGE(1.) .AND. (SIZE(svals) /=1 .OR. svals(1) /= '')
    2012   lerr = ANY(ll); IF(.NOT.lerr) RETURN
    2013   IF(getKeyByIndex_smmm(['name'], tname, ky)) RETURN
     2037  ll = val == -HUGE(1.)
     2038  lerr = ANY(ll); IF(.NOT.lerr) THEN; IF(PRESENT(nam)) nam = tname; RETURN; END IF
    20142039  s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(PACK(tname, MASK=ll)))//' is not a'
    20152040  CALL msg(TRIM(s)//' a real: '//TRIM(strStack(svals, MASK=ll)), modname)
    20162041END FUNCTION getKeyByIndex_rmmm
    20172042!==============================================================================================================================
    2018 LOGICAL FUNCTION getKeyByIndex_lmmm(keyn, val, ky, def, lDisp) RESULT(lerr)
    2019   CHARACTER(LEN=*),          INTENT(IN)  :: keyn(:)
    2020   LOGICAL,      ALLOCATABLE, INTENT(OUT) ::  val(:)
    2021   TYPE(keys_type), OPTIONAL, INTENT(IN)  ::   ky(:)
    2022   LOGICAL,         OPTIONAL, INTENT(IN)  ::  def
    2023   LOGICAL,         OPTIONAL, INTENT(IN)  :: lDisp
     2043LOGICAL FUNCTION getKeyByIndex_lmmm(keyn, val, ky, nam, def, lDisp) RESULT(lerr)
     2044  CHARACTER(LEN=*),                             INTENT(IN)  :: keyn(:)
     2045  LOGICAL,                         ALLOCATABLE, INTENT(OUT) ::  val(:)
     2046  TYPE(keys_type),       OPTIONAL,              INTENT(IN)  ::   ky(:)
     2047  CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) ::  nam(:)
     2048  LOGICAL,               OPTIONAL,              INTENT(IN)  ::  def
     2049  LOGICAL,               OPTIONAL,              INTENT(IN)  :: lDisp
    20242050!------------------------------------------------------------------------------------------------------------------------------
    20252051  CHARACTER(LEN=maxlen) :: s
     
    20272053  LOGICAL,               ALLOCATABLE ::    ll(:)
    20282054  INTEGER,               ALLOCATABLE :: ivals(:)
    2029   IF(     PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, bool2str(def), lDisp)
    2030   IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, lDisp=lDisp)
     2055  IF(     PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, bool2str(def), lDisp)
     2056  IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, lDisp=lDisp)
    20312057  IF(lerr) RETURN
    20322058  ivals = str2bool(svals)
    2033   ll = ivals == -1 .AND. (SIZE(svals) /=1 .OR. svals(1) /= '')
    2034   lerr = ANY(ll); IF(.NOT.lerr) RETURN
    2035   IF(getKeyByIndex_smmm(['name'], tname, ky)) RETURN
     2059  ll = ivals == -1
     2060  lerr = ANY(ll); IF(.NOT.lerr) THEN; val = ivals == 1; IF(PRESENT(nam)) nam = tname; RETURN; END IF
    20362061  s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(tname, MASK=ll))//' is not'
    20372062  CALL msg(TRIM(s)//' a boolean: '//TRIM(strStack(svals, MASK=ll)), modname)
    2038   IF(.NOT.lerr) val = ivals == 1
    20392063END FUNCTION getKeyByIndex_lmmm
    20402064!==============================================================================================================================
     
    20472071!=== TRY TO GET THE KEY NAMED "key" FOR THE TRACER NAMED "tname" IN:                                                        ===
    20482072!===  * ARGUMENT "ky" DATABASE IF SPECIFIED ; OTHERWISE:                                                                    ===
    2049 !===  * IN INTERNAL TRACERS DATABASE "tracers(:)" (IF UNFOUND, IN INTERNAL ISOTOPES DATABASE "isotope%keys(:)")             ===
     2073!===  * IN INTERNAL TRACERS DATABASE "tracers(:)%keys" (IF UNFOUND, IN INTERNAL ISOTOPES DATABASE "isotope%keys(:)")        ===
    20502074!=== THE RETURNED VALUE (STRING, AN INTEGER, A REAL OR A LOGICAL) CAN BE EITHER:                                            ===
    20512075!===  * A SCALAR                                                                                                            ===
     
    21092133  tnam = strHead(delPhase(tname),'_',.TRUE.)                                             !--- Remove phase and tag
    21102134  IF(lerr .AND. PRESENT(ky))         val = fgetKey(ky)                                   !--- "ky"
    2111   IF(lerr .AND. ALLOCATED (tracers)) val = fgetKey(tracers(:))                           !--- "tracers"
     2135  IF(lerr .AND. ALLOCATED (tracers)) val = fgetKey(tracers(:)%keys)                      !--- "tracers"
    21122136  IF(lerr .AND. ASSOCIATED(isotope)) val = fgetKey(isotope%keys(:))                      !--- "isotope"
    21132137  IF(lerr .AND. PRESENT(def)) THEN
     
    21212145 CHARACTER(LEN=maxlen) FUNCTION fgetKey(ky) RESULT(val)
    21222146  TYPE(keys_type),  INTENT(IN)  :: ky(:)
    2123   CHARACTER(LEN=maxlen), ALLOCATABLE :: tname_all(:)
    2124   lerr = SIZE(ky) == 0;                 IF(lerr) RETURN
    2125   lerr = getKey('name', tname_all, ky); IF(lerr) RETURN
    2126            val = fgetKeyIdx(strIdx(tname_all, tname), [keyn], ky, lerr)
    2127   IF(lerr) val = fgetKeyIdx(strIdx(tname_all, tnam ), [keyn], ky, lerr)
     2147  lerr = SIZE(ky) == 0
     2148  IF(lerr) RETURN
     2149           val = fgetKeyIdx(strIdx(ky%name, tname), [keyn], ky, lerr)
     2150  IF(lerr) val = fgetKeyIdx(strIdx(ky%name, tnam ), [keyn], ky, lerr)
     2151
    21282152END FUNCTION fgetKey
    21292153
     
    21422166  IF(lerr) RETURN
    21432167  val = str2int(sval)
    2144   lerr = val == -HUGE(1) .AND. sval /= ''
     2168  lerr = val == -HUGE(1)
    21452169  s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not'
    21462170  CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr)
     
    21592183  IF(lerr) RETURN
    21602184  val = str2real(sval)
    2161   lerr = val == -HUGE(1.) .AND. sval /= ''
     2185  lerr = val == -HUGE(1.)
    21622186  s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not'
    21632187  CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr)
     
    21772201  IF(lerr) RETURN
    21782202  ival = str2bool(sval)
    2179   lerr = ival == -1 .AND. sval /= ''
     2203  lerr = ival == -1
    21802204  s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not'
    21812205  CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr)
     
    22122236  IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
    22132237  val = str2int(svals)
    2214   lerr = ANY(val == -HUGE(1)) .AND. sval /= ''
     2238  lerr = ANY(val == -HUGE(1))
    22152239  s = 'key "'//TRIM(keyn)//'" of '//TRIM(tname)//' is not'
    22162240  CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr)
     
    22322256  IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
    22332257  val = str2real(svals)
    2234   lerr = ANY(val == -HUGE(1.)) .AND. sval /= ''
     2258  lerr = ANY(val == -HUGE(1.))
    22352259  s = 'key "'//TRIM(keyn)//'" of '//TRIM(tname)//' is not'
    22362260  CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr)
     
    22532277  IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
    22542278  ivals = str2bool(svals)
    2255   lerr = ANY(ivals == -1) .AND. sval /= ''
     2279  lerr = ANY(ivals == -1)
    22562280  s = 'key "'//TRIM(keyn)//'" of '//TRIM(tname)//' is not'
    22572281  CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr)
     
    22882312  IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
    22892313  val = str2int(svals)
    2290   lerr = ANY(val == -HUGE(1)) .AND. sval /= ''
     2314  lerr = ANY(val == -HUGE(1))
    22912315  s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not'
    22922316  CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr)
     
    23082332  IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
    23092333  val = str2real(svals)
    2310   lerr = ANY(val == -HUGE(1.)) .AND. sval /= ''
     2334  lerr = ANY(val == -HUGE(1.))
    23112335  s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not'
    23122336  CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr)
     
    23292353  IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
    23302354  ivals = str2bool(svals)
    2331   lerr = ANY(ivals == -1) .AND. sval /= ''
     2355  lerr = ANY(ivals == -1)
    23322356  s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not'
    23332357  CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr)
     
    23882412  lerr = .TRUE.
    23892413  IF(PRESENT(ky)) THEN;                 val = fgetKey(ky)                                !--- "ky"
    2390   ELSE IF(ALLOCATED(tracers)) THEN;     val = fgetKey(tracers(:))                        !--- "tracers"
     2414  ELSE IF(ALLOCATED(tracers)) THEN;     val = fgetKey(tracers(:)%keys)                   !--- "tracers"
    23912415     IF(lerr .AND. ASSOCIATED(isotope)) val = fgetKey(isotope%keys(:))                   !--- "isotope"
    23922416  END IF
     
    24032427  TYPE(keys_type),       INTENT(IN)  :: ky(:)
    24042428  LOGICAL,               ALLOCATABLE :: ler(:)
    2405   CHARACTER(LEN=maxlen), ALLOCATABLE :: tname_all(:)
    2406   lerr = SIZE(ky) == 0;                 IF(lerr) RETURN
    2407   lerr = getKey('name', tname_all, ky); IF(lerr) RETURN
     2429  lerr = SIZE(ky) == 0; IF(lerr) RETURN
    24082430  ALLOCATE(ler(SIZE(tname)))
    2409   val = [(fgetKeyIdx(strIdx(tname_all, tname(iq)), keyn, ky, ler(iq)), iq = 1, SIZE(tname))]
     2431  val = [(fgetKeyIdx(strIdx(ky(:)%name, tname(iq)), keyn, ky, ler(iq)), iq = 1, SIZE(tname))]
    24102432  lerr = ANY(ler)
    24112433END FUNCTION fgetKey
     
    24272449  IF(lerr) RETURN
    24282450  val = str2int(svals)
    2429   ll = val == -HUGE(1) .AND. (SIZE(svals) /=1 .OR. svals(1) /= '')
     2451  ll = val == -HUGE(1)
    24302452  lerr = ANY(ll); IF(.NOT.lerr) RETURN
    24312453  s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(tname, MASK=ll))//' is not'
     
    24472469  IF(lerr) RETURN
    24482470  val = str2real(svals)
    2449   ll = val == -HUGE(1.) .AND. (SIZE(svals) /=1 .OR. svals(1) /= '')
     2471  ll = val == -HUGE(1.)
    24502472  lerr = ANY(ll); IF(.NOT.lerr) RETURN
    24512473  s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(tname, MASK=ll))//' is not'
     
    24682490  IF(lerr) RETURN
    24692491  ivals = str2bool(svals)
    2470   ll = ivals == -1 .AND. (SIZE(svals) /=1 .OR. svals(1) /= '')
     2492  ll = ivals == -1
    24712493  lerr = ANY(ll); IF(.NOT.lerr) THEN; val = ivals == 1; RETURN; END IF
    24722494  s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(tname, MASK=ll))//' is not'
     
    24802502!==============================================================================================================================
    24812503SUBROUTINE setKeysDBase(tracers_, isotopes_, isotope_)
    2482   TYPE(keys_type), OPTIONAL, INTENT(IN) ::  tracers_(:)
     2504  TYPE(trac_type), OPTIONAL, INTENT(IN) ::  tracers_(:)
    24832505  TYPE(isot_type), OPTIONAL, INTENT(IN) :: isotopes_(:)
    24842506  TYPE(isot_type), OPTIONAL, INTENT(IN) :: isotope_
     
    24892511  IF(PRESENT(isotopes_)) THEN; isotopes = isotopes_; ELSE; ALLOCATE(isotopes(0)); END IF
    24902512  IF(PRESENT(isotope_ )) THEN
    2491     ix = strIdx(isotopes(:)%name, isotope_%name)
     2513    ix = strIdx(isotopes(:)%parent, isotope_%parent)
    24922514    IF(ix /= 0) THEN
    24932515      isotopes(ix) = isotope_
     
    25002522!==============================================================================================================================
    25012523SUBROUTINE getKeysDBase(tracers_, isotopes_, isotope_)
    2502   TYPE(keys_type), OPTIONAL, ALLOCATABLE, INTENT(OUT) ::  tracers_(:)
     2524  TYPE(trac_type), OPTIONAL, ALLOCATABLE, INTENT(OUT) ::  tracers_(:)
    25032525  TYPE(isot_type), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: isotopes_(:)
    25042526  TYPE(isot_type), OPTIONAL,              INTENT(OUT) :: isotope_
     
    25072529  IF(PRESENT( tracers_)) THEN;  tracers_ =  tracers; ELSE; ALLOCATE( tracers_(0)); END IF
    25082530  IF(PRESENT(isotopes_)) THEN; isotopes_ = isotopes; ELSE; ALLOCATE(isotopes_(0)); END IF
    2509   IF(PRESENT(isotope_ )) THEN; ix = strIdx(isotopes(:)%name, isotope%name); IF(ix /= 0) isotope_=isotopes(ix); END IF
     2531  IF(PRESENT(isotope_ )) THEN; ix = strIdx(isotopes(:)%parent, isotope%parent); IF(ix /= 0) isotope_=isotopes(ix); END IF
    25102532END SUBROUTINE getKeysDBase
    25112533!==============================================================================================================================
     
    25832605  CHARACTER(LEN=*),             INTENT(IN)    :: tname
    25842606  TYPE(keys_type),              INTENT(IN)    ::  keys
    2585   TYPE(keys_type), ALLOCATABLE, INTENT(INOUT) :: tracs(:)
    2586   TYPE(keys_type), ALLOCATABLE :: tr(:)
     2607  TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: tracs(:)
     2608  TYPE(trac_type), ALLOCATABLE :: tr(:)
    25872609  CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:)
    25882610  INTEGER :: nt, ix
    25892611  IF(ALLOCATED(tracs)) THEN
    2590      lerr = getKey('name', tnames, ky=tracs(:)); IF(lerr) RETURN
     2612     lerr = getKey('name', tnames, ky=tracs(:)%keys); IF(lerr) RETURN
    25912613     nt = SIZE(tracs)
    25922614     ix = strIdx(tnames, tname)
     
    26002622     ix = 1; ALLOCATE(tracs(1))
    26012623  END IF
    2602   CALL addKey('name', tname, tracs(ix))
    2603   tracs(ix) = keys
     2624  CALL addKey('name', tname, tracs(ix)%keys)
     2625  tracs(ix)%name = tname
     2626  tracs(ix)%keys = keys
    26042627
    26052628END FUNCTION addTracer_1
     
    26162639LOGICAL FUNCTION delTracer_1(tname, tracs) RESULT(lerr)
    26172640  CHARACTER(LEN=*),                     INTENT(IN)    :: tname
    2618   TYPE(keys_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: tracs(:)
    2619   TYPE(keys_type), ALLOCATABLE :: tr(:)
     2641  TYPE(trac_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: tracs(:)
     2642  TYPE(trac_type), ALLOCATABLE :: tr(:)
    26202643  CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:)
    26212644  INTEGER :: nt, ix
     
    26232646  IF(fmsg('Can''t remove tracer "'//TRIM(tname)//'" from an empty tracers descriptor', modname, lerr)) RETURN
    26242647  nt = SIZE(tracs)
    2625   lerr = getKey('name', tnames, ky=tracs(:)); IF(lerr) RETURN
     2648  lerr = getKey('name', tnames, ky=tracs(:)%keys); IF(lerr) RETURN
    26262649  ix = strIdx(tnames, tname)
    26272650  CALL msg('Removing tracer "'             //TRIM(tname)//'"', modname, ix /= 0)
     
    26672690
    26682691!==============================================================================================================================
    2669 !======== CONVERT WATER-DERIVED NAMES FROM FORMER TO CURRENT CONVENTION & VICE VERSA ; OTHER NAMES ARE LEFT UNTOUCHED =========
    2670 !===== OLD NAMES STRUCTURE:  H2O[<phase>][_<isotope>][_<tag>] (<phase> from "old_phases",        <isotope> from "oldH2OIso") ==
    2671 !====  NEW NAMES STRUCTURE: <var>[<phase_sep><phase>][_<tag>] (<phase> from "known_phases", <var>='H2O' or from "newH2OIso") ==
     2692!============ CONVERT WATER-DERIVED NAMES FROM FORMER TO CURRENT CONVENTION ; OTHER NAMES ARE LEFT UNTOUCHED ==================
     2693!======= NAMES STRUCTURE: H2O[<phase>][_<isotope>][_<tag>] (<phase> from "old_phases", <isotope> from "oldH2OIso") ============
    26722694!==============================================================================================================================
    26732695CHARACTER(LEN=maxlen) FUNCTION old2newH2O_1(oldName, iPhase) RESULT(newName)
     
    27022724END FUNCTION old2newH2O_m
    27032725!==============================================================================================================================
     2726
     2727
     2728!==============================================================================================================================
     2729!============ CONVERT WATER-DERIVED NAMES FROM CURRENT TO FORMER CONVENTION ; OTHER NAMES ARE LEFT UNTOUCHED ==================
     2730!==== NAMES STRUCTURE: <var>[<phase_sep><phase>][_<tag>] (<phase> from "known_phases", <var> = 'H2O' or from "newH2OIso") =====
     2731!==============================================================================================================================
    27042732CHARACTER(LEN=maxlen) FUNCTION new2oldH2O_1(newName, iPhase) RESULT(oldName)
    27052733  CHARACTER(LEN=*),  INTENT(IN)  :: newName
  • LMDZ6/trunk/libf/phylmd/infotrac_phy.F90

    r5184 r5190  
    33MODULE infotrac_phy
    44
    5    USE       strings_mod, ONLY: msg, maxlen, cat, dispTable, int2str, bool2str, strStack, strParse, strCount, strIdx
    6    USE readTracFiles_mod, ONLY: readTracersFiles, maxTableWidth,  tisot=>isot_type, addPhase, addKey, iH2O, &
    7         indexUpdate, keys_type, testTracersFiles, processIsotopes, trac=>tracers,   delPhase, getKey, tran0
    8    USE readTracFiles_mod, ONLY: new2oldH2O
    9 
     5   USE       strings_mod, ONLY: msg, fmsg, maxlen, cat, dispTable, int2str, bool2str, strStack, strParse, strIdx
     6   USE readTracFiles_mod, ONLY: trac_type, readTracersFiles, tracers, setGeneration, itZonIso, nzone, tran0, isoZone, &
     7        delPhase, niso, getKey, isot_type, processIsotopes,  isotope, maxTableWidth, iqIsoPha, nphas, ixIso, isoPhas, &
     8        addPhase, iH2O, addKey, isoSelect, testTracersFiles, isoKeys, indexUpdate,  iqWIsoPha, nbIso, ntiso, isoName, isoCheck
    109   IMPLICIT NONE
    1110
     
    1716   PUBLIC :: nqtot,   nbtr,   nqo,   nqCO2,   nqtottr      !--- Main dimensions
    1817   PUBLIC :: conv_flg, pbl_flg                             !--- Convection & boundary layer activation keys
    19    PUBLIC :: new2oldH2O                                    !--- For backwards compatibility in phyetat0
    20    PUBLIC :: addPhase, delPhase                            !--- Add/remove the phase from the name of a tracer
    21 #if defined CPP_StratAer || defined REPROBUS
     18#ifdef CPP_StratAer
    2219   PUBLIC :: nbtr_bin, nbtr_sulgas                         !--- Number of aerosols bins and sulfur gases for StratAer model
    2320   PUBLIC :: id_OCS_strat, id_SO2_strat, id_H2SO4_strat, id_BIN01_strat, id_TEST_strat
    2421#endif
    2522
     23   !=== FOR WATER
     24   PUBLIC :: ivap, iliq, isol
    2625   !=== FOR ISOTOPES: General
    2726   PUBLIC :: isot_type, nbIso                              !--- Derived type, full isotopes families database + nb of families
    28    PUBLIC :: isoSelect, ixIso, isoFamilies                 !--- Isotopes families selection tool + selected index + list
     27   PUBLIC :: isoSelect, ixIso                              !--- Isotopes family selection tool + selected family index
    2928   !=== FOR ISOTOPES: Specific to water
    30    PUBLIC :: iH2O                                          !--- Value of "ixIso" for "H2O" isotopes class
    31    PUBLIC :: ivap, iliq, isol
     29   PUBLIC :: iH2O                                          !--- H2O isotopes class index
    3230   !=== FOR ISOTOPES: Depending on the selected isotopes family
    33    PUBLIC :: isotope                                       !--- Selected isotopes database (argument of getKey)
    34    PUBLIC :: isoKeys, isoName, isoZone, isoPhas            !--- Isotopes keys & names, tagging zones names, phases
    35    PUBLIC ::    niso,   ntiso,   nzone,   nphas            !--- Number of   "   "
    36    PUBLIC :: itZonIso                                      !--- index "it" in "isoName(1:niso)" = f(tagging idx, isotope idx)
    37    PUBLIC :: iqIsoPha                                      !--- index "iq" in "qx"              = f(isotope idx,   phase idx)
    38    PUBLIC :: iqWIsoPha                                     !--- Same as iqIsoPha but with normal water phases
     31   PUBLIC :: isotope, isoKeys                              !--- Selected isotopes database + associated keys (cf. getKey)
     32   PUBLIC :: isoName, isoZone, isoPhas                     !--- Isotopes and tagging zones names, phases
     33   PUBLIC :: niso,    nzone,   nphas,   ntiso              !---  " " numbers + isotopes & tagging tracers number
     34   PUBLIC :: itZonIso                                      !--- idx "it" (in "isoName(1:niso)") = function(tagging idx, isotope idx)
     35   PUBLIC :: iqIsoPha                                      !--- idx "iq" (in "qx") = function(isotope idx, phase idx) + aliases
     36   PUBLIC :: iqWIsoPha                                      !--- Same as iqIsoPha but with normal water phases
     37
    3938   PUBLIC :: isoCheck                                      !--- Run isotopes checking routines
    4039   !=== FOR BOTH TRACERS AND ISOTOPES
     
    4443!  |--------------------+-----------------------+-----------------+---------------+----------------------------|
    4544!  | water in different |    water tagging      |  water isotopes | other tracers | additional tracers moments |
    46 !  | phases: H2O_[glsrb]|      isotopes         |                 |               |  for higher order schemes  |
     45!  | phases: H2O_[gls|      isotopes         |                 |               |  for higher order schemes  |
    4746!  |--------------------+-----------------------+-----------------+---------------+----------------------------|
    4847!  |                    |                       |                 |               |                            |
     
    5857!  |-----------------------------------------------------------------------------------------------------------|
    5958!  NOTES FOR THIS TABLE:
    60 !  * Used "niso", "nzone" and "ntiso" are components of "isotopes(ip)" for water (isotopes(ip)%name == 'H2O'),
     59!  * Used "niso", "nzone" and "ntiso" are components of "isotopes(ip)" for water (isotopes(ip)%parent == 'H2O'),
    6160!    since water is so far the sole tracers family, except passive CO2, removed from the main tracers table.
    6261!  * For water, "nqo" is equal to the more general field "isotopes(ip)%nphas".
    6362!  * "niso", "nzone", "ntiso", "nphas" are defined for other isotopic tracers families, if any.
    64 !  * If you deal with an isotopes family other than "H2O" ("Sulf" in the example), a good practice is to keep
    65 !    track of the isotopes class (of its index) before switching to it at the beginning of the dedicated code:
    66 !  - first time (use selection by name and compute the corresponding index iSulf) :
    67 !  i0=ixIso; IF(.NOT.isoSelect('Sulf')) CALL abort_physic("Can't select isotopes class", modname, 1); iS=ixIso
    68 !  - next times (use selection by index - "iS" has been computed at first call):
    69 !  i0=ixIso; IF(.NOT.isoSelect(iS))     CALL abort_physic("Can't select isotopes class", modname, 1)
    70 !    and to switch back to the original category when you're done with "Sulf":
    71 !            IF(.NOT.isoSelect(i0))     CALL abort_physic("Can't select isotopes class", modname, 1)
    72 !    to restore the original isotopes category (before dealing with "Sulf" (most of the time "H2O").
    7363!
    7464!=== DERIVED TYPE EMBEDDING MOST OF THE TRACERS-RELATED QUANTITIES (LENGTH: nqtot)
     
    7868!  |-------------+------------------------------------------------------+-------------+------------------------+
    7969!  | name        | Name (short)                                         | tname       |                        |
    80 !  | keys        | key/val pairs accessible with "getKey" routine       | /           |                        |
    8170!  | gen0Name    | Name of the 1st generation ancestor                  | /           |                        |
    8271!  | parent      | Name of the parent                                   | /           |                        |
    8372!  | longName    | Long name (with adv. scheme suffix) for outputs      | ttext       |                        |
    8473!  | type        | Type (so far: tracer or tag)                         | /           | tracer,tag             |
    85 !  | phase       | Phases list ("g"as / "l"iquid / "s"olid              |             | [g|l|s|r|b]            |
    86 !  |             |              "r"(cloud) / "b"lowing)                 | /           |                        |
     74!  | phase       | Phases list ("g"as / "l"iquid / "s"olid)             | /           | [g][l][s]              |
    8775!  | component   | Name(s) of the merged/cumulated section(s)           | /           | coma-separated names   |
    8876!  | iGeneration | Generation (>=1)                                     | /           |                        |
     
    9179!  | nqDescen    | Number of the descendants   (all generations)        | nqdesc      | 1:nqtot                |
    9280!  | nqChildren  | Number of childs            (1st generation only)    | nqfils      | 1:nqtot                |
    93 !  | isAdvected  | Advected tracers flag (.TRUE. if iadv >= 0)          | /           | nqtrue  .TRUE. values  |
    94 !  | isInPhysics | Tracers not extracted from the main table in physics | /           | nqtottr .TRUE. values  |
     81!  | keys        | key/val pairs accessible with "getKey" routine       | /           |                        |
     82!  | isAdvected  | advected tracers flag (.TRUE. if iadv >= 0)          | /           | nqtrue  .TRUE. values  |
     83!  | isInPhysics | tracers not extracted from the main table in physics | /           | nqtottr .TRUE. values  |
    9584!  | iso_iGroup  | Isotopes group index in isotopes(:)                  | /           | 1:nbIso                |
    9685!  | iso_iName   | Isotope  name  index in isotopes(iso_iGroup)%trac(:) | iso_indnum  | 1:niso                 |
     
    10493!  |  entry | length | Meaning                                          |    Former name     | Possible values |
    10594!  |-----------------+--------------------------------------------------+--------------------+-----------------+
    106 !  | name            | Name of the isotopes class (family)              |                    |                 |
     95!  | parent          | Parent tracer (isotopes family name)             |                    |                 |
    10796!  | keys   | niso   | Isotopes keys/values pairs list + number         |                    |                 |
    10897!  | trac   | ntiso  | Isotopes + tagging tracers list + number         | / | ntraciso       |                 |
    10998!  | zone   | nzone  | Geographic tagging zones   list + number         | / | ntraceurs_zone |                 |
    110 !  | phase  | nphas  | Phases                     list + number         |                    | [g|l|s|r|b] 1:5 |
     99!  | phase  | nphas  | Phases                     list + number         |                    | [g][l][s], 1:3 |
    111100!  | iqIsoPha        | Index in "qx"           = f(name(1:ntiso)),phas) | iqiso              | 1:nqtot         |
    112 !  | iqWIsoPha       | Index in "qx"       = f(name(1:ntiso+nqo)),phas) |   ?                | 1:nqtot         |
     101!  | iqWIsoPha       | Index in "qx"           = f(name(1:ntiso)),phas) | iqiso              | 1:nqtot         |
    113102!  | itZonIso        | Index in "trac(1:ntiso)"= f(zone, name(1:niso))  | index_trac         | 1:ntiso         |
    114103!  +-----------------+--------------------------------------------------+--------------------+-----------------+
    115104
    116 !------------------------------------------------------------------------------------------------------------------------------
    117    TYPE :: trac_type                                            !=== TYPE FOR A SINGLE TRACER NAMED "name"
    118      CHARACTER(LEN=maxlen) :: name        = ''                  !--- Name of the tracer
    119      TYPE(keys_type)       :: keys                              !--- <key>=<val> pairs vector (general container)
    120      CHARACTER(LEN=maxlen) :: gen0Name    = ''                  !--- First generation ancestor name
    121      CHARACTER(LEN=maxlen) :: parent      = ''                  !--- Parent name
    122      CHARACTER(LEN=maxlen) :: longName    = ''                  !--- Long name (with advection scheme suffix)
    123      CHARACTER(LEN=maxlen) :: type        = 'tracer'            !--- Type  (so far: 'tracer' / 'tag')
    124      CHARACTER(LEN=maxlen) :: phase       = 'g'                 !--- Phase ('g'as / 'l'iquid / 's'olid)
    125      CHARACTER(LEN=maxlen) :: component   = ''                  !--- Coma-separated list of components (Ex: lmdz,inca)
    126      INTEGER               :: iGeneration = -1                  !--- Generation number (>=0)
    127      INTEGER               :: iqParent    = 0                   !--- Parent index
    128      INTEGER,  ALLOCATABLE :: iqDescen(:)                       !--- Descendants index (in growing generation order)
    129      INTEGER               :: nqDescen    = 0                   !--- Number of descendants (all generations)
    130      INTEGER               :: nqChildren  = 0                   !--- Number of children  (first generation)
    131      LOGICAL               :: isAdvected  = .FALSE.             !--- "true" tracers: iadv > 0.   COUNT(isAdvected )=nqtrue
    132      LOGICAL               :: isInPhysics = .TRUE.              !--- "true" tracers: in tr_seri. COUNT(isInPhysics)=nqtottr
    133      INTEGER               :: iso_iGroup  = 0                   !--- Isotopes group index in isotopes(:)
    134      INTEGER               :: iso_iName   = 0                   !--- Isotope  name  index in isotopes(iso_iGroup)%trac(:)
    135      INTEGER               :: iso_iZone   = 0                   !--- Isotope  zone  index in isotopes(iso_iGroup)%zone(:)
    136      INTEGER               :: iso_iPhase  = 0                   !--- Isotope  phase index in isotopes(iso_iGroup)%phase
    137    END TYPE trac_type
    138 !------------------------------------------------------------------------------------------------------------------------------
    139   TYPE :: isot_type                                             !=== TYPE FOR THE ISOTOPES FAMILY DESCENDING ON TRACER "name"
    140     CHARACTER(LEN=maxlen)              :: name                  !--- Isotopes family name (ex: H2O)
    141     TYPE(keys_type),       ALLOCATABLE :: keys(:)               !--- Isotopes keys/values pairs list     (length: niso)
    142     LOGICAL                            :: check=.FALSE.         !--- Flag for checking routines triggering
    143     CHARACTER(LEN=maxlen), ALLOCATABLE :: trac(:)               !--- Isotopes + tagging tracers list     (length: ntiso)
    144     CHARACTER(LEN=maxlen), ALLOCATABLE :: zone(:)               !--- Geographic tagging zones names list (length: nzone)
    145     CHARACTER(LEN=maxlen)              :: phase = 'g'           !--- Phases list: [g|l|s|r|b]            (length: nphas)
    146     INTEGER                            :: niso  = 0             !--- Number of isotopes, excluding tagging tracers
    147     INTEGER                            :: ntiso = 0             !--- Number of isotopes, including tagging tracers
    148     INTEGER                            :: nzone = 0             !--- Number of geographic tagging zones
    149     INTEGER                            :: nphas = 0             !--- Number of phases
    150     INTEGER,               ALLOCATABLE :: iqIsoPha(:,:)         !--- Idx in "tracers(1:nqtot)" = f(     name(1:ntiso) ,phas)
    151     INTEGER,               ALLOCATABLE :: iqWIsoPha(:,:)        !--- Idx in "tracers(1:nqtot)" = f([H2O,name(1:ntiso)],phas)
    152     INTEGER,               ALLOCATABLE :: itZonIso(:,:)         !--- Idx in "trac(1:ntiso)"    = f(zone,name(1:niso))
    153   END TYPE isot_type
    154 !------------------------------------------------------------------------------------------------------------------------------
    155   INTERFACE isoSelect; MODULE PROCEDURE isoSelectByIndex, isoSelectByName; END INTERFACE isoSelect
    156 !------------------------------------------------------------------------------------------------------------------------------
    157 
    158    !=== INDICES FOR WATER
    159    INTEGER, SAVE :: ivap, iliq, isol
    160 !$OMP THREADPRIVATE(ivap, iliq, isol)
    161 
    162105   !=== DIMENSIONS OF THE TRACERS TABLES AND OTHER SCALAR VARIABLES
    163    INTEGER,               SAVE :: nqtot,   &                    !--- Tracers nb in dynamics (incl. higher moments + H2O)
    164                                   nbtr,    &                    !--- Tracers nb in physics  (excl. higher moments + H2O)
    165                                   nqo,     &                    !--- Number of water phases
     106   INTEGER,               SAVE :: nqtot,  &                     !--- Tracers nb in dynamics (incl. higher moments + H2O)
     107                                  nbtr,   &                     !--- Tracers nb in physics  (excl. higher moments + H2O)
     108                                  nqo,    &                     !--- Number of water phases
    166109                                  nqtottr, &                    !--- Number of tracers passed to phytrac (TO BE DELETED ?)
    167110                                  nqCO2                         !--- Number of tracers of CO2  (ThL)
     
    169112!$OMP THREADPRIVATE(nqtot, nbtr, nqo, nqtottr, nqCO2, type_trac)
    170113
    171    !=== NUMBER AND LIST OF DEFINED ISOTOPES FAMILIES
    172    INTEGER,               SAVE              :: nbIso            !--- Number of defined isotopes classes
    173    CHARACTER(LEN=maxlen), SAVE, ALLOCATABLE :: isoFamilies(:)   !--- Generation 0 tracer name for each isotopes family (nbIso)
    174 !$OMP THREADPRIVATE(isoFamilies)
    175 
    176    !=== QUANTITIES RELATED TO THE CURRENTLY SELECTED ISOTOPES CLASS (USUALLY H2O)
    177    TYPE(isot_type),       SAVE, POINTER :: isotope              !--- Selected isotopes database (=isotopes(ixIso))
    178    TYPE(keys_type),       SAVE, POINTER :: isoKeys(:)           !--- Database to get isotopes keys using "getKey"       (niso)
    179    CHARACTER(LEN=maxlen), SAVE, POINTER :: isoName(:),      &   !--- Isotopes list including tagging tracers, no phase (ntiso)
    180                                            isoZone(:),      &   !--- Geographic tagging zones list                     (nzone)
    181                                            isoPhas              !--- Used phases names ([g|l|s|r|b])                   (nphas)
    182    INTEGER,               SAVE, POINTER :: itZonIso(:,:),   &   !--- Idx "it" in isoName(1:niso) = f(tagging idx, isotope idx)
    183                                            iqIsoPha(:,:),   &   !--- Idx "iq" in qx              = f(isotope idx,   phase idx)
    184                                            iqWIsoPha(:,:)       !--- Idx "iq" in qx = f([parent trac,isotope idx],  phase idx)
    185    INTEGER,               SAVE          :: ixIso,           &   !--- Idx in "isoFamilies" of currently selectd class
    186                                            niso,            &   !--- Number of isotopes
    187                                            ntiso,           &   !--- Number of isotopes + tagging tracers
    188                                            nzone,           &   !--- Number of tagging zones
    189                                            nphas                !--- Number of phases
    190    LOGICAL,               SAVE          :: isoCheck             !--- Isotopes checking routines triggering flag
    191 !$OMP THREADPRIVATE(isotope, isoKeys, isoName, isoZone, isoPhas, itZonIso, iqIsoPha, iqWIsoPha, niso, ntiso, nzone, nphas, isoCheck)
     114   !=== INDICES OF WATER
     115   INTEGER,               SAVE :: ivap,iliq,isol ! Indices for vap, liq and ice
     116!$OMP THREADPRIVATE(ivap,iliq,isol)
    192117
    193118   !=== VARIABLES FOR INCA
    194    INTEGER, DIMENSION(:), SAVE, ALLOCATABLE :: &
    195                     conv_flg, pbl_flg                           !--- Convection / boundary layer activation (nbtr)
     119   INTEGER,               SAVE, ALLOCATABLE :: conv_flg(:), &   !--- Convection     activation ; needed for INCA        (nbtr)
     120                                                pbl_flg(:)      !--- Boundary layer activation ; needed for INCA        (nbtr)
    196121!$OMP THREADPRIVATE(conv_flg, pbl_flg)
    197122
    198    !=== TRACERS/ISOTOPES DESCRIPTORS: EFFECTIVE STORAGE (LOCAL DERIVED TYPES)
    199    TYPE(trac_type), SAVE, ALLOCATABLE, TARGET ::  tracers(:)
    200    TYPE(isot_type), SAVE, ALLOCATABLE, TARGET :: isotopes(:)
    201 !$OMP THREADPRIVATE(tracers, isotopes)
    202 
    203 #if defined CPP_StratAer || defined REPROBUS
     123#ifdef CPP_StratAer
    204124  !=== SPECIFIC TO STRATOSPHERIC AEROSOLS (CK/OB)
    205125  INTEGER, SAVE ::  nbtr_bin, nbtr_sulgas         !--- number of aerosols bins and sulfur gases for StratAer model
     
    213133SUBROUTINE init_infotrac_phy
    214134   USE ioipsl_getin_p_mod, ONLY: getin_p
    215    USE mod_phys_lmdz_para, ONLY: is_master, is_omp_master
    216135#ifdef REPROBUS
    217136   USE CHEM_REP, ONLY: Init_chem_rep_trac
     
    242161!------------------------------------------------------------------------------------------------------------------------------
    243162! Local variables
    244    INTEGER, ALLOCATABLE :: hadv(:), vadv(:), itmp(:)                 !--- Horizontal/vertical transport scheme number
     163   INTEGER, ALLOCATABLE :: hadv(:), vadv(:)                          !--- Horizontal/vertical transport scheme number
    245164#ifdef INCA
    246165   INTEGER, ALLOCATABLE :: had (:), hadv_inca(:), conv_flg_inca(:), &!--- Variables specific to INCA
     
    254173   CHARACTER(LEN=2)      ::   suff(9)                                !--- Suffixes for schemes of order 3 or 4 (Prather)
    255174   CHARACTER(LEN=3)      :: descrq(30)                               !--- Advection scheme description tags
    256    CHARACTER(LEN=maxlen) :: msg1, texp, ttp, ky                      !--- Strings for messages and expanded tracers type
     175   CHARACTER(LEN=maxlen) :: msg1, texp, ttp                          !--- String for messages and expanded tracers type
    257176   INTEGER :: fType                                                  !--- Tracers description file type ; 0: none
    258177                                                                     !--- 1/2/3: "traceur.def"/"tracer.def"/"tracer_*.def"
    259178   INTEGER :: nqtrue                                                 !--- Tracers nb from tracer.def (no higher order moments)
    260179   INTEGER :: iad                                                    !--- Advection scheme number
    261    INTEGER :: iq, jq, it, nt, im, nm                                 !--- Indexes and temporary variables
    262    LOGICAL :: lInit
    263    TYPE(keys_type), ALLOCATABLE, TARGET :: tra(:)                    !--- Tracers  descriptor as in readTracFiles_mod
    264    TYPE(tisot),     ALLOCATABLE         :: iso(:)                    !--- Isotopes descriptor as in readTracFiles_mod
     180   INTEGER :: iq, jq, nt, im, nm, k                                 !--- Indexes and temporary variables
     181   LOGICAL :: lerr, lInit
    265182   TYPE(trac_type), ALLOCATABLE, TARGET :: ttr(:)
    266    TYPE(trac_type), POINTER             :: t(:), t1
    267    TYPE(keys_type), POINTER             :: k(:)
    268    CHARACTER(LEN=maxlen),   ALLOCATABLE :: types_trac(:)             !--- Keywords for tracers type(s), parsed version
     183   TYPE(trac_type), POINTER             :: t1, t(:)
     184   CHARACTER(LEN=maxlen),   ALLOCATABLE :: types_trac(:)  !--- Keyword for tracers type(s), parsed version
     185   
    269186   CHARACTER(LEN=*), PARAMETER :: modname="init_infotrac_phy"
    270187!------------------------------------------------------------------------------------------------------------------------------
     
    278195
    279196   CALL getin_p('type_trac',type_trac)
    280    CALL msg('type_trac = "'//TRIM(type_trac)//'"', modname, is_master)
    281    IF(strCount(type_trac, '|', nt)) CALL abort_physic(modname, 'Could''nt parse the "type_trac" string with delimiter "|"', 1)
    282    IF(nt >= 3) CALL abort_physic(modname, 'you need to modify type_trac, this version is not supported by lmdz', 1)
    283    IF(strParse(type_trac, '|', types_trac, n=nt)) CALL abort_physic(modname, "couldn't parse "//'"type_trac"', 1)
    284    IF(nt == 2) type_trac = types_trac(2) ! TO BE DELETED SOON
    285 
    286    lInit = .NOT.ALLOCATED(trac)
    287 
    288 !##############################################################################################################################
    289    IF(lInit .AND. is_master) THEN                                    !=== SKIPED IF ALREADY DONE
     197
     198   lerr=strParse(type_trac, '|', types_trac, n=nt)
     199   IF (nt .GT. 1) THEN
     200      IF (nt .GT. 2) CALL abort_physic(modname, 'you need to modify type_trac, this version is not supported by lmdz', 1)
     201      IF (nt .EQ. 2) type_trac=types_trac(2)
     202   ENDIF
     203
     204   
     205   CALL msg('type_trac = "'//TRIM(type_trac)//'"', modname)
     206   lInit = .NOT.ALLOCATED(tracers)
     207
     208!##############################################################################################################################
     209   IF(lInit) THEN                                                    !=== SKIPED IF ALREADY DONE IN dyn3d_common/infotrac  ####
    290210!##############################################################################################################################
    291211   !--- MESSAGE ABOUT THE CHOSEN CONFIGURATION
     
    320240!##############################################################################################################################
    321241
    322 !==============================================================================================================================
    323 ! 0) DETERMINE THE TYPE OF THE INPUT TRACERS DESCRIPTION FILE AND READ IT ; TRANSFER THE NEEDED QUANTITIES TO LOCAL "tracers".
    324 !==============================================================================================================================
    325    texp = type_trac                                                            !=== EXPANDED (WITH "|" SEPARATOR) "type_trac"
     242   nqCO2 = COUNT( [type_trac == 'inco', type_trac == 'co2i'] )
     243
     244!==============================================================================================================================
     245! 1) Get the numbers of: true (first order only) tracers "nqtrue", water tracers "nqo" (vapor/liquid/solid)
     246!==============================================================================================================================
     247   texp = type_trac                                                  !=== EXPANDED VERSION OF "type_trac", WITH "|" SEPARATOR
    326248   IF(texp == 'inco') texp = 'co2i|inca'
    327249   IF(texp /= 'lmdz') texp = 'lmdz|'//TRIM(texp)
    328    IF(testTracersFiles(modname, texp, fType, lInit.AND.is_master)) CALL abort_physic(modname, 'problem with tracers file(s)',1)
     250
     251   !=== DETERMINE THE TYPE OF THE INPUT TRACERS DESCRIPTION FILE
     252   IF(testTracersFiles(modname, texp, fType, lInit)) CALL abort_physic(modname, 'problem with tracers file(s)',1)
     253
    329254   ttp = type_trac; IF(fType /= 1) ttp = texp
    330    !---------------------------------------------------------------------------------------------------------------------------
    331    IF(fType == 0) CALL abort_physic(modname, 'Missing "traceur.def", "tracer.def" or "tracer_<keyword>.def tracers file.',1)
    332    !---------------------------------------------------------------------------------------------------------------------------
    333    IF(fType == 1 .AND. ANY(['inca', 'inco'] == type_trac)) &                   !=== FOUND OLD STYLE INCA "traceur.def"
    334       CALL abort_physic(modname, 'retro-compatibility with old-style INCA traceur.def files has been disabled.', 1)
    335    !---------------------------------------------------------------------------------------------------------------------------
    336 
    337 !##############################################################################################################################
    338    IF(lInit .AND. is_omp_master) THEN
    339       IF(readTracersFiles(ttp, tra, type_trac == 'repr')) CALL abort_physic(modname, 'problem with tracers file(s)',1)
     255
     256!##############################################################################################################################
     257   IF(lInit) THEN
     258      IF(readTracersFiles(ttp, lRepr=type_trac=='repr')) CALL abort_physic(modname, 'problem with tracers file(s)',1)
    340259   ELSE
    341       tra = trac
    342    END IF
    343    CALL msg('No tracers description file(s) reading needed: already done', modname, .NOT.lInit.AND.is_master)
    344 !##############################################################################################################################
    345 
    346    !--- POPULATE SOME EXPLICIT (ACCESSIBLE THROUGH "%") KEYS OF THE LOCAL TRACERS DESCRIPTION DERIVED TYPE
    347    !    To be defined: iqParent, iq/nqDescen, nqChildren (in indexUpdate), longName, iso_i*, isAdvected, isInPhysics (later)
    348    ALLOCATE(tracers(SIZE(tra)))
    349    DO iq = 1, SIZE(tra); t1 => tracers(iq)
    350       t1%keys = tra(iq)
    351       msg1 = '" for tracer nr. '//TRIM(int2str(iq))
    352       ky='name       '; IF(getKey(ky, t1%name,        iq, tra)) CALL abort_physic(modname, 'No key "'//TRIM(ky)//TRIM(msg1), 1)
    353       msg1 = '" for "'//TRIM(t1%name)//'"'
    354       ky='gen0Name   '; IF(getKey(ky, t1%gen0Name,    iq, tra)) CALL abort_physic(modname, 'No key "'//TRIM(ky)//TRIM(msg1), 1)
    355       ky='parent     '; IF(getKey(ky, t1%parent,      iq, tra)) CALL abort_physic(modname, 'No key "'//TRIM(ky)//TRIM(msg1), 1)
    356       ky='type       '; IF(getKey(ky, t1%type,        iq, tra)) CALL abort_physic(modname, 'No key "'//TRIM(ky)//TRIM(msg1), 1)
    357       ky='phase      '; IF(getKey(ky, t1%phase,       iq, tra)) CALL abort_physic(modname, 'No key "'//TRIM(ky)//TRIM(msg1), 1)
    358       ky='component  '; IF(getKey(ky, t1%component,   iq, tra)) CALL abort_physic(modname, 'No key "'//TRIM(ky)//TRIM(msg1), 1)
    359       ky='iGeneration'; IF(getKey(ky, t1%iGeneration, iq, tra)) CALL abort_physic(modname, 'No key "'//TRIM(ky)//TRIM(msg1), 1)
    360    END DO
    361 
    362 !==============================================================================================================================
    363 ! 1) Get various numbers: "nqtrue" (first order only tracers), "nqo" (water phases), 'nbtr' (tracers passed to physics), etc.
    364 !==============================================================================================================================
    365    nqtrue = SIZE(tracers)                                                                               !--- "true" tracers
    366    nqo    =      COUNT(tracers(:)%component == 'lmdz' .AND. delPhase(tracers(:)%name)     == 'H2O')     !--- Water phases
    367    nbtr = nqtrue-COUNT(tracers(:)%component == 'lmdz' .AND. delPhase(tracers(:)%gen0Name) == 'H2O')     !--- Passed to phytrac
    368    nqCO2  =      COUNT( [type_trac == 'inco', type_trac == 'co2i'] )
     260      CALL msg('No tracers description file(s) reading needed: already done in the dynamics', modname)
     261   END IF
     262!##############################################################################################################################
     263
     264   !---------------------------------------------------------------------------------------------------------------------------
     265   IF(fType == 0) CALL abort_physic(modname, 'Missing tracers file: "traceur.def", "tracer.def" or "tracer_<keyword>.def file.',1)
     266   !---------------------------------------------------------------------------------------------------------------------------
     267   IF(fType == 1 .AND. ANY(['inca','inco']==type_trac) .AND. lInit) THEN  !=== FOUND OLD STYLE INCA "traceur.def"
     268   !---------------------------------------------------------------------------------------------------------------------------
    369269#ifdef INCA
    370    nqINCA =      COUNT(tracers(:)%component == 'inca')
    371 #endif
     270      nqo = SIZE(tracers) - nqCO2
     271      CALL Init_chem_inca_trac(nqINCA)                               !--- Get nqINCA from INCA
     272      nbtr = nqINCA + nqCO2                                          !--- Number of tracers passed to phytrac
     273      nqtrue = nbtr + nqo                                            !--- Total number of "true" tracers
     274      IF(ALL([2,3] /= nqo)) CALL abort_physic(modname, 'Only 2 or 3 water phases allowed ; found nqo='//TRIM(int2str(nqo)), 1)
     275      ALLOCATE(hadv(nqtrue), hadv_inca(nqINCA), conv_flg_inca(nqINCA), solsym_inca(nqINCA))
     276      ALLOCATE(vadv(nqtrue), vadv_inca(nqINCA),  pbl_flg_inca(nqINCA))
     277      CALL init_transport(solsym_inca, conv_flg_inca, pbl_flg_inca, hadv_inca, vadv_inca)
     278      ALLOCATE(ttr(nqtrue))
     279      ttr(1:nqo+nqCO2)                  = tracers
     280      ttr(1    :      nqo   )%component = 'lmdz'
     281      ttr(1+nqo:nqCO2+nqo   )%component = 'co2i'
     282      ttr(1+nqo+nqCO2:nqtrue)%component = 'inca'
     283      ttr(1+nqo      :nqtrue)%name      = [('CO2     ', k=1, nqCO2), solsym_inca]
     284      ttr(1+nqo+nqCO2:nqtrue)%parent    = tran0
     285      ttr(1+nqo+nqCO2:nqtrue)%phase     = 'g'
     286      lerr = getKey('hadv', had, ky=tracers(:)%keys)
     287      lerr = getKey('vadv', vad, ky=tracers(:)%keys)
     288      hadv(1:nqo+nqCO2) = had(:); hadv(1+nqo+nqCO2:nqtrue) = hadv_inca
     289      vadv(1:nqo+nqCO2) = vad(:); vadv(1+nqo+nqCO2:nqtrue) = vadv_inca
     290      CALL MOVE_ALLOC(FROM=ttr, TO=tracers)
     291      DO iq = 1, nqtrue
     292         t1 => tracers(iq)
     293         CALL addKey('name',      t1%name,      t1%keys)
     294         CALL addKey('component', t1%component, t1%keys)
     295         CALL addKey('parent',    t1%parent,    t1%keys)
     296         CALL addKey('phase',     t1%phase,     t1%keys)
     297      END DO
     298      IF(setGeneration(tracers)) CALL abort_physic(modname,'See below',1) !- SET FIELDS %iGeneration, %gen0Name
     299      DEALLOCATE(had, hadv_inca, vad, vadv_inca, conv_flg_inca, pbl_flg_inca, solsym_inca)
     300#endif
     301   !---------------------------------------------------------------------------------------------------------------------------
     302   ELSE                                                              !=== OTHER CASES (OLD OR NEW FORMAT, NO INCA MODULE)
     303   !---------------------------------------------------------------------------------------------------------------------------
     304      nqo    =        COUNT(delPhase(tracers(:)%name)     == 'H2O' &
     305                               .AND. tracers(:)%component == 'lmdz') !--- Number of water phases
     306      nqtrue = SIZE(tracers)                                         !--- Total number of "true" tracers
     307      nbtr   = nqtrue-COUNT(delPhase(tracers(:)%gen0Name) == 'H2O' &
     308                               .AND. tracers(:)%component == 'lmdz') !--- Number of tracers passed to phytrac
     309#ifdef INCA
     310      nqINCA = COUNT(tracers(:)%component == 'inca')
     311#endif
     312      lerr = getKey('hadv', hadv, ky=tracers(:)%keys)
     313      lerr = getKey('vadv', vadv, ky=tracers(:)%keys)
     314   !---------------------------------------------------------------------------------------------------------------------------
     315   END IF
     316   !---------------------------------------------------------------------------------------------------------------------------
     317
     318   !--- Transfert the number of tracers to Reprobus
    372319#ifdef REPROBUS
    373    CALL Init_chem_rep_trac(nbtr, nqo, tracers(:)%name)                         !--- Transfert the number of tracers to Reprobus
    374 #endif
     320   CALL Init_chem_rep_trac(nbtr, nqo, tracers(:)%name)
     321#endif
     322
     323!##############################################################################################################################
     324   IF(lInit) THEN                                                    !=== SKIPED IF ALREADY DONE IN dyn3d_common/infotrac  ####
     325!##############################################################################################################################
    375326
    376327!==============================================================================================================================
    377328! 2) Calculate nqtot, number of tracers needed (greater if advection schemes 20 or 30 have been chosen).
    378329!==============================================================================================================================
    379    IF(getKey('hadv', hadv, ky=tra)) CALL abort_physic(modname, 'missing key "hadv"', 1)
    380    IF(getKey('vadv', vadv, ky=tra)) CALL abort_physic(modname, 'missing key "vadv"', 1)
    381330   DO iq = 1, nqtrue
    382331      IF( hadv(iq)<20 .OR. (ANY(hadv(iq)==[20,30]) .AND. hadv(iq)==vadv(iq)) ) CYCLE
     
    399348!==============================================================================================================================
    400349   ALLOCATE(ttr(nqtot))
    401    jq = nqtrue+1
     350   jq = nqtrue+1; tracers(:)%iadv = -1
    402351   DO iq = 1, nqtrue
    403352      t1 => tracers(iq)
     
    410359      IF(iad == -1) CALL abort_physic(modname, msg1, 1)
    411360
    412       !--- SET FIELDS longName, isAdvected, isInPhysics
     361      !--- SET FIELDS %longName, %isAdvected, %isInPhysics
    413362      t1%longName   = t1%name; IF(iad > 0) t1%longName=TRIM(t1%name)//descrq(iad)
    414363      t1%isAdvected = iad >= 0
    415       t1%isInPhysics= delPhase(t1%gen0Name) /= 'H2O' .OR. t1%component /= 'lmdz' !=== MORE EXCEPTIONS ? CO2i, SURSAT CLOUD H2O
     364      t1%isInPhysics= delPhase(t1%gen0Name) /= 'H2O' &
     365                          .OR. t1%component /= 'lmdz' !=== OTHER EXCEPTIONS TO BE ADDED: CO2i, SURSATURATED WATER CLOUD...
    416366      ttr(iq)       = t1
    417367
     
    422372      IF(nm == 0) CYCLE                                              !--- No higher moments
    423373      ttr(jq+1:jq+nm)             = t1
    424       ttr(jq+1:jq+nm)%name        = [ (TRIM(t1%name)    //'-'//TRIM(suff(im)), im=1, nm) ]
    425       ttr(jq+1:jq+nm)%gen0Name    = [ (TRIM(t1%name)    //'-'//TRIM(suff(im)), im=1, nm) ]
    426       ttr(jq+1:jq+nm)%parent      = [ (TRIM(t1%parent)  //'-'//TRIM(suff(im)), im=1, nm) ]
    427       ttr(jq+1:jq+nm)%longName    = [ (TRIM(t1%longName)//'-'//TRIM(suff(im)), im=1, nm) ]
    428       ttr(jq+1:jq+nm)%isAdvected  = [ (.FALSE., im=1, nm) ]
    429       ttr(jq+1:jq+nm)%isInPhysics = [ (.FALSE., im=1, nm) ]
     374      ttr(jq+1:jq+nm)%name        = [(TRIM(t1%name)    //'-'//TRIM(suff(im)), im=1, nm) ]
     375      ttr(jq+1:jq+nm)%parent      = [(TRIM(t1%parent)  //'-'//TRIM(suff(im)), im=1, nm) ]
     376      ttr(jq+1:jq+nm)%longName    = [(TRIM(t1%longName)//'-'//TRIM(suff(im)), im=1, nm) ]
     377      ttr(jq+1:jq+nm)%isAdvected  = [(.FALSE., im=1, nm) ]
    430378      jq = jq + nm
    431379   END DO
     
    433381   CALL MOVE_ALLOC(FROM=ttr, TO=tracers)
    434382
    435    !--- SET FIELDS iqParent, iqDescen, nqDescen, nqChildren
    436    IF(indexUpdate(tracers%keys)) CALL abort_physic(modname, 'problem with tracers indices update', 1)
    437    k => tracers(:)%keys
    438    DO iq = 1, SIZE(tracers); t1 => tracers(iq); msg1 = '" for "'//TRIM(t1%name)//'"'
    439       ky='iqParent  '; IF(getKey(ky, t1%iqParent,   iq, k)) CALL abort_physic(modname, 'missing key "'//TRIM(ky)//TRIM(msg1), 1)
    440       ky='iqDescen  '; IF(getKey(ky, t1%iqDescen,   iq, k)) CALL abort_physic(modname, 'missing key "'//TRIM(ky)//TRIM(msg1), 1)
    441       ky='nqDescen  '; IF(getKey(ky, t1%nqDescen,   iq, k)) CALL abort_physic(modname, 'missing key "'//TRIM(ky)//TRIM(msg1), 1)
    442       ky='nqChildren'; IF(getKey(ky, t1%nqChildren, iq, k)) CALL abort_physic(modname, 'missing key "'//TRIM(ky)//TRIM(msg1), 1)
    443    END DO
    444 
    445    !=== DETERMINE ISOTOPES RELATED PARAMETERS ; DEFINE THE EXPLICIT KEYS iso_i*
    446    IF(processIsotopes(tracers%keys, iso)) CALL abort_physic(modname, 'problem while processing isotopes parameters', 1)
    447 
    448    !--- POPULATE SOME EXPLICIT (ACCESSIBLE THROUGH "%") KEYS OF THE LOCAL ISOTOPES DESCRIPTION DERIVED TYPE
    449    nbIso = SIZE(iso)
    450    ALLOCATE(isotopes(nbIso))
    451    IF(nbIso /= 0) THEN
    452       k => tracers(:)%keys
    453       IF(getKey('iso_iGroup', itmp, ky=k)) CALL abort_physic(modname, 'missing key "iso_iGroup"', 1); tracers%iso_iGroup = itmp
    454       IF(getKey('iso_iName',  itmp, ky=k)) CALL abort_physic(modname, 'missing key "iso_iName"',  1); tracers%iso_iName  = itmp
    455       IF(getKey('iso_iZone',  itmp, ky=k)) CALL abort_physic(modname, 'missing key "iso_iZone"',  1); tracers%iso_iZone  = itmp
    456       IF(getKey('iso_iPhas',  itmp, ky=k)) CALL abort_physic(modname, 'missing key "iso_iPhas"',  1); tracers%iso_iPhase = itmp
    457       isotopes(:)%name  = iso(:)%name                           !--- Isotopes family name (ex: H2O)
    458       isotopes(:)%phase = iso(:)%phase                          !--- Phases list: [g][l][s]              (length: nphas)
    459       isotopes(:)%niso  = iso(:)%niso                           !--- Number of isotopes, excluding tagging tracers
    460       isotopes(:)%ntiso = iso(:)%ntiso                          !--- Number of isotopes, including tagging tracers
    461       isotopes(:)%nzone = iso(:)%nzone                          !--- Number of geographic tagging zones
    462       isotopes(:)%nphas = iso(:)%nphas                          !--- Number of phases
    463       isotopes(:)%check = .FALSE.                               !--- Flag for checking routines triggering
    464       CALL getin_p('ok_iso_verif', isotopes(:)%check)
    465       DO it = 1, nbIso
    466          isotopes(it)%keys     = iso(it)%keys                   !--- Isotopes keys/values pairs list     (length: niso)
    467          isotopes(it)%trac     = iso(it)%trac                   !--- Isotopes + tagging tracers list     (length: ntiso)
    468          isotopes(it)%zone     = iso(it)%zone                   !--- Geographic tagging zones names list (length: nzone)
    469          isotopes(it)%iqIsoPha = iso(it)%iqIsoPha(:,:)          !--- Idx in "tracers(1:nqtot)" = f(name(1:ntiso)),phas)
    470          isotopes(it)%iqWIsoPha= iso(it)%iqWIsoPha(:,:)         !--- Idx in "tracers(1:nqtot)" = f([trPrnt,name(1:ntiso)],phas)
    471          isotopes(it)%itZonIso = iso(it)%itZonIso(:,:)          !--- Idx in "tracers(1:ntiso)" = f(  zone,name(1:niso))
    472       END DO
    473       IF(isoSelect(1, .TRUE.)) CALL abort_physic(modname, "Can't select the first isotopes family", 1)
    474       IF(.NOT.isoSelect('H2O', .TRUE.)) iH2O = ixIso
    475    END IF
    476    isoFamilies = isotopes(:)%name
    477 
     383   !--- SET FIELDS %iqParent, %nqChildren, %iGeneration, %iqDescen, %nqDescen
     384   IF(indexUpdate(tracers)) CALL abort_gcm(modname, 'problem when processing isotopes parameters', 1)
     385
     386!##############################################################################################################################
     387   END IF
     388!##############################################################################################################################
     389
     390!##############################################################################################################################
     391   IF(.NOT.lInit) THEN
     392!##############################################################################################################################
     393     nqtot = SIZE(tracers)
     394!##############################################################################################################################
     395   ELSE
     396!##############################################################################################################################
     397
     398   !=== READ PHYSICAL PARAMETERS FOR ISOTOPES
     399   niso = 0; nzone = 0; nphas = nqo; ntiso = 0; isoCheck = .FALSE.
     400   IF(processIsotopes()) CALL abort_physic(modname, 'Problem when processing isotopes parameters', 1)
     401
     402!##############################################################################################################################
     403   END IF
     404!##############################################################################################################################
    478405   !--- Convection / boundary layer activation for all tracers
    479    IF(.NOT.ALLOCATED(conv_flg)) ALLOCATE(conv_flg(nbtr)); conv_flg(1:nbtr) = 1
    480    IF(.NOT.ALLOCATED( pbl_flg)) ALLOCATE( pbl_flg(nbtr));  pbl_flg(1:nbtr) = 1
     406   IF (.NOT.ALLOCATED(conv_flg)) ALLOCATE(conv_flg(nbtr)); conv_flg(1:nbtr) = 1
     407   IF (.NOT.ALLOCATED(pbl_flg)) ALLOCATE( pbl_flg(nbtr));  pbl_flg(1:nbtr) = 1
    481408
    482409   !--- Note: nqtottr can differ from nbtr when nmom/=0
     
    486413
    487414   !=== DISPLAY THE RESULTS
    488    IF(.NOT.is_master) RETURN
    489415   CALL msg('nqo    = '//TRIM(int2str(nqo)),    modname)
    490416   CALL msg('nbtr   = '//TRIM(int2str(nbtr)),   modname)
     
    498424#endif
    499425   t => tracers
    500    CALL msg('Information stored in '//TRIM(modname)//': ', modname)
    501    IF(dispTable('isssssssssiiiiiiii', ['iq  ', 'name', 'lNam', 'g0Nm', 'prnt', 'type', 'phas', 'comp',     &
    502                        'isPh', 'isAd', 'iGen', 'iqPr', 'nqDe', 'nqCh', 'iGrp', 'iNam', 'iZon', 'iPha'],    &
    503       cat(t%name, t%longName, t%gen0Name, t%parent, t%type, t%phase, t%component,                          &
    504                                                          bool2str(t%isInPhysics), bool2str(t%isAdvected)), &
     426   CALL msg('Information stored in infotrac_phy :', modname)
     427   IF(dispTable('issssssssiiiiiiii', ['iq  ', 'name', 'lNam', 'g0Nm', 'prnt', 'type', 'phas', 'comp',      &
     428                              'isPh', 'iGen', 'iqPr', 'nqDe', 'nqCh', 'iGrp', 'iNam', 'iZon', 'iPha'],     &
     429      cat(t%name, t%longName, t%gen0Name, t%parent, t%type, t%phase, t%component, bool2str(t%isInPhysics)),&
    505430      cat([(iq, iq=1, nqtot)], t%iGeneration, t%iqParent, t%nqDescen, t%nqChildren, t%iso_iGroup,          &
    506431                  t%iso_iName, t%iso_iZone, t%iso_iPhase), nColMax=maxTableWidth, nHead=2, sub=modname))   &
    507432      CALL abort_physic(modname, "problem with the tracers table content", 1)
     433   IF(niso > 0) THEN
     434      CALL msg('Where, for isotopes family "'//TRIM(isotope%parent)//'":', modname)
     435      CALL msg('  isoKeys%name = '//strStack(isoKeys%name), modname)
     436      CALL msg('  isoName = '//strStack(isoName),      modname)
     437      CALL msg('  isoZone = '//strStack(isoZone),      modname)
     438      CALL msg('  isoPhas = '//TRIM(isoPhas),          modname)
     439   ELSE
     440      CALL msg('No isotopes identified.', modname)
     441   END IF
     442
     443#ifdef ISOVERIF
     444   CALL msg('iso_iName = '//strStack(int2str(PACK(tracers(:)%iso_iName, MASK=tracers(:)%iso_iGroup==iH2O))), modname)
     445#endif
    508446#ifdef CPP_StratAer
    509447   IF (type_trac == 'coag') THEN
     
    525463   END IF
    526464#endif
    527    CALL msg('No isotopes identified.', modname, nbIso == 0)
    528    IF(nbIso == 0) RETURN
    529    DO it = 1, nbIso
    530       IF(isoSelect(it, .TRUE.)) CALL abort_physic(modname, 'Problem when selecting isotopes class', 1)
    531       CALL msg('For isotopes family "'//TRIM(isoFamilies(it))//'":', modname)
    532       CALL msg('  isoName = '//strStack(isotope%trac),  modname)
    533       CALL msg('  isoZone = '//strStack(isotope%zone),  modname)
    534       CALL msg('  isoPhas = '//    TRIM(isotope%phase), modname)
    535    END DO
    536    IF(isoSelect('H2O', .TRUE.)) THEN
    537       IF(isoSelect(1,  .TRUE.)) CALL abort_physic(modname, 'Problem when selecting isotopes class', 1)
    538    ELSE
    539       iH2O = ixIso
    540    END IF
    541    IF(ALLOCATED(isotope%keys(ixIso)%key)) &
    542       CALL msg('  isoKeys('//TRIM(int2str(ixIso))//') = '//TRIM(strStack(isotope%keys(ixIso)%key)), modname)
    543 #ifdef ISOVERIF
    544    CALL msg('iso_iName(H2O) = '//TRIM(strStack(int2str(PACK(tracers%iso_iName, MASK=tracers%iso_iGroup==iH2O)))),modname)
    545 #endif
     465   CALL msg('end', modname)
    546466
    547467END SUBROUTINE init_infotrac_phy
    548468
    549 !==============================================================================================================================
    550 LOGICAL FUNCTION isoSelectByName(iClass, lVerbose) RESULT(lerr)
    551    IMPLICIT NONE
    552    CHARACTER(LEN=*),  INTENT(IN) :: iClass
    553    LOGICAL, OPTIONAL, INTENT(IN) :: lVerbose
    554    INTEGER :: iIso
    555    LOGICAL :: lV
    556    lV = .FALSE.; IF(PRESENT(lVerbose)) lV = lVerbose
    557    iIso = strIdx(isotopes(:)%name, iClass)
    558    lerr = iIso == 0
    559    IF(lerr) THEN
    560       niso = 0; ntiso = 0; nzone = 0; nphas = 0; isoCheck=.FALSE.
    561       CALL msg('no isotope family named "'//TRIM(iClass)//'"', ll=lV)
    562       RETURN
    563    END IF
    564    lerr = isoSelectByIndex(iIso, lV)
    565 END FUNCTION isoSelectByName
    566 !==============================================================================================================================
    567 LOGICAL FUNCTION isoSelectByIndex(iIso, lVerbose) RESULT(lerr)
    568    IMPLICIT NONE
    569    INTEGER,           INTENT(IN) :: iIso
    570    LOGICAL, OPTIONAL, INTENT(IN) :: lVerbose
    571    LOGICAL :: lV
    572    lV = .FALSE.;  IF(PRESENT(lVerbose)) lV = lVerbose
    573    lerr = .FALSE.
    574    IF(iIso == ixIso) RETURN                                          !--- Nothing to do if the index is already OK
    575    lerr = iIso<=0 .OR. iIso>SIZE(isotopes)
    576    CALL msg('Inconsistent isotopes family index '//TRIM(int2str(iIso))//': should be > 0 and <= '&
    577           //TRIM(int2str(SIZE(isotopes)))//'"', ll = lerr .AND. lV)
    578    IF(lerr) RETURN
    579    ixIso = iIso                                                      !--- Update currently selected family index
    580    isotope  => isotopes(ixIso)                                       !--- Select corresponding component
    581    isoKeys  => isotope%keys;     niso     = isotope%niso
    582    isoName  => isotope%trac;     ntiso    = isotope%ntiso
    583    isoZone  => isotope%zone;     nzone    = isotope%nzone
    584    isoPhas  => isotope%phase;    nphas    = isotope%nphas
    585    itZonIso => isotope%itZonIso; isoCheck = isotope%check
    586    iqIsoPha => isotope%iqIsoPha
    587    iqWIsoPha=> isotope%iqWIsoPha
    588 END FUNCTION isoSelectByIndex
    589 !==============================================================================================================================
    590 
    591469END MODULE infotrac_phy
  • LMDZ6/trunk/libf/phylmd/phyetat0_mod.F90

    r5183 r5190  
    3232  USE geometry_mod,     ONLY: longitude_deg, latitude_deg
    3333  USE iostart,          ONLY: close_startphy, get_field, get_var, open_startphy
    34   USE infotrac_phy,     ONLY: nqtot, nbtr, type_trac, tracers, new2oldH2O
    35   USE strings_mod,      ONLY: maxlen
     34  USE infotrac_phy,     ONLY: nqtot, nbtr, type_trac, tracers
     35  USE readTracFiles_mod,ONLY: maxlen, new2oldH2O
    3636  USE traclmdz_mod,     ONLY: traclmdz_from_restart
    3737  USE carbon_cycle_mod, ONLY: carbon_cycle_init, carbon_cycle_cpl, carbon_cycle_tr, carbon_cycle_rad, co2_send, RCO2_glo
  • LMDZ6/trunk/libf/phylmd/physiq_mod.F90

    r5189 r5190  
    3939    USE ioipsl_getin_p_mod, ONLY : getin_p
    4040    USE indice_sol_mod
    41     USE infotrac_phy, ONLY: nqtot, nbtr, nqo, tracers, type_trac, addPhase
     41    USE infotrac_phy, ONLY: nqtot, nbtr, nqo, tracers, type_trac
     42    USE readTracFiles_mod, ONLY: addPhase
    4243    USE strings_mod,  ONLY: strIdx
    4344    USE iophy
  • LMDZ6/trunk/libf/phylmdiso/isotopes_mod.F90

    r5183 r5190  
    44MODULE isotopes_mod
    55   USE strings_mod,  ONLY: msg, real2str, int2str, bool2str, maxlen, strIdx, strStack
    6    USE infotrac_phy, ONLY: isoName, isoSelect, niso, ntiso, nbIso, isoFamilies
    7    USE iso_params_mod
     6   USE infotrac_phy, ONLY: isoName
    87   IMPLICIT NONE
    98   INTERFACE get_in; MODULE PROCEDURE getinp_s, getinp_i, getinp_r, getinp_l;  END INTERFACE get_in
     
    1211  !--- Contains all isotopic variables + their initialization
    1312  !--- Isotopes-specific routines are in isotopes_routines_mod to avoid circular dependencies with isotopes_verif_mod.
    14 
    15    !--- Negligible lower thresholds: no need to check for absurd values under these lower limits
    16    REAL, PARAMETER :: &
    17       ridicule      = 1e-12,              & ! For mixing ratios
    18       ridicule_rain = 1e-8,               & ! For rain fluxes (rain, zrfl...) in kg/s <-> 1e-3 mm/day
    19       ridicule_evap = ridicule_rain*1e-2, & ! For evaporations                in kg/s <-> 1e-3 mm/day
    20       ridicule_qsol = ridicule_rain,      & ! For qsol                        in kg <-> 1e-8 kg
    21       ridicule_snow = ridicule_qsol         ! For snow                        in kg <-> 1e-8 kg
    22    REAL, PARAMETER :: expb_max = 30.0
    23 
    24    !--- Fractionation coefficients for H217O
    25    REAL, PARAMETER :: fac_coeff_eq17_liq = 0.529,    &
    26                       fac_coeff_eq17_ice = 0.529
    27 
    28    !--- H218O reference
    29    REAL, PARAMETER :: fac_enrichoce18 = 0.0005,  alpha_liq_sol_O18 = 1.00291,                    &
    30                       talph1_O18 = 1137.,        talps1_O18 = 11.839,     tkcin0_O18 = 0.006,    &
    31                       talph2_O18 = -0.4156,      talps2_O18 = -0.028244,  tkcin1_O18 = 0.000285, &
    32                       talph3_O18 = -2.0667E-3,  tdifrel_O18 = 1./0.9723,  tkcin2_O18 = 0.00082
    33 
    34    !--- Parameters that do not depend on the nature of water isotopes:
    35    REAL, PARAMETER :: pxtmelt = 273.15           !--- temperature at which ice formation starts
    36    REAL, PARAMETER :: pxtice  = 273.15 -  10.0   !--- temperature at which all condensate is ice:
    37    REAL, PARAMETER :: pxtmin  = 273.15 - 120.0   !--- computation done only under -120°C
    38    REAL, PARAMETER :: pxtmax  = 273.15 +  60.0   !--- computation done only  over  +60°C
    39    REAL, PARAMETER :: tdifexp = 0.58             !--- a constant for alpha_eff for equilibrium below cloud base:
    40    REAL, PARAMETER :: tv0cin  = 7.0              !--- wind threshold (m/s) for smooth/rough regime (Merlivat and Jouzel 1979)
    41    REAL, PARAMETER :: musi    = 1.0              !--- facteurs lambda et mu dans Si=musi-lambda*T
    42    REAL, PARAMETER :: Kd      = 2.5e-9    ! m2/s !--- diffusion in soil
    43    REAL, PARAMETER :: rh_cste_surf_cond = 0.6    !--- cste_surf_cond case: rhs and/or Ts set to constants
    44    REAL, PARAMETER :: T_cste_surf_cond = 288.0
    4513
    4614   !--- Isotopes indices (in [1,niso] ; non-existing => 0 index)
     
    12189   !--- Vectors of length "niso"
    12290   REAL, ALLOCATABLE, DIMENSION(:), SAVE :: &
    123                     alpha, tnat, toce, tcorr, tdifrel
    124 !$OMP THREADPRIVATE(alpha, tnat, toce, tcorr, tdifrel)
     91                    tnat, toce, tcorr, tdifrel
     92!$OMP THREADPRIVATE(tnat, toce, tcorr, tdifrel)
    12593   REAL, ALLOCATABLE, DIMENSION(:), SAVE :: &
    12694                    talph1, talph2, talph3, talps1, talps2
     
    132100                    alpha_liq_sol, Rdefault, Rmethox
    133101!$OMP THREADPRIVATE(alpha_liq_sol, Rdefault, Rmethox)
     102!   REAL, SAVE ::    fac_coeff_eq17_liq, fac_coeff_eq17_ice
     103!!$OMP THREADPRIVATE(fac_coeff_eq17_liq, fac_coeff_eq17_ice)
     104
     105   !--- H2[18]O reference
     106   REAL, PARAMETER :: fac_enrichoce18=0.0005
     107   REAL, PARAMETER :: alpha_liq_sol_O18=1.00291
     108   REAL, PARAMETER :: talph1_O18=1137.
     109   REAL, PARAMETER :: talph2_O18=-0.4156
     110   REAL, PARAMETER :: talph3_O18=-2.0667E-3
     111   REAL, PARAMETER :: talps1_O18=11.839
     112   REAL, PARAMETER :: talps2_O18=-0.028244
     113   REAL, PARAMETER :: tdifrel_O18=1./0.9723
     114   REAL, PARAMETER :: tkcin0_O18=0.006
     115   REAL, PARAMETER :: tkcin1_O18=0.000285
     116   REAL, PARAMETER :: tkcin2_O18=0.00082
     117   REAL, PARAMETER :: fac_coeff_eq17_liq=0.529
     118   REAL, PARAMETER :: fac_coeff_eq17_ice=0.529
     119
     120   !---- Parameters that do not depend on the nature of water isotopes:
     121   REAL, PARAMETER :: pxtmelt = 273.15 ! temperature at which ice formation starts
     122   REAL, PARAMETER :: pxtice  = 273.15-10.0 ! -- temperature at which all condensate is ice:
     123   REAL, PARAMETER :: pxtmin = 273.15 - 120.0   ! On ne calcule qu'au dessus de -120°C
     124   REAL, PARAMETER :: pxtmax = 273.15 +  60.0   ! On ne calcule qu'au dessus de +60°C
     125   REAL, PARAMETER :: tdifexp = 0.58 ! -- a constant for alpha_eff for equilibrium below cloud base:
     126   REAL, PARAMETER :: tv0cin  = 7.0 ! wind threshold (m/s) for smooth/rough regime (Merlivat and Jouzel 1979)
     127   REAL, PARAMETER :: musi=1.0  ! facteurs lambda et mu dans Si=musi-lambda*T
     128   REAL, PARAMETER :: Kd=2.5e-9 ! m2/s ! diffusion dans le sol
     129   REAL, PARAMETER :: rh_cste_surf_cond = 0.6 ! cas où cste_surf_cond: on met rhs ou/et Ts cste pour voir
     130   REAL, PARAMETER :: T_cste_surf_cond = 288.0
     131
     132
     133   !--- Negligible lower thresholds: no need to check for absurd values under these lower limits
     134   REAL, PARAMETER :: &
     135      ridicule      = 1e-12,              & ! For mixing ratios
     136      ridicule_rain = 1e-8,               & ! For rain fluxes (rain, zrfl...) in kg/s <-> 1e-3 mm/day
     137      ridicule_evap = ridicule_rain*1e-2, & ! For evaporations                in kg/s <-> 1e-3 mm/day
     138      ridicule_qsol = ridicule_rain,      & ! For qsol                        in kg <-> 1e-8 kg
     139      ridicule_snow = ridicule_qsol         ! For snow                        in kg <-> 1e-8 kg
     140   REAL, PARAMETER :: expb_max = 30.0
    134141
    135142   !--- Specific to HTO:
     
    148155
    149156SUBROUTINE iso_init()
     157   USE infotrac_phy,       ONLY: ntiso, niso, getKey
     158    USE strings_mod,       ONLY: maxlen
    150159   IMPLICIT NONE
    151160
    152161   !=== Local variables:
    153    INTEGER :: ixt, ii, is
    154    LOGICAL :: ltnat1
    155    CHARACTER(LEN=maxlen) :: modname, sxt
     162   INTEGER :: ixt
     163
    156164 
    157165   !--- For H2[17]O
     
    162170   LOGICAL, PARAMETER ::   ok_nocinsat = .FALSE. ! if T: no sursaturation effect for ice
    163171   LOGICAL, PARAMETER :: Rdefault_smow = .FALSE. ! if T: Rdefault=smow; if F: nul
     172   LOGICAL, PARAMETER :: tnat1 = .TRUE. ! If T: all tnats are 1.
    164173
    165174   !--- For [3]H
    166175   INTEGER :: iessai
     176
     177   CHARACTER(LEN=maxlen) :: modname, sxt
    167178
    168179   modname = 'iso_init'
     
    176187   CALL msg('64: niso = '//TRIM(int2str(niso)), modname)
    177188
    178    DO ii = 1, nbIso
    179       CALL msg('Can''t select isotopes class "'//TRIM(isoFamilies(ii))//'"', modname, isoSelect(ii, lVerbose=.TRUE.))
    180 
    181 !==============================================================================================================================
    182       IF(isoFamilies(ii) == 'H2O') THEN
    183 !==============================================================================================================================
    184          !--- Init de ntracisoOR: on ecrasera en cas de traceurs de tagging isotopiques
    185          !                     (nzone>0) si complications avec ORCHIDEE
    186          ntracisoOR = ntiso
    187 
    188          !--- Type of water isotopes:
    189          iso_eau = strIdx(isoName, 'H216O'); CALL msg('iso_eau='//int2str(iso_eau), modname)
    190          iso_HDO = strIdx(isoName, 'HDO');   CALL msg('iso_HDO='//int2str(iso_HDO), modname)
    191          iso_O18 = strIdx(isoName, 'H218O'); CALL msg('iso_O18='//int2str(iso_O18), modname)
    192          iso_O17 = strIdx(isoName, 'H217O'); CALL msg('iso_O17='//int2str(iso_O17), modname)
    193          iso_HTO = strIdx(isoName, 'HTO');   CALL msg('iso_HTO='//int2str(iso_HTO), modname)
    194 
    195          !--- Initialisation: reading the isotopic parameters.
    196          CALL get_in('lambda',     lambda_sursat, 0.004); IF(ok_nocinsat) lambda_sursat = 0.
    197          CALL get_in('thumxt1',    thumxt1,       0.75*1.2)
    198          CALL get_in('ntot',       ntot,          20,  .FALSE.)
    199          CALL get_in('h_land_ice', h_land_ice,    20., .FALSE.)
    200          CALL get_in('P_veg',      P_veg,         1.0, .FALSE.)
    201          CALL get_in('bidouille_anti_divergence', bidouille_anti_divergence, .FALSE.)
    202          CALL get_in('essai_convergence',         essai_convergence,         .FALSE.)
    203          CALL get_in('initialisation_iso',        initialisation_iso,        0)
    204 
    205 !        IF(nzone>0 .AND. initialisation_iso==0) &
    206 !           CALL get_in('initialisation_isotrac',initialisation_isotrac)
    207          CALL get_in('modif_sst',      modif_sst,         0)
    208          CALL get_in('deltaTtest',     deltaTtest,      0.0)     !--- For modif_sst>=1
    209          CALL get_in('deltaTtestpoles',deltaTtestpoles, 0.0)     !--- For modif_sst>=2
    210          CALL get_in( 'sstlatcrit',    sstlatcrit,     30.0)     !--- For modif_sst>=3
    211          CALL get_in('dsstlatcrit',   dsstlatcrit,      0.0)     !--- For modif_sst>=3
     189   !--- Init de ntracisoOR: on ecrasera en cas de traceurs de tagging isotopiques
     190   !                     (nzone>0) si complications avec ORCHIDEE
     191   ntracisoOR = ntiso 
     192
     193   !--- Type of water isotopes:
     194   iso_eau = strIdx(isoName, 'H216O'); CALL msg('iso_eau='//int2str(iso_eau), modname)
     195   iso_HDO = strIdx(isoName, 'HDO');   CALL msg('iso_HDO='//int2str(iso_HDO), modname)
     196   iso_O18 = strIdx(isoName, 'H218O'); CALL msg('iso_O18='//int2str(iso_O18), modname)
     197   iso_O17 = strIdx(isoName, 'H217O'); CALL msg('iso_O17='//int2str(iso_O17), modname)
     198   iso_HTO = strIdx(isoName, 'HTO');   CALL msg('iso_HTO='//int2str(iso_HTO), modname)
     199
     200   !--- Initialiaation: reading the isotopic parameters.
     201   CALL get_in('lambda',     lambda_sursat, 0.004)
     202   CALL get_in('thumxt1',    thumxt1,       0.75*1.2)
     203   CALL get_in('ntot',       ntot,          20,  .FALSE.)
     204   CALL get_in('h_land_ice', h_land_ice,    20., .FALSE.)
     205   CALL get_in('P_veg',      P_veg,         1.0, .FALSE.)
     206   CALL get_in('bidouille_anti_divergence', bidouille_anti_divergence, .FALSE.)
     207   CALL get_in('essai_convergence',         essai_convergence,         .FALSE.)
     208   CALL get_in('initialisation_iso',        initialisation_iso,        0)
     209
     210!  IF(nzone>0 .AND. initialisation_iso==0) &
     211!      CALL get_in('initialisation_isotrac',initialisation_isotrac)
     212   CALL get_in('modif_sst',      modif_sst,         0)
     213   CALL get_in('deltaTtest',     deltaTtest,      0.0)     !--- For modif_sst>=1
     214   CALL get_in('deltaTtestpoles',deltaTtestpoles, 0.0)     !--- For modif_sst>=2
     215   CALL get_in( 'sstlatcrit',    sstlatcrit,     30.0)     !--- For modif_sst>=3
     216   CALL get_in('dsstlatcrit',   dsstlatcrit,      0.0)     !--- For modif_sst>=3
    212217#ifdef ISOVERIF
    213          CALL msg('iso_init 270:  sstlatcrit='//real2str( sstlatcrit), modname, sstlatcrit < 0.0) !--- For modif_sst>=2
    214          CALL msg('iso_init 279: dsstlatcrit='//real2str(dsstlatcrit), modname, sstlatcrit < 0.0) !--- For modif_sst>=3
    215          IF(modif_sst >= 2 .AND. sstlatcrit < 0.0) STOP
     218   CALL msg('iso_init 270:  sstlatcrit='//real2str( sstlatcrit), modname, sstlatcrit < 0.0) !--- For modif_sst>=2
     219   CALL msg('iso_init 279: dsstlatcrit='//real2str(dsstlatcrit), modname, sstlatcrit < 0.0) !--- For modif_sst>=3
     220   IF(modif_sst >= 2 .AND. sstlatcrit < 0.0) STOP
    216221#endif             
    217222
    218          CALL get_in('modif_sic', modif_sic,  0)
    219          IF(modif_sic >= 1) &
    220          CALL get_in('deltasic',  deltasic, 0.1)
    221 
    222          CALL get_in('albedo_prescrit', albedo_prescrit, 0)
    223          IF(albedo_prescrit == 1) THEN
    224             CALL get_in('lon_min_albedo', lon_min_albedo, -200.)
    225             CALL get_in('lon_max_albedo', lon_max_albedo,  200.)
    226             CALL get_in('lat_min_albedo', lat_min_albedo, -100.)
    227             CALL get_in('lat_max_albedo', lat_max_albedo,  100.)
    228          END IF
    229          CALL get_in('deltaO18_oce',        deltaO18_oce,   0.0)
    230          CALL get_in('deltaP_BL',           deltaP_BL,     10.0)
    231          CALL get_in('ruissellement_pluie', ruissellement_pluie, 0)
    232          CALL get_in('alphak_stewart',      alphak_stewart,      1)
    233          CALL get_in('tdifexp_sol',         tdifexp_sol,      0.67)
    234          CALL get_in('calendrier_guide',    calendrier_guide,    0)
    235          CALL get_in('cste_surf_cond',      cste_surf_cond,      0)
    236          CALL get_in('mixlen',              mixlen,           35.0)
    237          CALL get_in('evap_cont_cste',      evap_cont_cste,      0)
    238          CALL get_in('deltaO18_evap_cont',  deltaO18_evap_cont,0.0)
    239          CALL get_in('d_evap_cont',         d_evap_cont,       0.0)
    240          CALL get_in('nudge_qsol',          nudge_qsol,          0)
    241          CALL get_in('region_nudge_qsol',   region_nudge_qsol,   1)
    242          nlevmaxO17 = 50
    243          CALL msg('nlevmaxO17='//TRIM(int2str(nlevmaxO17)))
    244          CALL get_in('no_pce',   no_pce,     0)
    245          CALL get_in('A_satlim', A_satlim, 1.0)
    246          CALL get_in('ok_restrict_A_satlim', ok_restrict_A_satlim, 0)
     223   CALL get_in('modif_sic', modif_sic,  0)
     224   IF(modif_sic >= 1) &
     225   CALL get_in('deltasic',  deltasic, 0.1)
     226
     227   CALL get_in('albedo_prescrit', albedo_prescrit, 0)
     228   IF(albedo_prescrit == 1) THEN
     229      CALL get_in('lon_min_albedo', lon_min_albedo, -200.)
     230      CALL get_in('lon_max_albedo', lon_max_albedo,  200.)
     231      CALL get_in('lat_min_albedo', lat_min_albedo, -100.)
     232      CALL get_in('lat_max_albedo', lat_max_albedo,  100.)
     233   END IF
     234   CALL get_in('deltaP_BL',           deltaP_BL,     10.0)
     235   CALL get_in('ruissellement_pluie', ruissellement_pluie, 0)
     236   CALL get_in('alphak_stewart',      alphak_stewart,      1)
     237   CALL get_in('tdifexp_sol',         tdifexp_sol,      0.67)
     238   CALL get_in('calendrier_guide',    calendrier_guide,    0)
     239   CALL get_in('cste_surf_cond',      cste_surf_cond,      0)
     240   CALL get_in('mixlen',              mixlen,           35.0)
     241   CALL get_in('evap_cont_cste',      evap_cont_cste,      0)
     242   CALL get_in('deltaO18_evap_cont',  deltaO18_evap_cont,0.0)
     243   CALL get_in('d_evap_cont',         d_evap_cont,       0.0)
     244   CALL get_in('nudge_qsol',          nudge_qsol,          0)
     245   CALL get_in('region_nudge_qsol',   region_nudge_qsol,   1)
     246   nlevmaxO17 = 50
     247   CALL msg('nlevmaxO17='//TRIM(int2str(nlevmaxO17)))
     248   CALL get_in('no_pce',   no_pce,     0)
     249   CALL get_in('A_satlim', A_satlim, 1.0)
     250   CALL get_in('ok_restrict_A_satlim', ok_restrict_A_satlim, 0)
    247251#ifdef ISOVERIF
    248          CALL msg(' 315: A_satlim='//real2str(A_satlim), modname, A_satlim > 1.0)
    249          IF(A_satlim > 1.0) STOP
     252   CALL msg(' 315: A_satlim='//real2str(A_satlim), modname, A_satlim > 1.0)
     253   IF(A_satlim > 1.0) STOP
    250254#endif
    251 !        CALL get_in('slope_limiterxy',   slope_limiterxy,  2.0)
    252 !        CALL get_in('slope_limiterz',    slope_limiterz,   2.0)
    253          CALL get_in('modif_ratqs',       modif_ratqs,        0)
    254          CALL get_in('Pcrit_ratqs',       Pcrit_ratqs,    500.0)
    255          CALL get_in('ratqsbasnew',       ratqsbasnew,     0.05)
    256          CALL get_in('fac_modif_evaoce',  fac_modif_evaoce, 1.0)
    257          CALL get_in('ok_bidouille_wake', ok_bidouille_wake,  0)
    258          ! si oui, la temperature de cond est celle de l'environnement, pour eviter
    259          ! bugs quand temperature dans ascendances convs est mal calculee
    260          CALL get_in('cond_temp_env',        cond_temp_env,        .FALSE.)
    261          IF(ANY(isoName == 'HTO')) &
    262          CALL get_in('ok_prod_nucl_tritium', ok_prod_nucl_tritium, .FALSE., .FALSE.)
    263          CALL get_in('tnateq1', ltnat1, .TRUE.)
    264 
    265          CALL msg('iso_O18, iso_HDO, iso_eau = '//TRIM(strStack(int2str([iso_O18, iso_HDO, iso_eau]))), modname)
    266 
    267          !--------------------------------------------------------------
    268          ! Parameters that depend on the nature of water isotopes:
    269          !--------------------------------------------------------------
    270          ALLOCATE(tnat (niso), talph1(niso),  talps1(niso), tkcin0(niso), tdifrel (niso), alpha        (niso))
    271          ALLOCATE(toce (niso), talph2(niso),  talps2(niso), tkcin1(niso), Rdefault(niso), alpha_liq_sol(niso))
    272          ALLOCATE(tcorr(niso), talph3(niso),                tkcin2(niso), Rmethox (niso))
    273 
    274          !=== H216O
    275          is = iso_eau
    276          IF(is /= 0) THEN
    277             tdifrel (is) = 1.0
    278             alpha   (is) = alpha_ideal_H216O
    279             tnat    (is) = tnat_H216O; IF(ltnat1) tnat(is) = 1.0
    280             toce    (is) = tnat(is)
    281             tcorr   (is) = 1.0
    282             talph1  (is) = 0.0;  talps1(is) = 0.0;  tkcin0(is)  = 0.0
    283             talph2  (is) = 0.0;  talps2(is) = 0.0;  tkcin1(is)  = 0.0
    284             talph3  (is) = 0.0;                     tkcin2(is)  = 0.0
    285             Rdefault(is) = tnat(is)*1.0
    286             Rmethox (is) = 1.0
    287             alpha_liq_sol(is) = 1.0
    288          END IF
    289 
    290          !=== H217O
    291          is = iso_O17
    292          IF(is /= 0) THEN; pente_MWL = 0.528
    293             tdifrel (is) = 1./0.98555  ! used in 1D and in LdG model ; tdifrel=1./0.985452: from Amaelle
    294             alpha   (is) = alpha_ideal_H217O
    295             tnat    (is) = tnat_H217O; IF(ltnat1) tnat(is) = 1.0
    296             toce    (is) = tnat(is)*(1.0+deltaO18_oce/1000.0)**pente_MWL
    297             tcorr   (is) = 1.0+fac_enrichoce18*pente_MWL
    298             fac_kcin = (tdifrel(is)-1.0)/(tdifrel_O18-1.0)           ! fac_kcin=0.5145:     from Amaelle
    299             talph1  (is) = talph1_O18;  talps1(is) = talps1_O18;  tkcin0(is) = tkcin0_O18*fac_kcin
    300             talph2  (is) = talph2_O18;  talps2(is) = talps2_O18;  tkcin1(is) = tkcin1_O18*fac_kcin
    301             talph3  (is) = talph3_O18;                            tkcin2(is) = tkcin2_O18*fac_kcin
    302             Rdefault(is) = tnat(is)*(1.0-3.15/1000.)
    303             Rmethox (is) = tnat(is)*(1.0+230./1000.)
    304             alpha_liq_sol(is) = alpha_liq_sol_O18**fac_coeff_eq17_liq
    305          END IF
    306 
    307          !=== H218O
    308          is = iso_O18
    309          IF(is /= 0) THEN
    310             tdifrel (is) = tdifrel_O18
    311             alpha   (is) = alpha_ideal_H218O
    312             tnat    (is) = tnat_H218O; IF(ltnat1) tnat(is) = 1.0
    313             toce    (is) = tnat(is)*(1.0+deltaO18_oce/1000.0)
    314             tcorr   (is) = 1.0+fac_enrichoce18
    315             talph1  (is) = talph1_O18;  talps1(is) = talps1_O18;  tkcin0(is) = tkcin0_O18
    316             talph2  (is) = talph2_O18;  talps2(is) = talps2_O18;  tkcin1(is) = tkcin1_O18
    317             talph3  (is) = talph3_O18;                            tkcin2(is) = tkcin2_O18
    318             Rdefault(is) = tnat(is)*(1.0-6.00/1000.)
    319             Rmethox (is) = tnat(is)*(1.0+130./1000.)  ! Zahn & al. 2006
    320             alpha_liq_sol(is) = alpha_liq_sol_O18
    321          END IF
    322 
    323          !=== HDO
    324          is = iso_HDO
    325          IF(is /= 0) THEN; pente_MWL = 8.0
    326             tdifrel (is) = 1./0.9755                  ! fac_kcin=0.88
    327             alpha   (is) = alpha_ideal_HDO
    328             tnat    (is) = tnat_HDO; IF(ltnat1) tnat(is) = 1.0
    329             toce    (is) = tnat(is)*(1.0+deltaO18_oce/1000.0*pente_MWL)
    330             tcorr   (is) = 1.0+fac_enrichoce18*pente_MWL
    331             fac_kcin = (tdifrel(is)-1.0)/(tdifrel_O18-1.0)
    332             talph1  (is) = 24844.;      talps1(is) = 16288.;      tkcin0(is) = tkcin0_O18*fac_kcin
    333             talph2  (is) = -76.248;     talps2(is) = -0.0934;     tkcin1(is) = tkcin1_O18*fac_kcin
    334             talph3  (is) = 52.612E-3;                             tkcin2(is) = tkcin2_O18*fac_kcin
    335             Rdefault(is) = tnat(is)*(1.0+(10.0-6.0*pente_MWL)/1000.)
    336             Rmethox (is) = tnat(is)*(1.0-25.0/1000.)
    337             alpha_liq_sol(is) = 1.0212      ! Lehmann & Siegenthaler, 1991, Jo. of Glaciology, vol 37, p 23
    338                                             ! alpha_liq_sol=1.0192: Weston, Ralph, 1955
    339          END IF
    340 
    341          !=== HTO
    342          is = iso_HTO
    343          IF(is /= 0) THEN
    344             tdifrel (is) = 1./0.968
    345             alpha   (is) = alpha_ideal_HTO
    346             tnat    (is) = tnat_HTO; IF(ltnat1) tnat(is) = 1.0
    347             toce    (is) = 4.0E-19          ! ratio T/H = 0.2 TU Dreisigacker & Roether 1978
    348             tcorr   (is) = 1.0
    349             talph1  (is) = 46480.;      talps1(is) = 46480.;      tkcin0(is) = 0.01056
    350             talph2  (is) = -103.87;     talps2(is) = -103.87;     tkcin1(is) = 0.0005016
    351             talph3  (is) = 0.0;                                   tkcin2(is) = 0.0014432
    352             Rdefault(is) = 0.0
    353             Rmethox (is) = 0.0
    354             alpha_liq_sol(is) = 1.0
    355          END IF
    356 
    357          IF(.NOT. Rdefault_smow) THEN
    358             Rdefault(:) = 0.0; IF(iso_eau > 0) Rdefault(iso_eau) = 1.0
    359          END IF
    360          WRITE(*,*) 'Rdefault = ',Rdefault
    361          WRITE(*,*) 'toce = ', toce
    362 
    363          !--- Sensitivity test: no kinetic effect in sfc evaporation
    364          IF(ok_nocinsfc) THEN
    365             tkcin0(1:niso) = 0.0
    366             tkcin1(1:niso) = 0.0
    367             tkcin2(1:niso) = 0.0
    368          END IF
    369 
    370          CALL msg('285: verif initialisation:', modname)
    371          DO ixt=1,niso
    372             sxt=int2str(ixt)
    373             CALL msg(' * isoName('//TRIM(sxt)//') = <'//TRIM(isoName(ixt))//'>',  modname)
    374             CALL msg(  '    tnat('//TRIM(sxt)//') = '//TRIM(real2str(tnat(ixt))), modname)
    375 !           CALL msg('    alpha_liq_sol('//TRIM(sxt)//') = '//TRIM(real2str(alpha_liq_sol(ixt))), modname)
    376 !           CALL msg(        '   tkcin0('//TRIM(sxt)//') = '//TRIM(real2str(tkcin0(ixt))),        modname)
    377 !           CALL msg(       '   tdifrel('//TRIM(sxt)//') = '//TRIM(real2str(tdifrel(ixt))),       modname)
    378          END DO
    379          CALL msg('69:     lambda = '//TRIM(real2str(lambda_sursat)), modname)
    380          CALL msg('69:    thumxt1 = '//TRIM(real2str(thumxt1)),       modname)
    381          CALL msg('69: h_land_ice = '//TRIM(real2str(h_land_ice)),    modname)
    382          CALL msg('69:      P_veg = '//TRIM(real2str(P_veg)),         modname)
    383 !==============================================================================================================================
    384       ELSE
    385 !==============================================================================================================================
    386          CALL abort_physic('"isotopes_mod" is not set up yet for isotopes family "'//TRIM(isoFamilies(ii))//'"', modname, 1)
    387 !==============================================================================================================================
    388       END IF
    389 !==============================================================================================================================
     255!  CALL get_in('slope_limiterxy',   slope_limiterxy,  2.0)
     256!  CALL get_in('slope_limiterz',    slope_limiterz,   2.0)
     257   CALL get_in('modif_ratqs',       modif_ratqs,        0)
     258   CALL get_in('Pcrit_ratqs',       Pcrit_ratqs,    500.0)
     259   CALL get_in('ratqsbasnew',       ratqsbasnew,     0.05)
     260   CALL get_in('fac_modif_evaoce',  fac_modif_evaoce, 1.0)
     261   CALL get_in('ok_bidouille_wake', ok_bidouille_wake,  0)
     262   ! si oui, la temperature de cond est celle de l'environnement, pour eviter
     263   ! bugs quand temperature dans ascendances convs est mal calculee
     264   CALL get_in('cond_temp_env',        cond_temp_env,        .FALSE.)
     265   IF(ANY(isoName == 'HTO')) &
     266   CALL get_in('ok_prod_nucl_tritium', ok_prod_nucl_tritium, .FALSE., .FALSE.)
     267
     268   ! Ocean composition
     269   CALL get_in('deltaO18_oce',  deltaO18_oce, 0.0)
     270   
     271   CALL msg('iso_O18, iso_HDO, iso_eau = '//TRIM(strStack(int2str([iso_O18, iso_HDO, iso_eau]))), modname)
     272
     273   !--------------------------------------------------------------
     274   ! Isotope fractionation factors and a few isotopic constants
     275   !--------------------------------------------------------------
     276   ALLOCATE(tkcin0(niso))
     277   ALLOCATE(tkcin1(niso))
     278   ALLOCATE(tkcin2(niso))
     279   ALLOCATE(tnat(niso))
     280   ALLOCATE(tdifrel(niso))
     281   ALLOCATE(toce(niso))
     282   ALLOCATE(tcorr(niso))
     283   ALLOCATE(talph1(niso))
     284   ALLOCATE(talph2(niso))
     285   ALLOCATE(talph3(niso))
     286   ALLOCATE(talps1(niso))
     287   ALLOCATE(talps2(niso))
     288   ALLOCATE(alpha_liq_sol(niso))
     289   ALLOCATE(Rdefault(niso))
     290   ALLOCATE(Rmethox(niso))
     291
     292   do ixt=1,niso
     293     if (ixt.eq.iso_HTO) then  ! Tritium
     294       tkcin0(ixt) = 0.01056
     295       tkcin1(ixt) = 0.0005016
     296       tkcin2(ixt) = 0.0014432
     297       if (tnat1) then
     298               tnat(ixt)=1
     299       else
     300               tnat(ixt)=0.
     301       endif
     302       toce(ixt)=4.0E-19 ! rapport T/H = 0.2 TU Dreisigacker and Roether 1978
     303       tcorr(ixt)=1.
     304       tdifrel(ixt)=1./0.968
     305       talph1(ixt)=46480.
     306       talph2(ixt)=-103.87
     307       talph3(ixt)=0.
     308       talps1(ixt)=46480.
     309       talps2(ixt)=-103.87
     310       alpha_liq_sol(ixt)=1.
     311       Rmethox(ixt)=0.0
     312     endif
     313     if (ixt.eq.iso_O17) then  ! O17
     314       pente_MWL=0.528
     315       tdifrel(ixt)=1./0.98555 ! valeur utilisée en 1D et dans modèle de LdG ! tdifrel(ixt)=1./0.985452 ! donné par Amaelle
     316       fac_kcin= (tdifrel(ixt)-1.0)/(tdifrel_O18-1.0) ! fac_kcin=0.5145 ! donné par Amaelle
     317       tkcin0(ixt) = tkcin0_O18*fac_kcin
     318       tkcin1(ixt) = tkcin1_O18*fac_kcin
     319       tkcin2(ixt) = tkcin2_O18*fac_kcin
     320       if (tnat1) then
     321               tnat(ixt)=1
     322       else
     323               tnat(ixt)=0.004/100. ! O17 représente 0.004% de l'oxygène
     324       endif
     325       toce(ixt)=tnat(ixt)*(1.0+deltaO18_oce/1000.0)**pente_MWL
     326       tcorr(ixt)=1.0+fac_enrichoce18*pente_MWL ! donné par Amaelle           
     327       talph1(ixt)=talph1_O18
     328       talph2(ixt)=talph2_O18
     329       talph3(ixt)=talph3_O18
     330       talps1(ixt)=talps1_O18
     331       talps2(ixt)=talps2_O18     
     332       alpha_liq_sol(ixt)=(alpha_liq_sol_O18)**fac_coeff_eq17_liq
     333       Rdefault(ixt)=tnat(ixt)*(-3.15/1000.0+1.0)
     334       Rmethox(ixt)=(230./1000.+1.)*tnat(ixt) !Zahn et al 2006
     335     endif
     336     if (ixt.eq.iso_O18) then  ! Oxygene18
     337       tkcin0(ixt) = tkcin0_O18
     338       tkcin1(ixt) = tkcin1_O18
     339       tkcin2(ixt) = tkcin2_O18
     340       if (tnat1) then
     341               tnat(ixt)=1
     342       else
     343               tnat(ixt)=2005.2E-6
     344       endif
     345       toce(ixt)=tnat(ixt)*(1.0+deltaO18_oce/1000.0)
     346       tcorr(ixt)=1.0+fac_enrichoce18
     347       tdifrel(ixt)=tdifrel_O18
     348       talph1(ixt)=talph1_O18
     349       talph2(ixt)=talph2_O18
     350       talph3(ixt)=talph3_O18
     351       talps1(ixt)=talps1_O18
     352       talps2(ixt)=talps2_O18
     353       alpha_liq_sol(ixt)=alpha_liq_sol_O18   
     354       Rdefault(ixt)=tnat(ixt)*(-6.0/1000.0+1.0)
     355       Rmethox(ixt)=(130./1000.+1.)*tnat(ixt) !Zahn et al 2006 
     356     endif
     357     if (ixt.eq.iso_HDO) then ! Deuterium
     358       pente_MWL=8.0
     359       tdifrel(ixt)=1./0.9755 !          fac_kcin=0.88
     360       fac_kcin= (tdifrel(ixt)-1)/(tdifrel_O18-1)
     361       tkcin0(ixt) = tkcin0_O18*fac_kcin
     362       tkcin1(ixt) = tkcin1_O18*fac_kcin
     363       tkcin2(ixt) = tkcin2_O18*fac_kcin
     364       if (tnat1) then
     365               tnat(ixt)=1
     366       else
     367               tnat(ixt)=155.76E-6
     368       endif
     369       toce(ixt)=tnat(ixt)*(1.0+pente_MWL*deltaO18_oce/1000.0)
     370       tcorr(ixt)=1.0+fac_enrichoce18*pente_MWL         
     371       talph1(ixt)=24844.
     372       talph2(ixt)=-76.248
     373       talph3(ixt)=52.612E-3
     374       talps1(ixt)=16288.
     375       talps2(ixt)=-0.0934
     376       !ZXalpha_liq_sol=1.0192 ! Weston, Ralph, 1955
     377       alpha_liq_sol(ixt)=1.0212
     378       ! valeur de Lehmann & Siegenthaler, 1991, Journal of
     379       ! Glaciology, vol 37, p 23
     380       Rdefault(ixt)=tnat(ixt)*((-6.0*pente_MWL+10.0)/1000.0+1.0)
     381       Rmethox(ixt)=tnat(ixt)*(-25.0/1000.+1.) ! Zahn et al 2006
     382     endif
     383     if (ixt.eq.iso_eau) then ! Oxygene16
     384       tkcin0(ixt) = 0.0
     385       tkcin1(ixt) = 0.0
     386       tkcin2(ixt) = 0.0
     387       tnat(ixt)=1.
     388       toce(ixt)=tnat(ixt)
     389       tcorr(ixt)=1.0
     390       tdifrel(ixt)=1.
     391       talph1(ixt)=0.
     392       talph2(ixt)=0.
     393       talph3(ixt)=0.
     394       talps1(ixt)=0.
     395       talph3(ixt)=0.
     396       alpha_liq_sol(ixt)=1.
     397       Rdefault(ixt)=tnat(ixt)*1.0
     398       Rmethox(ixt)=1.0
     399     endif
     400   enddo ! ixt=1,niso
     401
     402   IF(.NOT.Rdefault_smow) then
     403        Rdefault(:) = 0.0
     404        if (iso_eau.gt.0) Rdefault(iso_eau) = 1.0 ! correction Camille 30 mars 2023
     405   ENDIF
     406   write(*,*) 'Rdefault=',Rdefault
     407   write(*,*) 'toce=',toce
     408
     409   !--- Sensitivity test: no kinetic effect in sfc evaporation
     410   IF(ok_nocinsfc) THEN
     411      tkcin0(1:niso) = 0.0
     412      tkcin1(1:niso) = 0.0
     413      tkcin2(1:niso) = 0.0
     414   END IF
     415
     416   CALL msg('285: verif initialisation:', modname)
     417   DO ixt=1,niso
     418      sxt=int2str(ixt)
     419      CALL msg(' * isoName('//TRIM(sxt)//') = <'//TRIM(isoName(ixt))//'>',  modname)
     420      CALL msg(  '    tnat('//TRIM(sxt)//') = '//TRIM(real2str(tnat(ixt))), modname)
     421!     CALL msg('    alpha_liq_sol('//TRIM(sxt)//') = '//TRIM(real2str(alpha_liq_sol(ixt))), modname)
     422!     CALL msg(        '   tkcin0('//TRIM(sxt)//') = '//TRIM(real2str(tkcin0(ixt))),        modname)
     423!     CALL msg(       '   tdifrel('//TRIM(sxt)//') = '//TRIM(real2str(tdifrel(ixt))),       modname)
    390424   END DO
     425   CALL msg('69:     lambda = '//TRIM(real2str(lambda_sursat)), modname)
     426   CALL msg('69:    thumxt1 = '//TRIM(real2str(thumxt1)),       modname)
     427   CALL msg('69: h_land_ice = '//TRIM(real2str(h_land_ice)),    modname)
     428   CALL msg('69:      P_veg = '//TRIM(real2str(P_veg)),         modname)
    391429
    392430END SUBROUTINE iso_init
  • LMDZ6/trunk/libf/phylmdiso/isotopes_routines_mod.F90

    r5183 r5190  
    1641916419   USE isotopes_mod,      ONLY: isoName,iso_HDO,iso_eau
    1642016420   USE phyetat0_get_mod,  ONLY: phyetat0_get, phyetat0_srf
    16421    USE infotrac_phy,      ONLY: new2oldH2O
    16422    USE strings_mod,       ONLY: strIdx, strHead, strTail, maxlen, msg, int2str
     16421   USE readTracFiles_mod, ONLY: new2oldH2O
     16422   USE strings_mod,       ONLY: strIdx, strTail, maxlen, msg, int2str
    1642316423#ifdef ISOVERIF
    1642416424   USE isotopes_verif_mod
     
    1645916459      outiso = isoName(ixt)
    1646016460      oldIso = strTail(new2oldH2O(outiso), '_')            !--- Remove "H2O_" from "H2O_<iso>[_<tag>]"
    16461       oldIso2= TRIM(strHead(outiso,'_'))//strTail(outiso,'_') ! CR 2023: most recent possibility
     16461      i = INDEX(outiso, '_', .TRUE.)
     16462      oldIso2 = outiso(1:i-1)//outiso(i+1:LEN_TRIM(outiso)) ! CR 2023: on ajoute cette possibilité aussi, elle correspond au cas le plus récent.
    1646216463!      write(*,*) 'tmp 16541:'
    1646316464!      write(*,*) 'outiso=',outiso
  • LMDZ6/trunk/libf/phylmdiso/isotrac_mod.F90

    r5183 r5190  
    33
    44MODULE isotrac_mod
    5   USE infotrac_phy, ONLY: niso, ntiso, nzone, delPhase
    6   USE isotopes_mod, ONLY: ridicule, get_in
     5  USE infotrac_phy,      ONLY: niso, ntiso, nzone
     6  USE readTracFiles_mod, ONLY: delPhase
     7  USE isotopes_mod,      ONLY: ridicule, get_in
    78
    89  IMPLICIT NONE
  • LMDZ6/trunk/libf/phylmdiso/phyetat0_mod.F90

    r5183 r5190  
    4040  USE geometry_mod,     ONLY: longitude_deg, latitude_deg
    4141  USE iostart,          ONLY: close_startphy, get_field, get_var, open_startphy
    42   USE infotrac_phy,     ONLY: nqtot, nbtr, type_trac, tracers, new2oldH2O
    43   USE strings_mod,      ONLY: maxlen
     42  USE infotrac_phy,     ONLY: nqtot, nbtr, type_trac, tracers
     43  USE readTracFiles_mod,ONLY: maxlen, new2oldH2O
    4444  USE traclmdz_mod,     ONLY: traclmdz_from_restart
    4545  USE carbon_cycle_mod, ONLY: carbon_cycle_init, carbon_cycle_cpl, carbon_cycle_tr, carbon_cycle_rad, co2_send, RCO2_glo
  • LMDZ6/trunk/libf/phylmdiso/physiq_mod.F90

    r5189 r5190  
    3939    USE ioipsl_getin_p_mod, ONLY : getin_p
    4040    USE indice_sol_mod
    41     USE infotrac_phy, ONLY: nqtot, nbtr, nqo, tracers, type_trac,addPhase, ivap, iliq, isol
     41    USE infotrac_phy, ONLY: nqtot, nbtr, nqo, tracers, type_trac,ivap,iliq,isol
     42    USE readTracFiles_mod, ONLY: addPhase
    4243    USE strings_mod,  ONLY: strIdx
    4344    USE iophy
     
    26232624       ENDDO
    26242625    ENDDO
    2625    
    2626     ! Lea Raillard qs_ini for cloud phase param.
    2627     qs_ini(:,:)=qs_seri(:,:)
    26282626
    26292627    ! C Risi: dispatcher les isotopes dans les xt_seri
     
    71447142       ENDDO
    71457143    ENDDO
     7144   
     7145    ! Lea Raillard qs_ini for cloud phase param.
     7146    qs_ini(:,:)=qs_seri(:,:)
    71467147
    71477148    ! C Risi: dispatcher les isotopes dans les xt_seri
Note: See TracChangeset for help on using the changeset viewer.