Changeset 5190 for LMDZ6/trunk/libf/misc
- Timestamp:
- Sep 15, 2024, 10:38:32 AM (5 months ago)
- Location:
- LMDZ6/trunk/libf/misc
- Files:
-
- 1 deleted
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
LMDZ6/trunk/libf/misc/readTracFiles_mod.f90
r5184 r5190 10 10 11 11 PUBLIC :: maxlen !--- PARAMETER FOR CASUAL STRING LENGTH 12 PUBLIC :: keys_type, tracers, setGeneration, indexUpdate !--- TRACERS DESCRIPTION DATABASE + ASSOCIATED TOOLS12 PUBLIC :: trac_type, tracers, setGeneration, indexUpdate !--- TRACERS DESCRIPTION DATABASE + ASSOCIATED TOOLS 13 13 PUBLIC :: testTracersFiles, readTracersFiles !--- TRACERS FILES READING ROUTINES 14 14 PUBLIC :: getKeysDBase, setKeysDBase !--- TOOLS TO GET/SET THE DATABASE (tracers & isotopes) 15 15 PUBLIC :: addTracer, delTracer !--- ADD/REMOVE A TRACER FROM 16 PUBLIC :: addKey, delKey, getKey 16 PUBLIC :: addKey, delKey, getKey, keys_type !--- TOOLS TO SET/DEL/GET KEYS FROM/TO tracers & isotopes 17 17 PUBLIC :: addPhase, delPhase, getPhase, getiPhase, & !--- FUNCTIONS RELATED TO THE PHASES 18 18 nphases, old_phases, phases_sep, known_phases, phases_names !--- + ASSOCIATED VARIABLES … … 35 35 PUBLIC :: itZonIso !--- Idx IN isoName(1:niso) = f(tagging idx, isotope idx) 36 36 PUBLIC :: iqIsoPha !--- Idx IN qx(1:nqtot) = f(isotope idx, phase idx) 37 PUBLIC :: iqWIsoPha !--- SAME AS iqIsoPha BUT ISOTOPES LIST STARTS WITH PARENT TRAC37 PUBLIC :: iqWIsoPha !--- Idx IN qx(1:nqtot) = f(isotope idx, phase idx) but with normal water first 38 38 PUBLIC :: isoCheck !--- FLAG TO RUN ISOTOPES CHECKING ROUTINES 39 39 … … 41 41 !------------------------------------------------------------------------------------------------------------------------------ 42 42 TYPE :: keys_type !=== TYPE FOR A SET OF KEYS ASSOCIATED TO AN ELEMENT 43 CHARACTER(LEN=maxlen) :: name !--- Tracer name 43 44 CHARACTER(LEN=maxlen), ALLOCATABLE :: key(:) !--- Keys string list 44 45 CHARACTER(LEN=maxlen), ALLOCATABLE :: val(:) !--- Corresponding values string list 45 46 END TYPE keys_type 46 47 !------------------------------------------------------------------------------------------------------------------------------ 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) 49 73 TYPE(keys_type), ALLOCATABLE :: keys(:) !--- Isotopes keys/values pairs list (length: niso) 50 74 LOGICAL :: check=.FALSE. !--- Flag for checking routines triggering … … 64 88 TYPE :: dataBase_type !=== TYPE FOR TRACERS SECTION 65 89 CHARACTER(LEN=maxlen) :: name !--- Section name 66 TYPE( keys_type), ALLOCATABLE :: trac(:) !--- Tracers descriptors90 TYPE(trac_type), ALLOCATABLE :: trac(:) !--- Tracers descriptors 67 91 END TYPE dataBase_type 68 92 !------------------------------------------------------------------------------------------------------------------------------ … … 115 139 116 140 !=== TRACERS AND ISOTOPES DESCRIPTORS, USED BY getKey 117 TYPE( keys_type), ALLOCATABLE, TARGET, SAVE :: tracers(:)141 TYPE(trac_type), ALLOCATABLE, TARGET, SAVE :: tracers(:) 118 142 TYPE(isot_type), ALLOCATABLE, TARGET, SAVE :: isotopes(:) 119 143 … … 169 193 !------------------------------------------------------------------------------------------------------------------------------ 170 194 CHARACTER(LEN=*), INTENT(IN) :: type_trac !--- List of components used 171 TYPE( keys_type), ALLOCATABLE, TARGET, OPTIONAL, INTENT(OUT) :: tracs(:) !--- Tracers descriptor for external storage195 TYPE(trac_type), ALLOCATABLE, TARGET, OPTIONAL, INTENT(OUT) :: tracs(:) !--- Tracers descriptor for external storage 172 196 LOGICAL, OPTIONAL, INTENT(IN) :: lRepr !--- Activate the HNO3 exceptions for REPROBUS 173 197 CHARACTER(LEN=maxlen), ALLOCATABLE :: s(:), sections(:), trac_files(:) 174 CHARACTER(LEN=maxlen) :: str, fname, tname, pname, cname , ttype198 CHARACTER(LEN=maxlen) :: str, fname, tname, pname, cname 175 199 INTEGER :: nsec, ierr, it, ntrac, ns, ip, ix, fType 176 200 INTEGER, ALLOCATABLE :: iGen(:) … … 208 232 CALL msg('This file is for air tracers only', modname, ns == 3 .AND. it == 1) 209 233 CALL msg('This files specifies the transporting fluid', modname, ns == 4 .AND. it == 1) 210 k => tracers(it) 234 k => tracers(it)%keys 211 235 212 236 !=== NAME OF THE TRACER … … 214 238 ix = strIdx(oldHNO3, s(3)) 215 239 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 218 243 219 244 !=== NAME OF THE COMPONENT 220 245 cname = type_trac !--- Name of the model component 221 246 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 223 249 224 250 !=== NAME OF THE PARENT … … 229 255 IF(ix /= 0 .AND. lRep) pname = newHNO3(ix) !--- Exception for HNO3 (REPROBUS ONLY) 230 256 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) 232 259 233 260 !=== 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) 235 263 CALL addKey('hadv', s(1), k) !--- Set the horizontal advection schemes number 236 264 CALL addKey('vadv', s(2), k) !--- Set the vertical advection schemes number … … 238 266 CLOSE(90) 239 267 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' 241 270 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 244 272 END DO 245 273 lerr = checkTracers(tracers, fname, fname); IF(lerr) RETURN !--- Detect orphans and check phases … … 263 291 END IF 264 292 lerr = indexUpdate(tracers); IF(lerr) RETURN !--- Set iqParent, iqDescen, nqDescen, nqChildren 265 IF(PRESENT(tracs)) tracs = tracers293 IF(PRESENT(tracs)) CALL MOVE_ALLOC(FROM=tracers, TO=tracs) 266 294 END FUNCTION readTracersFiles 267 295 !============================================================================================================================== … … 311 339 ! Purpose: Read the sections "snames(is)" (pipe-separated list) from each "fnames(is)" 312 340 ! file and create the corresponding tracers set descriptors in the database "dBase": 313 ! * dBase(id)%name : section name314 ! * 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)%name316 ! * dBase(id)%trac(it)% val(:): values of keys associated to tracer dBase(id)%trac(it)%name341 ! * 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 317 345 !------------------------------------------------------------------------------------------------------------------------------ 318 346 CHARACTER(LEN=*), INTENT(IN) :: fnames(:) !--- Files names … … 367 395 ndb= SIZE(dBase) !--- Current number of sections in the database 368 396 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" 372 398 END IF 373 399 ll = strParse(snam, '|', keys = sec) !--- Requested sections names … … 382 408 !------------------------------------------------------------------------------------------------------------------------------ 383 409 CHARACTER(LEN=maxlen), ALLOCATABLE :: s(:), v(:) 384 TYPE(keys_type), ALLOCATABLE :: tt(:) 410 TYPE(trac_type), ALLOCATABLE :: tt(:) 411 TYPE(trac_type) :: tmp 385 412 CHARACTER(LEN=1024) :: str, str2 386 413 CHARACTER(LEN=maxlen) :: secn … … 418 445 tt = dBase(ndb)%trac(:) 419 446 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) 422 450 END IF 423 451 END DO … … 432 460 433 461 !============================================================================================================================== 434 LOGICAL FUNCTION addDefault(t, defName) RESULT(lerr)462 SUBROUTINE addDefault(t, defName) 435 463 !------------------------------------------------------------------------------------------------------------------------------ 436 464 ! Purpose: Add the keys from virtual tracer named "defName" (if any) and remove this virtual tracer. 437 465 !------------------------------------------------------------------------------------------------------------------------------ 438 TYPE( keys_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: t(:)466 TYPE(trac_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: t(:) 439 467 CHARACTER(LEN=*), INTENT(IN) :: defName 440 468 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) 445 472 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 449 477 END DO 450 478 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 FUNCTIONaddDefault452 !============================================================================================================================== 453 454 !============================================================================================================================== 455 LOGICAL FUNCTION subDefault(t, defName, lSubLocal) RESULT(lerr)479 END SUBROUTINE addDefault 480 !============================================================================================================================== 481 482 !============================================================================================================================== 483 SUBROUTINE subDefault(t, defName, lSubLocal) 456 484 !------------------------------------------------------------------------------------------------------------------------------ 457 485 ! Purpose: Substitute the keys from virtual tracer named "defName" (if any) and remove this virtual tracer. 458 486 ! Substitute the keys locally (for the current tracer) if the flag "lSubLocal" is .TRUE. 459 487 !------------------------------------------------------------------------------------------------------------------------------ 460 TYPE( keys_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: t(:)488 TYPE(trac_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: t(:) 461 489 CHARACTER(LEN=*), INTENT(IN) :: defName 462 490 LOGICAL, INTENT(IN) :: lSubLocal 463 491 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) 468 495 IF(i0 == 0) RETURN 496 k0 => t(i0)%keys 469 497 DO it = 1, SIZE(t); IF(it == i0) CYCLE !--- Loop on the tracers 498 ky => t(it)%keys 470 499 471 500 !--- 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 DO501 DO ik = 1, SIZE(k0%key); CALL strReplace(ky%val, k0%key(ik), k0%val(ik), .TRUE.); END DO 473 502 474 503 IF(.NOT.lSubLocal) CYCLE 475 504 !--- 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 DO505 DO ik = 1, SIZE(ky%key); CALL strReplace(ky%val, ky%key(ik), ky%val(ik), .TRUE.); END DO 477 506 END DO 478 507 tt = [t(1:i0-1),t(i0+1:SIZE(t))]; CALL MOVE_ALLOC(FROM=tt, TO=t) !--- Remove the virtual tracer named "defName" 479 508 480 END FUNCTIONsubDefault509 END SUBROUTINE subDefault 481 510 !============================================================================================================================== 482 511 … … 489 518 ! * Default values are provided for these keys because they are necessary. 490 519 !------------------------------------------------------------------------------------------------------------------------------ 491 TYPE( keys_type), ALLOCATABLE, INTENT(INOUT) :: tr(:) !--- Tracer derived type vector520 TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: tr(:) !--- Tracer derived type vector 492 521 CHARACTER(LEN=*), INTENT(IN) :: sname !--- Current section name 493 522 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: fname !--- Tracers description file name 494 TYPE( keys_type), ALLOCATABLE :: ttr(:)523 TYPE(trac_type), ALLOCATABLE :: ttr(:) 495 524 CHARACTER(LEN=maxlen), ALLOCATABLE :: ta(:), pa(:), tname(:), parent(:), dType(:) 496 525 CHARACTER(LEN=maxlen) :: msg1, modname … … 500 529 lerr = .FALSE. 501 530 nt = SIZE(tr) 502 lerr = getKey('name', tname, tr(:) ); IF(lerr) RETURN503 lerr = getKey('parent', parent, tr(:) , def = tran0); IF(lerr) RETURN504 lerr = getKey('type', dType, tr(:) , def = 'tracer'); IF(lerr) RETURN531 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 505 534 nq = 0 506 535 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ … … 508 537 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 509 538 !--- 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) 511 541 512 542 !--- Determine the number of tracers and parents ; coherence checking … … 535 565 DO ipr = 1, npr !--- Loop on parents list elts 536 566 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) 543 578 iq = iq + 1 544 579 END DO … … 562 597 ! Check also for orphan tracers (tracers without parent). 563 598 !------------------------------------------------------------------------------------------------------------------------------ 564 TYPE( keys_type), INTENT(INOUT) :: tr(:) !--- Tracer derived type vector599 TYPE(trac_type), INTENT(INOUT) :: tr(:) !--- Tracer derived type vector 565 600 INTEGER :: iq, jq, ig 566 601 CHARACTER(LEN=maxlen), ALLOCATABLE :: parent(:), tname(:) … … 568 603 CHARACTER(LEN=maxlen) :: modname 569 604 modname = 'setGeneration' 570 lerr = getKey('name', tname, ky=tr(:) ); IF(lerr) RETURN571 lerr = getKey('parent', parent, ky=tr(:) ); IF(lerr) RETURN605 lerr = getKey('name', tname, ky=tr(:)%keys); IF(lerr) RETURN 606 lerr = getKey('parent', parent, ky=tr(:)%keys); IF(lerr) RETURN 572 607 DO iq = 1, SIZE(tr) 573 608 jq = iq; ig = 0 … … 578 613 ig = ig + 1 579 614 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) 582 619 END DO 583 620 END FUNCTION setGeneration … … 592 629 ! * check wether the phases are known or not (elements of "known_phases") 593 630 !------------------------------------------------------------------------------------------------------------------------------ 594 TYPE( keys_type), INTENT(IN) :: tr(:) !--- Tracers descriptionvector631 TYPE(trac_type), INTENT(IN) :: tr(:) !--- Tracer derived type vector 595 632 CHARACTER(LEN=*), INTENT(IN) :: sname !--- Section name 596 633 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: fname !--- File name … … 607 644 mesg = 'Check section "'//TRIM(sname)//'"' 608 645 IF(PRESENT(fname)) mesg=TRIM(mesg)//' in file "'//TRIM(fname)//'"' 609 lerr = getKey('iGeneration', iGen, tr(:) );IF(lerr) RETURN610 lerr = getKey('name', tname, tr(:) );IF(lerr) RETURN646 lerr = getKey('iGeneration', iGen, tr(:)%keys); IF(lerr) RETURN 647 lerr = getKey('name', tname, tr(:)%keys); IF(lerr) RETURN 611 648 612 649 !=== CHECK FOR ORPHAN TRACERS … … 615 652 !=== CHECK PHASES 616 653 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' !--- Phase654 IF(getKey(['phases','phase '], pha, iq, tr(:)%keys, lDisp=.FALSE.)) pha = 'g' !--- Phase 618 655 np = LEN_TRIM(pha); bp(iq)=' ' 619 656 DO ip = 1, np; p = pha(ip:ip); IF(INDEX(known_phases, p) == 0) bp(iq) = TRIM(bp(iq))//p; END DO … … 630 667 ! Purpose: Make sure that tracers are not repeated. 631 668 !------------------------------------------------------------------------------------------------------------------------------ 632 TYPE( keys_type), INTENT(IN) :: tr(:) !--- Tracers descriptionvector669 TYPE(trac_type), INTENT(IN) :: tr(:) !--- Tracer derived type vector 633 670 CHARACTER(LEN=*), INTENT(IN) :: sname !--- Section name 634 671 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: fname !--- File name … … 647 684 nq=SIZE(tr,DIM=1); lerr=.FALSE. !--- Number of lines ; error flag 648 685 tdup(:) = '' 649 lerr = getKey('name', tname, tr ); IF(lerr) RETURN650 lerr = getKey('type', dType, tr ); IF(lerr) RETURN651 lerr = getKey('iGeneration', iGen, tr ); IF(lerr) RETURN686 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 652 689 DO iq = 1, nq 653 690 IF(dType(iq) == 'tag') CYCLE !--- Tags can be repeated … … 661 698 DO k = 1, nq 662 699 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 phases700 IF(getKey(['phases','phase '], phase, k, tr%keys, lDisp=.FALSE.)) phase='g'!--- Get current phases 664 701 IF(INDEX(phase, p) /= 0) np = np + 1 !--- One more appearance of current tracer with phase "p" 665 702 END DO … … 681 718 ! Purpose: Expand the phases in the tracers descriptor "tr". Phases are not repeated for a tracer, thanks to "checkUnique". 682 719 !------------------------------------------------------------------------------------------------------------------------------ 683 TYPE( keys_type), ALLOCATABLE, INTENT(INOUT) :: tr(:) !--- Tracers descriptionvector684 !------------------------------------------------------------------------------------------------------------------------------ 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(:) 686 723 INTEGER, ALLOCATABLE :: i0(:), iGen(:) 687 724 CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:), gen0N(:), phase(:), parents(:), dType(:) … … 695 732 nq = SIZE(tr, DIM=1) 696 733 nt = 0 697 lerr = getKey('name', tname, tr ); IF(lerr) RETURN!--- Names of the tracers698 lerr = getKey('gen0Name', gen0N, tr ); IF(lerr) RETURN!--- Names of the tracers of first generation699 lerr = getKey('iGeneration', iGen, tr ); IF(lerr) RETURN!--- Generation number700 lerr = getKey('phases', phase, tr ); IF(lerr) RETURN!--- Phases names701 lerr = getKey('parent', parents, tr ); IF(lerr) RETURN!--- Parents names702 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') 703 740 DO iq = 1, nq !--- GET THE NUMBER OF TRACERS 704 741 IF(iGen(iq) /= 0) CYCLE !--- Only deal with generation 0 tracers … … 726 763 IF(lTag) nam = TRIM(nam)//'_'//TRIM(tname(iq)) !--- <parent>_<name> for tags 727 764 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) 730 770 IF(lExt) THEN 731 771 parent = parents(iq); IF(iGen(iq) > 0) parent = addPhase(parent, p) 732 772 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) 735 777 END IF 736 778 it = it+1 … … 740 782 END DO 741 783 CALL MOVE_ALLOC(FROM=ttr, TO=tr) 742 CALL delKey(['phases'], tr) !--- Remove "phases" key, useless since "phase" is defined784 CALL delKey(['phases'],tr) !--- Remove few keys entries 743 785 744 786 END FUNCTION expandPhases … … 755 797 ! TO BE ADDED IF NECESSARY: HIGHER MOMENTS AT THE END 756 798 !------------------------------------------------------------------------------------------------------------------------------ 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(:) 761 804 CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:), gen0N(:) 762 805 INTEGER :: ig, ng, iq, jq, ip, nq, n, ix(SIZE(tr)), k … … 764 807 ! tr2 is introduced in order to cope with a bug in gfortran 4.8.5 compiler 765 808 !------------------------------------------------------------------------------------------------------------------------------ 766 lerr = getKey('iGeneration', iGen, tr ); IF(lerr) RETURN!--- Generation number809 lerr = getKey('iGeneration', iGen, tr%keys); IF(lerr) RETURN !--- Generation number 767 810 nq = SIZE(tr) 768 811 DO ip = nphases, 1, -1 769 lerr = getKey('name', tname, tr ); IF(lerr) RETURN!--- Names of the tracers of first generation812 lerr = getKey('name', tname, tr%keys); IF(lerr) RETURN !--- Names of the tracers of first generation 770 813 iq = strIdx(tname, addPhase('H2O', ip)) 771 814 IF(iq == 0) CYCLE … … 783 826 END DO 784 827 ELSE 785 lerr = getKey('gen0Name', gen0N, tr); IF(lerr) RETURN!--- Names of the tracers iq = 1828 lerr = getKey('gen0Name', gen0N, tr%keys); IF(lerr) RETURN !--- Names of the tracers iq = 1 786 829 DO jq = 1, nq !--- Loop on generation 0 tracers 787 830 IF(iGen(jq) /= 0) CYCLE !--- Skip generations /= 0 … … 805 848 LOGICAL FUNCTION mergeTracers(sections, tr) RESULT(lerr) 806 849 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(:) 809 853 INTEGER, ALLOCATABLE :: ixct(:), ixck(:) 810 854 INTEGER :: is, ik, ik1, ik2, nk2, i1, i2, nt2 … … 814 858 lerr = .FALSE. 815 859 keys = ['parent ', 'type ', 'iGeneration'] !--- Mandatory keys 816 t1 => sections(1)%trac(:) !--- Alias: first tracers section817 lerr = getKey('name', n1, t1); IF(lerr) RETURN !--- Names of the tracers860 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 818 862 tr = t1 819 863 !---------------------------------------------------------------------------------------------------------------------------- … … 821 865 !---------------------------------------------------------------------------------------------------------------------------- 822 866 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 824 869 nt2 = SIZE(t2(:), DIM=1) !--- Number of tracers in section 825 870 ixct = strIdx(n1(:), n2(:)) !--- Indexes of common tracers … … 829 874 CALL msg(n1(PACK(ixct, MASK = ixct/=0)), modname, nmax=128) !--- Display duplicates (the 128 first at most) 830 875 !-------------------------------------------------------------------------------------------------------------------------- 831 DO i2=1,nt2; tnam = TRIM( n2(i2))!=== LOOP ON COMMON TRACERS876 DO i2=1,nt2; tnam = TRIM(t2(i2)%name) !=== LOOP ON COMMON TRACERS 832 877 !-------------------------------------------------------------------------------------------------------------------------- 833 878 i1 = ixct(i2); IF(i1 == 0) CYCLE !--- Idx in t1(:) ; skip new tracers … … 836 881 s1=' of "'//TRIM(tnam)//'" in "'//TRIM(sections(is)%name)//'" not matching previous value' 837 882 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) 840 885 lerr = v1 /= v2; IF(fmsg(TRIM(keys(ik))//TRIM(s1), modname, lerr)) RETURN 841 886 END DO 842 887 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 section845 ixck = strIdx( t1(i1)%key(:), t2(i2)%key(:)) !--- Common keys indexes846 !--- 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)] 849 894 850 895 !=== 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) 854 900 855 901 !=== FOR TRACERS COMMON TO PREVIOUS AND CURRENT SECTIONS: CHECK WETHER SOME KEYS HAVE DIFFERENT VALUES ; KEEP OLD ONE 856 902 DO ik2 = 1, nk2 !--- Collect the corresponding indices 857 903 ik1 = ixck(ik2); IF(ik1 == 0) CYCLE 858 IF( t1(i1)%val(ik1) == t2(i2)%val(ik2)) ixck(ik2)=0904 IF(k1(i1)%val(ik1) == k2(i2)%val(ik2)) ixck(ik2)=0 859 905 END DO 860 906 IF(ALL(ixck==0)) CYCLE !--- No identical keys with /=values => nothing to display 861 907 CALL msg('Key(s)'//TRIM(s1), modname) !--- Display the keys with /=values (names list) 862 908 DO ik2 = 1, nk2 !--- Loop on keys found in both t1(:) and t2(:) 863 knam = t2(i2)%key(ik2) !--- Name of the current key909 knam = k2(i2)%key(ik2) !--- Name of the current key 864 910 ik1 = ixck(ik2) !--- Corresponding index in t1(:) 865 911 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(:) 867 913 CALL msg(' * '//TRIM(knam)//'='//TRIM(v2)//' ; previous value kept:'//TRIM(v1), modname) 868 914 END DO … … 879 925 LOGICAL FUNCTION cumulTracers(sections, tr, lRename) RESULT(lerr) 880 926 TYPE(dataBase_type), TARGET, INTENT(IN) :: sections(:) 881 TYPE( keys_type), ALLOCATABLE, INTENT(OUT) :: tr(:)927 TYPE(trac_type), ALLOCATABLE, INTENT(OUT) :: tr(:) 882 928 LOGICAL, OPTIONAL, INTENT(IN) :: lRename !--- .TRUE.: add a section suffix to identical names 883 929 CHARACTER(LEN=maxlen) :: tnam_new, modname … … 888 934 tr = [( sections(is)%trac(:), is = 1, SIZE(sections) )] !--- Concatenated tracers vector 889 935 IF(PRESENT(lRename)) THEN; IF(lRename) RETURN; END IF !--- No renaming: finished 890 lerr = getKey('name', tname, tr ); IF(lerr) RETURN!--- Names891 lerr = getKey('parent', parent, tr ); IF(lerr) RETURN!--- Parents892 lerr = getKey('component', comp, tr ); IF(lerr) RETURN!--- Component name936 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 893 939 !---------------------------------------------------------------------------------------------------------------------------- 894 940 DO iq = 1, SIZE(tr); IF(COUNT(tname == tname(iq)) == 1) CYCLE !=== LOOP ON TRACERS 895 941 !---------------------------------------------------------------------------------------------------------------------------- 896 942 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 898 945 !-------------------------------------------------------------------------------------------------------------------------- 899 946 DO jq = 1, SIZE(tr); IF(parent(jq) /= tname(iq)) CYCLE !=== LOOP ON TRACERS PARENTS 900 947 !-------------------------------------------------------------------------------------------------------------------------- 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 902 950 !-------------------------------------------------------------------------------------------------------------------------- 903 951 END DO … … 946 994 tmp = int2str([(iq, iq=1, nq)]) 947 995 ELSE 948 lerr = getKey(nam, tmp, dBase(idb)%trac(:) , lDisp=lMandatory)996 lerr = getKey(nam, tmp, dBase(idb)%trac(:)%keys, lDisp=lMandatory) 949 997 END IF 950 998 IF(lerr) THEN; lerr = lMandatory; RETURN; END IF … … 965 1013 LOGICAL FUNCTION aliasTracer(tname, trac, alias) RESULT(lerr) !=== TRACER NAMED "tname" - SCALAR 966 1014 CHARACTER(LEN=*), INTENT(IN) :: tname 967 TYPE( keys_type), TARGET, INTENT(IN) :: trac(:)968 TYPE( keys_type), POINTER, INTENT(OUT) :: alias1015 TYPE(trac_type), TARGET, INTENT(IN) :: trac(:) 1016 TYPE(trac_type), POINTER, INTENT(OUT) :: alias 969 1017 INTEGER :: it 970 1018 CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:) 971 1019 alias => NULL() 972 lerr = getKey('name', tnames, trac(:) )1020 lerr = getKey('name', tnames, trac(:)%keys) 973 1021 it = strIdx(tnames, tname) 974 1022 lerr = it /= 0; IF(.NOT.lerr) alias => trac(it) … … 976 1024 !============================================================================================================================== 977 1025 LOGICAL 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(:) 979 1027 INTEGER, INTENT(IN) :: idx(:) 980 TYPE( keys_type), ALLOCATABLE, INTENT(OUT) :: alias(:)1028 TYPE(trac_type), ALLOCATABLE, INTENT(OUT) :: alias(:) 981 1029 alias = trac(idx) 982 1030 lerr = indexUpdate(alias) … … 984 1032 !------------------------------------------------------------------------------------------------------------------------------ 985 1033 LOGICAL 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(:) 987 1035 CHARACTER(LEN=*), INTENT(IN) :: tname(:) 988 TYPE( keys_type), ALLOCATABLE, INTENT(OUT) :: alias(:)1036 TYPE(trac_type), ALLOCATABLE, INTENT(OUT) :: alias(:) 989 1037 CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:) 990 lerr = getKey('name', tnames, trac(:) )1038 lerr = getKey('name', tnames, trac(:)%keys) 991 1039 alias = trac(strIdx(tnames, tname)) 992 1040 lerr = indexUpdate(alias) … … 994 1042 !============================================================================================================================== 995 1043 LOGICAL 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(:) 997 1045 CHARACTER(LEN=*), INTENT(IN) :: gen0Nm 998 TYPE( keys_type), ALLOCATABLE, INTENT(OUT) :: alias(:)1046 TYPE(trac_type), ALLOCATABLE, INTENT(OUT) :: alias(:) 999 1047 CHARACTER(LEN=maxlen), ALLOCATABLE :: gen0N(:) 1000 lerr = getKey('gen0Name', gen0N, trac(:) )1048 lerr = getKey('gen0Name', gen0N, trac(:)%keys) 1001 1049 alias = trac(strFind(delPhase(gen0N), gen0Nm)) 1002 1050 lerr = indexUpdate(alias) … … 1006 1054 1007 1055 !============================================================================================================================== 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) ========= 1009 1057 !============================================================================================================================== 1010 1058 LOGICAL FUNCTION indexUpdate(tr) RESULT(lerr) 1011 TYPE( keys_type), INTENT(INOUT) :: tr(:)1059 TYPE(trac_type), INTENT(INOUT) :: tr(:) 1012 1060 INTEGER :: iq, jq, nq, ig, nGen 1013 1061 INTEGER, ALLOCATABLE :: iqDescen(:), ix(:), iy(:) 1014 1062 CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:), parent(:) 1015 1063 INTEGER, DIMENSION(SIZE(tr)) :: iqParent, iGen 1016 lerr = getKey('name', tnames, tr ); IF(lerr) RETURN!--- Names1017 lerr = getKey('parent', parent, tr ); IF(lerr) RETURN!--- Parents1064 lerr = getKey('name', tnames, tr%keys); IF(lerr) RETURN !--- Names 1065 lerr = getKey('parent', parent, tr%keys); IF(lerr) RETURN !--- Parents 1018 1066 nq = SIZE(tr) 1019 1067 1020 !=== iqParent 1068 !=== iqParent, iGeneration 1021 1069 DO iq = 1, nq; iGen(iq) = 0; jq = iq 1022 1070 iqParent(iq) = strIdx(tnames, parent(iq)) 1023 1071 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) 1025 1074 END DO 1026 1075 … … 1029 1078 DO iq = 1, nq 1030 1079 ix = [iq]; ALLOCATE(iqDescen(0)) 1031 CALL addKey('nqChildren', 0, tr(iq))1032 1080 DO ig = iGen(iq)+1, nGen 1033 1081 iy = find(iqParent, ix); iqDescen = [iqDescen, iy]; ix = iy 1034 1082 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) 1036 1085 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) 1039 1090 DEALLOCATE(iqDescen) 1040 1091 END DO … … 1044 1095 1045 1096 !============================================================================================================================== 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" ==== 1048 1099 !=== * For each isotopes class, the <key>=<val> vector of each tracer is moved into the isotopes descriptor "isot" ==== 1049 1100 !=== NOTES: ==== 1050 1101 !=== * 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(:,:) ==== 1052 1103 !=== * Same syntax for isotopes file and "tracer.def": a tracers section contains one line for each of its isotopes ==== 1053 1104 !=== * Each tracers section can contain a "params" virtual isotope line of isotopes parameters default values ==== … … 1058 1109 LOGICAL FUNCTION readIsotopesFile(fnam, isot) RESULT(lerr) 1059 1110 CHARACTER(LEN=*), INTENT(IN) :: fnam !--- Input file name 1060 TYPE(isot_type), TARGET, INTENT(INOUT) :: isot(:) !--- Isotopes descriptors (field % namemust be defined!)1111 TYPE(isot_type), TARGET, INTENT(INOUT) :: isot(:) !--- Isotopes descriptors (field %parent must be defined!) 1061 1112 LOGICAL :: lFound 1062 1113 INTEGER :: is, iis, it, idb, ndb, nb0 1063 CHARACTER(LEN=maxlen), ALLOCATABLE :: vals(:) , tname(:), iname(:)1114 CHARACTER(LEN=maxlen), ALLOCATABLE :: vals(:) 1064 1115 CHARACTER(LEN=maxlen) :: modname 1065 TYPE( keys_type), POINTER ::t1116 TYPE(trac_type), POINTER :: tt(:), t 1066 1117 TYPE(dataBase_type), ALLOCATABLE :: tdb(:) 1067 1118 modname = 'readIsotopesFile' 1068 1119 1069 1120 !--- 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 1076 1125 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 %name1126 lerr = readSections(fnam,strStack(isot(:)%parent,'|')); IF(lerr) RETURN !--- Read sections, one each parent tracer 1078 1127 ndb = SIZE(dBase, DIM=1) !--- Current database size 1079 1128 DO idb = nb0, ndb … … 1081 1130 1082 1131 !--- 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') 1084 1133 1085 1134 !--- 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 1087 1138 1088 1139 !--- 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) RETURN1090 lerr = getKey('name', iname, isot(iis)%keys); IF(lerr) RETURN1091 1140 DO it = 1, SIZE(dBase(idb)%trac) 1092 1141 t => dBase(idb)%trac(it) 1093 is = strIdx(i name, 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" 1094 1143 IF(is == 0) CYCLE 1095 lerr = ANY(reduceExpr(t% val, vals)); IF(lerr) RETURN!--- Reduce expressions ; detect non-numerical elements1096 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 1097 1146 isot(iis)%keys(is)%val = vals 1098 1147 END DO 1099 1148 1100 1149 !--- CHECK FOR MISSING ISOTOPES (NO KEYS ALLOCATED) 1101 lerr = checkList(i name, .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) )], & 1102 1151 'Check file "'//TRIM(fnam)//'" in section "'//TRIM(dBase(idb)%name)//'"', 'isotopes', 'missing') 1103 1152 IF(lerr) RETURN … … 1112 1161 1113 1162 !--- 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(i name, 'H2O'))%check, .FALSE.)1163 CALL get_in('ok_iso_verif', isot(strIdx(isot%parent, 'H2O'))%check, .FALSE.) 1115 1164 1116 1165 lerr = dispIsotopes() … … 1122 1171 INTEGER :: ik, nk, ip, it, nt 1123 1172 CHARACTER(LEN=maxlen) :: prf 1124 CHARACTER(LEN=maxlen), ALLOCATABLE :: ttl(:), val(:,:) , tname(:)1173 CHARACTER(LEN=maxlen), ALLOCATABLE :: ttl(:), val(:,:) 1125 1174 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 1128 1176 nk = SIZE(isot(ip)%keys(1)%key) !--- Same keys for each isotope 1129 1177 nt = SIZE(isot(ip)%keys) !--- Number of isotopes … … 1131 1179 ALLOCATE(ttl(nk+2), val(nt,nk+1)) 1132 1180 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 1135 1182 DO ik = 1, nk 1136 1183 DO it = 1, nt … … 1152 1199 !=== IF ISOTOPES (2ND GENERATION TRACERS) ARE DETECTED: === 1153 1200 !=== * 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 !============================================================================================================================== 1205 LOGICAL 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 1170 1216 1171 1217 lerr = .FALSE. 1172 1218 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 1188 1228 1189 1229 !--- 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 "i Classes" ARE AVAILABLE OR NOT1194 IF(PRESENT(i Classes)) THEN1195 DO it = 1, SIZE(i Classes)1196 lerr = ALL( iCla /= iClasses(it))1197 IF(fmsg('No isotopes class "'//TRIM(i Classes(it))//'" found among tracers', modname, lerr)) RETURN1230 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 1198 1238 END DO 1199 iCla = iClasses1239 p = iNames; nbIso = SIZE(p) 1200 1240 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 1210 1244 IF(nbIso==0) RETURN !=== NO ISOTOPES: FINISHED 1211 1245 1212 1246 !--- 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") 1233 1266 ! NOTE: One might like to create a similar variable for 2nd generation tagging tracers (tagging the gen1 tracers) 1234 str 2= PACK(delPhase(tname), MASK=ll)1235 CALL strReduce(str 2)1236 i 1%ntiso = i1%niso + SIZE(str2)!--- Number of isotopes + their geographic tracers [ntiso]1237 ALLOCATE(i 1%trac(i1%ntiso))1238 DO it = 1, i1%niso; i1%trac(it) = str1(it); END DO1239 DO it = i1%niso+1, i1%ntiso; i1%trac(it) = str2(it-i1%niso); END DO1240 1241 !=== Phases for tracer "i Class"1242 i 1%phase = ''1243 DO ip = 1, nphases; ph = known_phases(ip:ip); IF( ANY(tname == addPhase(iClass, ph))) i1%phase = TRIM(i1%phase)//ph; END DO1244 i 1%nphas = LEN_TRIM(i1%phase) !--- Equal to "nqo" for water1267 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 1245 1278 1246 1279 !=== 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 1257 1288 END DO 1258 1289 1259 1290 !=== Table used to get iq (index in dyn array, size nqtot) from the isotope and phase indexes ; the full isotopes list 1260 1291 ! (including tagging tracers) is sorted this way: iso1, iso2, ..., iso1_zone1, iso2_zone1, ..., iso1_zoneN, iso2_zoneN 1261 i 1%iqIsoPha = RESHAPE( [( (strIdx(tname, addPhase(i1%trac(it),i1%phase(ip:ip))), it=1, i1%ntiso), ip=1, i1%nphas)], &1262 [i 1%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] ) 1263 1294 !=== Table used to get iq (index in dyn array, size nqtot) from the water and isotope and phase indexes ; the full isotopes list 1264 1295 ! (including tagging tracers) is sorted this way: iso1, iso2, ..., iso1_zone1, iso2_zone1, ..., iso1_zoneN, iso2_zoneN 1265 i 1%iqWIsoPha = RESHAPE( [( [strIdx(tname, addPhase('H2O', i1%phase(ip:ip))), i1%iqIsoPha(:,ip)], ip=1, i1%nphas)], &1266 [1+i 1%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] ) 1267 1298 !=== Table used to get ix (index in tagging tracers isotopes list, size ntiso) from the zone and isotope indexes 1268 i 1%itZonIso = RESHAPE( [( (strIdx(i1%trac(:), TRIM(i1%trac(it))//'_'//TRIM(i1%zone(iz))), iz=1, i1%nzone), it=1, i1%niso )], &1269 [i 1%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] ) 1270 1301 END DO 1271 1302 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 1276 1305 1277 1306 !--- GET THE isoCheck ENTRY FROM THE *.DEF FILES (MIGHT BE CHANGED TO A CLASS-DEPENDANT KEYWORD) … … 1282 1311 1283 1312 !=== 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 1289 1314 1290 1315 CONTAINS … … 1294 1319 !------------------------------------------------------------------------------------------------------------------------------ 1295 1320 INTEGER :: ix, it, ip, np, iz, nz, npha, nzon 1321 TYPE(isot_type), POINTER :: i 1296 1322 DO ix = 1, nbIso 1297 IF( PRESENT(isot)) i1 => isot (ix) 1298 IF(.NOT.PRESENT(isot)) i1 => isotopes(ix) 1323 i => isotopes(ix) 1299 1324 !--- Check whether each isotope and tagging isotopic tracer is present in the same number of phases 1300 DO it = 1, i 1%ntiso; npha = i1%nphas1301 np = SUM([(COUNT(t name(:) == 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)]) 1302 1327 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) 1304 1329 IF(lerr) RETURN 1305 1330 END DO 1306 DO it = 1, i 1%niso; nzon = i1%nzone1307 nz = SUM([(COUNT(i 1%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)]) 1308 1333 lerr = nz /= nzon 1309 CALL msg(TRIM(int2str(nz))//' tagging zones instead of '//TRIM(int2str(nzon))//' for '//TRIM(i 1%trac(it)), modname, lerr)1334 CALL msg(TRIM(int2str(nz))//' tagging zones instead of '//TRIM(int2str(nzon))//' for '//TRIM(i%trac(it)), modname, lerr) 1310 1335 IF(lerr) RETURN 1311 1336 END DO … … 1320 1345 !============================================================================================================================== 1321 1346 !=== 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(i Class, isot, lVerbose) RESULT(lerr)1347 ! Single generic "isoSelect" routine, using the predefined index of the parent (fast version) or its name (first call). 1348 !============================================================================================================================== 1349 LOGICAL FUNCTION isoSelectByName(iName, lVerbose) RESULT(lerr) 1325 1350 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 1330 1353 INTEGER :: iIso 1331 1354 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) 1335 1357 lerr = iIso == 0 1336 1358 IF(lerr) THEN 1337 1359 niso = 0; ntiso = 0; nzone = 0; nphas = 0; isoCheck=.FALSE. 1338 CALL msg('no isotope family named "'//TRIM(i Class)//'"', ll=lV)1360 CALL msg('no isotope family named "'//TRIM(iName)//'"', ll=lV) 1339 1361 RETURN 1340 1362 END IF 1341 lerr = isoSelectByIndex(iIso, iso,lV)1363 lerr = isoSelectByIndex(iIso, lV) 1342 1364 END FUNCTION isoSelectByName 1343 1365 !============================================================================================================================== 1344 LOGICAL FUNCTION isoSelectByIndex(iIso, isot,lVerbose) RESULT(lerr)1366 LOGICAL FUNCTION isoSelectByIndex(iIso, lVerbose) RESULT(lerr) 1345 1367 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 1350 1370 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 1353 1372 lerr = .FALSE. 1354 1373 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) 1356 1375 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) 1358 1377 IF(lerr) RETURN 1359 1378 ixIso = iIso !--- Update currently selected family index 1360 isotope => i (ixIso)!--- Select corresponding component1379 isotope => isotopes(ixIso) !--- Select corresponding component 1361 1380 isoKeys => isotope%keys; niso = isotope%niso 1362 1381 isoName => isotope%trac; ntiso = isotope%ntiso … … 1365 1384 itZonIso => isotope%itZonIso; isoCheck = isotope%check 1366 1385 iqIsoPha => isotope%iqIsoPha 1367 iqWIsoPha => isotope%iqWIsoPha1386 iqWIsoPha => isotope%iqWIsoPha 1368 1387 END FUNCTION isoSelectByIndex 1369 1388 !============================================================================================================================== … … 1509 1528 !=== OVERWRITE THE KEYS OF THE TRACER NAMED "tr0" WITH THE VALUES FOUND IN THE *.def FILES, IF ANY. =========================== 1510 1529 !============================================================================================================================== 1511 LOGICAL FUNCTION addKeysFromDef(t, tr0) RESULT(lerr)1512 TYPE( keys_type), ALLOCATABLE, INTENT(INOUT) :: t(:)1530 SUBROUTINE addKeysFromDef(t, tr0) 1531 TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: t(:) 1513 1532 CHARACTER(LEN=*), INTENT(IN) :: tr0 1514 1533 !------------------------------------------------------------------------------------------------------------------------------ 1515 CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:)1516 1534 CHARACTER(LEN=maxlen) :: val 1517 1535 INTEGER :: ik, jd 1518 lerr = getKey('name', tname, t); IF(lerr) RETURN 1519 jd = strIdx(tname(:), tr0) 1536 jd = strIdx(t%name, tr0) 1520 1537 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.) 1524 1541 END DO 1525 END FUNCTIONaddKeysFromDef1542 END SUBROUTINE addKeysFromDef 1526 1543 !============================================================================================================================== 1527 1544 … … 1533 1550 INTEGER, INTENT(IN) :: itr 1534 1551 CHARACTER(LEN=*), INTENT(IN) :: keyn(:) 1535 TYPE( keys_type), INTENT(INOUT) :: ky(:)1552 TYPE(trac_type), INTENT(INOUT) :: ky(:) 1536 1553 !------------------------------------------------------------------------------------------------------------------------------ 1537 1554 CHARACTER(LEN=maxlen), ALLOCATABLE :: k(:), v(:) … … 1539 1556 INTEGER :: iky 1540 1557 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) 1544 1561 END SUBROUTINE delKey_1 1545 1562 !============================================================================================================================== 1546 1563 SUBROUTINE delKey(keyn, ky) 1547 1564 CHARACTER(LEN=*), INTENT(IN) :: keyn(:) 1548 TYPE( keys_type), INTENT(INOUT) :: ky(:)1565 TYPE(trac_type), INTENT(INOUT) :: ky(:) 1549 1566 !------------------------------------------------------------------------------------------------------------------------------ 1550 1567 INTEGER :: iky … … 1594 1611 !=== TRY TO GET THE KEY NAMED "key" FOR THE "itr"th TRACER IN: === 1595 1612 !=== * 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(:)") === 1597 1614 !=== THE RETURNED VALUE (STRING, AN INTEGER, A REAL OR A LOGICAL) CAN BE EITHER: === 1598 1615 !=== * A SCALAR === … … 1660 1677 lerr = .TRUE. 1661 1678 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" 1663 1680 IF(lerr .AND. ASSOCIATED(isotope)) val = fgetKey(isotope%keys(:)) !--- "isotope" 1664 1681 IF(lerr .AND. PRESENT(def)) THEN … … 1765 1782 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 1766 1783 val = str2int(svals) 1767 lerr = ANY(val == -HUGE(1)) .AND. sval /= ''1784 lerr = ANY(val == -HUGE(1)) 1768 1785 s = 'key "'//TRIM(keyn)//'" of tracer nr. '//TRIM(int2str(itr))//' is not' 1769 1786 CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr) … … 1785 1802 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 1786 1803 val = str2real(svals) 1787 lerr = ANY(val == -HUGE(1.)) .AND. sval /= ''1804 lerr = ANY(val == -HUGE(1.)) 1788 1805 s = 'key "'//TRIM(keyn)//'" of tracer nr. '//TRIM(int2str(itr))//' is not' 1789 1806 CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr) … … 1806 1823 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 1807 1824 ivals = str2bool(svals) 1808 lerr = ANY(ivals == -1) .AND. sval /= ''1825 lerr = ANY(ivals == -1) 1809 1826 s = 'key "'//TRIM(keyn)//'" of tracer nr. '//TRIM(int2str(itr))//' is not' 1810 1827 CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr) … … 1843 1860 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 1844 1861 val = str2int(svals) 1845 lerr = ANY(val == -HUGE(1)) .AND. sval /= ''1862 lerr = ANY(val == -HUGE(1)) 1846 1863 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of tracer nr. '//TRIM(int2str(itr))//' is not' 1847 1864 CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr) … … 1864 1881 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 1865 1882 val = str2real(svals) 1866 lerr = ANY(val == -HUGE(1.)) .AND. sval /= ''1883 lerr = ANY(val == -HUGE(1.)) 1867 1884 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of tracer nr. '//TRIM(int2str(itr))//' is not' 1868 1885 CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr) … … 1886 1903 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 1887 1904 ivals = str2bool(svals) 1888 lerr = ANY(ivals == -1) .AND. sval /= ''1905 lerr = ANY(ivals == -1) 1889 1906 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of tracer nr. '//TRIM(int2str(itr))//' is not' 1890 1907 CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr) … … 1893 1910 !============================================================================================================================== 1894 1911 !============================================================================================================================== 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) 1912 LOGICAL 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) 1902 1920 END FUNCTION getKeyByIndex_s1mm 1903 1921 !============================================================================================================================== 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) 1922 LOGICAL 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) 1911 1930 END FUNCTION getKeyByIndex_i1mm 1912 1931 !============================================================================================================================== 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) 1932 LOGICAL 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) 1920 1940 END FUNCTION getKeyByIndex_r1mm 1921 1941 !============================================================================================================================== 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) 1942 LOGICAL 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) 1929 1950 END FUNCTION getKeyByIndex_l1mm 1930 1951 !============================================================================================================================== 1931 1952 !============================================================================================================================== 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 1953 LOGICAL 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 1938 1960 !------------------------------------------------------------------------------------------------------------------------------ 1939 1961 CHARACTER(LEN=maxlen) :: s 1962 CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:) 1940 1963 INTEGER :: iq, nq(3), k 1941 1964 LOGICAL :: lD, l(3) … … 1944 1967 lerr = .TRUE. 1945 1968 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" 1947 1970 IF(lerr .AND. ASSOCIATED(isotope)) val = fgetKey(isotope%keys(:)) !--- "isotope" 1948 1971 END IF 1949 IF(.NOT.lerr) RETURN1972 IF(.NOT.lerr) THEN; IF(PRESENT(nam)) nam = tname; RETURN; END IF 1950 1973 IF(.NOT.PRESENT(def)) THEN; CALL msg('No '//TRIM(s)//' found', modname, lD); RETURN; END IF 1951 1974 … … 1968 1991 INTEGER :: iq 1969 1992 lerr = SIZE(ky) == 0; IF(lerr) RETURN 1993 tname = ky%name 1970 1994 val = [(fgetKeyIdx(iq, keyn(:), ky, ler(iq)), iq = 1, SIZE(ky))] 1971 1995 lerr = ANY(ler) … … 1974 1998 END FUNCTION getKeyByIndex_smmm 1975 1999 !============================================================================================================================== 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 2000 LOGICAL 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 1982 2007 !------------------------------------------------------------------------------------------------------------------------------ 1983 2008 CHARACTER(LEN=maxlen) :: s 1984 2009 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:), tname(:) 1985 2010 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) 1988 2013 IF(lerr) RETURN 1989 2014 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 1993 2017 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(PACK(tname, MASK=ll)))//' is not' 1994 2018 CALL msg(TRIM(s)//' an integer: '//TRIM(strStack(svals, MASK=ll)), modname, lerr) 2019 IF(.NOT.lerr .AND. PRESENT(nam)) nam = tname 1995 2020 END FUNCTION getKeyByIndex_immm 1996 2021 !============================================================================================================================== 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 2022 LOGICAL 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 2003 2029 !------------------------------------------------------------------------------------------------------------------------------ 2004 2030 CHARACTER(LEN=maxlen) :: s 2005 2031 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:), tname(:) 2006 2032 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) 2009 2035 IF(lerr) RETURN 2010 2036 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 2014 2039 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(PACK(tname, MASK=ll)))//' is not a' 2015 2040 CALL msg(TRIM(s)//' a real: '//TRIM(strStack(svals, MASK=ll)), modname) 2016 2041 END FUNCTION getKeyByIndex_rmmm 2017 2042 !============================================================================================================================== 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 2043 LOGICAL 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 2024 2050 !------------------------------------------------------------------------------------------------------------------------------ 2025 2051 CHARACTER(LEN=maxlen) :: s … … 2027 2053 LOGICAL, ALLOCATABLE :: ll(:) 2028 2054 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) 2031 2057 IF(lerr) RETURN 2032 2058 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 2036 2061 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(tname, MASK=ll))//' is not' 2037 2062 CALL msg(TRIM(s)//' a boolean: '//TRIM(strStack(svals, MASK=ll)), modname) 2038 IF(.NOT.lerr) val = ivals == 12039 2063 END FUNCTION getKeyByIndex_lmmm 2040 2064 !============================================================================================================================== … … 2047 2071 !=== TRY TO GET THE KEY NAMED "key" FOR THE TRACER NAMED "tname" IN: === 2048 2072 !=== * 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(:)") === 2050 2074 !=== THE RETURNED VALUE (STRING, AN INTEGER, A REAL OR A LOGICAL) CAN BE EITHER: === 2051 2075 !=== * A SCALAR === … … 2109 2133 tnam = strHead(delPhase(tname),'_',.TRUE.) !--- Remove phase and tag 2110 2134 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" 2112 2136 IF(lerr .AND. ASSOCIATED(isotope)) val = fgetKey(isotope%keys(:)) !--- "isotope" 2113 2137 IF(lerr .AND. PRESENT(def)) THEN … … 2121 2145 CHARACTER(LEN=maxlen) FUNCTION fgetKey(ky) RESULT(val) 2122 2146 TYPE(keys_type), INTENT(IN) :: ky(:) 2123 CHARACTER(LEN=maxlen), ALLOCATABLE :: tname_all(:)2124 lerr = SIZE(ky) == 0;IF(lerr) RETURN2125 lerr = getKey('name', tname_all, ky); IF(lerr) RETURN2126 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 2128 2152 END FUNCTION fgetKey 2129 2153 … … 2142 2166 IF(lerr) RETURN 2143 2167 val = str2int(sval) 2144 lerr = val == -HUGE(1) .AND. sval /= ''2168 lerr = val == -HUGE(1) 2145 2169 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not' 2146 2170 CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr) … … 2159 2183 IF(lerr) RETURN 2160 2184 val = str2real(sval) 2161 lerr = val == -HUGE(1.) .AND. sval /= ''2185 lerr = val == -HUGE(1.) 2162 2186 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not' 2163 2187 CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr) … … 2177 2201 IF(lerr) RETURN 2178 2202 ival = str2bool(sval) 2179 lerr = ival == -1 .AND. sval /= ''2203 lerr = ival == -1 2180 2204 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not' 2181 2205 CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr) … … 2212 2236 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 2213 2237 val = str2int(svals) 2214 lerr = ANY(val == -HUGE(1)) .AND. sval /= ''2238 lerr = ANY(val == -HUGE(1)) 2215 2239 s = 'key "'//TRIM(keyn)//'" of '//TRIM(tname)//' is not' 2216 2240 CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr) … … 2232 2256 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 2233 2257 val = str2real(svals) 2234 lerr = ANY(val == -HUGE(1.)) .AND. sval /= ''2258 lerr = ANY(val == -HUGE(1.)) 2235 2259 s = 'key "'//TRIM(keyn)//'" of '//TRIM(tname)//' is not' 2236 2260 CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr) … … 2253 2277 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 2254 2278 ivals = str2bool(svals) 2255 lerr = ANY(ivals == -1) .AND. sval /= ''2279 lerr = ANY(ivals == -1) 2256 2280 s = 'key "'//TRIM(keyn)//'" of '//TRIM(tname)//' is not' 2257 2281 CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr) … … 2288 2312 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 2289 2313 val = str2int(svals) 2290 lerr = ANY(val == -HUGE(1)) .AND. sval /= ''2314 lerr = ANY(val == -HUGE(1)) 2291 2315 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not' 2292 2316 CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr) … … 2308 2332 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 2309 2333 val = str2real(svals) 2310 lerr = ANY(val == -HUGE(1.)) .AND. sval /= ''2334 lerr = ANY(val == -HUGE(1.)) 2311 2335 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not' 2312 2336 CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr) … … 2329 2353 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 2330 2354 ivals = str2bool(svals) 2331 lerr = ANY(ivals == -1) .AND. sval /= ''2355 lerr = ANY(ivals == -1) 2332 2356 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not' 2333 2357 CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr) … … 2388 2412 lerr = .TRUE. 2389 2413 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" 2391 2415 IF(lerr .AND. ASSOCIATED(isotope)) val = fgetKey(isotope%keys(:)) !--- "isotope" 2392 2416 END IF … … 2403 2427 TYPE(keys_type), INTENT(IN) :: ky(:) 2404 2428 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 2408 2430 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))] 2410 2432 lerr = ANY(ler) 2411 2433 END FUNCTION fgetKey … … 2427 2449 IF(lerr) RETURN 2428 2450 val = str2int(svals) 2429 ll = val == -HUGE(1) .AND. (SIZE(svals) /=1 .OR. svals(1) /= '')2451 ll = val == -HUGE(1) 2430 2452 lerr = ANY(ll); IF(.NOT.lerr) RETURN 2431 2453 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(tname, MASK=ll))//' is not' … … 2447 2469 IF(lerr) RETURN 2448 2470 val = str2real(svals) 2449 ll = val == -HUGE(1.) .AND. (SIZE(svals) /=1 .OR. svals(1) /= '')2471 ll = val == -HUGE(1.) 2450 2472 lerr = ANY(ll); IF(.NOT.lerr) RETURN 2451 2473 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(tname, MASK=ll))//' is not' … … 2468 2490 IF(lerr) RETURN 2469 2491 ivals = str2bool(svals) 2470 ll = ivals == -1 .AND. (SIZE(svals) /=1 .OR. svals(1) /= '')2492 ll = ivals == -1 2471 2493 lerr = ANY(ll); IF(.NOT.lerr) THEN; val = ivals == 1; RETURN; END IF 2472 2494 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(tname, MASK=ll))//' is not' … … 2480 2502 !============================================================================================================================== 2481 2503 SUBROUTINE setKeysDBase(tracers_, isotopes_, isotope_) 2482 TYPE( keys_type), OPTIONAL, INTENT(IN) :: tracers_(:)2504 TYPE(trac_type), OPTIONAL, INTENT(IN) :: tracers_(:) 2483 2505 TYPE(isot_type), OPTIONAL, INTENT(IN) :: isotopes_(:) 2484 2506 TYPE(isot_type), OPTIONAL, INTENT(IN) :: isotope_ … … 2489 2511 IF(PRESENT(isotopes_)) THEN; isotopes = isotopes_; ELSE; ALLOCATE(isotopes(0)); END IF 2490 2512 IF(PRESENT(isotope_ )) THEN 2491 ix = strIdx(isotopes(:)% name, isotope_%name)2513 ix = strIdx(isotopes(:)%parent, isotope_%parent) 2492 2514 IF(ix /= 0) THEN 2493 2515 isotopes(ix) = isotope_ … … 2500 2522 !============================================================================================================================== 2501 2523 SUBROUTINE getKeysDBase(tracers_, isotopes_, isotope_) 2502 TYPE( keys_type), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: tracers_(:)2524 TYPE(trac_type), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: tracers_(:) 2503 2525 TYPE(isot_type), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: isotopes_(:) 2504 2526 TYPE(isot_type), OPTIONAL, INTENT(OUT) :: isotope_ … … 2507 2529 IF(PRESENT( tracers_)) THEN; tracers_ = tracers; ELSE; ALLOCATE( tracers_(0)); END IF 2508 2530 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 IF2531 IF(PRESENT(isotope_ )) THEN; ix = strIdx(isotopes(:)%parent, isotope%parent); IF(ix /= 0) isotope_=isotopes(ix); END IF 2510 2532 END SUBROUTINE getKeysDBase 2511 2533 !============================================================================================================================== … … 2583 2605 CHARACTER(LEN=*), INTENT(IN) :: tname 2584 2606 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(:) 2587 2609 CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:) 2588 2610 INTEGER :: nt, ix 2589 2611 IF(ALLOCATED(tracs)) THEN 2590 lerr = getKey('name', tnames, ky=tracs(:) ); IF(lerr) RETURN2612 lerr = getKey('name', tnames, ky=tracs(:)%keys); IF(lerr) RETURN 2591 2613 nt = SIZE(tracs) 2592 2614 ix = strIdx(tnames, tname) … … 2600 2622 ix = 1; ALLOCATE(tracs(1)) 2601 2623 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 2604 2627 2605 2628 END FUNCTION addTracer_1 … … 2616 2639 LOGICAL FUNCTION delTracer_1(tname, tracs) RESULT(lerr) 2617 2640 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(:) 2620 2643 CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:) 2621 2644 INTEGER :: nt, ix … … 2623 2646 IF(fmsg('Can''t remove tracer "'//TRIM(tname)//'" from an empty tracers descriptor', modname, lerr)) RETURN 2624 2647 nt = SIZE(tracs) 2625 lerr = getKey('name', tnames, ky=tracs(:) ); IF(lerr) RETURN2648 lerr = getKey('name', tnames, ky=tracs(:)%keys); IF(lerr) RETURN 2626 2649 ix = strIdx(tnames, tname) 2627 2650 CALL msg('Removing tracer "' //TRIM(tname)//'"', modname, ix /= 0) … … 2667 2690 2668 2691 !============================================================================================================================== 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") ============ 2672 2694 !============================================================================================================================== 2673 2695 CHARACTER(LEN=maxlen) FUNCTION old2newH2O_1(oldName, iPhase) RESULT(newName) … … 2702 2724 END FUNCTION old2newH2O_m 2703 2725 !============================================================================================================================== 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 !============================================================================================================================== 2704 2732 CHARACTER(LEN=maxlen) FUNCTION new2oldH2O_1(newName, iPhase) RESULT(oldName) 2705 2733 CHARACTER(LEN=*), INTENT(IN) :: newName
Note: See TracChangeset
for help on using the changeset viewer.