! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE RADIATION ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE radiation(nx,ny,nz,rbufsz, & 2,3 ptprt,pprt,qv,qc,qr,qi,qs,qh, & ptbar,pbar,ppi,rhostr, & x,y,z,zp,j3inv, & soiltyp, tsfc, wetsfc,snowdpth, & radfrc, radsw, rnflx, & rsirbm,rsirdf,rsuvbm,rsuvdf, & cosz, cosss, & fdirir,fdifir,fdirpar,fdifpar, & tem1, tem2, tem3, tem4, tem5, & tem6, tem7, tem8, tem9, tem10, & tem11,tem12,tem13,tem14,tem15,tem16, & radbuf) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! This subroutine is the main driver of ARPS radiation package. To ! control the driver, the parameters and variables should be set: ! ! Input control variables (in namelist &radiation, arps.input) ! ! radopt Option to switch on/off radiation physics ! = 0, No radiation physics; ! = 1, Simplified surface radiation physics; ! = 2, Atmospheric radiation transfer parameterization. ! ! Notes: When sfcphy is chosen to 3 or 4, radopt=0 will be adjusted ! to 1 in order to compute the surface energy balance for ! soil model. However radopt=2 will not be changed. ! ! radstgr Option for radiation computing at staggering points ! = 0, No staggering; Radiation calculation on x-y plane is at ! all points; ! = 1, staggering; Radiation calculation on x-y plane is at ! (even,even) and (odd,odd) points. The values at ! (even,odd) (odd,even) points are averaged from the ! surrounding four points. For example for nx=ny=9, the ! directly calculation are performed at the "x" points, ! then calculate radiation variables at "o" by averaging ! from their surrounding "x" points. This scheme can ! reduce ALMOST HALF of radiation calculation. ! ! ! j ! ! 9 | x o x o x o x o x ! 8 | o x o x o x o x o ! 7 | x o x o x o x o x ! 6 | o x o x o x o x o ! 5 | x o x o x o x o x ! 4 | o x o x o x o x o ! 3 | x o x o x o x o x ! 2 | o x o x o x o x o ! 1 | x o x o x o x o x ! +------------------- i ! 1 2 3 4 5 6 7 8 9 ! ! On boundary, the zero-gradient is assumed. ! ! rlwopt Option to choose the longwave schemes. ! = 0, high = .false. in code, transmission functions are ! computed using the k-distribution method with linear ! pressure scaling. cooling rates are not calculated ! accurately for pressures less than 20 mb. The ! computation is faster with high=.false. than with ! high=.true. ! = 1, high = .true. in code, transmission functions in the ! co2, o3 in the co2, o3, and the three water vapor bands ! with strong absorption are computed using table look-up. ! cooling rates are computed accurately from the surface ! up to 0.01 mb. ! ! dtrad Time interval (seconds) to update the radiation forcing ! ! raddiag Option to dump radiation variables to a file in GrADS ! format for diagnostic review. The frequency is ! controled by dtrad. (Effective when radopt=2) ! = 0, no such dump ! = 1, dump to a file with a name like 'runname.radout' ! and its control file has a name like 'runname.radctl' ! !----------------------------------------------------------------------- ! ! AUTHOR: Yuhe Liu ! 03/11/1996 ! ! MODIFICATION HISTORY: ! ! 4/13/98 (D.Weber and V. Wong) ! Added precipitable water term in the radopt=1 air emissivity ! coefficient. ! ! 11/18/98 (Keith Brewster) ! Changed pibar to ppi (full pi). ! ! 12/8/1998 (Donghai Wang and Vince Wong) ! Added a new 2-D permanent array, snowcvr(nx,ny), for snow cover. ! We just used a simple scheme to consider the snow cover process. ! ! 2000/01/10 (Gene Bassett) ! Snow cover (0 or 1) changed to a fractional value (0 to 1) ! determined from snow depth. ! !----------------------------------------------------------------------- ! IMPLICIT NONE INTEGER :: nx,ny,nz INTEGER :: rbufsz ! !----------------------------------------------------------------------- ! ! Define ARPS variables ! !----------------------------------------------------------------------- ! REAL :: ptprt (nx,ny,nz) REAL :: pprt (nx,ny,nz) REAL :: qv (nx,ny,nz) REAL :: qc (nx,ny,nz) REAL :: qr (nx,ny,nz) REAL :: qi (nx,ny,nz) REAL :: qs (nx,ny,nz) REAL :: qh (nx,ny,nz) REAL :: ptbar (nx,ny,nz) REAL :: pbar (nx,ny,nz) REAL :: ppi (nx,ny,nz) REAL :: rhostr(nx,ny,nz) REAL :: x (nx) REAL :: y (ny) REAL :: z (nz) REAL :: zp (nx,ny,nz) ! The physical height coordinate defined at ! w-point of staggered grid. REAL :: j3inv (nx,ny,nz) INTEGER :: soiltyp(nx,ny) ! Soil type at each point REAL :: tsfc (nx,ny) REAL :: wetsfc (nx,ny) ! Surface soil moisture in the top 1 cm layer REAL :: snowdpth(nx,ny) ! Snow depth (m) REAL :: radfrc(nx,ny,nz) ! Radiation forcing (K/s) REAL :: radsw (nx,ny) ! Solar radiation down to the surface REAL :: rnflx (nx,ny) ! Net radiation flux absorbed by surface REAL :: rsirbm(nx,ny) ! Solar IR surface albedo for beam radiation REAL :: rsirdf(nx,ny) ! Solar IR surface albedo for diffuse radiation REAL :: rsuvbm(nx,ny) ! Solar UV surface albedo for beam radiation REAL :: rsuvdf(nx,ny) ! Solar UV surface albedo for diffuse radiation REAL :: cosz (nx,ny) ! Cosine of zenith REAL :: cosss (nx,ny) ! Cosine of angle between sun light and ! surface terrain slope REAL :: fdirir (nx,ny) ! all-sky direct downward IR flux ! (0.7-10 micron) at the surface REAL :: fdifir (nx,ny) ! all-sky diffuse downward IR flux ! at the surface REAL :: fdirpar(nx,ny) ! all-sky direct downward par flux ! (0.4-0.7 micron) at the surface REAL :: fdifpar(nx,ny) ! all-sky diffuse downward par flux ! at the surface REAL :: radbuf(rbufsz) ! temporary arrays used for radiation ! transfer computing ! !----------------------------------------------------------------------- ! ! Temporary arrays which have the vertical coordinate inversed, that ! is, k=1 is for top while k=nz is at the surface. ! !----------------------------------------------------------------------- ! REAL :: tem1 (nx,ny,nz) ! pinv, slpmag, slpdir REAL :: tem2 (nx,ny,nz) ! tinv REAL :: tem3 (nx,ny,nz) ! qvinv REAL :: tem4 (nx,ny,nz) ! o3a REAL :: tem5 (nx,ny,nz) ! ccld REAL :: tem6 (nx,ny,nz) ! flxir REAL :: tem7 (nx,ny,nz) ! flcir REAL :: tem8 (nx,ny,nz) ! flxuv REAL :: tem9 (nx,ny,nz) ! flcuv REAL :: tem10(nx,ny,nz) ! dfdts REAL :: tem11(nx,ny,nz) ! tauir REAL :: tem12(nx,ny,nz) ! taual REAL :: tem13(nx,ny,nz) ! tauswi REAL :: tem14(nx,ny,nz) ! tauswl REAL :: tem15(nx,ny,nz) ! reffi REAL :: tem16(nx,ny,nz) ! reffl ! !----------------------------------------------------------------------- ! ! Include files: ! !----------------------------------------------------------------------- ! INCLUDE 'globcst.inc' INCLUDE 'phycst.inc' INCLUDE 'radcst.inc' INCLUDE 'soilcst.inc' ! !----------------------------------------------------------------------- ! ! Local variables ! !----------------------------------------------------------------------- ! INTEGER :: i,j,k REAL :: albedo, albedoz REAL :: tema,temb REAL :: rad2deg REAL :: frac_snowcover ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! IF ( radopt == 1 .AND. ( sfcphy /= 3 .AND. sfcphy /= 4 ) ) THEN RETURN END IF ! !----------------------------------------------------------------------- ! ! Calculate solar zenith angle. Array radsw is used as a2dr2 ! temporarily. ! ! zp(*,*,2) = surface terrain ! cosz = cosine of zenith ! cosss = cosine of angle between sun light and terrain slope ! ! radsw = a2dr2, square ratio of average distance to the time ! dependent distance from the earth to the sun ! ! Array tem1 and tem2 are used as temporary 2-D arrays ! ! tem1(*,*,1) = rjday ! tem1(*,*,2) = tloc ! tem1(*,*,3) = latscl ! tem1(*,*,4) = lonscl ! ! tem2(*,*,1) = slpmag ! tem2(*,*,2) = slpdir ! tem2(*,*,3) = tem1(*,*) ! tem2(*,*,4) = tem2(*,*) ! !----------------------------------------------------------------------- ! CALL zenangl( nx,ny, x,y, zp(1,1,2), cosz, cosss, radsw, & tem1(1,1,1),tem1(1,1,2),tem1(1,1,3),tem1(1,1,4), & tem2(1,1,1),tem2(1,1,2),tem2(1,1,3),tem2(1,1,4) ) ! !----------------------------------------------------------------------- ! ! Calculate surface albedo which is dependent on solar zenith angle ! and soil moisture. Set the albedo for different types of solar ! flux to be same. ! ! rsirbm Solar IR surface albedo for beam radiation ! rsirdf Solar IR surface albedo for diffuse radiation ! rsuvbm Solar UV surface albedo for beam radiation ! rsuvdf Solar UV surface albedo for diffuse radiation ! !----------------------------------------------------------------------- ! rad2deg = 180.0/3.141592654 DO j=1,ny-1 DO i=1,nx-1 albedoz = 0.01 * ( EXP( 0.003286 & ! zenith dependent albedo * SQRT( ( ACOS(cosz(i,j))*rad2deg ) ** 3 ) ) - 1.0 ) IF ( sfcphy == 0 ) THEN ! soil type not defined tema = 0 ELSE tema = wetsfc(i,j)/wsat(soiltyp(i,j)) END IF frac_snowcover = MIN(snowdpth(i,j)/snowdepth_crit, 1.0) IF ( tema > 0.5 ) THEN albedo = albedoz + (1.-frac_snowcover)*0.14 & + frac_snowcover*snow_albedo ELSE albedo = albedoz + (1.-frac_snowcover)*(0.31 - 0.34 * tema) & + frac_snowcover*snow_albedo END IF rsirbm(i,j) = albedo rsirdf(i,j) = albedo rsuvbm(i,j) = albedo rsuvdf(i,j) = albedo END DO END DO IF ( radopt == 1 ) THEN DO k=1,nz-1 DO j=1,ny-1 DO i=1,nx-1 tem2(i,j,k) = (ptbar(i,j,k)+ptprt(i,j,k))*ppi(i,j,k) tem3(i,j,k) = pbar(i,j,k) + pprt(i,j,k) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Calculate solar radiation at the surface using a simplified ! scheme. ! ! tem1(*,*,1) = prcpln, precipitation path length ! ! tem2 = temperature ! tem3 = total pressure ! ! fdirir = fraction of solar radiation reaching the surface ! ! Note: added precipitable water contribution to the emissa term ! for radopt=1. ! !----------------------------------------------------------------------- ! CALL solrsfc( nx,ny,nz, & tem2, tem3, qv, cosz, tem1(1,1,1), fdirir ) DO j=1,ny-1 DO i=1,nx-1 tema = 0.5 * ( tem2(i,j,1) + tem2(i,j,2) ) ! surface air temp. ! ! new code to include the water part of the downward emissa ! coefficient.... ! temb = 0.0 DO k = 2,nz-2 temb = temb+rhostr(i,j,k)*qv(i,j,k)*(zp(i,j,k+1)-zp(i,j,k)) END DO temb = 0.17*ALOG10(temb*0.1) temb = MIN(1.0,temb+emissa) ! end of new code for emissa.. radsw(i,j) = solarc * radsw(i,j) * cosss(i,j) * fdirir(i,j) rnflx(i,j) = radsw(i,j) * (1.0-rsirbm(i,j)) & + temb * sbcst * tema**4 & - emissg * sbcst * tsfc(i,j)**4 END DO END DO ELSE IF ( radopt == 2 ) THEN ! !----------------------------------------------------------------------- ! ! Compute the atmospheric radiation forcing ! ! Temporary arrays are used for ! ! tem1 = pinv, Pressure in mb at scalar points ! tem2 = tinv, Temperature ! tem3 = qvinv, Water vapor mixing ratio (g/g) ! tem4 = o3a, Ozone (o3) mixing ratio (g/g) ! tem5 = ccld, Cloud coverage (fraction) ! tem6 = flxir, all-sky net downward LW flux ! tem7 = flcir, clear-sky net downward LW flux ! tem8 = flxuv, all-sky solar flux (downward minus upward) ! tem9 = flcuv, clear-sky solar flux (downward minus upward) ! tem10 = dfdts, Sensitivity of net downward flux to surface temperature ! tem11 = tauir, Cloud optical depth for LW IR ! tem12 = taual, Aerosol optical thickness ! tem13 = tauswi, Cloud optical depth for solar IR for ice particles ! tem14 = tauswl, Cloud optical depth for solar IR for liquid particles ! tem15 = reffi, Effective cloud-particle size for ice particles ! tem16 = reffl, Effective cloud-particle size for liquid particles ! ! cosss = cosine of angle between sun light and terrain slope ! ! radsw = a2dr2, input, square ratio of average distance to the ! time dependent distance from the earth to ! the sun ! = radsw, output, solar radiation reaching the surface ! rnflx = st4, temporary, longwave upward flux at surface ! = rnflx, output, net radiation flux absorbed by surface ! !----------------------------------------------------------------------- ! CALL radtrns(nx,ny,nz, rbufsz, & ptprt,pprt,qv,qc,qr,qi,qs,qh, & ptbar,pbar,ppi,rhostr, tsfc, & x,y,z,zp, j3inv, & radfrc, radsw,rnflx, cosss, & rsirbm,rsirdf,rsuvbm,rsuvdf, cosz, & fdirir,fdifir,fdirpar,fdifpar, rnflx, & tem1, tem2, tem3, tem4, tem5, & tem6, tem7, tem8, tem9, tem10, & tem11,tem12,tem13,tem14,tem15,tem16, & radbuf) END IF RETURN END SUBROUTINE radiation ! ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE SOLRSFC ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE solrsfc(nx,ny,nz, & 1 temp, pres, qv, cosz, prcpln, trsw ) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Calculate the atmosphere transmittance for solar radiation ! !----------------------------------------------------------------------- ! ! AUTHOR: Yuhe Liu ! 03/25/1996 ! !----------------------------------------------------------------------- ! IMPLICIT NONE INTEGER :: nx,ny,nz ! !----------------------------------------------------------------------- ! ! Define ARPS variables ! !----------------------------------------------------------------------- ! REAL :: temp (nx,ny,nz) ! temperature REAL :: pres (nx,ny,nz) ! total pressure REAL :: qv (nx,ny,nz) ! Mixing ratio REAL :: cosz (nx,ny) REAL :: prcpln(nx,ny) ! Precipitation path length REAL :: trsw (nx,ny) ! !----------------------------------------------------------------------- ! ! Include files: ! !----------------------------------------------------------------------- ! INCLUDE 'globcst.inc' INCLUDE 'phycst.inc' INCLUDE 'soilcst.inc' ! !----------------------------------------------------------------------- ! ! Local variables ! !----------------------------------------------------------------------- ! INTEGER :: i,j,k REAL :: dirf REAL :: trrg REAL :: trwv ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! !----------------------------------------------------------------------- ! ! Calculate the precipitation path length by a vertical integral if ! moist > 0. ! !----------------------------------------------------------------------- ! DO j = 1, ny-1 DO i = 1, nx-1 prcpln(i,j) = 0.0 END DO END DO IF ( moist /= 0 ) THEN DO j = 1, ny-1 DO i = 1, nx-1 prcpln(i,j) = 0.0 DO k = 2, nz-2 prcpln(i,j) = prcpln(i,j) & + 0.5*(qv(i,j,k)+qv(i,j,k+1)) & * 0.5*(pres(i,j,k)+pres(i,j,k+1))/101300.0 & * SQRT(2.*273.16/(temp(i,j,k)+temp(i,j,k+1))) & * (pres(i,j,k)-pres(i,j,k+1)) END DO prcpln(i,j) = prcpln(i,j) / g END DO END DO END IF DO j = 1, ny-1 DO i = 1, nx-1 ! !----------------------------------------------------------------------- ! ! Calculate the direction fractor of transmisivity ! !----------------------------------------------------------------------- ! dirf = 35.0 / SQRT( 1224.0 * cosz(i,j)**2 + 1.0 ) ! !----------------------------------------------------------------------- ! ! Calculate Rayleigh sccattering and absorption transmisivity, trrg. ! !----------------------------------------------------------------------- ! trrg = 1.021 - 0.084 * SQRT( dirf & * ( 949. * 0.5*(pres(i,j,2)+pres(i,j,1)) & * 1.e-8 + .051 ) ) ! Rayleigh scatt. and abs. transmission ! AB, Eq. 2, psfc in Pascal ! !----------------------------------------------------------------------- ! ! Calculate the transmisivity of water vapor, trwv. The ! precipitation path length used in the calculation has been ! calculated and stored in prcpln(i,j). ! ! For cloud cover, use constant dirfc = 5/3 as the direction ! fractor. (How to determine if cloudy or not?) ! ! For clear sky, use dirf as the direction fractor, instead of dirfc ! !----------------------------------------------------------------------- ! trwv = 1.0 - 2.9 * prcpln(i,j) * dirf & / ( 5.925 * prcpln(i,j) * dirf & + ( 1. + 141.5 * prcpln(i,j) * dirf ) ** 0.634 ) ! !----------------------------------------------------------------------- ! ! Calculate the fraction of solar radiation reaching the surface. ! !----------------------------------------------------------------------- ! trsw(i,j) = trrg * trwv END DO END DO RETURN END SUBROUTINE solrsfc ! ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE ZENANGL ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE zenangl(nx,ny, x,y, hterain, cosz, cosss, a2dr2, & 1,2 rjday,tloc, latscl,lonscl, slpmag,slpdir, & tem1,tem2) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Calculate cosine of solar zenith angle. ! !----------------------------------------------------------------------- ! ! AUTHOR: Yuhe Liu and Vince Wong ! 11/16/93 ! ! MODIFICATION HISTORY: ! 2/2/99 Vince Wong and Jik Leong ! This modification calculates the solar declination angle and ! equation of time using a method found on page C24 of the ! 1996 Astronomical Almanac. ! The mothod is good to 0.01 degrees in the sky over the ! period 1950 to 2050. ! !----------------------------------------------------------------------- ! ! INPUT: ! ! nx Number of grid points in the x-direction (east/west) ! ny Number of grid points in the y-direction (north/south) ! ! x X coordinates at scalar points ! y Y coordinates at scalar points ! hterain Surface terrain ! ! OUTPUT: ! ! cosz Cosine of zenith ! cosss Cosine of angle between sun light and terrain slope ! a2dr2 Square ratio of average distance to the time ! dependent distance from the earth to the sun ! ! WORK ARRAY: ! ! rjday Julian day at each grid point ! tloc Local time at each grid point ! latscl Latitudes at scalar points ! lonscl Longitudes at scalar points ! slpmag Surface terrain slope magnitude ! slpdir Surface terrain slope direction ! !----------------------------------------------------------------------- ! IMPLICIT NONE INTEGER :: nx,ny REAL :: x(nx) REAL :: y(ny) REAL :: hterain(nx,ny) REAL :: cosz(nx,ny), cosss(nx,ny), a2dr2(nx,ny) REAL :: rjday(nx,ny), tloc(nx,ny) REAL :: latscl(nx,ny), lonscl(nx,ny) REAL :: slpmag(nx,ny), slpdir(nx,ny) REAL :: tem1(nx,ny), tem2(nx,ny) ! !----------------------------------------------------------------------- ! ! Include file: ! !----------------------------------------------------------------------- ! INCLUDE 'globcst.inc' INCLUDE 'grid.inc' ! Grid & map parameters. INCLUDE 'phycst.inc' ! !----------------------------------------------------------------------- ! ! Local variables: ! !----------------------------------------------------------------------- ! INTEGER :: i,j REAL :: xs, ys REAL :: hour0, yrday REAL :: deg2rad, pi, pi2 REAL :: etau, shrangl, sdeclin REAL :: azimuth, sinz REAL :: dpsi, sinpsi, cospsi REAL :: anncyc REAL :: hr, days2k, lsun, gsun, obliq, lambda, xsun, ysun REAL :: asun, alpha, rad2deg LOGICAL :: firstcall ! First call flag of this subroutine SAVE firstcall, hour0, pi, pi2, deg2rad, yrday, rad2deg DATA firstcall/.true./ ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! IF (firstcall) THEN pi = 3.14159265358979 pi2 = 2.0 * pi deg2rad = pi/180.0 rad2deg = 1./deg2rad hour0 = FLOAT(hour) & + FLOAT(minute)/60.0 & + FLOAT(second)/3600.0 IF ( MOD(year, 4) == 0 ) THEN yrday = 366. ELSE yrday = 365. END IF firstcall = .false. END IF CALL sfcslp( nx,ny, hterain, slpmag,slpdir, tem1,tem2 ) IF ( mapproj == 0 ) THEN DO j=1,ny-1 DO i=1,nx-1 latscl(i,j) = ctrlat lonscl(i,j) = ctrlon END DO END DO ELSE DO j=1,ny-1 ys = 0.5*(y(j)+y(j+1)) DO i=1,nx-1 xs = 0.5*(x(i)+x(i+1)) CALL xytoll(1,1, xs,ys, latscl(i,j), lonscl(i,j)) END DO END DO END IF ! !----------------------------------------------------------------------- ! ! Calculate the local time at each grid point. The ! following formula is based on that the input time is the GMT ! time at the reference grid point of the center. ! !----------------------------------------------------------------------- ! DO j=1,ny-1 DO i=1,nx-1 latscl(i,j) = deg2rad * latscl(i,j) ! lat: -90 to 90 tloc(i,j) = hour0 + (curtim-dtbig)/3600.0 & + lonscl(i,j)/15.0 rjday(i,j) = jday + INT( tloc(i,j)/24.0 ) tloc(i,j) = MOD( tloc(i,j), 24.0 ) IF ( tloc(i,j) < 0. ) THEN tloc(i,j) = tloc(i,j) + 24.0 ! Local time rjday(i,j) = MOD( rjday(i,j)-1, yrday ) ! Julian day at each pts END IF END DO END DO DO j=1,ny-1 DO i=1,nx-1 anncyc = pi2 * ( rjday(i,j) - 1.0 ) / yrday a2dr2(i,j) = 1.000110 & + 0.034221 * COS(anncyc) & + 0.00128 * SIN(anncyc) & + 0.000719 * COS(2.*anncyc) & + 0.000077 * SIN(2.*anncyc) ! PX, Eq. 17 hr = hour + minute / 60. ! days before (-ve) or after (+ve) 1/1/2000 days2k = 367 * year - 7 * ( year + ( month + 9 ) / 12 ) / 4 & + 275 * month / 9 + day - 730531.5 + hr / 24. lsun = 280.461 + 0.9856474 * days2k ! Mean Longitude of the Sun 950 IF ( lsun < 0 ) THEN lsun = lsun + 360. GO TO 950 ELSE IF ( lsun > 360 ) THEN lsun = lsun - 360. GO TO 950 END IF gsun = 357.528 + 0.9856003 * days2k ! Mean anomaly of the Sun 960 IF ( gsun < 0 ) THEN gsun = gsun + 360. GO TO 960 ELSE IF ( gsun > 360 ) THEN gsun = gsun - 360. GO TO 960 END IF lambda = lsun + 1.915 * SIN(gsun*deg2rad) & ! Ecliptic longitude + 0.02 * SIN(2*gsun*deg2rad) 970 IF ( lambda < 0 ) THEN lambda = lambda + 360. GO TO 970 ELSE IF ( lambda > 360 ) THEN lambda = lambda - 360. GO TO 970 END IF obliq = 23.439 - 0.0000004 * days2k ! Obliquity of the ecliptic xsun = COS(lambda*deg2rad) ysun = COS(obliq*deg2rad) * SIN(lambda*deg2rad) asun = ATAN(ysun/xsun)*rad2deg IF ( xsun < 0. ) THEN alpha = asun + 180 ! Right Ascension (RA) ELSE IF ( ( ysun < 0. ) .AND. ( xsun > 0. ) ) THEN alpha = asun + 360 ELSE alpha = asun END IF etau = ( lsun - alpha ) * 4. / 60. ! Equation of time in hour ! etau = 0.158 * sin( pi*(rjday(i,j)+10.)/91.25 ) ! Equation of time ! : + 0.125 * sin( pi*rjday(i,j)/182.5 ) ! Wong, Eq. 8 shrangl = 15.0 * deg2rad & ! Hour angle * ( tloc(i,j) + etau - 12.0) ! Wong, Eq. 7 ! sdeclin = 23.5 * deg2rad ! : * cos( 2.0*pi*(rjday(i,j)-173.)/yrday ) ! Wong, Eq. 6 sdeclin = ASIN(SIN(obliq*deg2rad)*SIN(lambda*deg2rad)) ! Declination (in radian) cosz(i,j) = COS(latscl(i,j)) * COS(sdeclin) * COS(shrangl) & + SIN(latscl(i,j)) * SIN(sdeclin) ! print *, cos(latscl(i,j)),cos(sdeclin),cos(shrangl) ! print *, sin(latscl(i,j)),sin(sdeclin) ! print *,sdeclin,shrangl sinz = SIN ( ACOS(cosz(i,j)) ) ! !----------------------------------------------------------------------- ! ! Consider the effects of the terrain slope on the solar radiation. ! The slope magnitude and direction has been computed by subroutine ! SFCSLP and passed in by slpmag and slpdir. ! !----------------------------------------------------------------------- ! sinpsi = COS(sdeclin) * SIN(shrangl) / sinz cospsi = ( cosz(i,j) * SIN( latscl(i,j) ) - SIN( sdeclin ) ) & / ( sinz * COS( latscl(i,j) ) ) azimuth = ATAN2( sinpsi, cospsi ) dpsi = azimuth - slpdir(i,j) cosss(i,j) = COS( slpmag(i,j) ) * cosz(i,j) & + SIN( slpmag(i,j) ) * sinz * COS( dpsi ) cosz (i,j) = MAX( cosz (i,j), 0.0 ) cosss(i,j) = MAX( cosss(i,j), 0.0 ) END DO END DO RETURN END SUBROUTINE zenangl ! ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE SFCSLP ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE sfcslp( nx,ny, hterain, slpmag,slpdir, tem1,tem2 ) 1,7 ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! This program is to compute the terrain slope vector in terms of ! magnitude and direction. ! ! Magnitude slpmag: ! ! 1 ! cos(slpmag) = -----------------------------------, 0 <= slpmag <= pi/2 ! sqrt( 1 + (dz/dx)**2 + (dz/dy)**2 ) ! ! Direction slpdir: ! ! dz/dx ! tan(slpdir) = -----, - pi <= slpdir <= pi ! dz/dy ! !----------------------------------------------------------------------- ! ! AUTHOR: Yuhe Liu and Vince Wong ! 2/16/94 ! ! MODIFICATION HISTORY: ! ! !----------------------------------------------------------------------- ! ! INPUT: ! ! nx Number of grid points in the x-direction (east/west) ! ny Number of grid points in the y-direction (north/south) ! ! hterain The heights of terrain ! ! OUTPUT: ! ! slpmag Magnitude of terrain surface slope vector ! slpdir Direction of terrain surface slope vector from north ! clockwise ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! INTEGER :: nx,ny REAL :: hterain(nx,ny) ! The heights of terrain REAL :: slpmag (nx,ny) ! Terrain surface slope vector magnitude REAL :: slpdir (nx,ny) ! Terrain surface slope vector direction ! from north clockwise REAL :: tem1(nx,ny) ! 2-D temporary array REAL :: tem2(nx,ny) ! 2-D temporary array ! !----------------------------------------------------------------------- ! ! Local declarations ! !----------------------------------------------------------------------- ! REAL :: pi PARAMETER ( pi = 3.141592654) REAL :: twdxinv, twdyinv, dzsds2 INTEGER :: i, j INTEGER :: mptag1,mptag2 ! !----------------------------------------------------------------------- ! ! Include files: ! !----------------------------------------------------------------------- ! INCLUDE 'globcst.inc' INCLUDE 'grid.inc' ! Grid & map parameters. INCLUDE 'bndry.inc' INCLUDE 'mp.inc' ! Message passing parameters. ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! IF ( ternopt == 0 ) THEN DO j = 1, ny-1 DO i = 1, nx-1 slpmag(i,j) = 0. slpdir(i,j) = 0. END DO END DO ELSE ! !----------------------------------------------------------------------- ! ! dz dz ! Use the central difference to calculate ---- and ----. ! dx dy ! !----------------------------------------------------------------------- ! twdxinv = 1.0 / (2.0*dx) DO j = 1, ny-1 DO i = 2, nx-2 tem1(i,j) = ( hterain(i+1,j) - hterain(i-1,j) ) * twdxinv END DO END DO twdyinv = 1.0 / (2.0*dy) DO j = 2, ny-2 DO i = 1, nx-1 tem2(i,j) = ( hterain(i,j+1) - hterain(i,j-1) ) * twdyinv END DO END DO !call test_dump (tem1,"XXXradfrc_tem1",nx,ny,1,0,0) !call test_dump (tem2,"XXXradfrc_tem2",nx,ny,1,0,0) IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend1dew(tem1,nx,ny,ebc,wbc,0,mptag1,slpmag) ! use slpmag as temp CALL mpsend1dns(tem2,nx,ny,nbc,sbc,0,mptag2,slpmag) ! use slpmag as temp CALL mprecv1dew(tem1,nx,ny,ebc,wbc,0,mptag1,slpmag) ! use slpmag as temp CALL mprecv1dns(tem2,nx,ny,nbc,sbc,0,mptag2,slpmag) ! use slpmag as temp END IF CALL acct_interrupt(bc_acct) IF ( wbc == 1 ) THEN DO j = 1,ny-1 tem1(1,j) = - tem1(2,j) END DO ELSE IF ( wbc == 2 ) THEN IF (mp_opt == 0) THEN DO j = 1,ny-1 tem1(1,j) = tem1(nx-2,j) END DO END IF ELSE IF ( wbc /= 0 ) THEN DO j = 1, ny-1 tem1(1,j) = ( hterain(2,j) - hterain(1,j) ) / dx END DO END IF IF ( ebc == 1 ) THEN DO j = 1, ny-1 tem1(nx-1,j) = - tem1(nx-2,j) END DO ELSE IF ( ebc == 2 ) THEN IF (mp_opt == 0) THEN DO j = 1,ny-1 tem1(nx-1,j) = tem1(2,j) END DO END IF ELSE IF ( ebc /= 0 ) THEN DO j = 1, ny-1 tem1(nx-1,j) = ( hterain(nx-1,j) - hterain(nx-2,j) ) / dx END DO END IF IF ( sbc == 1 ) THEN DO i = 1, nx-1 tem2(i,1) = - tem2(i,2) END DO ELSE IF ( sbc == 2 ) THEN IF (mp_opt == 0) THEN DO i = 1, nx-1 tem2(i,1) = tem2(i,ny-2) END DO END IF ELSE IF ( sbc /= 0 ) THEN DO i = 1, nx-1 tem2(i,1) = ( hterain(i,2) - hterain(i,1) ) / dy END DO END IF IF ( nbc == 1 ) THEN DO i = 1, nx-1 tem2(i,ny-1) = - tem2(i,ny-2) END DO ELSE IF ( nbc == 2 ) THEN IF (mp_opt == 0) THEN DO i = 1, nx-1 tem2(i,ny-1) = tem2(i,2) END DO END IF ELSE IF ( nbc /= 0 ) THEN DO i = 1, nx-1 tem2(i,ny-1) = ( hterain(i,ny-1) - hterain(i,ny-2) ) / dy END DO END IF !call test_dump (tem1,"XXXAradfrc_tem1",nx,ny,1,0,1) !call test_dump (tem2,"XXXAradfrc_tem2",nx,ny,1,0,1) CALL acct_stop_inter DO j = 1, ny-1 DO i = 1, nx-1 dzsds2 = tem1(i,j)**2 + tem2(i,j)**2 slpmag(i,j) = ACOS( 1. / SQRT( 1. + dzsds2 ) ) IF ( dzsds2 == 0. ) THEN slpdir(i,j) = 0. ELSE slpdir(i,j) = ATAN2( tem1(i,j), tem2(i,j) ) END IF END DO END DO END IF RETURN END SUBROUTINE sfcslp