14#include "scaleFElib.h"
25 use scale_const,
only: &
26 undef => const_undef, &
47 private :: annual_mean_insol
48 private :: daily_mean_insol
49 private :: days_in_month
50 private :: is_leap_year
51 private :: seconds_to_hms
57 integer :: SOLARINS_TYPE_ID
59 integer,
parameter :: SOLARINS_SIMPLE_TYPE_ID_CONST = 1
60 integer,
parameter :: SOLARINS_SIMPLE_TYPE_ID_ANNUAL_MEAN = 2
61 integer,
parameter :: SOLARINS_SIMPLE_TYPE_ID_FRIERSON2006 = 3
64 real(RP) :: CONST_FLUX = 340.0_rp
66 integer :: ORBIT_REFERENCE_YEAR = 2000
67 integer :: ANNUAL_MEAN_YEAR = 2000
68 integer :: ANNUAL_SAMPLES_PER_DAY = 1
69 logical :: CACHE_ANNUAL_MEAN = .true.
71 integer,
parameter :: DATE_YEAR = 1
72 integer,
parameter :: DATE_MONTH = 2
73 integer,
parameter :: DATE_DAY = 3
74 integer,
parameter :: DATE_HOUR = 4
75 integer,
parameter :: DATE_MINUTE = 5
76 integer,
parameter :: DATE_SECOND = 6
77 integer,
parameter :: DATE_SIZE = 6
80 real(RP) :: FRIERSON2006_DELTA_s = 1.4e0_rp
85 use scale_atmos_solarins,
only: &
88 character(len=H_SHORT) :: solarins_type =
'ANNUAL_MEAN'
89 namelist / param_atmos_solarins_simple / &
92 orbit_reference_year, &
94 annual_samples_per_day, &
102 log_info(
"ATMOS_PHY_RD_SOLARINS_SIMPLE_setup",*)
'Setup'
106 read(io_fid_conf,nml=param_atmos_solarins_simple,iostat=ierr)
108 log_info(
"ATMOS_PHY_RD_SOLARINS_SIMPLE_setup",*)
'Not found namelist. Default used.'
109 elseif( ierr > 0 )
then
110 log_error(
"ATMOS_PHY_RD_SOLARINS_SIMPLE_setup",*)
'Not appropriate names in namelist PARAM_ATMOS_SOLARINS_SIMPLE. Check!'
113 log_nml(param_atmos_solarins_simple)
115 select case (solarins_type)
117 solarins_type_id = solarins_simple_type_id_const
119 solarins_type_id = solarins_simple_type_id_annual_mean
120 case (
'FRIERSON2006')
121 solarins_type_id = solarins_simple_type_id_frierson2006
123 log_error(
"ATMOS_PHY_RD_SOLARINS_SIMPLE_setup",*)
'Not appropriate SOLARINS_TYPE. Check!'
129 call atmos_solarins_setup( 0.0_rp, 0.0_rp, orbit_reference_year )
142 use scale_atmos_solarins,
only: &
143 atmos_solarins_constant
145 integer,
intent(in) :: np
146 real(rp),
intent(out) :: solins(np)
147 real(rp),
intent(out) :: cossza(np)
148 real(rp),
intent(in) :: lat(np)
151 select case (solarins_type_id)
152 case (solarins_simple_type_id_const)
153 solins(:) = const_flux
155 case (solarins_simple_type_id_annual_mean)
156 call annual_mean_insol( solins, &
159 case (solarins_simple_type_id_frierson2006)
160 solins(:) = 0.25_rp * atmos_solarins_constant &
161 * ( 1.0_rp + 0.25_rp * frierson2006_delta_s * ( 1.0_rp - 3.0_rp * sin(lat(:))**2 ) )
168 subroutine annual_mean_insol( solins, &
170 use scale_atmos_solarins,
only: &
171 atmos_solarins_ecliptic_longitude
173 integer,
intent(in) :: np
174 real(rp),
intent(out) :: solins(np)
175 real(rp),
intent(in) :: lat(np)
177 integer :: date(date_size)
178 integer :: month, day
179 integer :: ndays_month
182 real(rp) :: re_factor
185 real(rp) :: hour_angle
186 integer,
parameter :: offset_year = 0
190 real(rp) :: sample_second
192 real(rp) :: daily_solins(np)
193 real(rp) :: sum_flux(np)
196 date(date_year) = annual_mean_year
201 ndays_month = days_in_month( annual_mean_year, month )
202 date(date_month) = month
203 do day=1, ndays_month
205 do i=1, annual_samples_per_day
207 sample_second = 86400.0_rp &
208 * ( real(i,rp) - 0.5_rp ) / real(annual_samples_per_day,rp)
210 call seconds_to_hms( sample_second, &
211 date(date_hour), date(date_minute), date(date_second) )
213 call atmos_solarins_ecliptic_longitude( &
214 re_factor, sin_decl, cos_decl, hour_angle, &
217 call daily_mean_insol( daily_solins, &
218 lat, re_factor, sin_decl, cos_decl, np )
220 sum_flux(:) = sum_flux(:) + daily_solins(:)
221 nsample = nsample + 1
226 solins(:) = sum_flux(:) / real(nsample, rp)
228 end subroutine annual_mean_insol
231 subroutine daily_mean_insol( solins, &
232 lat, re_factor, sin_decl, cos_decl, Np )
233 use scale_atmos_solarins,
only: &
234 atmos_solarins_constant
236 integer,
intent(in) :: np
237 real(rp),
intent(out) :: solins(np)
238 real(rp),
intent(in) :: lat(np)
239 real(rp),
intent(in) :: re_factor
240 real(rp),
intent(in) :: sin_decl
241 real(rp),
intent(in) :: cos_decl
248 real(rp),
parameter :: pole_eps = 100.0_rp * epsilon(1.0_rp)
255 sin_lat = sin(lat(i))
256 cos_lat = cos(lat(i))
257 if ( abs(cos_lat) <= pole_eps )
then
258 if ( sin_lat * sin_decl > 0.0_rp )
then
263 else if ( abs(cos_decl) <= pole_eps )
then
264 if ( sin_lat * sin_decl > 0.0_rp )
then
270 cos_h0 = - ( sin_lat * sin_decl ) / ( cos_lat * cos_decl )
271 if ( cos_h0 >= 1.0_rp )
then
273 else if ( cos_h0 <= -1.0_rp )
then
280 solins(i) = atmos_solarins_constant * re_factor / pi &
281 * ( h0 * sin_lat * sin_decl + sin(h0) * cos_lat * cos_decl )
283 solins(i) = max( solins(i), 0.0_rp )
286 end subroutine daily_mean_insol
289 pure function days_in_month( YEAR, MONTH )
result(NDAYS)
291 integer,
intent(in) :: year
292 integer,
intent(in) :: month
295 integer,
parameter :: ndays_normal(12) = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
298 ndays = ndays_normal(month)
299 if ( month == 2 .and. is_leap_year(year) ) ndays = 29
301 end function days_in_month
305 pure function is_leap_year( YEAR )
result(IS_LEAP)
307 integer,
intent(in) :: year
311 is_leap = mod(year,4) == 0
313 if ( mod(year,100) == 0 ) is_leap = .false.
314 if ( mod(year,400) == 0 ) is_leap = .true.
316 end function is_leap_year
320 pure subroutine seconds_to_hms( DAY_SECOND, &
321 HOUR, MINUTE, SECOND )
323 real(rp),
intent(in) :: day_second
324 integer,
intent(out) :: hour
325 integer,
intent(out) :: minute
326 integer,
intent(out) :: second
328 integer :: total_second
331 total_second = int(day_second)
332 total_second = max(0, min(total_second, 86399))
334 hour = total_second / 3600
335 total_second = total_second - hour * 3600
337 minute = total_second / 60
338 second = total_second - minute * 60
340 end subroutine seconds_to_hms
module FElib / Atmosphere / Physics radiation / Solar insolation / Simple gray-radiation scheme
subroutine, public atm_phy_rd_solarins_simple_get(solins, cossza, lat, np)
Get solar insolation and cosine of the solar zenith angle for the given latitude array.
subroutine, public atm_phy_rd_solarins_simple_update()
subroutine, public atm_phy_rd_solarins_simple_setup()
Setup the simplified solar insolation module.