Ignore:
Timestamp:
Sep 22, 2021, 6:11:35 PM (3 years ago)
Author:
dcugnet
Message:
  • fix of the delPhase function.
  • getvar1 and getvar2 fixed and modified to avoid the usage of files with several time records and make the calls rather short.
  • works again with iadv==0
  • no more issues with tracers numbers (nqo, nqtot, etc.)
  • fixes in the algebrical reduction routine used for "isotopes_parems.def" (containing simple expressions with variables that have to be substituted).
  • still to be validated numerically
Location:
LMDZ6/branches/LMDZ-tracers/libf/misc
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • LMDZ6/branches/LMDZ-tracers/libf/misc/readTracFiles_mod.f90

    r3957 r3985  
    106106
    107107  !--- TELLS WHAT WAS IS ABOUT TO BE USED
    108   IF(test(fmsg(fType==0, 'No adequate tracers description file(s) found ; default values will be used'), lerr)) RETURN
     108  IF( fmsg(fType==0, 'No adequate tracers description file(s) found ; default values will be used')) RETURN
    109109  CALL msg(fType==1, 'Trying to read old-style tracers description file "traceur.def"')
    110110  CALL msg(fType==2, 'Trying to read the new style multi-sections tracers description file "tracer.def"')
     
    860860    !--- REDUCE THE EXPRESSIONS TO OBTAIN SCALARS AND TRANSFER THEM TO THE "isot" ISOTOPES DESCRIPTORS VECTOR
    861861    DO it = 1, SIZE(dBase(idb)%trac)
    862       is = strIdx(isot(iis)%keys(:)%name, dBase(idb)%trac(it)%name)  !--- Index of the "isot(iis)%keys(:)%name" tracer named "t%name"
     862      t => dBase(idb)%trac(it)
     863      is = strIdx(isot(iis)%keys(:)%name, t%name)                    !--- Index in "isot(iis)%keys(:)%name" of isotope "t%name"
    863864      IF(is == 0) CYCLE
    864       t => dBase(idb)%trac(it)
    865865      liso = reduceExpr(t%keys%val, vals)                            !--- Reduce expressions (for substituted variables)
    866       isot(iis)%keys(is)%key = PACK(t%keys%key, MASK=liso)
    867       isot(iis)%keys(is)%val = PACK(  vals,     MASK=liso)
     866      IF(test(ANY(liso), lerr)) RETURN                               !--- Some non-numerical elements were found
     867      isot(iis)%keys(is)%key = PACK(t%keys%key, MASK=.NOT.liso)
     868      isot(iis)%keys(is)%val = PACK(  vals,     MASK=.NOT.liso)
    868869    END DO
    869870
     
    12281229ELEMENTAL CHARACTER(LEN=256) FUNCTION delPhase(s) RESULT(out)
    12291230  CHARACTER(LEN=*), INTENT(IN) :: s
    1230   INTEGER :: l, i
     1231  INTEGER :: l, i, ix
    12311232  out = s
    1232   IF(s == '') RETURN
    1233   i = INDEX(s, '_'); l = LEN_TRIM(s)
    1234   IF(i == 0) THEN
    1235     IF(s(l-1:l-1)==phases_sep .AND. INDEX(known_phases,s(l:l)) /= 0) out = s(1:l-2)
    1236   ELSE; i=i-1
    1237     IF(s(i-1:i-1)==phases_sep .AND. INDEX(known_phases,s(i:i)) /= 0) out = s(1:i-2)//s(i+1:l)
     1233  IF(s == '') RETURN                                                           !--- Empty string: nothing to do
     1234  !--- Index of found phase in "known_phases"
     1235  ix = MAXLOC( [(i, i=1,nphases)], MASK=[( INDEX(s, phases_sep//known_phases(i:i))/=0, i=1, nphases)], DIM=1 )
     1236  IF(ix == 0) RETURN                                                           !--- No phase pattern found
     1237  i = INDEX(s, phases_sep//known_phases(ix:ix))                                !--- Index of <sep><pha> pattern in "str"
     1238  l = LEN_TRIM(s)
     1239  IF(i == l-1) THEN                                                            !--- <var><sep><pha>       => return <var>
     1240    out = s(1:l-2)
     1241  ELSE IF(s(i+2:i+2) == '_') THEN                                              !--- <var><sep><pha>_<tag> => return <var>_<tag>
     1242    out = s(1:i-1)//s(i+2:l)
    12381243  END IF
    12391244END FUNCTION delPhase
     
    12441249  INTEGER :: l, i
    12451250  out = s
    1246   IF(s == '') RETURN
    1247   i = INDEX(s, '_'); l = LEN_TRIM(s)
    1248   IF(i == 0) out =  TRIM(s)//phases_sep//pha
    1249   IF(i /= 0) out = s(1:i-1)//phases_sep//pha//'_'//s(i+1:l)
     1251  IF(s == '') RETURN                                                           !--- Empty string: nothing to do
     1252  i = INDEX(s, '_')                                                            !--- /=0 for <var>_<tag> tracers names
     1253  l = LEN_TRIM(s)
     1254  IF(i == 0) out =  TRIM(s)//phases_sep//pha                                   !--- <var>       => return <var><sep><pha>
     1255  IF(i /= 0) out = s(1:i-1)//phases_sep//pha//'_'//s(i+1:l)                    !--- <var>_<tag> => return <var><sep><pha>_<tag>
    12501256END FUNCTION addPhase_1
    12511257!------------------------------------------------------------------------------------------------------------------------------
  • LMDZ6/branches/LMDZ-tracers/libf/misc/strings_mod.F90

    r3957 r3985  
    187187!==============================================================================================================================
    188188!=== Extract the substring in front of the last (first if lFirst==TRUE) occurrence of separator "sep" in "str" ================
     189!=== Examples for str='a_b_c' and sep='_' and the bash command with the same effect:                           ================
     190!===    * strHead(..,.FALSE.) = 'a'           ${str%%$sep*}                                                    ================
     191!===    * strHead(..,.TRUE.)  = 'a_b'         ${str%$sep*}                                                     ================
    189192!==============================================================================================================================
    190193CHARACTER(LEN=256) FUNCTION strHead_1(str,sep,lFirst) RESULT(out)
     
    215218    out = [(strHead_1(str(k),lFirst=.NOT.lf), k=1, SIZE(str))]
    216219  END IF
    217 
    218220END FUNCTION strHead_m
    219221!==============================================================================================================================
    220 !=== Extract the substring following the last (first if lFirst==TRUE) occurrence of separator "sep" in "str" ==================
     222!=== Extract the substring following the last (first if lFirst==TRUE) occurrence of separator "sep" in "str"   ================
     223!=== Examples for str='a_b_c' and sep='_' and the bash command with the same effect:                           ================
     224!===    * strHead(..,.FALSE.) = 'b_c'         ${str#*$sep}                                                     ================
     225!===    * strHead(..,.TRUE.)  = 'c'           ${str##*$sep}                                                    ================
    221226!==============================================================================================================================
    222227CHARACTER(LEN=256) FUNCTION strTail_1(str,sep,lFirst) RESULT(out)
     
    430435  LOGICAL, OPTIONAL, INTENT(IN)  :: lSc                              !--- Care about nbs with front sign or in scient. notation
    431436
     437  INTEGER              :: idx0                                       !--- Used to display an identified non-numeric string
    432438  INTEGER, ALLOCATABLE :: ii(:)
    433439  LOGICAL              :: ll, ls
     
    435441!  modname = 'strIdx'
    436442  lerr = .FALSE.
    437   idx = strIdx1(rawList, del, ibeg, idel)
    438   IF(.NOT.PRESENT(lSc))                     RETURN                  !--- No need to check exceptions for numbers => finished
    439   IF(.NOT.        lSc )                     RETURN                  !--- No need to check exceptions for numbers => finished
     443  idx = strIdx1(rawList, del, ibeg, idel)                            !--- del(idel) appears in "rawList" at position idx
     444  IF(.NOT.PRESENT(lSc))               RETURN                         !--- No need to check exceptions for numbers => finished
     445  IF(.NOT.        lSc )               RETURN                         !--- No need to check exceptions for numbers => finished
     446  IF(idx == 0) THEN                                                  !--- No element of "del" in "rawList":
     447    lerr = .NOT.is_numeric(rawList(ibeg:))                           !--- String must be a number
     448    IF(lerr) idx = LEN_TRIM(rawList); RETURN                         !--- Update idx => rawList(ibeg:idx-1) is the whole string
     449  END IF
     450  idx0 = idx
     451  IF(test(idx==1.AND.INDEX('+-',del(idel))/=0, lerr)) RETURN         !--- Front separator different from +/-: error
     452  IF(idx/=1.AND.is_numeric(rawList(ibeg:idx-1)))      RETURN         !--- The input string tail is a valid number
     453  idx = strIdx1(rawList, del, idx+1, idel)                           !---   => TO THE NEXT DELIMITER
    440454  IF(idx == 0) THEN
    441     lerr = .NOT.is_numeric(rawList(ibeg:)); RETURN                  !--- No separator detected: string must be a number
    442   END IF
    443   IF(test(idx==1.AND.INDEX('+-',del(idel))/=0, lerr)) RETURN        !--- Front separator different from +/-: error
    444   IF(is_numeric(rawList(ibeg:idx-1)))                 RETURN        !--- The input string tail is a valid number
    445   idx = strIdx1(rawList, del, idx+1, idel)                          !---   => TO THE NEXT DELIMITER
     455    lerr = .NOT.is_numeric(rawList(ibeg:))                           !--- No delimiter detected: string must be a number
     456    IF(lerr) idx = idx0; RETURN
     457  END IF
     458  idx0 = idx
     459  IF(is_numeric(rawList(ibeg:idx-1)))                 RETURN         !--- The input string tail is a valid number
     460  IF(test(          INDEX('eE',rawList(idx-1:idx-1)) /= 0  &         !--- Sole possible exception: scientific notation: E+/-
     461               .OR. INDEX('+-',del(idel)) /=0, lerr)) RETURN
     462  idx = strIdx1(rawList, del, idx+1, idel)                           !---   => TO THE NEXT DELIMITER
    446463  IF(idx == 0) THEN
    447     lerr = .NOT.is_numeric(rawList(ibeg:)); RETURN                  !--- No separator detected: string must be a number
    448   END IF
    449   IF(is_numeric(rawList(ibeg:idx-1)))                 RETURN        !--- The input string tail is a valid number
    450   IF(test(          INDEX('eE',rawList(idx-1:idx-1)) /= 0  &        !--- Sole possible exception: scientific notation: E+/-
    451                .OR. INDEX('+-',del(idel)) /=0, lerr)) RETURN
    452   idx = strIdx1(rawList, del, idx+1, idel)                          !---   => TO THE NEXT DELIMITER
    453   IF(idx == 0) THEN
    454     lerr = .NOT.is_numeric(rawList(ibeg:)); RETURN                  !--- No separator detected: string must be a number
     464    lerr = .NOT.is_numeric(rawList(ibeg:))                           !--- No separator detected: string must be a number
     465    IF(lerr) idx = idx0; RETURN
    455466  END IF
    456467  lerr = .NOT.is_numeric(rawList(ibeg:idx-1))
    457 
    458468CONTAINS
    459469
     
    538548  DO
    539549    lerr = strIdx_prv(r, delimiter, ib, ie, jd, ll)
     550    IF(fmsg(lerr,'"'//TRIM(r(ib:ie-1))//'" is not numeric')) RETURN
    540551    IF(jd == 0) EXIT
    541     IF(fmsg(lerr,'"'//TRIM(r(ib:ie-1))//'" is not numeric')) RETURN
    542552    ib = ie + LEN(delimiter(jd))
    543553    DO WHILE(r(ib:ib) == ' ' .AND. ib < nr); ib = ib + 1; END DO     !--- Skip spaces before next chain
     
    11171127!=== Reduce an algebrical expression (basic operations and parenthesis) to a single number (string format) ====================
    11181128!==============================================================================================================================
    1119 LOGICAL FUNCTION reduceExpr_1(str, val) RESULT(out)
     1129LOGICAL FUNCTION reduceExpr_1(str, val) RESULT(lerr)
    11201130  CHARACTER(LEN=*),    INTENT(IN)  :: str
    11211131  CHARACTER(LEN=256),  INTENT(OUT) :: val
     
    11331143  ll = strCount(s,'(',nl)
    11341144  ll = strCount(s,')',nn)
    1135   out = nl == nn
    1136   IF(fmsg(.NOT.out, 'Mismatching number of opening and closing parenthesis: '//TRIM(s))) RETURN
     1145  lerr = nl /= nn
     1146  IF(fmsg(lerr, 'Mismatching number of opening and closing parenthesis: '//TRIM(s))) RETURN
    11371147  nl = 2*nl-1
    11381148
     
    11521162  DO WHILE(nl > 1)
    11531163    i = 1; DO WHILE(ip(i) /= 1 .OR. ip(i+1) /= 2); i = i + 1; END DO !IF(i > SIZE(ip)+1) EXIT;END DO
    1154     out = reduceExpr_basic(vl(i+1), v); IF(.NOT. out) RETURN
     1164    IF(test(reduceExpr_basic(vl(i+1), v), lerr)) RETURN
    11551165    v = TRIM(vl(i))//TRIM(v); IF(i+2<=nl) v=TRIM(v)//TRIM(vl(i+2))
    11561166    vv = v//REPEAT(' ',768)
     
    11601170    nl = SIZE(vl)
    11611171  END DO
    1162   out = reduceExpr_basic(vl(1), val)
     1172  lerr = reduceExpr_basic(vl(1), val)
    11631173END FUNCTION reduceExpr_1
    11641174
     
    11671177!=== Reduce a simple algebrical expression (basic operations, no parenthesis) to a single number (string format) ==============
    11681178!==============================================================================================================================
    1169 LOGICAL FUNCTION reduceExpr_basic(str, val) RESULT(out)
     1179LOGICAL FUNCTION reduceExpr_basic(str, val) RESULT(lerr)
    11701180  CHARACTER(LEN=*),   INTENT(IN)  :: str
    11711181  CHARACTER(LEN=*),   INTENT(OUT) :: val
     
    11781188  DOUBLE PRECISION :: v, vm, vp
    11791189  INTEGER      :: i, ni, io
    1180   LOGICAL :: ll
    11811190
    11821191!  modname = 'reduceExpr_basic'
    1183   out = .TRUE.
     1192  lerr = .FALSE.
    11841193  IF(is_numeric(str)) THEN; val=TRIM(str); RETURN; END IF
    11851194  op = ['^','/','*','+','-']                                                   !--- List of recognized operations
    11861195  s = str
    1187   ll = strParse_m(s, op, ky, .TRUE., id = id)                                  !--- Parse the values
     1196  IF(test(strParse_m(s, op, ky, .TRUE., id = id), lerr)) RETURN                !--- Parse the values
    11881197  vl = str2dble(ky)                                                            !--- Conversion to doubles
    1189   out = ALL(vl < HUGE(1.d0))
    1190   IF(fmsg(.NOT.out,'Some values are non-numeric in: '//TRIM(s))) RETURN        !--- Non-numerical values found
     1198  lerr = ANY(vl >= HUGE(1.d0))
     1199  IF(fmsg(lerr,'Some values are non-numeric in: '//TRIM(s))) RETURN            !--- Non-numerical values found
    11911200  DO io = 1, SIZE(op)                                                          !--- Loop on known operators (order matters !)
    11921201    DO i = SIZE(id), 1, -1                                                     !--- Loop on found operators
     
    12111220
    12121221!==============================================================================================================================
    1213 FUNCTION reduceExpr_m(str, val) RESULT(out)
    1214   LOGICAL,            ALLOCATABLE              :: out(:)
     1222FUNCTION reduceExpr_m(str, val) RESULT(lerr)
     1223  LOGICAL,            ALLOCATABLE              :: lerr(:)
    12151224  CHARACTER(LEN=*),                INTENT(IN)  :: str(:)
    12161225  CHARACTER(LEN=256), ALLOCATABLE, INTENT(OUT) :: val(:)
    12171226  INTEGER :: i
    1218   ALLOCATE(out(SIZE(str)),val(SIZE(str)))
    1219   out(:) = [(reduceExpr_1(str(i), val(i)), i=1, SIZE(str))]
     1227  ALLOCATE(lerr(SIZE(str)),val(SIZE(str)))
     1228  lerr(:) = [(reduceExpr_1(str(i), val(i)), i=1, SIZE(str))]
    12201229END FUNCTION reduceExpr_m
    12211230!==============================================================================================================================
     
    12301239  INTEGER :: e
    12311240  CHARACTER(LEN=12) :: fmt
     1241  IF(TRIM(str) == '') THEN; out = .FALSE.; RETURN; END IF
    12321242  WRITE(fmt,'("(f",i0,".0)")') LEN_TRIM(str)
    12331243  READ(str,fmt,IOSTAT=e) x
Note: See TracChangeset for help on using the changeset viewer.