85 module module_radiation_astronomy
90 use module_iounitdef
, only : niradsf
97 character(40),
parameter :: &
98 & VTAGAST=
'NCEP-Radiation_astronomy v5.2 Jan 2013 '
102 real (kind=kind_phys),
parameter :: degrad = 180.0/
con_pi
103 real (kind=kind_phys),
parameter :: tpi = 2.0 *
con_pi
104 real (kind=kind_phys),
parameter :: hpi = 0.5 *
con_pi
105 real (kind=kind_phys),
parameter :: f12 = 12.0
106 real (kind=kind_phys),
parameter :: f3600 = 3600.0
107 real (kind=kind_phys),
parameter :: czlimt = 0.0001
109 real (kind=kind_phys),
parameter :: pid12 = (2.0*asin(1.0))/f12
112 real (kind=kind_phys),
public :: solc0 =
con_solr
113 integer :: isolflg = 10
114 character(26) :: solar_fname =
' '
183 integer,
intent(in) :: me
188 logical :: file_exist
192 if ( me == 0 ) print *, vtagast
204 print *,
' - Using old fixed solar constant =', solc0
206 elseif (
isolar == 10 )
then
208 print *,
' - Using new fixed solar constant =', solc0
210 elseif (
isolar == 1 )
then
211 solar_fname(15:26) =
'noaa_a0.txt'
214 print *,
' - Using NOAA annual mean TSI table in ABS scale', &
215 &
' with cycle approximation (old values)!'
218 inquire (file=solar_fname, exist=file_exist)
219 if ( .not. file_exist )
then
223 print *,
' Requested solar data file "',solar_fname, &
225 print *,
' Using the default solar constant value =',solc0,&
226 &
' reset control flag isolflg=',isolflg
229 elseif (
isolar == 2 )
then
230 solar_fname(15:26) =
'noaa_an.txt'
233 print *,
' - Using NOAA annual mean TSI table in TIM scale', &
234 &
' with cycle approximation (new values)!'
237 inquire (file=solar_fname, exist=file_exist)
238 if ( .not. file_exist )
then
242 print *,
' Requested solar data file "',solar_fname, &
244 print *,
' Using the default solar constant value =',solc0,&
245 &
' reset control flag isolflg=',isolflg
248 elseif (
isolar == 3 )
then
249 solar_fname(15:26) =
'cmip_an.txt'
252 print *,
' - Using CMIP5 annual mean TSI table in TIM scale', &
253 &
' with cycle approximation'
256 inquire (file=solar_fname, exist=file_exist)
257 if ( .not. file_exist )
then
261 print *,
' Requested solar data file "',solar_fname, &
263 print *,
' Using the default solar constant value =',solc0,&
264 &
' reset control flag isolflg=',isolflg
267 elseif (
isolar == 4 )
then
268 solar_fname(15:26) =
'cmip_mn.txt'
271 print *,
' - Using CMIP5 monthly mean TSI table in TIM scale', &
272 &
' with cycle approximation'
275 inquire (file=solar_fname, exist=file_exist)
276 if ( .not. file_exist )
then
280 print *,
' Requested solar data file "',solar_fname, &
282 print *,
' Using the default solar constant value =',solc0,&
283 &
' reset control flag isolflg=',isolflg
290 print *,
' - !!! ERROR in selection of solar constant data', &
291 &
' source, ISOL =',
isolar
292 print *,
' Using the default solar constant value =',solc0, &
293 &
' reset control flag isolflg=',isolflg
321 & ( jdate,kyear,deltsw,deltim,lsol_chg, me, &
322 & slag, sdec, cdec, solcon &
374 integer,
intent(in) :: jdate(:), kyear, me
375 logical,
intent(in) :: lsol_chg
377 real (kind=kind_phys),
intent(in) :: deltsw, deltim
380 real (kind=kind_phys),
intent(out) :: slag, sdec, cdec, solcon
383 real (kind=kind_phys),
parameter :: hrday = 1.0/24.0
384 real (kind=kind_phys),
parameter :: minday= 1.0/1440.0
385 real (kind=kind_phys),
parameter :: secday= 1.0/86400.0
387 real (kind=kind_phys) :: smean, solc1, dtswh, smon(12)
388 real (kind=kind_phys) :: fjd, fjd1, dlt, r1, alp
390 integer :: jd, jd1, iyear, imon, iday, ihr, imin, isec
392 integer :: i, iyr, iyr1, iyr2, jyr, nn, nswr, icy1, icy2, icy
394 logical :: file_exist
395 character :: cline*60
410 if ( isolflg==4 )
then
418 inquire (file=solar_fname, exist=file_exist)
419 if ( .not. file_exist )
then
420 print *,
' !!! ERROR! Can not find solar constant file!!!'
426 open (niradsf,file=solar_fname,form=
'formatted', &
430 read (niradsf, * ) iyr1,iyr2,icy1,icy2,smean,cline(1:60)
435 print *,
' Updating solar constant with cycle approx'
436 print *,
' Opened solar constant data file: ',solar_fname
475 if ( iyr < iyr1 )
then
476 icy = icy1 - iyr1 + 1
477 lab_dowhile1 :
do while ( iyr < iyr1 )
482 print *,
' *** Year',iyear,
' out of table range!', &
484 print *,
' Using the closest-cycle year (',iyr,
')'
486 elseif ( iyr > iyr2 )
then
487 icy = iyr2 - icy2 + 1
488 lab_dowhile2 :
do while ( iyr > iyr2 )
493 print *,
' *** Year',iyear,
' out of table range!', &
495 print *,
' Using the closest-cycle year (',iyr,
')'
501 if ( isolflg < 4 )
then
503 lab_dowhile3 :
do while ( i >= iyr1 )
506 read (niradsf,*) jyr, solc1
508 if ( i == iyr .and. iyr == jyr )
then
509 solc0 = smean + solc1
512 print *,
' CHECK: Solar constant data used for year',&
521 elseif ( isolflg == 4 )
then
523 lab_dowhile4 :
do while ( i >= iyr1 )
526 read (niradsf,*) jyr, smon(1:12)
528 if ( i == iyr .and. iyr == jyr )
then
532 solc0 = smean + smon(imon)
535 print *,
' CHECK: Solar constant data used for year',&
536 & iyr,
' and month',imon
554 jd1 = iw3jdn(iyear,imon,iday)
561 fjd1= 0.5 + float(ihr)*hrday + float(imin)*minday &
562 & + float(isec)*secday
564 fjd1= float(ihr - 12)*hrday + float(imin)*minday &
565 & + float(isec)*secday
582 solcon = solc0 / (r1*r1)
595 & ( jd, fjd, dlt, alp, r1, solcon )
602 nswr = nint(deltsw / deltim)
603 dtswh = deltsw / f3600
605 if ( deltsw >= f3600 )
then
606 nn = max(6, min(12, nint(f3600/deltim) ))
607 nstp = nint(dtswh) * nn + 1
609 nstp = max(2, min(20, nswr)) + 1
616 print *,
' for cosz calculations: nswr,deltim,deltsw,dtswh =', &
617 & nswr,deltim,deltsw,dtswh,
' anginc,nstp =',
anginc,
nstp
665 real (kind=kind_phys),
intent(in) :: fjd
666 integer,
intent(in) :: jd
669 real (kind=kind_phys),
intent(out) :: r1, dlt, alp
672 real (kind=kind_phys),
parameter :: cyear = 365.25
673 real (kind=kind_phys),
parameter :: ccr = 1.3e-6
674 real (kind=kind_phys),
parameter :: tpp = 1.55
676 real (kind=kind_phys),
parameter :: svt6 = 78.035
678 integer,
parameter :: jdor = 2415020
681 real (kind=kind_phys) :: dat, t1, year, tyear, ec, angin, ador, &
682 & deleqn, sni, tini, er, qq, e1, ep, cd, eq, date, em, &
685 integer :: jdoe, iter
691 t1 = float(jd - jdor) / 36525.0
695 year = 0.25964134e0 + 0.304e-5 * t1
696 tyear= 0.24219879e0 - 0.614e-5 * t1
700 ec = 0.01675104e0 - (0.418e-4 + 0.126e-6 * t1) * t1
701 angin= 23.452294e0 - (0.0130125e0 + 0.164e-5 * t1) * t1
704 jdoe = ador + (svt6 * cyear) / (year - tyear)
708 deleqn= float(jdoe - jd) * (year - tyear) / cyear
710 sni = sin( angin / degrad )
711 tini = 1.0 / tan( angin / degrad )
712 er = sqrt( (1.0 + ec) / (1.0 - ec) )
713 qq = deleqn * tpi / year
721 lab_do_1 :
do while ( cd > ccr )
723 ep = e1 - (e1 - ec*sin(e1) - qq) / (1.0 - ec*cos(e1))
729 write(6,*)
' ITERATION COUNT FOR LOOP 32 =', iter
730 write(6,*)
' E, EP, CD =', e1, ep, cd
736 eq = 2.0 * atan( er * tan( 0.5*e1 ) )
740 dat = float(jd - jdor) - tpp + fjd
741 date = mod(dat, year)
745 em = tpi * date / year
750 lab_do_2 :
do while ( cr > ccr )
752 ep = e1 - (e1 - ec*sin(e1) - em) / (1.0 - ec*cos(e1))
758 write(6,*)
' ITERATION COUNT FOR LOOP 31 =', iter
764 w1 = 2.0 * atan( er * tan( 0.5*e1 ) )
766 r1 = 1.0 - ec*cos(e1)
768 sindec = sni * sin(w1 - eq)
772 alp = asin( tan(dlt)*tini )
775 if (tst < 0.0) alp =
con_pi - alp
776 if (alp < 0.0) alp = alp + tpi
778 sun = tpi * (date - deleqn) / year
779 if (sun < 0.0) sun = sun + tpi
780 sollag = sun - alp - 0.03255e0
802 & ( xlon,sinlat,coslat,solhr, im, me, &
839 integer,
intent(in) :: IM, me
841 real (kind=kind_phys),
intent(in) :: sinlat(:), coslat(:), &
845 real (kind=kind_phys),
intent(out) :: coszen(:), coszdg(:)
848 real (kind=kind_phys) :: coszn, cns, ss, cc, solang, rstp
850 integer :: istsun(im), i, it, j, lat
854 solang = pid12 * (solhr - f12)
855 rstp = 1.0 / float(
nstp)
869 coszn = ss + cc * cos(cns + xlon(i))
870 coszen(i) = coszen(i) + max(0.0, coszn)
871 if (coszn > czlimt) istsun(i) = istsun(i) + 1
878 coszdg(i) = coszen(i) * rstp
879 if (istsun(i) > 0) coszen(i) = coszen(i) / istsun(i)
892 & ( jd, fjd, dlt, alp, r1, solc &
921 integer,
intent(in) :: jd
923 real (kind=kind_phys),
intent(in) :: fjd, dlt, alp, r1, solc
928 real (kind=kind_phys),
parameter :: sixty = 60.0
930 character(LEN=1),
parameter :: sign =
'-'
931 character(LEN=1),
parameter :: sigb =
' '
933 character(LEN=1) :: dsig
934 character(LEN=4) :: month(12)
936 data month /
'JAN.',
'FEB.',
'MAR.',
'APR.',
'MAY ',
'JUNE', &
937 &
'JULY',
'AUG.',
'SEP.',
'OCT.',
'NOV ',
'DEC.' /
939 integer :: iday, imon, iyear, ihr, ltd, ltm, &
940 & ihalp, iyy, jda, mfjd, idaywk, idayyr
941 real (kind=kind_phys) :: xmin, dltd, dltm, dlts, halp, ymin, &
950 mfjd= nint( fjd*1440.0 )
952 xmin= float(mfjd) - (ihr + 12)*sixty
955 mfjd= nint( fjd*1440.0 )
957 xmin= float(mfjd) - (ihr - 12)*sixty
962 call w3fs26(jda, iyear,imon,iday, idaywk,idayyr)
968 dltm = sixty * (abs(dltd) - abs(float(ltd)))
970 dlts = sixty * (dltm - float(ltm))
972 if ((dltd < 0.0) .and. (ltd == 0.0))
then
978 halp = 6.0 * alp / hpi
980 ymin = abs(halp - float(ihalp)) * sixty
982 asec = (ymin - float(iyy)) * sixty
987 print 101, iday, month(imon), iyear, ihr, xmin, jd, fjd
988 101
format(
'0 FORECAST DATE',9x,i3,a5,i6,
' AT',i3,
' HRS',f6.2,
' MINS'/&
989 &
' JULIAN DAY',12x,i8,2x,
'PLUS',f11.6)
991 print 102, r1, halp, ihalp, iyy, asec
992 102
format(
' RADIUS VECTOR',9x,f10.7/
' RIGHT ASCENSION OF SUN', &
993 & f12.7,
' HRS, OR',i4,
' HRS',i4,
' MINS',f6.1,
' SECS')
995 print 103, dltd, dsig, ltd, ltm, dlts, eqt, eqsec,
sollag, solc
996 103
format(
' DECLINATION OF THE SUN',f12.7,
' DEGS, OR ',a1,i3, &
997 &
' DEGS',i4,
' MINS',f6.1,
' SECS'/
' EQUATION OF TIME',6x, &
998 & f12.7,
' MINS, OR',f10.2,
' SECS, OR',f9.6,
' RADIANS'/ &
999 &
' SOLAR CONSTANT',8x,f12.7,
' (DISTANCE AJUSTED)'//)
1009 end module module_radiation_astronomy
real(kind=kind_phys), parameter con_pi
pi
integer iyr_sav
saved year of data used
real(kind=kind_phys) anginc
solar angle increment per interation of cosz calc
real(kind=kind_phys), parameter con_solr
solar constant ( )-nasa-sorce Tim(2008)
integer nstp
total number of zenith angle iterations
real(kind=kind_phys) sollag
equation of time
subroutine, public coszmn(xlon, sinlat, coslat, solhr, IM, me, coszen, coszdg )
This subroutine computes mean cos solar zenith angle over SW calling interval.
subroutine solar(jd, fjd, r1, dlt, alp )
This subroutine computes radius vector, declination and right ascension of sun, and equation of time...
real(kind=kind_phys) cosdec
cosine of the solar declination angle
real(kind=kind_phys) sindec
sine of the solar declination angle
subroutine, public sol_init(me)
This subroutine initializes astronomy process, and set up module constants.
integer, save isolar
solar constant scheme control flag =0:fixed value=1366.0 (old standard) =10:fixed value=1360...
real(kind=kind_phys), dimension(12) smon_sav
saved monthly solar constants (isolflg=4 only)
subroutine prtime(jd, fjd, dlt, alp, r1, solc )
This subroutine prints out forecast date, time, and astronomy quantities.
subroutine, public sol_update(jdate, kyear, deltsw, deltim, lsol_chg, me, slag, sdec, cdec, solcon )
This subroutine computes solar parameters at forecast time.
real(kind=kind_phys), parameter con_solr_old
solar constant ( )-liu(2002)
character, save solar_file
external solar constant data table,solarconstant_noaa_a0.txt