Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ifs-source/arpifs/m7/hamm7_init.F90
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ SUBROUTINE hamm7_init(YGFL, YRRIP, CHEM_SCHEME)
USE YOMLUN, ONLY : NULOUT

! --- M7 modules --------------------------------------------------------------
USE MO_KIND, ONLY: THRESHOLD
USE MO_TIME_CONTROL, ONLY: init_mo_time_control
USE MO_SPECIES, ONLY: speclist ! tracer species in HAM
USE MO_HAM, ONLY: &
Expand Down Expand Up @@ -478,6 +479,8 @@ SUBROUTINE hamm7_init(YGFL, YRRIP, CHEM_SCHEME)
! -- LOG
WRITE(NULOUT,'("====== HAMM7_INIT ===== ")')

WRITE(NULOUT,*) "TOLERANCE (EPS): ", THRESHOLD

WRITE(NULOUT,'("Number of size classes:", I3)') znclass
WRITE(NULOUT,'(" class# / IFS id / HM7 id / IFSNAME / M7NAME ")')
DO J_CLASS = 1,NCLASS
Expand Down
12 changes: 7 additions & 5 deletions ifs-source/arpifs/m7/module/mo_ham_activ.F90
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@

MODULE mo_ham_activ

USE mo_kind, ONLY: dp
USE mo_kind, ONLY: dp, THRESHOLD
USE mo_ham, ONLY: sizeclass,nclass

!#ifdef _OPENMP
Expand Down Expand Up @@ -207,7 +207,7 @@ SUBROUTINE ham_activ_abdulrazzak_ghan(kproma, kbdim, klev, krow, ktdia, &
pfracn(1:kproma,:,:) = 0._dp
pcdncact(1:kproma,:) = 0._dp

zeps=EPSILON(1._dp)
zeps=THRESHOLD ! EPSILON(1._dp)

!--- Conversions to SI units [g mol-1 to kg mol-1]:

Expand Down Expand Up @@ -320,6 +320,7 @@ SUBROUTINE ham_activ_abdulrazzak_ghan(kproma, kbdim, klev, krow, ktdia, &
!<<dod
END DO ! jclass

! PLS - TODO: SAFE DIVISION
WHERE (zsum(:) > zeps)
psmax(jl,jk,:)=1._dp/SQRT(zsum(:))
ELSEWHERE
Expand Down Expand Up @@ -558,7 +559,7 @@ SUBROUTINE ham_activ_koehler_ab(kproma, kbdim, klev, krow, ktdia, &
zsumtop(1:kproma,:,:) = 0._dp
zsumbot(1:kproma,:,:) = 0._dp

zeps=EPSILON(1._dp)
zeps=THRESHOLD !EPSILON(1._dp)

!--- Conversions to SI units [g mol-1 to kg mol-1]:

Expand Down Expand Up @@ -596,6 +597,7 @@ SUBROUTINE ham_activ_koehler_ab(kproma, kbdim, klev, krow, ktdia, &
jclass = aerocomp(jn)%iclass

IF (nion > 0 .AND. sizeclass(jclass)%lactivation) THEN !>>dod<< #377
! PLS - TODO: SAFE DIVISION
WHERE(zmasssum(1:kproma,:,jclass)>zeps)

zmassfrac(1:kproma,:)=pxtm1(1:kproma,:,jt)/zmasssum(1:kproma,:,jclass)
Expand Down Expand Up @@ -696,7 +698,7 @@ SUBROUTINE ham_avail_activ_lin_leaitch(kproma, kbdim, klev, krow, &

DO jclass=1, nclass !SF the ham_m7_logtail calculation is now done mode per mode for better efficiency
IF (sizeclass(jclass)%lactivation) THEN
IF (cfracn(jclass) > EPSILON(1._dp)) THEN !SF #279: only performs this calculation when relevant
IF (cfracn(jclass) > THRESHOLD ) THEN !SF #279: only performs this calculation when relevant
!SF stratiform:
zr(1:kproma,:,jclass)=crcut

Expand Down Expand Up @@ -786,7 +788,7 @@ SUBROUTINE ham_activ_diag_lin_leaitch(kproma, kbdim, klev, krow, prho, pxtm1, pc
REAL(dp) :: zeps
REAL(dp) :: ztmp1(kbdim,klev), ztmp2(kbdim,klev)

zeps = EPSILON(1._dp)
zeps = THRESHOLD !EPSILON(1._dp)

DO jclass=1, nclass
!>>dod #377
Expand Down
209 changes: 17 additions & 192 deletions ifs-source/arpifs/m7/module/mo_ham_m7.F90
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,15 @@

MODULE mo_ham_m7

USE mo_kind, ONLY: dp
USE mo_kind, ONLY: dp, THRESHOLD

IMPLICIT NONE

PRIVATE
IMPLICIT NONE

PUBLIC :: m7, m7_cumulative_normal
PRIVATE
PUBLIC :: m7, m7_cumulative_normal

!REAL(dp), PUBLIC, ALLOCATABLE :: rwet_m7(:,:,:), rdry_m7(:,:,:)
!REAL(dp), PUBLIC, ALLOCATABLE :: densaer_m7(:,:,:), aerwat_m7(:,:,:)
!REAL(dp), PUBLIC, ALLOCATABLE :: rwet_m7(:,:,:), rdry_m7(:,:,:)
!REAL(dp), PUBLIC, ALLOCATABLE :: densaer_m7(:,:,:), aerwat_m7(:,:,:)

CONTAINS

Expand Down Expand Up @@ -143,192 +142,17 @@ SUBROUTINE m7_cumulative_normal ( arg, presult, ccum )
! functions, and proper selection of the machine-dependent
! constants.
!
! Explanation of machine-dependent constants.
!
! MIN = smallest machine representable number.
!
! EPS = argument below which anorm(x) may be represented by
! 0.5 and above which x*x will not underflow.
! A conservative value is the largest machine number X
! such that 1.0 + X = 1.0 to machine precision.
!
! Error returns
!
! The program returns ANORM = 0 for ARG .LE. XLOW.
!
! Author:
!
! W. J. Cody
! Mathematics and Computer Science Division
! Argonne National Laboratory
! Argonne, IL 60439
!
! Latest modification: March 15, 1992
!
USE mo_kind, ONLY: dp
!
IMPLICIT NONE
!
REAL(dp), PARAMETER, DIMENSION ( 5 ) :: a = (/ &
2.2352520354606839287e00_dp, &
1.6102823106855587881e02_dp, &
1.0676894854603709582e03_dp, &
1.8154981253343561249e04_dp, &
6.5682337918207449113e-2_dp /)
REAL(dp) :: arg
REAL(dp), PARAMETER, DIMENSION ( 4 ) :: b = (/ &
4.7202581904688241870e01_dp, &
9.7609855173777669322e02_dp, &
1.0260932208618978205e04_dp, &
4.5507789335026729956e04_dp /)
REAL(dp), PARAMETER, DIMENSION ( 9 ) :: c = (/ &
3.9894151208813466764e-1_dp, &
8.8831497943883759412e00_dp, &
9.3506656132177855979e01_dp, &
5.9727027639480026226e02_dp, &
2.4945375852903726711e03_dp, &
6.8481904505362823326e03_dp, &
1.1602651437647350124e04_dp, &
9.8427148383839780218e03_dp, &
1.0765576773720192317e-8_dp /)
REAL(dp) :: ccum
REAL(dp), PARAMETER, DIMENSION ( 8 ) :: d = (/ &
2.2266688044328115691e01_dp, &
2.3538790178262499861e02_dp, &
1.5193775994075548050e03_dp, &
6.4855582982667607550e03_dp, &
1.8615571640885098091e04_dp, &
3.4900952721145977266e04_dp, &
3.8912003286093271411e04_dp, &
1.9685429676859990727e04_dp /)
REAL(dp) :: del
!@@@ REAL(dp) :: dpmpar
REAL(dp) :: eps
INTEGER :: i
REAL(dp) :: zmin
REAL(dp), PARAMETER, DIMENSION ( 6 ) :: p = (/ &
2.1589853405795699e-1_dp, &
1.274011611602473639e-1_dp, &
2.2235277870649807e-2_dp, &
1.421619193227893466e-3_dp, &
2.9112874951168792e-5_dp, &
2.307344176494017303e-2_dp /)
REAL(dp), PARAMETER, DIMENSION ( 5 ) :: q = (/ &
1.28426009614491121e00_dp, &
4.68238212480865118e-1_dp, &
6.59881378689285515e-2_dp, &
3.78239633202758244e-3_dp, &
7.29751555083966205e-5_dp /)
REAL(dp) :: presult
REAL(dp), PARAMETER :: root32 = 5.656854248_dp
REAL(dp), PARAMETER :: sixten = 16.0_dp
REAL(dp) :: temp
REAL(dp), PARAMETER :: sqrpi = 3.9894228040143267794e-1_dp
REAL(dp), PARAMETER :: thrsh = 0.66291_dp
REAL(dp) :: x
REAL(dp) :: xden
REAL(dp) :: xnum
REAL(dp) :: y
REAL(dp) :: xsq


!REAL(dp), ALLOCATABLE :: rwet_m7(:,:,:), rdry_m7(:,:,:)
!REAL(dp), ALLOCATABLE :: densaer_m7(:,:,:), aerwat_m7(:,:,:)
!
! Machine dependent constants
!
eps = EPSILON ( 1.0_dp ) * 0.5_dp
!
!@@@ Simplified calculation of the smallest machine representable number
! (Higher accuracy than needed!)
!
!@@@ min = dpmpar(2)

zmin = EPSILON ( 1.0_dp )

x = arg
y = ABS ( x )

IF ( y <= thrsh ) THEN
!
! Evaluate anorm for |X| <= 0.66291
!
IF ( y > eps ) THEN
xsq = x * x
ELSE
xsq = 0.0_dp
END IF

xnum = a(5) * xsq
xden = xsq
DO i = 1, 3
xnum = ( xnum + a(i) ) * xsq
xden = ( xden + b(i) ) * xsq
END DO
presult = x * ( xnum + a(4) ) / ( xden + b(4) )
temp = presult
presult = 0.5_dp + temp
ccum = 0.5_dp - temp
!
! Evaluate ANORM for 0.66291 <= |X| <= sqrt(32)
!
ELSE IF ( y <= root32 ) THEN

xnum = c(9) * y
xden = y
!DIR$ UNROLL
!CDIR UNROLL=7
DO i = 1, 7
xnum = ( xnum + c(i) ) * y
xden = ( xden + d(i) ) * y
END DO
presult = ( xnum + c(8) ) / ( xden + d(8) )
xsq = AINT ( y * sixten ) / sixten
del = ( y - xsq ) * ( y + xsq )
presult = EXP(-xsq*xsq*0.5_dp) * EXP(-del*0.5_dp) * presult
ccum = 1.0_dp - presult

IF ( x > 0.0_dp ) THEN
temp = presult
presult = ccum
ccum = temp
END IF
!
! Evaluate anorm for |X| > sqrt(32).
!
ELSE

presult = 0.0_dp
xsq = 1.0_dp / ( x * x )
xnum = p(6) * xsq
xden = xsq
DO i = 1, 4
xnum = ( xnum + p(i) ) * xsq
xden = ( xden + q(i) ) * xsq
END DO
REAL(dp), INTENT(IN) :: arg
REAL(dp), INTENT(OUT) :: ccum
REAL(dp), INTENT(OUT) :: presult

presult = xsq * ( xnum + p(5) ) / ( xden + q(5) )
presult = ( sqrpi - presult ) / y
xsq = AINT ( x * sixten ) / sixten
del = ( x - xsq ) * ( x + xsq )
presult = EXP ( - xsq * xsq * 0.5_dp ) * EXP ( - del * 0.5_dp ) * presult
ccum = 1.0_dp - presult

IF ( x > 0.0_dp ) THEN
temp = presult
presult = ccum
ccum = temp
END IF

END IF

IF ( presult < zmin ) THEN
presult = 0.0_dp
END IF

IF ( ccum < zmin ) THEN
ccum = 0.0_dp
END IF
presult = 0.5_dp * (1.0_dp + erf(arg / sqrt(2.0_dp)))
ccum = 0.5_dp * erfc(arg / sqrt(2.0_dp))

END SUBROUTINE m7_cumulative_normal

Expand Down Expand Up @@ -2387,7 +2211,7 @@ SUBROUTINE m7_nuck(kproma, kbdim, klev, krow, &

zqtmst = 1.0_dp/ztmst

zeps = EPSILON(1.0_dp)
zeps = THRESHOLD !EPSILON(1.0_dp)

! Relative humidity [%]:

Expand Down Expand Up @@ -3039,7 +2863,7 @@ SUBROUTINE m7_dconc(kproma, kbdim, klev, krow, paerml, paernl, pm6dry)
zfconm(:,:,:) = 1._dp
zfconn(:,:,:) = 1._dp

zeps = EPSILON(1._dp)
zeps = THRESHOLD !EPSILON(1._dp)

!
!--- 1) Identify how much the mode jclass has grown into the next higher mode
Expand Down Expand Up @@ -3491,7 +3315,7 @@ SUBROUTINE m7_coaset(kproma, kbdim, klev, krow, paernl, ptp1, &
zhu2, zhu

!---executable procedure
zeps = EPSILON(1._dp)
zeps = THRESHOLD !EPSILON(1._dp)

!---1) gridpoint properties
DO jk=1,klev
Expand Down Expand Up @@ -3732,7 +3556,7 @@ SUBROUTINE m7_concoag (kproma, kbdim, klev, krow, &

!--- 0) Initializations:

zeps=EPSILON(1._dp)
zeps=THRESHOLD !EPSILON(1._dp)


!--- 1) Redistribution of mass and numbers after nucleation, coagulation ----
Expand Down Expand Up @@ -4099,7 +3923,7 @@ SUBROUTINE m7_delcoa(kproma, kbdim, klev, krow, paerml, &
!--- 0) Initialisations: ------------------------------------------------

ztmst = time_step_len
zeps = EPSILON(1._dp)
zeps = THRESHOLD !EPSILON(1._dp)

za4av = 0._dp
za4av1(:,:) = 0._dp
Expand Down Expand Up @@ -4480,6 +4304,7 @@ SUBROUTINE m7_delcoa(kproma, kbdim, klev, krow, paerml, &
DO kmod=1,nclass
IF (kmod>jclass) THEN
!kai
! PLS - TODO: SAFE DIVISION
IF (abs(zbftot).gt.zeps) then
pbfract1(jl,jk,kmod-jclass)=pbfract1(jl,jk,kmod-jclass)/zbftot
ELSE
Expand Down
Loading