ROMS
Loading...
Searching...
No Matches
ana_srflux.h
Go to the documentation of this file.
1!!
2 SUBROUTINE ana_srflux (ng, tile, model)
3!
4!! git $Id$
5!!======================================================================
6!! Copyright (c) 2002-2025 The ROMS Group !
7!! Licensed under a MIT/X style license !
8!! See License_ROMS.md !
9!=======================================================================
10! !
11! This subroutine sets kinematic surface solar shortwave radiation !
12! flux "srflx" (degC m/s) using an analytical expression. !
13! !
14!=======================================================================
15!
16 USE mod_param
17 USE mod_forces
18 USE mod_grid
19 USE mod_ncparam
20!
21! Imported variable declarations.
22!
23 integer, intent(in) :: ng, tile, model
24!
25! Local variable declarations.
26!
27 character (len=*), parameter :: MyFile = &
28 & __FILE__
29!
30#include "tile.h"
31!
32 CALL ana_srflux_tile (ng, tile, model, &
33 & lbi, ubi, lbj, ubj, &
34 & imins, imaxs, jmins, jmaxs, &
35 & grid(ng) % lonr, &
36 & grid(ng) % latr, &
37#ifdef ALBEDO
38 & forces(ng) % cloud, &
39 & forces(ng) % Hair, &
40 & forces(ng) % Tair, &
41 & forces(ng) % Pair, &
42#endif
43 & forces(ng) % srflx)
44!
45! Set analytical header file name used.
46!
47#ifdef DISTRIBUTE
48 IF (lanafile) THEN
49#else
50 IF (lanafile.and.(tile.eq.0)) THEN
51#endif
52 ananame(27)=myfile
53 END IF
54!
55 RETURN
56 END SUBROUTINE ana_srflux
57!
58!***********************************************************************
59 SUBROUTINE ana_srflux_tile (ng, tile, model, &
60 & LBi, UBi, LBj, UBj, &
61 & IminS, ImaxS, JminS, JmaxS, &
62 & lonr, latr, &
63#ifdef ALBEDO
64 & cloud, Hair, Tair, Pair, &
65#endif
66 & srflx)
67!***********************************************************************
68!
69 USE mod_param
70 USE mod_scalars
71!
72 USE dateclock_mod, ONLY : caldate
74#ifdef DISTRIBUTE
76#endif
77!
78! Imported variable declarations.
79!
80 integer, intent(in) :: ng, tile, model
81 integer, intent(in) :: LBi, UBi, LBj, UBj
82 integer, intent(in) :: IminS, ImaxS, JminS, JmaxS
83!
84#ifdef ASSUMED_SHAPE
85 real(r8), intent(in) :: lonr(LBi:,LBj:)
86 real(r8), intent(in) :: latr(LBi:,LBj:)
87# ifdef ALBEDO
88 real(r8), intent(in) :: cloud(LBi:,LBj:)
89 real(r8), intent(in) :: Hair(LBi:,LBj:)
90 real(r8), intent(in) :: Tair(LBi:,LBj:)
91 real(r8), intent(in) :: Pair(LBi:,LBj:)
92# endif
93 real(r8), intent(out) :: srflx(LBi:,LBj:)
94#else
95 real(r8), intent(in) :: lonr(LBi:UBi,LBj:UBj)
96 real(r8), intent(in) :: latr(LBi:UBi,LBj:UBj)
97# ifdef ALBEDO
98 real(r8), intent(in) :: cloud(LBi:UBi,LBj:UBj)
99 real(r8), intent(in) :: Hair(LBi:UBi,LBj:UBj)
100 real(r8), intent(in) :: Tair(LBi:UBi,LBj:UBj)
101 real(r8), intent(in) :: Pair(LBi:UBi,LBj:UBj)
102# endif
103 real(r8), intent(out) :: srflx(LBi:UBi,LBj:UBj)
104#endif
105!
106! Local variable declarations.
107!
108 integer :: i, j
109!
110#if defined ALBEDO || defined DIURNAL_SRFLUX
111 real(dp) :: hour, yday
112 real(r8) :: Dangle, Hangle, LatRad
113 real(r8) :: cff1, cff2
114# ifdef ALBEDO
115 real(r8) :: Rsolar, e_sat, vap_p, zenith
116# endif
117#endif
118 real(r8) :: cff
119!
120 real(r8), parameter :: alb_w=0.06_r8
121
122#include "set_bounds.h"
123
124#if defined ALBEDO || defined DIURNAL_SRFLUX
125!
126!-----------------------------------------------------------------------
127! Compute shortwave radiation (degC m/s):
128!
129! ALBEDO option: Compute shortwave radiation flux using the Laevastu
130! cloud correction to the Zillman equation for cloudless
131! radiation (Parkinson and Washington 1979, JGR, 84, 311-337). Notice
132! that flux is scaled from W/m2 to degC m/s by dividing by (rho0*Cp).
133!
134! DIURNAL_SRFLUX option: Modulate shortwave radiation SRFLX (which
135! read and interpolated elsewhere) by the local
136! diurnal cycle (a function of longitude, latitude and day-of-year).
137! This option is provided for cases where SRFLX computed by SET_DATA is
138! an average over >= 24 hours. For "diurnal_srflux" to work ana_srflux
139! must be undefined. If you want a strictly analytical diurnal cycle
140! enter it explicitly at the end of this subroutine or use the "albedo"
141! option.
142!
143! For a review of shortwave radiation formulations check:
144!
145! Niemela, S., P. Raisanen, and H. Savijarvi, 2001: Comparison of
146! surface radiative flux parameterizations, Part II, Shortwave
147! radiation, Atmos. Res., 58, 141-154.
148!
149!-----------------------------------------------------------------------
150!
151! Get time clock day-of-year and hour.
152!
153 CALL caldate (tdays(ng), yd_dp=yday, h_dp=hour)
154!
155! Estimate solar declination angle (radians).
156!
157 dangle=23.44_dp*cos((172.0_dp-yday)*2.0_dp*pi/365.2425_dp)
158 dangle=dangle*deg2rad
159!
160! Compute hour angle (radians).
161!
162 hangle=(12.0_r8-hour)*pi/12.0_r8
163!
164# ifdef ALBEDO
165 rsolar=csolar/(rho0*cp)
166# endif
167 DO j=jstrt,jendt
168 DO i=istrt,iendt
169!
170! Local daylight, GMT time zone, is a function of the declination
171! (Dangle) and hour angle adjusted for the local meridian
172! (Hangle-lonr(i,j)*deg2rad).
173!
174 latrad=latr(i,j)*deg2rad
175 cff1=sin(latrad)*sin(dangle)
176 cff2=cos(latrad)*cos(dangle)
177# if defined ALBEDO
178!
179! Estimate variation in optical thickness of the atmosphere over
180! the course of a day under cloudless skies (Zillman, 1972). To
181! obtain incoming shortwave radiation multiply by (1.0-0.6*c**3),
182! where c is the fractional cloud cover.
183!
184! The equation for saturation vapor pressure is from Gill (Atmosphere-
185! Ocean Dynamics, pp 606).
186!!
187!! If specific humidity in kg/kg.
188!!
189!! vap_p=Pair(i,j)*Hair(i,j)/(0.62197_r8+0.378_r8*Hair(i,j))
190!!
191!
192 srflx(i,j)=0.0_r8
193 zenith=cff1+cff2*cos(hangle-lonr(i,j)*deg2rad)
194 IF (zenith.gt.0.0_r8) THEN
195 cff=(0.7859_r8+0.03477_r8*tair(i,j))/ &
196 & (1.0_r8+0.00412_r8*tair(i,j))
197 e_sat=10.0_r8**cff ! saturation vapor pressure (hPa=mbar)
198 vap_p=e_sat*hair(i,j) ! water vapor pressure (hPa=mbar)
199 srflx(i,j)=rsolar*zenith*zenith* &
200 & (1.0_r8-0.6_r8*cloud(i,j)**3)/ &
201 & ((zenith+2.7_r8)*vap_p*1.0e-3_r8+ &
202 & 1.085_r8*zenith+0.1_r8)
203 END IF
204!
205! Add correction for ocean albedo. Notice that the correction is not
206! needed below because it is assumed that the input (>=24h-average)
207! and 'srflx' is NET downward shortwave radiation.
208!
209 srflx(i,j)=(1.0_r8-alb_w)*srflx(i,j)
210
211# elif defined DIURNAL_SRFLUX
212!
213! SRFLX is reset on each time step in subroutine SET_DATA which
214! interpolates values in the forcing file to the current date.
215! This DIURNAL_SRFLUX option is provided so that SRFLX values
216! corresponding to a greater or equal daily average can be modulated
217! by the local length of day to produce a diurnal cycle with the
218! same daily average as the original data. This approach assumes
219! the net effect of clouds is incorporated into the SRFLX data.
220!
221! Normalization = (1/2*pi)*INTEGRAL{ABS(a+b*COS(t)) dt} from 0 to 2*pi
222! = (a*ARCCOS(-a/b)+SQRT(b**2-a**2))/pi for |a| < |b|
223!
224 IF (abs(cff1).gt.abs(cff2)) THEN
225 IF (cff1*cff2.gt.0.0_r8) THEN
226 cff=cff1 ! All day case
227 srflx(i,j)=max(0.0_r8, &
228 & srflx(i,j)/cff* &
229 & (cff1+cff2*cos(hangle-lonr(i,j)*deg2rad)))
230 ELSE
231 srflx(i,j)=0.0_r8 ! All night case
232 END IF
233 ELSE
234 cff=(cff1*acos(-cff1/cff2)+sqrt(cff2*cff2-cff1*cff1))/pi
235 srflx(i,j)=max(0.0_r8, &
236 & srflx(i,j)/cff* &
237 & (cff1+cff2*cos(hangle-lonr(i,j)*deg2rad)))
238 END IF
239# endif
240 END DO
241 END DO
242#else
243!
244!-----------------------------------------------------------------------
245! Set incoming solar shortwave radiation (degC m/s). Usually, the
246! shortwave radiation from input files is Watts/m2 and then converted
247! to degC m/s by multiplying by conversion factor 1/(rho0*Cp) during
248! reading (Fscale). However, we are already inside ROMS kernel here
249! and all the fluxes are kinematic so shortwave radiation units need
250! to be degC m/s.
251!-----------------------------------------------------------------------
252!
253 cff=1.0_r8/(rho0*cp)
254# if defined UPWELLING
255 DO j=jstrt,jendt
256 DO i=istrt,iendt
257 srflx(i,j)=cff*150.0_r8
258 END DO
259 END DO
260# else
261 DO j=jstrt,jendt
262 DO i=istrt,iendt
263 srflx(i,j)=0.0_r8
264 END DO
265 END DO
266# endif
267#endif
268!
269! Exchange boundary data.
270!
271 IF (ewperiodic(ng).or.nsperiodic(ng)) THEN
272 CALL exchange_r2d_tile (ng, tile, &
273 & lbi, ubi, lbj, ubj, &
274 & srflx)
275 END IF
276
277#ifdef DISTRIBUTE
278 CALL mp_exchange2d (ng, tile, model, 1, &
279 & lbi, ubi, lbj, ubj, &
280 & nghostpoints, &
281 & ewperiodic(ng), nsperiodic(ng), &
282 & srflx)
283#endif
284!
285 RETURN
286 END SUBROUTINE ana_srflux_tile
subroutine ana_srflux(ng, tile, model)
Definition ana_srflux.h:3
subroutine ana_srflux_tile(ng, tile, model, lbi, ubi, lbj, ubj, imins, imaxs, jmins, jmaxs, lonr, latr, cloud, hair, tair, pair, srflx)
Definition ana_srflux.h:67
subroutine, public caldate(currenttime, yy_i, yd_i, mm_i, dd_i, h_i, m_i, s_i, yd_dp, dd_dp, h_dp, m_dp, s_dp)
Definition dateclock.F:76
subroutine exchange_r2d_tile(ng, tile, lbi, ubi, lbj, ubj, a)
type(t_forces), dimension(:), allocatable forces
Definition mod_forces.F:554
type(t_grid), dimension(:), allocatable grid
Definition mod_grid.F:365
logical lanafile
character(len=256), dimension(39) ananame
integer nghostpoints
Definition mod_param.F:710
logical, dimension(:), allocatable ewperiodic
logical, dimension(:), allocatable nsperiodic
real(dp) cp
real(dp), dimension(:), allocatable tdays
real(dp), parameter deg2rad
real(dp) csolar
real(dp) rho0
real(dp), parameter pi
subroutine mp_exchange2d(ng, tile, model, nvar, lbi, ubi, lbj, ubj, nghost, ew_periodic, ns_periodic, a, b, c, d)