ROMS
Loading...
Searching...
No Matches
ana_specir.h
Go to the documentation of this file.
1!!
2 SUBROUTINE ana_specir (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 surface solar downwelling spectral irradiance !
12! at just beneath the sea surface, Ed(lambda,0-), in micromol quanta !
13! per meter squared per second. !
14! !
15! Reference: !
16! !
17! Gregg, W.W. and K.L. Carder, 1990: A simple spectral solar !
18! irradiance model for cloudless maritime atmospheres, !
19! Limmol. Oceanogr., 35(8), 1657-1675. !
20! !
21!=======================================================================
22!
23 USE mod_param
24 USE mod_forces
25 USE mod_grid
26 USE mod_ncparam
27!
28! Imported variable declarations.
29!
30 integer, intent(in) :: ng, tile, model
31!
32! Local variable declarations.
33!
34 character (len=*), parameter :: MyFile = &
35 & __FILE__
36!
37#include "tile.h"
38!
39 CALL ana_specir_tile (ng, tile, model, &
40 & lbi, ubi, lbj, ubj, &
41 & imins, imaxs, jmins, jmaxs, &
42 & grid(ng) % lonr, &
43 & grid(ng) % latr, &
44 & forces(ng) % cloud, &
45 & forces(ng) % Hair, &
46 & forces(ng) % Tair, &
47 & forces(ng) % Pair, &
48 & forces(ng) % Uwind, &
49 & forces(ng) % Vwind, &
50 & forces(ng) % SpecIr, &
51 & forces(ng) % avcos)
52!
53! Set analytical header file name used.
54!
55#ifdef DISTRIBUTE
56 IF (lanafile) THEN
57#else
58 IF (lanafile.and.(tile.eq.0)) THEN
59#endif
60 ananame(25)=myfile
61 END IF
62!
63 RETURN
64 END SUBROUTINE ana_specir
65!
66!***********************************************************************
67 SUBROUTINE ana_specir_tile (ng, tile, model, &
68 & LBi, UBi, LBj, UBj, &
69 & IminS, ImaxS, JminS, JmaxS, &
70 & lonr, latr, &
71 & cloud, Hair, Tair, Pair, &
72 & Uwind, Vwind, &
73 & SpecIr, avcos)
74!***********************************************************************
75!
76 USE mod_param
77 USE mod_eclight
78 USE mod_iounits
79 USE mod_scalars
80!
81 USE dateclock_mod, ONLY : caldate
83#ifdef DISTRIBUTE
85#endif
86!
87 implicit none
88!
89! Imported variable declarations.
90!
91 integer, intent(in) :: ng, tile, model
92 integer, intent(in) :: LBi, UBi, LBj, UBj
93 integer, intent(in) :: IminS, ImaxS, JminS, JmaxS
94!
95#ifdef ASSUMED_SHAPE
96 real(r8), intent(in) :: lonr(LBi:,LBj:)
97 real(r8), intent(in) :: latr(LBi:,LBj:)
98 real(r8), intent(in) :: cloud(LBi:,LBj:)
99 real(r8), intent(in) :: Hair(LBi:,LBj:)
100 real(r8), intent(in) :: Tair(LBi:,LBj:)
101 real(r8), intent(in) :: Pair(LBi:,LBj:)
102 real(r8), intent(in) :: Uwind(LBi:,LBj:)
103 real(r8), intent(in) :: Vwind(LBi:,LBj:)
104 real(r8), intent(out) :: SpecIr(LBi:,LBj:,:)
105 real(r8), intent(out) :: avcos(LBi:,LBj:,:)
106#else
107 real(r8), intent(in) :: lonr(LBi:UBi,LBj:UBj)
108 real(r8), intent(in) :: latr(LBi:UBi,LBj:UBj)
109 real(r8), intent(in) :: cloud(LBi:UBi,LBj:UBj)
110 real(r8), intent(in) :: Hair(LBi:UBi,LBj:UBj)
111 real(r8), intent(in) :: Tair(LBi:UBi,LBj:UBj)
112 real(r8), intent(in) :: Pair(LBi:UBi,LBj:UBj)
113 real(r8), intent(in) :: UWind(LBi:UBi,LBj:UBj)
114 real(r8), intent(in) :: Vwind(LBi:UBi,LBj:UBj)
115 real(r8), intent(out) :: SpecIr(LBi:UBi,LBj:UBj,NBands)
116 real(r8), intent(out) :: avcos(LBi:UBi,LBj:UBj,NBands)
117#endif
118!
119! Local constant declarations.
120!
121 real(r8) :: am = 1.0_r8 ! Aerosol type 1-10: ocean to land
122 real(r8) :: betalam = 0.55_r8
123 real(r8) :: p0 = 29.92_r8 ! Standard pressure (inches of Hg)
124 real(r8) :: rex = -1.6364_r8
125 real(r8) :: roair = 1200.0_r8 ! Density of air (g/m3)
126 real(r8) :: rn = 1.341_r8 ! Index of refraction of pure seawater
127 real(r8) :: vis = 15.0_r8 ! Visibility (km)
128 real(r8) :: wv = 1.5_r8 ! Precipitable water (cm): water vapor
129!
130! Local variable declarations.
131!
132 integer :: i, iband, ic, j, nc
133!
134 real(dp) :: hour, yday
135 real(r8) :: Dangle, Hangle, LatRad, LonRad
136 real(r8) :: cff, cff1, cff2
137 real(r8) :: alpha, beta, gamma, theta, rtheta, rthetar
138 real(r8) :: atra, gtra, otra, rtra, wtra
139 real(r8) :: alg, arg, asymp, cosunz, Fa
140 real(r8) :: frh, rh, rlam, rlogc
141 real(r8) :: rm, rmin, rmo, rmp, rod, rof
142 real(r8) :: ros, rospd, rosps, rpls
143 real(r8) :: sumx, sumx2, sumxy, sumy
144 real(r8) :: taa, tas, to3, wa, wspeed, zenith
145!
146 real(r8), dimension(NBands) :: Fo, Edir, Edif, Ed, qlam
147!
148 real(r8), dimension(3) :: a_arr, dndr
149 real(r8), dimension(3) :: ro = (/ 0.03_r8, 0.24_r8, 2.00_r8 /)
150 real(r8), dimension(3) :: r_arr = (/ 0.10_r8, 1.00_r8, 10.0_r8 /)
151!
152#include "set_bounds.h"
153!
154!-----------------------------------------------------------------------
155! Compute spectral irradiance: Using RADTRAN formulations.
156!-----------------------------------------------------------------------
157!
158! Get time clock day-of-year and hour.
159!
160 CALL caldate (tdays(ng), yd_dp=yday, h_dp=hour)
161!
162! Estimate solar declination angle (radians).
163!
164 dangle=23.44_dp*cos((172.0_dp-yday)*2.0_dp*pi/365.25_dp)
165 dangle=dangle*deg2rad
166!
167! Compute hour angle (radians).
168!
169 hangle=(12.0_r8-hour)*pi/12.0_r8
170!
171! Conversion constant from E to micromol quanta.
172! 1/(Plank*c*(avos#*1.0e6).
173!
174 cff=1.0e-9_r8/(6.6256e-34_r8*2.998e8_r8*6.023e17_r8)
175 DO iband=1,nbands
176 qlam(iband)=ec_wave_ab(iband)*cff
177 END DO
178!
179! Correct solar constant for Earth-Sun distance.
180!
181 cff=(1.0_dp+0.0167_dp*cos(2.0_dp*pi*(yday-3.0_dp)/365.0_dp))**2
182 DO iband=1,nbands
183 fo(iband)=ec_fobar(iband)*cff
184 END DO
185!
186! Compute spectral irradiance.
187!
188 DO j=jstrt,jendt
189 DO i=istrt,iendt
190
191 latrad=latr(i,j)*deg2rad
192 lonrad=lonr(i,j)*deg2rad
193!
194! Compute Climatological Ozone.
195!
196 to3=(235.0_r8+(150.0_r8+40.0_r8* &
197 & sin(0.9865_dp*(yday-30.0_dp)*deg2rad)+ &
198 & 20.0_r8*sin(3.0_r8*lonrad))* &
199 & sin(1.28_r8*latrad)*sin(1.28_r8*latrad))* &
200 & 0.001_r8 ! sco3 conversion
201!
202! Local daylight is a function of the declination (Dangle) and hour
203! angle adjusted for the local meridian (Hangle-lonr(i,j)*deg2rad).
204!
205 cosunz=sin(latrad)*sin(dangle)+ &
206 & cos(latrad)*cos(dangle)*cos(hangle-lonr(i,j)*deg2rad)
207 zenith=acos(cosunz)
208 theta=zenith*rad2deg
209!
210! Model for atmospheric transmittance of solar irradiance through
211! a maritime atmosphere. Computes direct and diffuse separately.
212! Includes water vapor and oxygen absorption.
213!
214! Compute atmospheric path lengths (air mass); pressure-corrected
215!
216 IF ((theta.ge.0.0_r8).and.(theta.le.90.0_r8)) THEN
217!
218! Modified March, 1994 according to Kasten and Young 1989.
219!
220 rm=1.0_r8/(cosunz+0.50572_r8*(96.07995_r8-theta)**rex)
221 rmp=rm*(pair(i,j)*0.02952756_r8)/p0
222 rmo=(1.0_r8+22.0_r8/6370.0_r8)/ &
223 & sqrt(cosunz*cosunz+44.0_r8/6370.0_r8)
224!
225! Computes aerosol parameters according to a simplified version
226! of the Navy marine aerosol model.
227!
228! Compute wind speed (24 hour mean is equal to current wind).
229!
230 wspeed=sqrt(uwind(i,j)*uwind(i,j)+vwind(i,j)*vwind(i,j))
231!
232! Relative humidity factor, frh.
233!
234 rh=hair(i,j)
235 IF (rh.ge.100.0_r8) rh=99.9_r8
236 frh=((2.0_r8-rh*0.01_r8)/ &
237 (6.0_r8*(1.0_r8-rh*0.01_r8)))**0.333_r8
238!
239! Size distribution amplitude components.
240!
241 a_arr(1)=2000.0_r8*am*am
242 a_arr(2)=5.866_r8*(wspeed-2.2_r8)
243 a_arr(3)=0.01527_r8*(wspeed-2.2_r8)*0.05_r8 !from Hughes 1987
244 IF (a_arr(2).lt.0.5_r8) a_arr(2)=0.5_r8
245 IF (a_arr(3).lt.0.000014_r8) a_arr(3)=0.000014_r8
246!
247! Compute size distribution at three selected radii according to
248! Navy method.
249!
250 cff=1.0_r8/frh
251 DO nc=1,3
252 dndr(nc)=0.0_r8
253 DO ic=1,3
254 arg=log(r_arr(nc)/(frh*ro(ic)))
255 dndr(nc)=dndr(nc)+a_arr(ic)*exp(-arg*arg)*cff
256 END DO
257 END DO
258!
259! Least squares approximation
260!
261 sumx=0.0_r8
262 sumy=0.0_r8
263 sumxy=0.0_r8
264 sumx2=0.0_r8
265 DO ic=1,3
266 cff1=log10(r_arr(ic))
267 cff2=log10(dndr(ic))
268 sumx=sumx+cff1
269 sumy=sumy+cff2
270 sumxy=sumxy+cff1*cff2
271 sumx2=sumx2+cff1*cff1
272 END DO
273 gamma=sumxy/sumx2
274 rlogc=sumy/3.0_r8-gamma*sumx/3.0_r8 ! no used
275 alpha=-(gamma+3.0_r8)
276!
277! Compute aerosol turbity coefficient, beta.
278!
279 beta=(3.91_r8/vis)*betalam**alpha
280!
281! Compute asymmetry parameter -- a function of alpha.
282!
283 IF (alpha.gt.1.2_r8) THEN
284 asymp=0.65_r8
285 ELSE IF (alpha .lt. 0.0_r8) THEN
286 asymp=0.82_r8
287 ELSE
288 asymp=-0.14167_r8*alpha+0.82_r8
289 END IF
290!
291! Single scattering albedo at 550; function of RH.
292!
293 wa=(-0.0032_r8*am+0.972_r8)*exp(0.000306_r8*rh)
294!
295! Forward scattering probability.
296!
297 alg=log(1.0_r8-asymp)
298 fa=1.0_r8-0.5_r8* &
299 & exp((alg*(1.459_r8+alg*(0.1595_r8+alg*0.4129_r8))+ &
300 & alg*(0.0783_r8+alg*(-0.3824_r8-alg*0.5874_r8))* &
301 & cosunz)*cosunz)
302!
303! Compute surface reflectance for direct (rod) and diffuse (ros)
304! components separately, as a function of theta, wind speed or
305! stress.
306!
307! Foam and diffuse reflectance
308!
309 IF (wspeed.gt.4.0_r8) THEN
310 IF (wspeed.le.7.0_r8) THEN
311 rof=roair*(0.00062_r8+0.00156_r8/wspeed)* &
312 & 0.000022_r8*wspeed*wspeed-0.00040_r8
313 ELSE
314 rof=(roair*(0.00049_r8+0.000065_r8*wspeed)* &
315 & 0.000045_r8-0.000040_r8)*wspeed*wspeed
316 END IF
317 rosps=0.057_r8
318 ELSE
319 rof=0.0_r8
320 rosps=0.066_r8
321 END IF
322!
323! Direct Fresnel reflectance for theta < 40, wspeed < 2 m/s.
324!
325 IF ((theta.lt.40.0_r8).or.(wspeed.lt.2.0_r8)) THEN
326 IF (theta.eq.0.0_r8) THEN
327 rospd=0.0211_r8
328 ELSE
329 rtheta=zenith
330 rthetar=asin(sin(rtheta)/rn)
331 rmin=rtheta-rthetar
332 rpls=rtheta+rthetar
333 rospd=0.5_r8*((sin(rmin)*sin(rmin))/ &
334 & (sin(rpls)*sin(rpls))+ &
335 & (tan(rmin)*tan(rmin))/ &
336 & (tan(rpls)*tan(rpls)))
337 END IF
338!
339! Empirical fit otherwise.
340!
341 ELSE
342 rospd=0.0253_r8*exp((-0.000714_r8*wspeed+0.0618_r8)* &
343 & (theta-40.0_r8))
344 END IF
345!
346! Reflectance totals.
347!
348 rod=rospd+rof
349 ros=rosps+rof
350!
351! Compute spectral irradiance for selected spectral bands.
352!
353 DO iband=1,nbands
354 rlam=ec_wave_ab(iband)*0.001_r8
355!
356! Transmittance, Rayleigh, by the method of Bird.
357!
358 rtra=exp(-rmp/(115.6406_r8*rlam**4-1.335_r8*rlam**2))
359!
360! Ozone.
361!
362 otra=exp(-ec_aoz(iband)*to3*rmo)
363!
364! Aerosols.
365!
366 arg=beta*rm*rlam**(-alpha)
367 atra=exp(-arg)
368 taa=exp(-(1.0_r8-wa)*arg)
369 tas=exp(-wa*arg)
370!
371! Oxygen/gases.
372!
373 gtra=exp((-1.41_r8*ec_ag(iband)*rmp)/ &
374 & ((1.0_r8+118.3_r8*ec_ag(iband)*rmp)**0.45_r8))
375!
376! Water Vapor.
377!
378 wtra=exp((-0.2385_r8*ec_aw(iband)*wv*rm)/ &
379 & ((1.0_r8+20.07_r8*ec_aw(iband)*wv*rm)**0.45_r8))
380!
381! Direct irradiance.
382!
383 edir(iband)=fo(iband)*cosunz*rtra*otra*atra*gtra* &
384 & wtra*(1.0_r8-rod)
385!
386! Total diffuse irradiance.
387!
388 edif(iband)=(1.0_r8-ros)* &
389 & fo(iband)*cosunz*gtra*wtra*otra* &
390 & (taa*0.5_r8*(1.0_r8-rtra**0.95_r8)+ &
391 & taa*fa*(1.0_r8-tas)*rtra**1.5_r8)
392!
393! Cloud effects approximations, Kasten and Czeplak (1980).
394! (See Hydrolight Technical Notes).
395!
396 IF (cloud(i,j).gt.0.25_r8) THEN
397 ed(iband)=(edir(iband)+edif(iband))* &
398 & (1.0_r8-0.75_r8*cloud(i,j)**3.4_r8)
399 edif(iband)=ed(iband)* &
400 & (0.3_r8+0.7_r8*cloud(i,j)**2.0_r8)
401 ELSE
402 ed(iband)=edir(iband)+edif(iband)
403 END IF
404!
405! Convert from W/cm/um to micromole quanta/m2/s.
406!
407 specir(i,j,iband)=ed(iband)*10.0_r8*qlam(iband)
408!
409! Correction of zenith angle after crossing air/sea interface.
410!
411 cff1=cos(asin((sin(zenith))/rn))
412 cff2=edif(iband)/ed(iband)
413 avcos(i,j,iband)=cff1*(1.0_r8-cff2)+0.86_r8*cff2
414 END DO
415 ELSE
416 DO iband=1,nbands
417 specir(i,j,iband)=0.0_r8
418 avcos(i,j,iband)=0.66564_r8
419 END DO
420 END IF
421 END DO
422 END DO
423!
424! Exchange boundary data.
425!
426 IF (ewperiodic(ng).or.nsperiodic(ng)) THEN
427 CALL exchange_r3d_tile (ng, tile, &
428 & lbi, ubi, lbj, ubj, 1, nbands, &
429 & specir)
430 CALL exchange_r3d_tile (ng, tile, &
431 & lbi, ubi, lbj, ubj, 1, nbands, &
432 & avcos)
433 END IF
434
435#ifdef DISTRIBUTE
436 CALL mp_exchange3d (ng, tile, model, 2, &
437 & lbi, ubi, lbj, ubj, 1, nbands, &
438 & nghostpoints, &
439 & ewperiodic(ng), nsperiodic(ng), &
440 & specir, avcos)
441#endif
442!
443 RETURN
444 END SUBROUTINE ana_specir_tile
subroutine ana_specir(ng, tile, model)
Definition ana_specir.h:3
subroutine ana_specir_tile(ng, tile, model, lbi, ubi, lbj, ubj, imins, imaxs, jmins, jmaxs, lonr, latr, cloud, hair, tair, pair, uwind, vwind, specir, avcos)
Definition ana_specir.h:74
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_r3d_tile(ng, tile, lbi, ubi, lbj, ubj, lbk, ubk, 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), dimension(:), allocatable tdays
real(dp), parameter deg2rad
real(dp), parameter rad2deg
real(dp), parameter pi
subroutine mp_exchange3d(ng, tile, model, nvar, lbi, ubi, lbj, ubj, lbk, ubk, nghost, ew_periodic, ns_periodic, a, b, c, d)