Changeset 16 for readTracFiles_mod.f90
- Timestamp:
- Apr 5, 2022, 1:13:00 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
readTracFiles_mod.f90
r14 r16 14 14 PUBLIC :: getKey_init, getKey, fGetKey, setDirectKeys !--- GET/SET KEYS FROM/TO tracers & isotopes 15 15 16 PUBLIC :: known_phases, old_phases, nphases, phases_names, & !--- VARIABLES RELATED TO THE PHASES 17 phases_sep, delPhase, addPhase, new2oldPhase, & !--- + ROUTINES TO ADD/REMOVE PHASE TO/FROM A NAME 18 old2newName, new2oldName 16 PUBLIC :: addPhase, new2oldName, getPhase, & !--- FUNCTIONS RELATED TO THE PHASES 17 delPhase, old2newName, getiPhase, & !--- + ASSOCIATED VARIABLES 18 known_phases, old_phases, phases_sep, phases_names, nphases 19 20 PUBLIC :: oldH2OIso, newH2OIso !--- NEEDED FOR BACKWARD COMPATIBILITY (OLD traceur.def) 19 21 20 22 PUBLIC :: tran0, idxAncestor, ancestor !--- GENERATION 0 TRACER + TOOLS FOR GENERATIONS 21 22 23 !------------------------------------------------------------------------------------------------------------------------------ 23 24 TYPE :: dataBase_type !=== TYPE FOR TRACERS SECTION … … 35 36 INTERFACE ancestor; MODULE PROCEDURE ancestor_1, ancestor_m; END INTERFACE ancestor 36 37 INTERFACE addPhase; MODULE PROCEDURE addPhase_s1, addPhase_sm, addPhase_i1, addPhase_im; END INTERFACE addPhase 38 INTERFACE old2newName; MODULE PROCEDURE old2newName_1, old2newName_m; END INTERFACE old2newName 39 INTERFACE new2oldName; MODULE PROCEDURE new2oldName_1, new2oldName_m; END INTERFACE new2oldName 37 40 !------------------------------------------------------------------------------------------------------------------------------ 38 41 … … 50 53 LOGICAL, SAVE :: tracs_merge = .TRUE. !--- Merge/stack tracers lists 51 54 LOGICAL, SAVE :: lSortByGen = .TRUE. !--- Sort by growing generation 55 56 !--- KEPT JUST TO MANAGE OLD WATER ISOTOPES NAMES 57 !--- Apart from that context, on limitaion on isotopes names (as long as they have a corresponding line in isotopes_params.def) 58 CHARACTER(LEN=maxlen), SAVE :: oldH2OIso(5) = ['eau', 'HDO', 'O18', 'O17', 'HTO' ] 59 CHARACTER(LEN=maxlen), SAVE :: newH2OIso(5) = ['H2[16]O', 'H[2]HO ', 'H2[18]O', 'H2[17]O', 'H[3]HO '] 60 52 61 53 62 !=== LOCAL COPIES OF THE TRACERS AND ISOTOPES DESCRIPTORS, USED BY getKey (INITIALIZED IN getKey_init) … … 179 188 WHERE(tracs%gen0Name(1:3) /= 'H2O') tracs%isInPhysics=.TRUE. !--- Set %isInPhysics: passed to physics 180 189 CALL setDirectKeys(tracs) !--- Set %iqParent, %iqDescen, %nqDescen, %nqChilds 181 182 190 END FUNCTION readTracersFiles 183 191 !============================================================================================================================== … … 832 840 SUBROUTINE indexUpdate(tr) 833 841 TYPE(trac_type), INTENT(INOUT) :: tr(:) 834 INTEGER :: iq, ig, ng, ngen842 INTEGER :: iq, ig, ng, igen, ngen 835 843 INTEGER, ALLOCATABLE :: ix(:) 836 844 tr(:)%iqParent = strIdx( tr(:)%name, tr(:)%parent ) !--- Parent index 837 845 ngen = MAXVAL(tr(:)%iGeneration, MASK=.TRUE.) 838 846 DO iq = 1, SIZE(tr) 839 ng = tr(iq)%iGeneration !--- Generation of the current tracer 840 ix = idxAncestor(tr, igen = ng); ix = PACK(ix, ix/=0) !--- Indexes of the tracers with ancestor tr(iq) 841 !--- Childs indexes in growing generation order 842 tr(iq)%iqDescen = [( PACK(ix, MASK = tr(ix)%iGeneration == ig), ig = ng+1, ngen)] 843 tr(iq)%nqDescen = SUM( [( COUNT(tr(ix)%iGeneration == ig), ig = ng+1, ngen)] ) 844 tr(iq)%nqChilds = COUNT(tr(ix)%iGeneration == ng+1) 847 ig = tr(iq)%iGeneration 848 IF(ALLOCATED(tr(iq)%iqDescen)) DEALLOCATE(tr(iq)%iqDescen) 849 ALLOCATE(tr(iq)%iqDescen(0)) 850 ix = idxAncestor(tr, igen=ig) !--- Ancestor of generation "ng" for each tr 851 DO igen = ig+1, ngen 852 tr(iq)%iqDescen = [tr(iq)%iqDescen, find(ix==iq .AND. tr%iGeneration==igen)] 853 tr(iq)%nqDescen = SIZE(tr(iq)%iqDescen) 854 IF(igen == ig+1) tr(iq)%nqChilds=tr(iq)%nqDescen 855 END DO 845 856 END DO 846 857 END SUBROUTINE indexUpdate … … 966 977 !=== Geographic tagging tracers descending on tracer "iname": mask, names, number 967 978 ll = t(:)%type=='tag' .AND. delPhase(t(:)%gen0Name) == iname .AND. t(:)%iGeneration == 2 968 i%zone = PACK(strTail(t(:)%name,'_' ,lFirst=.TRUE.), MASK = ll)!--- Tagging zones names for isotopes category "iname"979 i%zone = PACK(strTail(t(:)%name,'_'), MASK = ll) !--- Tagging zones names for isotopes category "iname" 969 980 CALL strReduce(i%zone) 970 981 i%nzone = SIZE(i%zone) !--- Tagging zones number for isotopes category "iname" … … 1313 1324 END FUNCTION delPhase 1314 1325 !------------------------------------------------------------------------------------------------------------------------------ 1315 CHARACTER(LEN=maxlen) FUNCTION addPhase_s1(s,pha ,ph_sep) RESULT(out)1326 CHARACTER(LEN=maxlen) FUNCTION addPhase_s1(s,pha) RESULT(out) 1316 1327 CHARACTER(LEN=*), INTENT(IN) :: s 1317 1328 CHARACTER(LEN=1), INTENT(IN) :: pha 1318 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: ph_sep1319 CHARACTER(LEN=1) :: psep1320 1329 INTEGER :: l, i 1321 1330 out = s 1322 1331 IF(s == '') RETURN !--- Empty string: nothing to do 1323 psep = phases_sep; IF(PRESENT(ph_sep)) psep = ph_sep1324 1332 i = INDEX(s, '_') !--- /=0 for <var>_<tag> tracers names 1325 1333 l = LEN_TRIM(s) 1326 IF(i == 0) out = TRIM(s)// TRIM(psep)//pha !--- <var> => return <var><sep><pha>1327 IF(i /= 0) out = s(1:i-1)// TRIM(psep)//pha//'_'//s(i+1:l) !--- <var>_<tag> => return <var><sep><pha>_<tag>1334 IF(i == 0) out = TRIM(s)//phases_sep//pha !--- <var> => return <var><sep><pha> 1335 IF(i /= 0) out = s(1:i-1)//phases_sep//pha//'_'//s(i+1:l) !--- <var>_<tag> => return <var><sep><pha>_<tag> 1328 1336 END FUNCTION addPhase_s1 1329 1337 !------------------------------------------------------------------------------------------------------------------------------ 1330 FUNCTION addPhase_sm(s,pha ,ph_sep) RESULT(out)1338 FUNCTION addPhase_sm(s,pha) RESULT(out) 1331 1339 CHARACTER(LEN=*), INTENT(IN) :: s(:) 1332 1340 CHARACTER(LEN=1), INTENT(IN) :: pha 1333 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: ph_sep1334 1341 CHARACTER(LEN=maxlen), ALLOCATABLE :: out(:) 1335 CHARACTER(LEN=1) :: psep1336 1342 INTEGER :: k 1337 psep = phases_sep; IF(PRESENT(ph_sep)) psep = ph_sep 1338 out = [( addPhase_s1(s(k), pha, psep), k=1, SIZE(s) )] 1343 out = [( addPhase_s1(s(k), pha), k=1, SIZE(s) )] 1339 1344 END FUNCTION addPhase_sm 1340 1345 !------------------------------------------------------------------------------------------------------------------------------ 1341 CHARACTER(LEN=maxlen) FUNCTION addPhase_i1(s,ipha,ph _sep) RESULT(out)1346 CHARACTER(LEN=maxlen) FUNCTION addPhase_i1(s,ipha,phases) RESULT(out) 1342 1347 CHARACTER(LEN=*), INTENT(IN) :: s 1343 1348 INTEGER, INTENT(IN) :: ipha 1344 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: ph_sep 1345 CHARACTER(LEN=1) :: psep 1349 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: phases 1346 1350 out = s 1347 1351 IF(s == '') RETURN !--- Empty string: nothing to do 1348 psep = phases_sep; IF(PRESENT(ph_sep)) psep = ph_sep1349 IF( psep == '') out = addPhase_s1(s, old_phases(ipha:ipha), psep)1350 IF( psep /= '') out = addPhase_s1(s, known_phases(ipha:ipha), psep)1352 IF(ipha==0) RETURN !--- Null index: no phase to add 1353 IF( PRESENT(phases)) out = addPhase_s1(s, phases(ipha:ipha)) 1354 IF(.NOT.PRESENT(phases)) out = addPhase_s1(s, known_phases(ipha:ipha)) 1351 1355 END FUNCTION addPhase_i1 1352 1356 !------------------------------------------------------------------------------------------------------------------------------ 1353 FUNCTION addPhase_im(s,ipha,ph _sep) RESULT(out)1357 FUNCTION addPhase_im(s,ipha,phases) RESULT(out) 1354 1358 CHARACTER(LEN=*), INTENT(IN) :: s(:) 1355 1359 INTEGER, INTENT(IN) :: ipha 1356 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: ph _sep1360 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: phases 1357 1361 CHARACTER(LEN=maxlen), ALLOCATABLE :: out(:) 1358 CHARACTER(LEN=1) :: psep1359 1362 INTEGER :: k 1360 psep = phases_sep; IF(PRESENT(ph_sep)) psep = ph_sep1361 out = [( addPhase_i1(s(k), ipha, psep), k=1, SIZE(s) )]1363 IF( PRESENT(phases)) out = [( addPhase_i1(s(k), ipha, phases), k=1, SIZE(s) )] 1364 IF(.NOT.PRESENT(phases)) out = [( addPhase_i1(s(k), ipha, known_phases), k=1, SIZE(s) )] 1362 1365 END FUNCTION addPhase_im 1363 1366 !------------------------------------------------------------------------------------------------------------------------------ 1364 1367 1365 1368 1366 INTEGER FUNCTION getiPhase(tname, lPhase) RESULT(iphase) 1367 CHARACTER(LEN=*), INTENT(IN) :: tname 1368 LOGICAL, OPTIONAL, INTENT(OUT) :: lPhase 1369 CHARACTER(LEN=maxlen) :: s1 1369 !============================================================================================================================== 1370 !=== GET PHASE INDEX IN THE POSSIBLE PHASES LIST OR IN A SPECIFIED LIST ("phases") ============================================ 1371 !============================================================================================================================== 1372 INTEGER FUNCTION getiPhase(tname, phases) RESULT(iPhase) 1373 CHARACTER(LEN=*), INTENT(IN) :: tname 1374 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: phases 1375 CHARACTER(LEN=maxlen) :: phase 1376 IF( PRESENT(phases)) phase = getPhase(tname, phases, iPhase) 1377 IF(.NOT.PRESENT(phases)) phase = getPhase(tname, known_phases, iPhase) 1378 END FUNCTION getiPhase 1379 !------------------------------------------------------------------------------------------------------------------------------ 1380 CHARACTER(LEN=1) FUNCTION getPhase(tname, phases, iPhase) RESULT(phase) 1381 CHARACTER(LEN=*), INTENT(IN) :: tname 1382 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: phases 1383 INTEGER, OPTIONAL, INTENT(OUT) :: iPhase 1370 1384 INTEGER :: ip 1371 IF(PRESENT(lPhase)) lPhase = .TRUE. 1372 1373 !--- Old tracer name descending on water: H2O[v][l][i][_<isotope>][_<tag>] 1374 iphase = strIdx([('H2O'//old_phases(ip:ip), ip=1, nphases)], tname(1:MIN(4,LEN_TRIM(tname)))) 1375 IF(iphase /= 0) RETURN 1376 1377 !--- New tracer name: <name>[_<phase>][_<tag>] 1378 iphase = INDEX(known_phases, TRIM(strHead(strTail(tname, phases_sep, .TRUE.), '_', .TRUE.))) 1379 IF(iphase /= 0) RETURN 1380 1381 !---Default case: 1 (gaseous phase) 1382 iphase = 1 1383 IF(PRESENT(lPhase)) lPhase = .FALSE. 1384 END FUNCTION getiPhase 1385 1386 !------------------------------------------------------------------------------------------------------------------------------ 1387 CHARACTER(LEN=1) FUNCTION new2oldPhase(np) RESULT(op) 1388 CHARACTER(LEN=1), INTENT(IN) :: np 1389 op = old_phases(INDEX(known_phases,np):INDEX(known_phases,np)) 1390 END FUNCTION new2oldPhase 1391 !------------------------------------------------------------------------------------------------------------------------------ 1392 1393 !------------------------------------------------------------------------------------------------------------------------------ 1394 CHARACTER(LEN=maxlen) FUNCTION old2newName(oldName, iPhase) RESULT(newName) 1385 phase = TRIM(strHead(strTail(tname, phases_sep, .TRUE.), '_', .TRUE.)) 1386 IF( PRESENT(phases)) ip = INDEX( phases, phase) 1387 IF(.NOT.PRESENT(phases)) ip = INDEX(known_phases, phase) 1388 IF(ip == 0) phase = 'g' 1389 IF(PRESENT(iPhase)) iPhase = ip 1390 END FUNCTION getPhase 1391 !------------------------------------------------------------------------------------------------------------------------------ 1392 1393 1394 !------------------------------------------------------------------------------------------------------------------------------ 1395 CHARACTER(LEN=maxlen) FUNCTION old2newName_1(oldName, iPhase) RESULT(newName) 1395 1396 !--- Convert an old style name into a new one. 1396 1397 ! Only usable with old style "traceur.def" files, in which only water isotopes are allowed. … … 1399 1400 CHARACTER(LEN=*), INTENT(IN) :: oldName 1400 1401 INTEGER, OPTIONAL, INTENT(OUT) :: iPhase 1401 CHARACTER(LEN=maxlen) :: oldIso(5) = ['eau', 'HDO', 'O18', 'O17', 'HTO' ]1402 CHARACTER(LEN=maxlen) :: newIso(5) = ['H2[16]O', 'H[2]HO ', 'H2[18]O', 'H2[17]O', 'H[3]HO ']1403 1402 CHARACTER(LEN=maxlen), ALLOCATABLE :: tmp(:) 1404 1403 INTEGER :: ix, ip, it, nt 1405 LOGICAL :: lPhase, lerr 1406 ip = getiPhase(oldName, lPhase) !--- Get the phase ; lPhase==T: phase is needed 1404 LOGICAL :: lerr 1405 newName = oldName 1406 IF(PRESENT(iPhase)) iPhase = 1 !--- Default: gaseous phase 1407 IF(oldName(1:MIN(3,LEN_TRIM(oldName))) /= 'H2O') RETURN !--- Not a water descendant 1408 lerr = strParse(oldName, '_', tmp, n=nt) 1409 ip = strIdx([('H2O'//old_phases(ip:ip), ip=1, nphases)], tmp(1)) !--- Phase index (/=0 if any) 1407 1410 IF(PRESENT(iPhase)) iPhase = ip 1408 IF(.NOT.lPhase) THEN; newName = oldName ; RETURN; END IF !--- Not a water descendant 1409 newName = addPhase('H2O', ip) 1410 lerr = strParse(oldName, '_', tmp, n=nt) 1411 IF(nt == 1) RETURN !--- H2O with phase 1412 ix = strIdx(oldIso, tmp(2)) 1413 newName = tmp(2); IF(ix /= 0) newName = newIso(ix) !--- Isotope name 1414 IF(lPhase) newName = addPhase(newName, ip) !--- Phase is needed 1411 newName = addPhase('H2O', ip) !--- Water 1412 IF(nt == 1) RETURN !--- Water: finished 1413 ix = strIdx(oldH2OIso, tmp(2)) !--- Index in the known isotopes list 1414 IF(ix == 0) newName = addPhase(tmp(2), ip) !--- Not an isotope 1415 IF(ix /= 0) newName = addPhase(newH2OIso(ix), ip) !--- Isotope 1415 1416 IF(nt == 3) newName = TRIM(newName)//'_'//TRIM(tmp(3)) !--- Tagging tracer 1416 END FUNCTION old2newName 1417 !------------------------------------------------------------------------------------------------------------------------------ 1418 1419 !------------------------------------------------------------------------------------------------------------------------------ 1420 CHARACTER(LEN=maxlen) FUNCTION new2oldName(newName, iPhase) RESULT(oldName) 1417 END FUNCTION old2newName_1 1418 !------------------------------------------------------------------------------------------------------------------------------ 1419 FUNCTION old2newName_m(oldName, iPhase) RESULT(newName) 1420 CHARACTER(LEN=*), INTENT(IN) :: oldName(:) 1421 INTEGER, OPTIONAL, INTENT(OUT) :: iPhase 1422 CHARACTER(LEN=maxlen) :: newName(SIZE(oldName)) 1423 INTEGER :: i 1424 newName = [(old2newName_1(oldName(i), iPhase), i=1, SIZE(oldName))] 1425 END FUNCTION old2newName_m 1426 !------------------------------------------------------------------------------------------------------------------------------ 1427 1428 !------------------------------------------------------------------------------------------------------------------------------ 1429 CHARACTER(LEN=maxlen) FUNCTION new2oldName_1(newName, iPhase) RESULT(oldName) 1421 1430 !--- Convert a new style name into an old one. 1422 1431 ! Only convertable names are water descendants names H2O_<phase>, <isotope>_<phase>, <isotope>_<phase>_<tag>, with: … … 1424 1433 CHARACTER(LEN=*), INTENT(IN) :: newName 1425 1434 INTEGER, OPTIONAL, INTENT(OUT) :: iPhase 1426 CHARACTER(LEN=maxlen) :: oldIso(5) = ['eau', 'HDO', 'O18', 'O17', 'HTO' ]1427 CHARACTER(LEN=maxlen) :: newIso(5) = ['H2[16]O', 'H[2]HO ', 'H2[18]O', 'H2[17]O', 'H[3]HO '], tag1428 1435 INTEGER :: ix, ip, it, nt 1429 LOGICAL :: l Phase, lH2O1430 lH2O = newName(1:MIN(3,LEN_TRIM(newName)))=='H2O'1431 ix = strIdx( newIso, strHead(strHead(newName,'_',.TRUE.),phases_sep,.TRUE.)) !--- Isotope index1432 IF(ix == 0 .AND. .NOT.lH2O) THEN; oldName=newName; RETURN; END IF !--- Not a water descendant1433 i p = getiPhase(newName, lPhase) !--- Get the phase ; lPhase==T: phase is needed1434 oldName = 'H2O'; IF(lPhase) oldName = addPhase('H2O', ip, '') !--- H2O with phase1435 IF(ix == 0) RETURN1436 oldName = TRIM(old Name)//'_'//oldIso(ix) !--- Isotope1437 tag = strTail(delPhase(newName), TRIM(new Iso(ix)))1436 LOGICAL :: lH2O 1437 CHARACTER(LEN=maxlen) :: tag 1438 ix = strIdx([(addPhase('H2O',ip), ip=1, nphases)], newName) !--- Phase index for H2O_<phase> 1439 IF(ix /= 0) THEN; oldName = 'H2O'//old_phases(ix:ix); RETURN; END IF !--- H2O_<phase> case 1440 ix = strIdx(newH2OIso, strHead(newName, phases_sep, .TRUE.)) !--- Isotope index 1441 IF(ix == 0) THEN; oldName = newName; RETURN; END IF !--- Not a water descendant 1442 ip = getiPhase(newName) !--- Phase index 1443 oldName = TRIM(oldH2OIso(ix))//old_phases(ip:ip) !--- <isotope>_<phase> 1444 tag = strTail(delPhase(newName), TRIM(newH2OIso(ix))) !--- Get "_<tag>" if any 1438 1445 IF(tag /= delPhase(newName) .AND. tag /= '') oldName = TRIM(oldName)//tag !--- Tagging tracer 1439 END FUNCTION new2oldName 1446 END FUNCTION new2oldName_1 1447 !------------------------------------------------------------------------------------------------------------------------------ 1448 FUNCTION new2oldName_m(newName, iPhase) RESULT(oldName) 1449 CHARACTER(LEN=*), INTENT(IN) :: newName(:) 1450 INTEGER, OPTIONAL, INTENT(OUT) :: iPhase 1451 CHARACTER(LEN=maxlen) :: oldName(SIZE(newName)) 1452 INTEGER :: i 1453 oldName = [(new2oldName_1(newName(i), iPhase), i=1, SIZE(newName))] 1454 END FUNCTION new2oldName_m 1440 1455 !------------------------------------------------------------------------------------------------------------------------------ 1441 1456
Note: See TracChangeset
for help on using the changeset viewer.