@@ -3241,14 +3241,15 @@ SUBROUTINE FAIRALL(num_nodes, &
32413241
32423242 use schism_glbl, only : rkind, uu2, vv2,tr_nd, & ! tnd, snd, &
32433243 & idry, nvrt, ivcor,errmsg
3244- use schism_glbl, only : grav
3244+ use schism_glbl, only : grav ! GRAV
32453245! use schism_glbl, only : rho0
32463246 use schism_msgp, only : myrank,parallel_abort
32473247
32483248! ================================================== Hernan G. Arango ===
32493249! Copyright (c) 2002-2007 The ROMS/TOMS Group !
32503250! Licensed under a MIT/X style license !
32513251! See License_ROMS.txt !
3252+ ! Edited by Jerome Lefevre and Joseph Zhang
32523253! =======================================================================
32533254! This routine computes the bulk parameterization of surface wind !
32543255! stress and surface net heat fluxes. !
@@ -3354,7 +3355,7 @@ SUBROUTINE FAIRALL(num_nodes, &
33543355! 4000, and varies only slightly (see Gill, 1982, Appendix 3).
33553356 REAL (rkind),parameter :: Cp= 3985.0d0
33563357! Functions:
3357- REAL (rkind) :: bulk_psit,bulk_psiu
3358+ REAL (rkind) :: bulk_psit,bulk_psiu,tmp1,tmp2,tmp3
33583359
33593360
33603361#ifdef DEBUG
@@ -3366,7 +3367,7 @@ SUBROUTINE FAIRALL(num_nodes, &
33663367
33673368! set inverse of specific heat for seawater (kg-degC/Joule).
33683369! cp is defined in scalars.h
3369- cpi= 1.0d0 / cp
3370+ cpi= 1.0d0 / Cp
33703371!
33713372! Input bulk parameterization fields
33723373!
@@ -3383,7 +3384,7 @@ SUBROUTINE FAIRALL(num_nodes, &
33833384! $OMP rho0i,cpi,patmb,rhoSea,Qsea,TseaK,TseaC,TairC,TairK,rhoAir,Qair,Q, &
33843385! $OMP VisAir,Hlv,delW,delT,delQ,u10,Zo10,Cd10,Ch10,Ct10,Cd,Ct,CC,Ri,Ribcu, &
33853386! $OMP Zetu,L10,Wstar,Tstar,Qstar,ZoW,ZoT,ZoT10,ZoQ,ZoL,L,Rr,Bf,Wpsi,Tpsi, &
3386- ! $OMP Qpsi,Wgus,charn,upvel,evap,wspd0,dry,i_node, sfc_lev)
3387+ ! $OMP Qpsi,Wgus,charn,upvel,evap,wspd0,dry,i_node, sfc_lev,tmp1,tmp2,tmp3 )
33873388 do i_node = 1 , num_nodes ! =npa
33883389! =================================================================
33893390#ifdef DEBUG
@@ -3457,10 +3458,11 @@ SUBROUTINE FAIRALL(num_nodes, &
34573458! Compute air saturation vapor pressure (mb), using Teten formula.
34583459!
34593460 cff= (1.0007d0+3.46d-6 * patmb)* 6.1121d0 * &
3460- & exp (17.502d0 * TairC/ (240.97d0 + TairC))
3461+ & exp (17.502d0 * TairC/ (240.97d0 + TairC)) ! check?
34613462!
34623463! Compute specific humidity at Saturation, Qair (kg/kg).
34633464!
3465+ if (patmb-0.378d0 * cff== 0.d0 ) call parallel_abort(' FAIRALL: Qair' )
34643466 Qair= 0.62197d0 * (cff/ (patmb-0.378d0 * cff))
34653467!
34663468! Compute specific humidity, Q (kg/kg).
@@ -3478,14 +3480,15 @@ SUBROUTINE FAIRALL(num_nodes, &
34783480! Compute water saturation vapor pressure (mb), using Teten formula.
34793481!
34803482 cff= (1.0007d0+3.46d-6 * patmb)* 6.1121d0 * &
3481- & exp (17.502d0 * TseaC/ (240.97d0 + TseaC))
3483+ & exp (17.502d0 * TseaC/ (240.97d0 + TseaC)) ! check?
34823484!
34833485! Vapor Pressure reduced for salinity (Kraus & Businger, 1994, pp 42).
34843486!
34853487 cff= cff* 0.98d0
34863488!
34873489! Compute Qsea (kg/kg) from vapor pressure.
34883490!
3491+ if (patmb-0.378d0 * cff== 0.d0 ) call parallel_abort(' FAIRALL: Qsea' )
34893492 Qsea= 0.62197d0 * (cff/ (patmb-0.378d0 * cff))
34903493!
34913494!- ----------------------------------------------------------------------
@@ -3495,8 +3498,7 @@ SUBROUTINE FAIRALL(num_nodes, &
34953498!
34963499! Moist air density (kg/m3).
34973500!
3498- rhoAir= patmb* 100.0d0 / (blk_Rgas* TairK* &
3499- & (1.0d0+0.61d0 * Q))
3501+ rhoAir= patmb* 100.0d0 / (blk_Rgas* TairK* (1.0d0+0.61d0 * Q)) ! Q>=0?
35003502!
35013503! Kinematic viscosity of dry air (m2/s), Andreas (1989).
35023504!
@@ -3513,7 +3515,7 @@ SUBROUTINE FAIRALL(num_nodes, &
35133515 & v_air(i_node)* v_air(i_node) )
35143516!
35153517 Wgus= 0.5d0
3516- delW= SQRT (wspd0* wspd0+ Wgus* Wgus)
3518+ delW= SQRT (wspd0* wspd0+ Wgus* Wgus) ! >0
35173519 delQ= Qsea- Q
35183520 delT= TseaC- TairC
35193521
@@ -3529,27 +3531,32 @@ SUBROUTINE FAIRALL(num_nodes, &
35293531! Neutral coefficients.
35303532!
35313533 ZoW= 1.0d-4
3532- u10= delW* LOG (10.0d0 / ZoW)/ LOG (blk_ZW/ ZoW)
3533- Wstar= 0.035d0 * u10
3534+ u10= delW* LOG (10.0d0 / ZoW)/ LOG (blk_ZW/ ZoW) ! >0; actually blk_ZW=10
3535+ Wstar= 0.035d0 * u10 ! >0
35343536 Zo10= 0.011d0 * Wstar* Wstar/ GRAV+0.11d0 * VisAir/ Wstar
3535- Cd10= (vonKar/ LOG (10.0d0 / Zo10))** 2.d0
3537+ if (Zo10<= 0.d0 .or. Zo10== 10.d0 ) call parallel_abort(' FAIRALL: Zo10' )
3538+ Cd10= (vonKar/ LOG (10.0d0 / Zo10))** 2.d0 ! >0; Zo10>0
35363539 Ch10= 0.00115d0
3537- Ct10= Ch10/ sqrt (Cd10)
3538- ZoT10= 10.0d0 / exp (vonKar/ Ct10)
3539- Cd= (vonKar/ LOG (blk_ZW/ Zo10))** 2.d0
3540+ Ct10= Ch10/ sqrt (Cd10) ! >0
3541+ if (vonKar/ Ct10> 500.d0 ) call parallel_abort(' FAIRALL: overflow, vonKar/Ct10>500' )
3542+ ZoT10= 10.0d0 / exp (vonKar/ Ct10) ! >0
3543+ if (blk_ZW/ Zo10<= 0.d0 .or. blk_ZW== Zo10.or. blk_ZT== ZoT10) call parallel_abort(' FAIRALL: Zo10' )
3544+ Cd= (vonKar/ LOG (blk_ZW/ Zo10))** 2.d0 ! >0
35403545!
35413546! Compute Richardson number.
3542- !
3543- Ct= vonKar/ LOG (blk_ZT/ ZoT10) ! T transfer coefficient
3544- CC= vonKar* Ct/ Cd
3545- Ribcu=- blk_ZW/ (blk_Zabl* 0.004d0 * blk_beta** 3.d0 )
3546- Ri=- GRAV* blk_ZW* (delT+0.61d0 * TairK* delQ)/ &
3547- (TairK* delW* delW)
3547+ ! blk_ZT/ZoT10 checked above
3548+ Ct= vonKar/ LOG (blk_ZT/ ZoT10) ! T transfer coefficient; /=0
3549+ CC= vonKar* Ct/ Cd ! /=0
3550+ Ribcu=- blk_ZW/ (blk_Zabl* 0.004d0 * blk_beta** 3.d0 ) ! /=0
3551+ Ri=- GRAV* blk_ZW* (delT+0.61d0 * TairK* delQ)/ (TairK* delW* delW) ! delW>0
35483552 if (Ri.lt. 0.0d0 ) then
3553+ if (1.0d0 + Ri/ Ribcu== 0.d0 ) call parallel_abort(' FAIRALL: Ri<0' )
35493554 Zetu= CC* Ri/ (1.0d0 + Ri/ Ribcu) ! Unstable
35503555 else
3556+ if (1.0d0+3.0d0 * Ri/ CC== 0.d0 ) call parallel_abort(' FAIRALL: Ri>=0' )
35513557 Zetu= CC* Ri/ (1.0d0+3.0d0 * Ri/ CC) ! Stable
35523558 endif
3559+ if (Zetu== 0.d0 ) call parallel_abort(' FAIRALL: Zetu=0' )
35533560 L10= blk_ZW/ Zetu
35543561 if (Zetu.gt. 50.0d0 ) then
35553562 IterMax= 1
@@ -3559,12 +3566,14 @@ SUBROUTINE FAIRALL(num_nodes, &
35593566!
35603567! First guesses for Monon-Obukhov similarity scales.
35613568!
3562- Wstar= delW* vonKar/ (LOG (blk_ZW/ Zo10)- &
3563- & bulk_psiu(blk_ZW/ L10))
3564- Tstar=- delT* vonKar/ (LOG (blk_ZT/ ZoT10)- &
3565- & bulk_psit(blk_ZT/ L10))
3566- Qstar=- delQ* vonKar/ (LOG (blk_ZQ/ ZoT10)- &
3567- & bulk_psit(blk_ZQ/ L10))
3569+ ! Zo10>0
3570+ tmp1= LOG (blk_ZW/ Zo10)- bulk_psiu(blk_ZW/ L10)
3571+ tmp2= LOG (blk_ZT/ ZoT10)- bulk_psit(blk_ZT/ L10)
3572+ tmp3= LOG (blk_ZQ/ ZoT10)- bulk_psit(blk_ZQ/ L10)
3573+ if (tmp1== 0.d0 .or. tmp2== 0.d0 .or. tmp3== 0.d0 ) call parallel_abort(' FAIRALL: tmp=0(0)' )
3574+ Wstar= delW* vonKar/ tmp1 ! (LOG(blk_ZW/Zo10)-bulk_psiu(blk_ZW/L10))
3575+ Tstar=- delT* vonKar/ tmp2 ! (LOG(blk_ZT/ZoT10)-bulk_psit(blk_ZT/L10))
3576+ Qstar=- delQ* vonKar/ tmp3 ! (LOG(blk_ZQ/ZoT10)-bulk_psit(blk_ZQ/L10))
35683577!
35693578! Modify Charnock for high wind speeds. The 0.125 factor below is for
35703579! 1.0/(18.0-10.0).
@@ -3580,6 +3589,7 @@ SUBROUTINE FAIRALL(num_nodes, &
35803589! Iterate until convergence. It usually converges within four
35813590! iterations.
35823591!
3592+ if (VisAir== 0.d0 ) call parallel_abort(' FAIRALL: VisAir=0' )
35833593 do Iter= 1 ,IterMax
35843594 ZoW= charn* Wstar* Wstar/ GRAV+0.11d0 * VisAir/ (Wstar+ eps)
35853595 Rr= ZoW* Wstar/ VisAir
@@ -3591,7 +3601,8 @@ SUBROUTINE FAIRALL(num_nodes, &
35913601 ZoL= vonKar* GRAV* blk_ZW* &
35923602 & (Tstar* (1.0d0+0.61d0 * Q)+ 0.61d0 * TairK* Qstar)/ &
35933603 & (TairK* Wstar* Wstar* (1.0d0+0.61d0 * Q)+ eps)
3594- L= blk_ZW/ (ZoL+ eps)
3604+ if (ZoL+ eps== 0.d0 ) call parallel_abort(' FAIRALL: ZoL+eps=0' )
3605+ L= blk_ZW/ (ZoL+ eps) ! /=0
35953606!
35963607! Evaluate stability functions at Z/L.
35973608!
@@ -3601,20 +3612,25 @@ SUBROUTINE FAIRALL(num_nodes, &
36013612!
36023613! Compute wind scaling parameters, Wstar.
36033614!
3604- Wstar= MAX (eps,delW* vonKar/ (LOG (blk_ZW/ ZoW)- Wpsi))
3605- Tstar=- delT* vonKar/ (LOG (blk_ZT/ ZoT)- Tpsi)
3606- Qstar=- delQ* vonKar/ (LOG (blk_ZQ/ ZoQ)- Qpsi)
3615+ if (ZoW<= 0.d0 ) call parallel_abort(' FAIRALL: ZoW<=0' )
3616+ tmp1= LOG (blk_ZW/ ZoW)- Wpsi
3617+ tmp2= LOG (blk_ZT/ ZoT)- Tpsi
3618+ tmp3= LOG (blk_ZQ/ ZoQ)- Qpsi
3619+ if (tmp1== 0.d0 .or. tmp2== 0.d0 .or. tmp3== 0.d0 ) call parallel_abort(' FAIRALL: tmp=0' )
3620+ Wstar= MAX (eps,delW* vonKar/ tmp1) ! (LOG(blk_ZW/ZoW)-Wpsi)) !>0
3621+ Tstar=- delT* vonKar/ tmp2 ! (LOG(blk_ZT/ZoT)-Tpsi)
3622+ Qstar=- delQ* vonKar/ tmp3 ! (LOG(blk_ZQ/ZoQ)-Qpsi)
36073623!
36083624! Compute gustiness in wind speed.
36093625!
36103626 Bf=- GRAV/ TairK* Wstar* (Tstar+0.61d0 * TairK* Qstar)
36113627 if (Bf.gt. 0.0d0 ) then
3612- Wgus= blk_beta* (Bf* blk_Zabl)** r3
3628+ Wgus= blk_beta* (Bf* blk_Zabl)** r3 ! >0
36133629 else
36143630 Wgus= 0.2d0
36153631 endif
3616- delW= SQRT (wspd0* wspd0+ Wgus* Wgus)
3617- enddo
3632+ delW= SQRT (wspd0* wspd0+ Wgus* Wgus) ! >0
3633+ enddo ! Iter
36183634!
36193635!- ----------------------------------------------------------------------
36203636! Compute Atmosphere/Ocean fluxes.
@@ -3623,8 +3639,8 @@ SUBROUTINE FAIRALL(num_nodes, &
36233639!
36243640! Compute transfer coefficients for momentum (Cd).
36253641!
3626- wspd= SQRT (wspd0* wspd0+ Wgus* Wgus)
3627- Cd= Wstar* Wstar/ (wspd* wspd+ eps)
3642+ wspd= SQRT (wspd0* wspd0+ Wgus* Wgus) ! >0
3643+ Cd= Wstar* Wstar/ (wspd* wspd+ eps) ! >0
36283644!
36293645! Compute turbulent sensible heat flux (W/m2), Hs.
36303646!
@@ -3712,6 +3728,7 @@ END SUBROUTINE FAIRALL
37123728 REAL(rkind) FUNCTION bulk_psiu (ZoL )
37133729
37143730 use schism_glbl, only : rkind
3731+ use schism_msgp, only : myrank,parallel_abort
37153732
37163733 IMPLICIT NONE
37173734!
@@ -3749,29 +3766,28 @@ REAL(rkind) FUNCTION bulk_psiu(ZoL)
37493766! Unstable conditions.
37503767!
37513768 if (ZoL.lt. 0.0d0 ) then
3752- x= (1.0d0-15.0d0 * ZoL)** 0.25d0
3769+ x= (1.0d0-15.0d0 * ZoL)** 0.25d0 ! >0
37533770 psik= 2.0d0 * LOG (0.5d0 * (1.0d0 + x))+ &
37543771 & LOG (0.5d0 * (1.0d0 + x* x))- 2.0d0 * ATAN (x)+ 0.5d0 * PI
37553772!
37563773! For very unstable conditions, use free-convection (Fairall).
37573774!
37583775 cff= SQRT (3.0d0 )
3759- y= (1.0d0-10.15d0 * ZoL)** r3
3776+ y= (1.0d0-10.15d0 * ZoL)** r3 ! >0
37603777 psic= 1.5d0 * LOG (r3* (1.0d0 + y+ y* y))- &
37613778 & cff* ATAN ((1.0d0+2.0d0 * y)/ cff)+ PI/ cff
37623779!
37633780! Match Kansas and free-convection forms with weighting Fw.
37643781!
3765- cff= ZoL* ZoL
3766- Fw= cff/ (1.0d0 + cff)
3782+ cff= ZoL* ZoL ! >0
3783+ Fw= cff/ (1.0d0 + cff) ! \in (0,1)
37673784 bulk_psiu= (1.0d0 - Fw)* psik+ Fw* psic
37683785!
37693786! Stable conditions.
37703787!
3771- else
3772- cff= MIN (50.0d0 ,0.35d0 * ZoL)
3773- bulk_psiu=- ((1.0d0 + ZoL)+ &
3774- & 0.6667d0 * (ZoL-14.28d0 )/ EXP (cff)+ 8.525d0 )
3788+ else ! ZoL>=0
3789+ cff= MIN (50.0d0 ,0.35d0 * ZoL) ! >=0
3790+ bulk_psiu=- ((1.0d0 + ZoL)+ 0.6667d0 * (ZoL-14.28d0 )/ EXP (cff)+ 8.525d0 )
37753791 endif
37763792 return
37773793 END FUNCTION bulk_psiu
@@ -3813,26 +3829,26 @@ REAL(rkind) FUNCTION bulk_psit(ZoL)
38133829! Unstable conditions.
38143830!
38153831 if (ZoL.lt. 0.0d0 ) then
3816- x= (1.0d0-15.0d0 * ZoL)** 0.5d0
3832+ x= (1.0d0-15.0d0 * ZoL)** 0.5d0 ! >0
38173833 psik= 2.0d0 * LOG (0.5d0 * (1.0d0 + x))
38183834!
38193835! For very unstable conditions, use free-convection (Fairall).
38203836!
38213837 cff= SQRT (3.0d0 )
3822- y= (1.0-34.15 * ZoL)** r3
3838+ y= (1.0-34.15 * ZoL)** r3 ! >0
38233839 psic= 1.5d0 * LOG (r3* (1.0d0 + y+ y* y))- &
38243840 & cff* ATAN ((1.0d0+2.0d0 * y)/ cff)+ PI/ cff
38253841!
38263842! Match Kansas and free-convection forms with weighting Fw.
38273843!
3828- cff= ZoL* ZoL
3829- Fw= cff/ (1.0d0 + cff)
3844+ cff= ZoL* ZoL ! >0
3845+ Fw= cff/ (1.0d0 + cff) ! \in (0,1)
38303846 bulk_psit= (1.0d0 - Fw)* psik+ Fw* psic
38313847!
38323848! Stable conditions.
38333849!
3834- else
3835- cff= MIN (50.0d0 ,0.35d0 * ZoL)
3850+ else ! ZoL>=0
3851+ cff= MIN (50.0d0 ,0.35d0 * ZoL) ! >=0
38363852 bulk_psit=- ((1.0d0+2.0d0 * ZoL)** 1.5d0 + &
38373853 & 0.6667d0 * (ZoL-14.28d0 )/ EXP (cff)+ 8.525d0 )
38383854 endif
0 commit comments