Line data Source code
1 : !-------------------------------------------------------------------------------
2 : ! This module uses the Lean solar irradiance data to provide a solar cycle
3 : ! scaling factor used in heating rate calculations
4 : !-------------------------------------------------------------------------------
5 : module rad_solar_var
6 :
7 : use shr_kind_mod , only : r8 => shr_kind_r8
8 : use solar_irrad_data, only : sol_irrad, we, nbins, has_spectrum, sol_tsi
9 : use solar_irrad_data, only : do_spctrl_scaling
10 : use cam_abortutils, only : endrun
11 :
12 : implicit none
13 : save
14 :
15 : private
16 : public :: rad_solar_var_init
17 : public :: get_variability
18 :
19 : real(r8), allocatable :: ref_band_irrad(:) ! scaling will be relative to ref_band_irrad in each band
20 : real(r8), allocatable :: irrad(:) ! solar irradiance at model timestep in each band
21 : real(r8) :: tsi_ref ! total solar irradiance assumed by rrtmg
22 :
23 : real(r8), allocatable :: radbinmax(:)
24 : real(r8), allocatable :: radbinmin(:)
25 : integer :: nradbins
26 :
27 : !-------------------------------------------------------------------------------
28 : contains
29 : !-------------------------------------------------------------------------------
30 :
31 1536 : subroutine rad_solar_var_init( )
32 : use radconstants, only : get_number_sw_bands
33 : use radconstants, only : get_sw_spectral_boundaries
34 : use radconstants, only : get_ref_solar_band_irrad
35 : use radconstants, only : get_ref_total_solar_irrad
36 :
37 : integer :: i
38 : integer :: ierr
39 : integer :: yr, mon, tod
40 : integer :: radmax_loc
41 :
42 :
43 1536 : call get_number_sw_bands(nradbins)
44 :
45 1536 : if ( do_spctrl_scaling ) then
46 :
47 1536 : if ( .not.has_spectrum ) then
48 0 : call endrun('rad_solar_var_init: solar input file must have irradiance spectrum')
49 : endif
50 :
51 4608 : allocate (radbinmax(nradbins),stat=ierr)
52 1536 : if (ierr /= 0) then
53 0 : call endrun('rad_solar_var_init: Error allocating space for radbinmax')
54 : end if
55 :
56 4608 : allocate (radbinmin(nradbins),stat=ierr)
57 1536 : if (ierr /= 0) then
58 0 : call endrun('rad_solar_var_init: Error allocating space for radbinmin')
59 : end if
60 :
61 4608 : allocate (ref_band_irrad(nradbins), stat=ierr)
62 1536 : if (ierr /= 0) then
63 0 : call endrun('rad_solar_var_init: Error allocating space for ref_band_irrad')
64 : end if
65 :
66 4608 : allocate (irrad(nradbins), stat=ierr)
67 1536 : if (ierr /= 0) then
68 0 : call endrun('rad_solar_var_init: Error allocating space for irrad')
69 : end if
70 :
71 1536 : call get_sw_spectral_boundaries(radbinmin, radbinmax, 'nm')
72 :
73 : ! Make sure that the far-IR is included, even if RRTMG does not
74 : ! extend that far down. 10^5 nm corresponds to a wavenumber of
75 : ! 100 cm^-1.
76 23040 : radmax_loc = maxloc(radbinmax,1)
77 1536 : radbinmax(radmax_loc) = max(100000._r8,radbinmax(radmax_loc))
78 :
79 : ! for rrtmg, reference spectrum from rrtmg
80 1536 : call get_ref_solar_band_irrad( ref_band_irrad )
81 :
82 : else
83 :
84 0 : call get_ref_total_solar_irrad(tsi_ref)
85 :
86 : endif
87 :
88 1536 : end subroutine rad_solar_var_init
89 :
90 : !-------------------------------------------------------------------------------
91 : !-------------------------------------------------------------------------------
92 38400 : subroutine get_variability( sfac )
93 :
94 : real(r8), intent(out) :: sfac(nradbins) ! scaling factors for CAM heating
95 :
96 : integer :: yr, mon, day, tod
97 :
98 38400 : if ( do_spctrl_scaling ) then
99 :
100 38400 : call integrate_spectrum( nbins, nradbins, we, radbinmin, radbinmax, sol_irrad, irrad)
101 :
102 576000 : sfac(:nradbins) = irrad(:nradbins)/ref_band_irrad(:nradbins)
103 :
104 : else
105 :
106 0 : sfac(:nradbins) = sol_tsi/tsi_ref
107 :
108 : endif
109 :
110 38400 : end subroutine get_variability
111 :
112 : !-------------------------------------------------------------------------------
113 : ! private method.........
114 : !-------------------------------------------------------------------------------
115 :
116 38400 : subroutine integrate_spectrum( nsrc, ntrg, src_x, min_trg, max_trg, src, trg )
117 :
118 : use mo_util, only : rebin
119 :
120 : implicit none
121 :
122 : !---------------------------------------------------------------
123 : ! ... dummy arguments
124 : !---------------------------------------------------------------
125 : integer, intent(in) :: nsrc ! dimension source array
126 : integer, intent(in) :: ntrg ! dimension target array
127 : real(r8), intent(in) :: src_x(nsrc+1) ! source coordinates
128 : real(r8), intent(in) :: max_trg(ntrg) ! target coordinates
129 : real(r8), intent(in) :: min_trg(ntrg) ! target coordinates
130 : real(r8), intent(in) :: src(nsrc) ! source array
131 : real(r8), intent(out) :: trg(ntrg) ! target array
132 :
133 : !---------------------------------------------------------------
134 : ! ... local variables
135 : !---------------------------------------------------------------
136 : real(r8) :: trg_x(2), targ(1) ! target coordinates
137 : integer :: i
138 :
139 576000 : do i = 1, ntrg
140 :
141 537600 : trg_x(1) = min_trg(i)
142 537600 : trg_x(2) = max_trg(i)
143 :
144 537600 : call rebin( nsrc, 1, src_x, trg_x, src(1:nsrc), targ(:) )
145 : ! W/m2/nm --> W/m2
146 576000 : trg( i ) = targ(1)*(trg_x(2)-trg_x(1))
147 :
148 : enddo
149 :
150 :
151 38400 : end subroutine integrate_spectrum
152 :
153 : end module rad_solar_var
|