- Timestamp:
- Jul 2, 2025, 3:49:50 PM (7 days ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
LMDZ6/trunk/libf/misc/strings_mod.f90
r5751 r5752 1598 1598 1599 1599 !============================================================================================================================== 1600 LOGICAL FUNCTION dispOutliers_1(ll, a, n, err_msg, nam, subn, nRowmax, nColMax, nHead, unit) RESULT(lerr)1601 IMPLICIT NONE1602 ! Display outliers list in tables1603 ! If "nam" is supplied, it means the last index is for tracers => one table each tracer for rank > 2.1604 LOGICAL, INTENT(IN) :: ll(:) !--- Linearized mask of outliers1605 REAL, INTENT(IN) :: a(:) !--- Linearized array of values1606 INTEGER, INTENT(IN) :: n(:) !--- Profile before linearization1607 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: err_msg, nam(:), subn !--- Error message, variables and calling subroutine names1608 INTEGER, OPTIONAL, INTENT(IN) :: nRowMax !--- Maximum number of lines to display (default: all)1609 INTEGER, OPTIONAL, INTENT(IN) :: nColMax !--- Maximum number of characters per line (default: 2048)1610 INTEGER, OPTIONAL, INTENT(IN) :: nHead !--- Number of front columns to duplicate (default: 1)1611 INTEGER, OPTIONAL, INTENT(IN) :: unit !--- Output unit (def: lunout)1612 !------------------------------------------------------------------------------------------------------------------------------1613 CHARACTER(LEN=maxlen), ALLOCATABLE :: ttl(:)1614 LOGICAL, ALLOCATABLE :: m(:)1615 INTEGER, ALLOCATABLE :: ki(:), kj(:)1616 INTEGER :: i, j, k, rk, rk1, ib, ie, itr, nm, unt, nRmx, nCmx, nHd, nv1617 CHARACTER(LEN=maxlen) :: mes, sub, fm='(f12.9)', v, s1618 CHARACTER(LEN=maxlen), ALLOCATABLE :: vnm(:)1619 1620 lerr = ANY(ll); IF(.NOT.lerr) RETURN !--- No outliers -> finished1621 1622 mes = 'outliers found'; IF(PRESENT(err_msg)) mes = err_msg !--- Error message1623 vnm = ['a']; IF(PRESENT(nam )) vnm = nam !--- Variables names1624 sub = 'dispOutliers'; IF(PRESENT(subn)) sub = subn !--- Calling subroutine name1625 nRmx= SIZE(a); IF(PRESENT(nRowMax)) nRmx=MIN(nRmx,nRowMax)!-- Maximum number of lines to print1626 nCmx= 2048; IF(PRESENT(nColMax)) nCmx=MIN(nCmx,nColMax)!-- Maximum number of characters each line1627 nHd = 1; IF(PRESENT(nHead)) nHd = nHead !--- Number of front columns to duplicate1628 unt = lunout; IF(PRESENT(unit)) unt = unit !--- Unit to print messages1629 1630 rk = SIZE(n); nv = SIZE(vnm)1631 lerr = nv/=1 .AND. nv/=n(rk); CALL msg('SIZE(nam) /= 1 and /= last "n" element', sub, lerr); IF(lerr) RETURN1632 lerr = SIZE(a) /= SIZE(ll); CALL msg('ll" and "a" sizes mismatch', sub, lerr); IF(lerr) RETURN1633 lerr = SIZE(a) /= PRODUCT(n); CALL msg('profile "n" does not match "a" and "ll', sub, lerr); IF(lerr) RETURN1634 CALL msg(mes, sub, unit=unt)1635 1636 !--- SCALAR CASE: single value to display1637 IF(rk==1.AND.n(1)==1) THEN1638 IF(ll(1)) WRITE(unt,'(a," = ",f12.9)')TRIM(nam(1)),a(1); RETURN1639 END IF1640 1641 rk1 = rk; IF(nv==1) rk1 = rk-1 !--- Rank of each displayed table1642 SELECT CASE(rk1) !--- Indices list1643 CASE(1,2); ki = [ (i,i=1,n(1)) ]1644 CASE(3); ki = [((i,i=1,n(1)),j=1,n(2))]; kj = [((j,i=1,n(1)),j=1,n(2))]1645 CASE DEFAULT; WRITE(unt,*)'Sorry: routine "dispOutliers" is limited to rank 3'; RETURN1646 END SELECT1647 1648 !--- VECTOR CASE: table " name | value " (known names) / ) / " i | a(i) " (unknown names)1649 IF(rk==1) THEN1650 ALLOCATE(ttl(2)); ttl(2) = TRIM(vnm(1))//'(i)'; ttl(1) = 'i'1651 IF(nv == 1) lerr = dispTable('sr', ttl, s=cat(PACK(nam,ll)), r=cat(PACK(a,ll)), &1652 rFmt=fm, nRowMax=nRmx, nColMax=nCmx, nHead=nHd, unit=unt, sub=sub)1653 IF(nv /= 1) lerr = dispTable('ir', ['name ','value'], i=cat(PACK(ki,m)), r=cat(PACK(a,ll)), &1654 rFmt=fm, nRowMax=nRmx, nColMax=nCmx, nHead=nHd, unit=unt, sub=sub)1655 CALL msg("can't display outliers table", sub, lerr, unt)1656 RETURN1657 END IF1658 1659 !--- OTHER CASES: one table for each tracer (last index)1660 ttl = [(ACHAR(k), k = 105, 104+rk)] !--- Titles list ('i', 'j', 'k'...)1661 s = strStack( ttl(1:rk-1) ) !--- Tracer name dummy indexes: (i, j, k, ...1662 1663 DO itr=1,n(rk)1664 nm = PRODUCT(n(1:rk-1)) !--- number of elements per tracer1665 ie = itr*nm; ib = ie-nm+1; m=ll(ib:ie) !--- section bounds for tracer "itr" ; outlayers mask1666 IF(.NOT.ANY(m)) CYCLE !--- no outlayers for tracer "itr"1667 v = TRIM(vnm(MIN(itr,SIZE(vnm))))//'('//TRIM(s) !--- "<name>("1668 IF(nv == 1) ttl(rk) = TRIM(v)//','//num2str(itr)//')' !--- "<name>(i,j,itr)" (single name)1669 IF(nv /= 1) ttl(rk) = TRIM(v)//')' !--- "<nam(itr)>(i,j)" (one name each table/itr index)1670 IF(rk==2) lerr = dispTable('ir', ttl, i=cat(PACK(ki,m)), r=cat(PACK(a(ib:ie),m)), &1671 rFmt=fm, nRowMax=nRmx, nColMax=nCmx, nHead=nHd, unit=unt, sub=sub)1672 IF(rk==3) lerr = dispTable('iir', ttl, i=cat(PACK(ki,m),PACK(kj,m)), r=cat(PACK(a(ib:ie),m)), &1673 rFmt=fm, nRowMax=nRmx, nColMax=nCmx, nHead=nHd, unit=unt, sub=sub)1674 CALL msg("can't display outliers table", sub, lerr, unt)1675 IF(lerr) RETURN1676 END DO1677 END FUNCTION dispOutliers_11678 !==============================================================================================================================1679 LOGICAL FUNCTION dispOutliers_2(ll, a, n, err_msg, nam, subn, nRowMax, nColMax, nHead, unit) RESULT(lerr)1680 IMPLICIT NONE1681 ! Display outliers list in tables1682 ! If "nam" is supplied and, it means the last index is for tracers => one table each tracer for rank > 2.1683 LOGICAL, INTENT(IN) :: ll(:) !--- Linearized mask of outliers1684 REAL, INTENT(IN) :: a(:,:) !--- Linearized arrays of values stacked along 2nd dim.1685 INTEGER, INTENT(IN) :: n(:) !--- Profile before linearization1686 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: err_msg, nam(:), subn !--- Error message, variables and calling subroutine names1687 INTEGER, OPTIONAL, INTENT(IN) :: nRowMax !--- Maximum number of lines to display (default: all)1688 INTEGER, OPTIONAL, INTENT(IN) :: nColMax !--- Maximum number of characters per line (default: 2048)1689 INTEGER, OPTIONAL, INTENT(IN) :: nHead !--- Number of front columns to duplicate (default: 1)1690 INTEGER, OPTIONAL, INTENT(IN) :: unit !--- Output unit (def: lunout)1691 !------------------------------------------------------------------------------------------------------------------------------1692 CHARACTER(LEN=maxlen) :: mes, sub, fm='(f12.9)', prf1693 CHARACTER(LEN=maxlen), ALLOCATABLE :: ttl(:), vnm(:)1694 INTEGER, ALLOCATABLE :: ki(:), kj(:), kl(:)1695 INTEGER :: i, j, k, rk, nv, unt, nRmx, nCmx, nHd1696 REAL, ALLOCATABLE :: val(:,:)1697 1698 lerr = ANY(ll); IF(.NOT.lerr) RETURN !--- No outliers -> finished1699 rk = SIZE(n); nv = SIZE(a,2)1700 mes = 'outliers found'; IF(PRESENT(err_msg)) mes = err_msg !--- Error message1701 vnm = [(ACHAR(k+96),k=1,nv)]; IF(PRESENT(nam )) vnm = nam !--- Variables names1702 sub = 'dispOutliers'; IF(PRESENT(subn)) sub = subn !--- Calling subroutine name1703 nRmx= SIZE(a); IF(PRESENT(nRowMax)) nRmx=MIN(nRmx,nRowMax)!-- Maximum number of lines to print1704 nCmx= 2048; IF(PRESENT(nColMax)) nCmx=MIN(nCmx,nColMax)!-- Maximum number of characters each line1705 nHd = 1; IF(PRESENT(nHead)) nHd = nHead !--- Number of front columns to duplicate1706 unt = lunout; IF(PRESENT(unit)) unt = unit !--- Unit to print messages1707 lerr= SIZE(vnm) /= nv; CALL msg('SIZE(nam) /= SIZE(a,2)', sub, lerr, unt); IF(lerr) RETURN1708 lerr= SIZE(a,1) /= SIZE(ll); CALL msg('"ll" and "a" sizes mismatch', sub, lerr, unt); IF(lerr) RETURN1709 lerr= SIZE(a,1) /= PRODUCT(n); CALL msg('profile "n" does not match "a" and "ll"', sub, lerr, unt); IF(lerr) RETURN1710 1711 SELECT CASE(rk) !--- Indices list1712 CASE(0); IF(ll(1)) THEN; WRITE(unt,'(a,", ",a," = ",2f12.9)')TRIM(vnm(1)),TRIM(vnm(2)),a(1,1),a(1,2); RETURN; END IF1713 CASE(1); ki = [ (i,i=1,n(1)) ]1714 CASE(2); ki = [ ((i,i=1,n(1)),j=1,n(2))]; kj = [ ((j,i=1,n(1)),j=1,n(2))]1715 CASE(3); ki = [(((i,i=1,n(1)),j=1,n(2)),k=1,n(3))]; kj = [(((j,i=1,n(1)),j=1,n(2)),k=1,n(3))]1716 kl = [(((k,i=1,n(1)),j=1,n(2)),k=1,n(3))]1717 CASE DEFAULT; WRITE(unt,*)'Sorry: routine "dispOutliers_2" is limited to rank 3'; RETURN1718 END SELECT1719 1720 ttl = [(ACHAR(k), k = 105, 104+rk), vnm] !--- Titles list ('i', 'j', 'k'...'var1', 'var2', ...)1721 prf = REPEAT('i',rk)//REPEAT('r',nv) !--- Profile1722 ALLOCATE(val(COUNT(ll),nv)); DO k=1, nv; val(:,k) = PACK(a(:,k),ll); END DO1723 IF(rk == 1) lerr = dispTable(prf, ttl, i = cat(PACK(ki,ll)), r = val, &1724 rFmt=fm, nRowMax=nRmx, nColMax=nCmx, nHead=nHd, unit=unt, sub=sub)1725 IF(rk == 2) lerr = dispTable(prf, ttl, i = cat(PACK(ki,ll),PACK(kj,ll)), r = val, &1726 rFmt=fm, nRowMax=nRmx, nColMax=nCmx, nHead=nHd, unit=unt, sub=sub)1727 IF(rk == 3) lerr = dispTable(prf, ttl, i = cat(PACK(ki,ll),PACK(kj,ll),PACK(kl,ll)), r = val, &1728 rFmt=fm, nRowMax=nRmx, nColMax=nCmx, nHead=nHd, unit=unt, sub=sub)1729 CALL msg("can't display outliers table", sub, lerr, unt)1730 END FUNCTION dispOutliers_21731 !==============================================================================================================================1732 1733 1734 !==============================================================================================================================1735 1600 !=== Reduce an algebrical expression (basic operations and parenthesis) to a single number (string format) ==================== 1736 1601 !==============================================================================================================================
Note: See TracChangeset
for help on using the changeset viewer.