2 ! 2016/02/23 David Wong extracted the complex number module and put it in a file
3 ! 2016/05/23 David Wong - replaced rrtmg_aero_optical_util_module with
4 ! cmaq_rrtmg_aero_optical_util_module to avoid duplication
5 ! of the same module name on WRF side of the two-way model
7 MODULE rrtmg_aero_optical_util_module
9 Integer :: AERO_UTIL_LOG = 0
12 public :: aero_optical, aero_optical2, aero_optical_CS, AERO_UTIL_LOG
15 module procedure ghintBH_1, ghintBH_2, ghintBH_Odd
19 module procedure ghintBH_CS_even, ghintBH_CS_odd
22 Logical, Parameter :: Use_Odd_Quadrature = .True.
23 Integer, Parameter :: Quadrature_Points = 3
25 !B.Hutzell One point quadature IGH = 1
27 real, parameter :: ghxi_1(1) = 0.00000000000
28 real, parameter :: ghwi_1(1) = 1.77245385091
30 !B.Hutzell Three point quadature IGH = 3
31 real, parameter :: ghxi_3(3) = (/ -1.22474487139, &
35 real, parameter :: ghwi_3(3) = (/ 0.295408975151, &
39 !B.Hutzell Five point quadature IGH = 5
40 real(8), parameter :: ghxi_5(5) = (/ -2.02018287046d0, &
46 real(8), parameter :: ghwi_5(5) = (/ 0.019953242059d0, &
52 !B.Hutzell Nine point quadature IGH = 9 points
53 !No. Abscissas Weight Total Weight
54 real, parameter :: ghxi_9(9) = (/ -3.19099320178, &
64 real, parameter :: ghwi_9(9) = (/ 3.96069772633E-5, &
76 ! ------------------------------------------------------------------
77 subroutine getqext_BH (xx, crefin, qextalf, qscatalf, gscatalfg,SUCCESS)
81 real, intent(in) :: XX
82 real, intent(out) :: qextalf, qscatalf, gscatalfg
83 complex, intent(in) :: CREFIN
84 logical, intent(out) :: success
87 real( 8 ), parameter :: one_third = 1.0d0 / 3.0d0
90 integer :: nstop, modulus
92 real :: QEXT, QSCA, QBACK, G_MIE, xx1
95 complex( 8 ) :: refractive_index
98 refractive_index = dcmplx( real( CREFIN ), imag( CREFIN ) )
100 modulus = int( abs( x * refractive_index ) )
101 nstop = int( x + 4.0d0 * x**one_third + 2.0d0 )
103 nxx = max( modulus, nstop ) + 15
107 CALL BHMIE_FLEXI (XX, NXX, NSTOP, CREFIN,QEXT,QSCA,QBACK,G_MIE, SUCCESS)
110 qscatalf = QSCA * xx1
111 gscatalfg = qscatalf * G_MIE
113 end subroutine getqext_bh
115 ! ------------------------------------------------------------------
116 SUBROUTINE BHMIE (X, REFREL, QQEXT, QQSCA, QBACK, GSCA, SUCCESS)
118 ! FSB Changed the call vector to return only QEXT, QSCAT QBACK GSCA
119 ! and ignore NANG, S1 and S2 and all calculations for them
124 real, intent(in) :: X ! X = pi*particle_diameter / Wavelength
125 complex, intent(in) :: REFREL
127 ! REFREL = (complex refr. index of sphere)/(real index of medium)
128 ! in the current use the index of refraction of the the medium
129 ! i taken at 1.0 real.
133 real, intent(out) :: QQEXT, QQSCA, QBACK, GSCA
134 logical, intent(out) :: SUCCESS
136 ! QQEXT Efficiency factor for extinction
137 ! QQSCA Efficiency factor for scattering
138 ! QQBACK Efficiency factor for back scatter
139 ! GSCA asymmetry factor <cos>
140 ! SUCCESS flag for successful calculation
142 ! Bohren, Craig F. and Donald R. Huffman, Absorption and
143 ! Scattering of Light by Small Particles, Wiley-Interscience
144 ! copyright 1983. Paperback Published 1998.
146 ! This code was originally listed in Appendix A. pp 477-482.
147 ! As noted below, the original code was subsequently
148 ! modified by Prof. Bruce T. Drain of Princetion University.
149 ! The code was further modified for a specific application
150 ! in a large three-dimensional code requiring as much
151 ! computational efficiency as possible.
152 ! Prof. Francis S. Binkowski of The University of North
153 ! Carolina at Chapel Hill.
155 ! Declare parameters:
156 ! Note: important that MXNANG be consistent with dimension of S1 and S2
157 ! in calling routine!
159 integer, parameter :: MXNANG=10, NMXX=600000 ! FSB new limits
160 real*8, parameter :: PII = 3.1415916536D0
161 real*8, parameter :: ONE = 1.0D0, TWO = 2.0D0
165 integer :: N,NSTOP,NMX,NN
166 real*8 :: QSCA, QEXT, DX1, DXX1
167 real*8 :: CHI,CHI0,CHI1,DX,EN,P,PSI,PSI0,PSI1,XSTOP,YMOD
168 real*8 :: TWO_N_M_ONE, TWO_N_P_ONE, EN1, FACTOR
169 complex*16 :: AN,AN1,BN,BN1,DREFRL,XI,XI1,Y, Y1, DREFRL1
170 complex*16 :: D(NMXX), FAC1, FAC2
173 !***********************************************************************
174 ! Subroutine BHMIE is the Bohren-Huffman Mie scattering subroutine
175 ! to calculate scattering and absorption by a homogenous isotropic
179 ! REFREL = (complex refr. index of sphere)/(real index of medium)
180 ! real refractive index of medium taken as 1.0
182 ! QEXT = efficiency factor for extinction
183 ! QSCA = efficiency factor for scattering
184 ! QBACK = efficiency factor for backscatter
185 ! see Bohren & Huffman 1983 p. 122
186 ! GSCA = <cos> asymmetry for scattering
188 ! Original program taken from Bohren and Huffman (1983), Appendix A
189 ! Modified by Prof. Bruce T.Draine, Princeton Univ. Obs., 90/10/26
190 ! in order to compute <cos(theta)>
191 ! 91/05/07 (BTD): Modified to allow NANG=1
192 ! 91/08/15 (BTD): Corrected error (failure to initialize P)
193 ! 91/08/15 (BTD): Modified to enhance vectorizability.
194 ! 91/08/15 (BTD): Modified to make NANG=2 if called with NANG=1
195 ! 91/08/15 (BTD): Changed definition of QBACK.
196 ! 92/01/08 (BTD): Converted to full double precision and double complex
197 ! eliminated 2 unneed lines of code
198 ! eliminated redundant variables (e.g. APSI,APSI0)
199 ! renamed RN -> EN = double precision N
200 ! Note that DOUBLE COMPLEX and DCMPLX are not part
201 ! of f77 standard, so this version may not be fully
202 ! portable. In event that portable version is
203 ! needed, use src/bhmie_f77.f
204 ! 93/06/01 (BTD): Changed AMAX1 to generic function MAX
205 ! FSB April 09,2012 This code was modified by:
206 ! Prof. Francis S. Binkowski University of North Carolina at
207 ! Chapel Hill, Institue for the Environment.
209 ! The modifications were made to enhance computation speed
210 ! for use in a three-dimensional code. This was done by
211 ! removing code that calculated angular scattering. The method
212 ! of calculating QEXT, QBACK was also changed.
214 !***********************************************************************
218 NANG = 2 ! FSB only this value
219 ! IF(NANG.GT.MXNANG)STOP'***Error: NANG > MXNANG in bhmie'
220 ! IF (NANG .LT. 2) NANG = 2
223 ! FSB Define reciprocals so that divisions can be replaced by multiplications.
226 DREFRL = DCMPLX( REFREL )
227 DREFRL1 = ONE / DREFRL
232 !*** Series expansion terminated after NSTOP terms
233 ! Logarithmic derivatives calculated from NMX on down
234 XSTOP = REAL( X + 4.0 * X**0.3333 + 2.0, 8)
235 NMX = INT( MAX(XSTOP,YMOD) ) + 15
237 ! BTD experiment 91/1/15: add one more term to series and compare results
238 ! NMX=AMAX1(XSTOP,YMOD)+16
239 ! test: compute 7001 wavelengths between .0001 and 1000 micron
240 ! for a=1.0micron SiC grain. When NMX increased by 1, only a single
241 ! computed number changed (out of 4*7001) and it only changed by 1/8387
242 ! conclusion: we are indeed retaining enough terms in series!
246 IF (NMX .GT. NMXX) THEN
247 WRITE(6,*)'Error: NMX > NMXX=',NMXX,' for |m|x=',YMOD
252 ! FSB all code relating to scattering angles is removed out for
253 ! reasons of efficiency when running in a three-dimensional
254 ! code. We only need QQSCA, QQEXT, GSCA AND QBACK
257 !*** Logarithmic derivative D(J) calculated by downward recurrence
258 ! beginning with initial value (0.,0.)
260 D(NMX) = DCMPLX(0.0D0,0.0D0)
263 EN = REAL(NMX - N + 1, 8 )
264 ! FSB In the following division by Y has been replaced by
265 ! multiplication by Y1, the reciprocal of Y.
266 D(NMX-N) = ( EN * Y1 ) - (ONE / ( D(NMX-N+1) + EN * Y1))
269 !*** Riccati-Bessel functions with real argument X
270 ! calculated by upward recurrence
276 XI1 = DCMPLX(PSI1,-CHI1)
281 XBACK = (0.0d0,0.0d0)
283 ! FSB Start main loop
287 TWO_N_M_ONE = TWO * EN - ONE
288 ! for given N, PSI = psi_n CHI = chi_n
289 ! PSI1 = psi_{n-1} CHI1 = chi_{n-1}
290 ! PSI0 = psi_{n-2} CHI0 = chi_{n-2}
291 ! Calculate psi_n and chi_n
292 PSI = TWO_N_M_ONE * PSI1 * DX1 - PSI0
293 CHI = TWO_N_M_ONE * CHI1 * DX1 - CHI0
294 XI = DCMPLX(PSI,-CHI)
296 !*** Compute AN and BN:
297 ! FSB Rearrange to get common terms
298 FAC1 = D(N) * DREFRL1 + EN * DX1
299 AN = (FAC1) * PSI - PSI1
300 AN = AN / ( (FAC1 )* XI - XI1 )
301 FAC2 = ( DREFRL * D(N) + EN * DX1)
302 BN = ( FAC2) * PSI -PSI1
303 BN = BN / ((FAC2) * XI - XI1 )
305 ! FSB calculate sum for QEXT as done by Wiscombe
307 TWO_N_P_ONE = (TWO * EN + ONE)
308 QEXT = QEXT + (TWO_N_P_ONE) * (REAL(AN) + REAL(BN) )
309 QSCA = QSCA + (TWO_N_P_ONE) * ( ABS(AN)**2+ ABS(BN)**2 )
311 ! FSB calculate XBACK from B & H Page 122
312 FACTOR = -1.0d0 * FACTOR ! calculate (-1.0 ** N)
313 XBACK = XBACK + (TWO_N_P_ONE) * factor * (AN - BN)
315 ! FSB calculate asymmetry factor
316 GSCA = GSCA + REAL( ((TWO_N_P_ONE)/(EN * (EN + ONE))) * &
317 (REAL(AN)*REAL(BN)+IMAG(AN)*IMAG(BN)))
320 GSCA = GSCA + REAL( (EN - EN1) * &
321 (REAL(AN1)*REAL(AN) + IMAG(AN1)*IMAG(AN) + &
322 REAL(BN1)*REAL(BN) + IMAG(BN1)*IMAG(BN)))
325 !*** Store previous values of AN and BN for use in computation of g=<cos(theta)>
329 ! FSB set up for next iteration
334 XI1 = DCMPLX(PSI1,-CHI1)
336 END DO ! main loop on n
338 !*** Have summed sufficient terms.
340 ! Now compute QQSCA,QQEXT,QBACK,and GSCA
341 GSCA = REAL( TWO / QSCA ) * GSCA
343 ! FSB in the following, divisions by DX * DX has been replaced by
344 ! multiplication by DXX1 the reciprocal of 1.0 / (DX *DX)
345 QQSCA = REAL( TWO * QSCA * DXX1 )
346 QQEXT = REAL( TWO * QEXT * DXX1 )
347 QBACK = REAL( REAL ( 0.5d0 * XBACK * CONJG(XBACK), 8 ) * DXX1 ) ! B&H Page 122
351 ! ------------------------------------------------------------------
352 subroutine aero_optical ( lamda_in, nmode, nr, ni, Vol, &
353 dgn, sig, bext, bscat, g_bar, &
356 ! *** calculate the extinction and scattering coefficients and
357 ! assymetry factors for each wavelength as a sum over the
358 ! individual lognormal modes. Each mode may have a different
359 ! set of refractive indices.
362 ! *** input variables
363 real, intent(in) :: lamda_in ! wavelengths [micro-m]
364 INTEGER, intent(in) :: nmode ! number of lognormal modes
365 real, intent(in) :: nr( nmode), ni(nmode) ! real and imaginary
367 real, intent(in) :: Vol(nmode) ! modal aerosol volumes [m**3 /m**3]
368 real, intent(in) :: dgn(nmode) ! geometric mean diameters
369 ! for number distribution [ m]
370 real, intent(in) :: sig(nmode) ! geometric standard deviation
372 real, intent(in), optional :: modulus(nmode) ! modulus of refracive index
374 ! *** output variables
375 real, intent(out) :: bext ! extinction coefficient [ 1 / m ]
376 real, intent(out) :: bscat ! scattering coefficient [ 1 / m ]
377 real, intent(out) :: g_bar ! assymetry factor for Mie and molecular scattering
378 logical, intent(out) :: success ! flag for successful calculation
379 ! *** internal variables
380 INTEGER :: j ! loop index
381 ! real :: xlnsig(nmode) ! natural log of geometric standard deviations
382 real :: beta_Sc, bsc !aerosol scattering coefficient
384 real :: beta_Ex ! aerosol extinction coefficients
385 real :: G ! modal aerosol assymetry factors
388 real :: lamdam1 ! 1/ lamda
389 real :: alphav ! Mie size parameter
393 real, parameter :: pi = 3.14159265359
395 Logical, Save :: Initialize = .True.
397 ! *** coded 09/08/2004 by Dr. Francis S. Binkowski
398 ! FSB Modified for RRTMG version December 2009.
399 ! FSB modified 10/06/2004, 10/12/2004, 10/18/2005
401 ! Formerly Carolina Environmental Program
402 ! FSB now the Institute for the Environment
403 ! University of North Carolina at Chapel Hill
404 ! email: frank_binkowski@unc.edu
407 ! *** initialize variables
408 lamdam1 = 1.0e6 / lamda_in ! lamda now in [ m ]
414 ! calculate the extinction and scattering coefficients
418 ! calculate Mie size parameter for volume distribution
419 ! exp(3.0 * xlnsig*xlnsig) converts dgn to dgv (volume diameter)
420 alphav = pi * dgn(j) * exp(3.0 * LSIGX * LSIGX) * lamdam1
422 if (present(modulus)) then
423 modalph = alphav * modulus(j)
426 CALL ghintBH (nr(j), ni(j), alphav, LSIGX, beta_EX, beta_Sc, G, success)
428 ! *** ghintBH returns the normalized values
429 ! Calculate the actual extinction and scattering coefficients
430 ! by multplying by the modal volume and dividing by the wavelength
432 vfac = Vol(j) * lamdam1
434 ! *** sum to get total extinction and scattering
435 ! and contribution to the overal assymetry factor
437 bext = bext + vfac * beta_Ex ! [ 1 / m ]
440 sum_g = sum_g + bsc * G
442 END DO ! loop on modes
444 ! *** calculate combined assymetry factor for all modes
446 g_bar = sum_g / bscat ! changed to divide by bscat
448 END SUBROUTINE aero_optical
450 ! ------------------------------------------------------------------
451 subroutine ghintBH_1 (nr, ni, alfv, xlnsig, Qext_GH, Qscat_GH, g_gh, success)
453 ! FSB *********** This is the newest (05_30_2012) version of GhintBH
454 ! this version does the Mie method and calculates the optimum set of
455 ! set of Gauss-Hermite abscissas and weights.
456 ! FSB Calls Penndorf codes for alfv .le. 0.3
458 ! Dr. Francis S. Binkowski, The University of North Carolina
460 ! FSB this code file now contains all of the necessary subroutines that
461 ! are called to perform an integral of the Bohren and Huffman
462 ! Mie codes ( as updated by Prof. Bruce C. Drain of Princeton)
463 ! calculates the extinction and scattering coefficients
464 ! normalized by wavelength and total particle volume
465 ! concentration for a log normal particle distribution
466 ! with the logarithm of the geometric standard deviation
467 ! given by xlnsig. The integral of the
468 ! asymmetry factor g is also calculated.
469 ! FSB Change 12/20/2011 This code now has a choice of IGH based
471 ! *** Does Gauss-Hermite quadrature of Qext / alfa & Qscat / alfa
472 ! and asymmetry factor <cos> over log normal distribution using
477 real, intent(in) :: nr, ni ! refractive indices
478 real, intent(in) :: alfv ! Mie parameter for dgv
479 real, intent(in) :: xlnsig ! log of geometric standard deviation
480 real, intent(out) :: Qext_GH ! normalized extinction efficiency
481 real, intent(out) :: Qscat_GH ! normalized scattering efficiency
482 real, intent(out) :: g_GH ! asymmetry factor <cos>
483 logical, intent(out) :: success ! flag for successful calculation
485 real :: bext_P, bscat_P, babs_P, g_PCS, xlnsg2 ! see below for definition
487 real :: aa1 ! see below for definition
488 real :: alfaip, alfaim ! Mie parameters at abscissas
490 ! *** these are Qext/alfa and Qscat/alfv at the abscissas
491 real :: qalfip_e, qalfim_e ! extinction
492 real :: qalfip_s, qalfim_s ! scattering
493 real :: gsalfp, gsalfm ! scattering times asymmetry factor
494 integer :: IGH ! index for GH quadrature
496 ! FSB define parameters
497 real, parameter :: pi = 3.14159265
498 real, parameter :: sqrtpi = 1.772454
499 real, parameter :: sqrtpi1 = 1.0 / sqrtpi
500 real, parameter :: sqrt2 = 1.414214
501 real, parameter :: three_pi_two = 3.0 * pi / 2.0
502 real, parameter :: const = three_pi_two * sqrtpi1
505 complex :: crefin ! complex index of refraction
506 real :: sum_e,sum_s, xi,wxi,xf
509 ! Gauss-Hermite abscissas and weights
510 ! *** the following weights and abscissas are from Abramowitz
511 ! Stegun, Table 25.10 page 924
512 ! FSB full precision from Table 25.10
514 ! FSB ten-point - IGH = 5
515 real, parameter :: ghxi_10(5) = (/ 0.342901327223705, &
521 real, parameter :: ghwi_10(5) = (/ 6.108626337353e-01, &
522 2.401386110823e-01, &
523 3.387439445548e-02, &
524 1.343645746781e-03, &
525 7.640432855233e-06 /)
527 ! FSB six-point - IGH = 3
528 real, parameter :: ghxi_6(3) = (/ 0.436077411927617, &
532 real, parameter :: ghwi_6(3) = (/ 7.246295952244e-01, &
533 1.570673203229e-01, &
534 4.530009905509e-03 /)
536 ! FSB two-point - IGH = 1
537 real, parameter :: ghxi_2(1) = (/ 0.707106781186548 /)
539 real, parameter :: ghwi_2(1) = (/ 8.862269254528e-01 /)
541 real :: GHXI(5), GHWI(5) ! weight and abscissas
542 integer :: NMAX ! number of weights and abscissa
544 ! FSB Check for valid range of Penndorf application.
545 if ( alfv .le. 0.3) then
546 xlnsg2 = xlnsig*xlnsig
547 call pennfsb (nr,ni,alfv,xlnsg2,bext_P,bscat_P,babs_P,g_PCS)
550 g_GH = g_PCS * exp(4.0 * xlnsg2) ! match GH integral
553 ! FSB We need to do a full Mie calculation now
554 ! Choose IGH. These choices are designed to improve
555 ! the computational efficiency without sacrificing accuracy.
557 IGH=3 ! default value; six_point is sufficient generally
561 if (nr .ge. 1.7) then
563 IGH = 5 ! more points needed here
567 if ( alfv .gt. 20.0 .or. alfv .lt. 0.5 ) then
568 IGH = 1 ! in this range fewer points are needed
575 else if (IGH == 3) then
585 end if ! set up number of abscissas and weights
587 ! FSB set complex refractive index.
590 ! FSB now start the integration code
591 aa1 = sqrt2 * xlnsig ! This 1.0 / Sqrt( A ) in derivation of the integral
592 ! where A = 1.0 / ( 2.0 * xlnsg**2 )
594 ! Then alpha = alfv * exp[ u / sqrt(A) ]
595 ! For Gauss-Hermite Quadrature u = xi
596 ! Therefore, xf = exp( xi / sqrt(A) ),
597 ! or xf = exp( xi * aa1 )
601 ! FSB do NMAX calls to the MIE codes
607 alfaim = alfv / xf ! division cheaper than another exp()
608 ! *** call subroutine to fetch the effficiencies
610 call getqext_BH (alfaip, crefin, qalfip_e, qalfip_s, gsalfp, success)
611 call getqext_BH (alfaim, crefin, qalfim_e, qalfim_s, gsalfm, success)
613 sum_e = sum_e + wxi * ( qalfip_e + qalfim_e )
614 sum_s = sum_s + wxi * ( qalfip_s + qalfim_s )
615 sum_sg = sum_sg + wxi * ( gsalfp + gsalfm )
618 g_GH = sum_sg / sum_s ! this is <cos>
619 Qext_GH = const * sum_e !
620 Qscat_GH = const * sum_s
623 end subroutine ghintBH_1
625 ! ------------------------------------------------------------------
626 subroutine pennfsb (n, k, xx, lnsg2, bext, bscat, babs, g)
628 ! FSB a new version of Penndorf's equations. This version does
629 ! analytical integration for Qext, Qscat, Qabs to generate
630 ! bext, bscat, babs. Note that the expressions for Qext & Qscat
631 ! hve been divide through by xx.
634 ! Caldas, M., V. Semiao, 2001, Radiative properties of small
635 ! particles: and extension of the Penndorff Model. Journal
636 ! of the Optical Society of America A, Vol. 18, No. 4,
639 ! Penndorf, R., 1962a,Scattering and extinction coefficients for small
640 ! absorbing and nonabsorbing aerosols,
641 ! J. Optical Society of America, 52, 896-904.
643 ! Penndorf, P., 1962b,Scattering and extinction coefficients for
644 ! small Spherical aerosols, J. Atmos. Sci., 19, p 193
646 ! FSB Coded by Dr. Francis S. Binkowski on October 25, 2011 by combining
647 ! two previous versions to get a common code for the Penndorf and
648 ! and Caldas & Semiao approaches. The Penndorf Qext, Qscat are much
649 ! better than the versions from Caldas & Semiao despite claims to
650 ! the contrary. The values of the asymmetry factor from Caldas & Semiao
651 ! are better than can be obtained from Penndorf.
653 ! FSB This version does the analytical integral ove a lognormal
658 real, intent(in) :: n, k ! refractive index
659 real, intent(in) :: xx ! pi * diameter / wavelength
660 real, intent(in) :: lnsg2 ! log(sigma_g)**2
661 real, intent(out) :: bext ! extinction coefficient
662 real, intent(out) :: bscat ! scattering coefficient
663 real, intent(out) :: babs ! absorption coefficient
664 real, intent(out) :: g ! asmmetry factor
667 complex*16 :: m, m2,m4,m6,m21,m22
668 complex*16 :: P,Q,R,S,T,U,V,W
669 complex*16 :: Qprime, Rprime,Sprime,Tprime
670 complex*16 :: Uprime, Vprime, Wprime
671 real*8 :: Qs, gQs, gpennCS
672 real*8 :: P1,P2, Q1, Q2 , S2,V1, V2 ! see usage
673 real*8 :: P1SQ, P2SQ ! see usage
674 real*8 :: y, y2, y3, y4, y6, y7, y8, y9
675 real*8 :: x, x2, x3, x4, x6, x7, x8, x9
677 ! FSB define useful numbers and fractions
678 real, parameter :: pi = 3.14159265358979324d0
679 real, parameter :: three_pi_two = 1.5d0 * pi
681 real*8, parameter :: one = 1.0d0
682 real*8, parameter :: two = 2.0d0
683 real*8, parameter :: three = 3.0d0
684 real*8, parameter :: four = 4.0d0
685 real*8, parameter :: five = 5.0d0
686 real*8, parameter :: six = 6.0d0
687 real*8, parameter :: eight = 8.0d0
688 real*8, parameter :: nine = 9.0d0
689 real*8, parameter :: fifteen = 15.0d0
690 real*8, parameter :: fortyfive = 45.0d0
691 ! real*8, parameter :: two5ths = two / five
692 real*8, parameter :: twothrds = two / three
693 real*8, parameter :: fourthirds = four / three
694 real*8, parameter :: onefifteenth = one / fifteen
695 real*8, parameter :: twofifteenths = two * onefifteenth
696 ! real*8, parameter :: fourninths = four / nine
697 real*8, parameter :: eightthirds = two * fourthirds
698 real*8, parameter :: one_big = one / 31500.0d0
699 real*8, parameter :: two_fortyfive = two / fortyfive
700 real*8, parameter :: four_225 = four / 225.0d0
701 real*8, parameter :: one_210 = one / 210.0d0
702 ! real*8, parameter :: one_half = one / two
703 ! real*8, parameter :: four_two = two
704 real*8, parameter :: nine_two = 4.5d0
705 ! real*8, parameter :: sixteen_two = eight
706 ! real*8, parameter :: thirtysix_two = 36.0 / two
707 ! real*8, parameter :: twentyfive_two = 25.0d0 / two
708 ! real*8, parameter :: sixtyfour_two = 64.0d0 / two
709 ! real*8, parameter :: fortynine_two = 49.0d0 / two
710 ! real*8, parameter :: eightyone_two = 81.0d0 / two
711 real*8 :: A,B,C,D,E, AA,BB,CC
714 mag = sqrt( n * n + k * k )
716 y = REAL( xx, 8 ) ! convert to real*8
717 ! FSB get powers of y
726 ! FSB Calculate integrals ove the lognormal distribution
727 ! this is done term by term and the form is
728 ! xn = yn * exp( (n**2) * lnsig2 /2.0d0)
731 x2 = y2 * exp( two * lnsg2)
732 x3 = y3 * exp( nine_two * lnsg2)
733 x4 = y4 ! * exp( eight * lnsg2)
734 x6 = y6 ! * exp( thirtysix_two * lnsg2)
735 x7 = y7 ! * exp( fortynine_two * lnsg2)
736 x8 = y8 ! * exp( fortynine_two * lnsg2)
737 x9 = y9 ! * exp( eightyone_two * lnsg2)
740 ! FSB explicitly calculate complex refrative index m
742 ! FSB get powers and functions of m
749 ! FSB calculate Penndorf's definitions from Table II of Penndorf (1962a)
751 Q = (m2 - two ) / m22
752 S = m21 / ( two * m2 + three)
754 ! FSB get real & imaginary parts following Penndorf's mptation
767 ! FSB Get bext from Penndorf (1962a) Equation (7) up to x4
768 ! consistent with equation (8)
769 ! We have then divided through by x and integrated analytically
770 bext = REAL( four * P2 + ( 2.4d0 * (P1 * Q2 + P2 * Q1 ) + twothrds * S2 &
771 + twofifteenths * V2 ) * x2 + ( eightthirds * ( P1SQ - P2SQ ) ) * x3, 4 )
773 ! FSB get bscat from Penndorf Equation (9) up to x4
774 ! we have divided through by x and integrated analytically
775 bscat = REAL( eightthirds * ( P1SQ + P2SQ ) * x3 )
777 ! babs = bext - bscat
779 ! FSB now get asymmetry factor from Caldas & Semiao (2001)
781 ! *** The following additional variables from Caldas & Semiao (2001)
782 ! are defined in Equations 10a to 10h.
784 R = (m6 + 20.0d0*m4 -200.0d0*m2 + 200.0d0) / m22**2
785 T = m21 / ( ( 2.0d0 * M2 + 3.0d0) **2 )
786 U = m21 / (3.0d0 * M2 + 4.0d0 )
787 W = m21 * ( 2.0d0 * m2 - 5.0d0)
789 ! *** further definitions from Caldas & Semiao (2001)
792 Sprime = 5.0d0 * S / P
793 Tprime = 375.0d0 * T / P
794 ! Uprime = 28.0d0 * U / P
796 Wprime = 5.0d0 * W / P
798 ! FSB calculate gQs and Qs from Caldas & Semiao (2001)
799 ! *** calculate Qs equation 13
800 ! Qs = eightthirds * abs(P)**2 &
801 ! * (x4 + onefifteenth * real(Qprime) * x6 &
802 ! + fourthirds * aimag(P) * x7 &
803 ! + one_big * ( 35.0d0 * abs(Qprime)**2 &
804 ! + 20.0d0 * real(Rprime) + 35.0d0 * abs(Vprime)**2 &
805 ! + 21.0d0 * abs(Sprime)**2 ) * x8 &
806 ! + two_fortyfive * aimag( Qprime * ( P - conjg(P) )) * x9 )
808 ! *** calculate gQs equation 15
810 ! gQs = four_225 * abs(P)**2 * ( &
811 ! (5.0d0 * Real(Vprime) + 3.0d0 * real(Sprime) ) * x6 &
812 ! + one_210 * ( 35.0d0 * real(Vprime*conjg(Qprime) ) &
813 ! + 21.0d0 * real(Sprime * conjg(Qprime) ) &
814 ! + 10.0d0 * real(Wprime)- 6.0d0 * real(Tprime) ) * x8 &
815 ! - twothrds * ( 5.0d0 * aimag(Vprime * conjg(P) ) &
816 ! + 3.0d0 * aimag(Sprime * conjg(P) ) ) * x9 )
818 ! FSB recast into specific terms
820 B = onefifteenth * real(Qprime) * x6
821 C = fourthirds * aimag(P) * x7
822 D = one_big * ( 35.0d0 * abs(Qprime)**2 &
823 + 20.0d0 * real(Rprime) + 35.0d0 * abs(Vprime)**2 &
824 + 21.0d0 * abs(Sprime)**2 ) * x8
825 E = two_fortyfive * aimag( Qprime * ( P - conjg(P) )) * x9
827 Qs = eightthirds * abs(P)**2 *( A + B + C + D + E )
829 AA = (5.0d0 * Real(Vprime) + 3.0d0 * real(Sprime) ) * x6
830 BB = one_210 * ( 35.0d0 * real(Vprime*conjg(Qprime) ) &
831 + 21.0d0 * real(Sprime * conjg(Qprime) ) &
832 + 10.0d0 * real(Wprime)- 6.0d0 * real(Tprime) ) * x8
833 CC = twothrds * ( 5.0d0 * aimag(Vprime * conjg(P) ) &
834 + 3.0d0 * aimag(Sprime * conjg(P) ) ) * x9
836 gQs = four_225 * abs(P)**2 * ( AA + BB + CC )
838 ! FSB calculate asymmetry factor and adjust with empirical term.
840 ! FSB now multiply by three_pi_two get output values
841 bext = three_pi_two * bext
842 bscat = three_pi_two * bscat
846 end subroutine pennfsb
848 ! ------------------------------------------------------------------
850 ! FSB a new version of Penndorf's equations. This version does
851 ! analytical integration for Qext, Qscat, Qabs to generate
852 ! bext, bscat, babs. Note that the expressions for Qext & Qscat
853 ! hve been divide through by xx.
856 ! Penndorf, R., 1962a,Scattering and extinction coefficients for small
857 ! absorbing and nonabsorbing aerosols,
858 ! J. Optical Society of America, 52, 896-904.
860 ! Penndorf, P., 1962b,Scattering and extinction coefficients for
861 ! small Spherical aerosols, J. Atmos. Sci., 19, p 193
863 ! FSB Coded by Dr. Francis S. Binkowski on October 25, 2011 by combining
864 ! two previous versions to get a common code for the Penndorf and
865 ! and Caldas & Semiao approaches. The Penndorf Qext, Qscat are much
866 ! better than the versions from Caldas & Semiao despite claims to
867 ! the contrary. The values of the asymmetry factor from Caldas & Semiao
868 ! are better than can be obtained from Penndorf.
869 ! FSB Modified by FSB on 12/02/2013 to remove the Caldas & Semiao parts.
870 ! This version is set up to calculate LW bext and bscat so that absorption
871 ! in the LW can be calculated. This will work with RRTMG LW.
872 ! FSB This version does the analytical integral ove a lognormal
875 subroutine pennfsbLW (crefin, xx, lnsig, bext, bscat)
879 complex, intent(in) :: crefin !complex refractive index
880 real, intent(in) :: xx ! pi * diameter / wavelength
881 real, intent(in) :: lnsig ! log(sigma_g)
882 real, intent(out) :: bext ! extinction coefficient
883 real, intent(out) :: bscat ! scattering coefficient
885 real*8 :: Qext, Qscat
888 complex*16 :: m, m2,m21,m22
889 complex*16 :: P,Q,S,V
890 real*8 :: P1,P2, Q1, Q2 , S2,V1, V2 ! see usage
891 real*8 :: P1SQ, P2SQ ! see usage
894 ! FSB define useful numbers and fractions
895 real*8, parameter :: one= 1.0d0
896 real*8, parameter :: two = 2.0d0
897 real*8, parameter :: three = 3.0d0
898 real*8, parameter :: four = 4.0d0
899 real*8, parameter :: eight = 8.0d0
900 real*8, parameter :: nine = 9.0d0
901 real*8, parameter :: fifteen = 15.0d0
902 real*8, parameter :: twothrds = two/three
903 real*8, parameter :: twofifteenths = two / fifteen
904 real*8, parameter :: eightthirds = eight / three
905 real*8, parameter :: nine_two = nine / two
907 ! FSB define useful numbers and fractions
908 real, parameter :: pi = four*atan(one)
909 real, parameter :: three_pi_two = 1.5d0 * pi
913 ! FSB Calculate integrals ove the lognormal distribution
914 ! this is done term by term; the form is
915 ! xn = yn * exp( (n**2) * lnsig2 /2.0d0)
916 lnsg2 = lnsig * lnsig
920 x2 = y2 * exp( two * lnsg2)
921 x3 = y3 * exp( nine_two * lnsg2)
923 m= conjg(crefin) ! Penndorf asuumes k is negative.
927 ! FSB calculate Penndorf's definitions from Table II of Penndorf (1962a)
929 Q = (m2 - two ) / m22
930 S = m21 / ( two * m2 + three)
932 ! FSB get real & imaginary parts following Penndorf's mptation
944 ! FSB Get bext from Penndorf (1962a) Equation (7) up to x4
945 ! consistent with equation (8)
946 ! We have then divided through by x and integrated analytically
948 + ( 2.4d0 * (P1 * Q2 + P2 * Q1 ) + twothrds * S2 &
949 + twofifteenths * V2 ) * x2 &
950 + ( eightthirds * ( P1SQ - P2SQ ) ) * x3
952 ! FSB get bscat from Penndorf Equation (9) up to x4
953 ! we have divided through by x and integrated analytically
954 Qscat = eightthirds * ( P1SQ + P2SQ ) * x3
956 ! FSB now multiply by three_pi_two get output values
957 bext = three_pi_two * Qext
958 bscat = three_pi_two * Qscat
960 end subroutine pennfsbLW
962 ! ------------------------------------------------------------------
963 subroutine aero_optical2( lamda_in, crefin, Vol, dgn, &
964 sig, bext, bscat, gfac, success )
966 ! FSB NOTE: this subroutine calculates for single mode
968 ! *** calculate the extinction and scattering coefficients and
969 ! assymetry factors for each wavelength as a sum over the
970 ! individual lognormal modes. Each mode may have a different
971 ! set of refractive indices.
975 ! *** input variables
976 real, intent(in) :: lamda_in ! wavelengths [micro-m]
977 complex, intent(in) :: crefin ! Complex refractive index
978 real, intent(in) :: Vol ! modal aerosol volumes [m**3 /m**3]
979 real, intent(in) :: dgn ! geometric mean diameters
980 ! for number distribution [ m]
981 real, intent(in) :: sig ! geometric standard deviation
983 ! *** output variables
984 real, intent(out) :: bext ! extinction coefficient [ 1 / m ]
985 real, intent(out) :: bscat ! scattering coefficient [ 1 / m ]
986 real, intent(out) :: gfac ! assymetry factor for Mie and molecular scattering
987 logical, intent(out) :: success ! flag for successful calculation
989 ! *** internal variables
990 ! real :: xlnsig(nmode) ! natural log of geometric standard deviations
991 real :: beta_Sc ! aerosol scattering coefficient
993 real :: beta_Ex ! aerosol extinction coefficients
994 real :: G ! modal aerosol assymetry factors
997 real :: lamdam1 ! 1/ lamda
998 real :: alphav ! Mie size parameter
1000 real, parameter :: pi = 3.14159265359
1002 Logical, Save :: Initialize = .True.
1004 ! FSB coded 04/15/2012 by Dr. Francis S. Binkowski
1005 ! modified from an earlier version
1006 ! Center for Environmental Modeling for PolicyDevelopment
1007 ! Institute for the Environment
1008 ! University of North Carolina at Chapel Hill
1009 ! email: frank_binkowski@unc.edu
1011 ! *** initialize variables
1012 lamdam1 = 1.0e6 / lamda_in ! lamda now in [ m ]
1018 ! calculate Mie size parameter for volume distribution
1019 ! exp(3.0 * xlnsig*xlnsig) converts dgn to dgv (volume diameter)
1020 alphav = pi * dgn * exp(3.0 * LSIGX * LSIGX) * lamdam1
1022 If(Initialize .And. AERO_UTIL_LOG .GT. 0 )Then
1023 If( Use_Odd_Quadrature )then
1024 write(AERO_UTIL_LOG,99501)Quadrature_Points
1026 write(AERO_UTIL_LOG,99504)
1027 Initialize = .False.
1031 If( Use_Odd_Quadrature )then
1032 CALL ghintBH (Initialize, crefin, alphav, LSIGX, beta_EX, beta_Sc, G, success)
1034 CALL ghintBH (crefin, alphav, LSIGX, beta_EX, beta_Sc, G, success)
1037 ! *** ghintBH returns the normalized values
1038 ! Calculate the actual extinction and scattering coefficients
1039 ! by multplying by the modal volume and dividing by the wavelength
1041 vfac = Vol * lamdam1
1042 bext = vfac * beta_Ex ! [ 1 / m ]
1043 bscat = vfac * beta_Sc ! [ 1 / m ]
1045 99501 Format(I2,' Quadrature Points for Volume Averaged Aerosol Optics')
1046 99504 Format('Even Number Quadrature Points for Volume Averaged Aerosol Optics')
1048 END SUBROUTINE aero_optical2
1050 ! ------------------------------------------------------------------
1051 subroutine aero_optical_CS ( lamda_in, refcor,refshell, VOLCOR, &
1052 VOLSHELL, DGNCOR, DGNSHELL, SIG, &
1053 bext, bscat, gfac, succesS )
1055 ! FSB NOTE: values for one mode are returend
1056 ! *** calculate the extinction and scattering coefficients and
1057 ! assymetry factors for each wavelength as a sum over the
1058 ! individual lognormal modes. Each mode may have a different
1059 ! set of refractive indices.
1062 ! *** input variables
1063 real,intent(in) :: lamda_in ! wavelengths [micro-m]
1064 complex,intent(in) :: refcor ! Complex refractive index -core
1065 complex,intent(in) :: refshell ! Complex refractive index -shell
1066 real,intent(in) :: VOLCOR ! volume of core
1067 real,intent(in) :: VOLSHELL ! volume of shell
1068 real,intent(in) :: DGNCOR ! geometric mean diameters
1069 ! for number distribution [m]
1070 real,intent(in) :: DGNSHELL ! geometric mean diameters
1071 ! for number distribution [m]
1072 real,intent(in) :: SIG ! geometric standard deviation
1074 ! *** output variables
1075 real,intent(out) :: bext ! extinction coefficient [ 1 / m ]
1076 real,intent(out) :: bscat ! scattering coefficient [ 1 / m ]
1077 real,intent(out) :: gfac ! assymetry factor
1078 logical, intent(OUT) :: success ! flag for successful calculation
1080 ! *** internal variables
1081 ! real :: xlnsig(nmode) ! natural log of geometric standard deviations
1082 real :: beta_Sc ! aerosol scattering coefficient
1084 real :: beta_Ex ! aerosol extinction coefficients
1085 real :: G ! modal aerosol assymetry factors
1087 real :: XX, YY ! Mie size parameter
1089 real :: lamdam1 ! 1/ lamda
1092 Logical, Save :: Initialize = .True.
1094 real, parameter :: pi = 3.14159265359
1096 ! FSB coded 04/15/2012 by Dr. Francis S. Binkowski
1097 ! modified from an earlier version
1098 ! Center for Environmental Modeling for PolicyDevelopment
1099 ! Institute for the Environment
1100 ! University of North Carolina at Chapel Hill
1101 ! email: frank_binkowski@unc.edu
1104 ! *** initialize variables
1105 lamdam1 = 1.0e6 / lamda_in ! lamda now in [ m ]
1107 ! calculate the extinction and scattering coefficients
1109 expfac = pi * exp(3.0 * LSIGX * LSIGX) * lamdam1
1111 ! calculate Mie size parameter for volume distribution
1112 ! exp(3.0 * xlnsig*xlnsig) converts dgn to dgv (volume diameter)
1113 XX = DGNCOR * expfac
1114 YY = DGNSHELL * expfac
1116 If(Initialize .And. AERO_UTIL_LOG .GT. 0 )Then
1117 If( Use_Odd_Quadrature )then
1118 write(AERO_UTIL_LOG,99500)Quadrature_Points
1120 write(AERO_UTIL_LOG,99502)
1121 Initialize = .False.
1125 If( Use_Odd_Quadrature )then
1126 CALL ghintBH_CS(Initialize,refcor,refshell,XX,YY,LSIGX,beta_EX,beta_Sc,G, success)
1128 CALL ghintBH_CS(refcor,refshell,XX,YY,LSIGX,beta_EX,beta_Sc,G, success)
1131 ! FSB ghintBH_CS returns the normalized values
1132 ! Calculate the actual extinction and scattering coefficients
1133 ! by multplying by the modal volume and dividing by the wavelength.
1134 ! For the coated-sphere (core-shell) calculation use the combined
1137 vfac = (VOLCOR + VOLSHELL) * lamdam1
1138 bext = vfac * beta_Ex ! [ 1 / m ]
1139 bscat = vfac * beta_Sc ! [ 1 / m ]
1141 99500 Format(I2,' Quadrature Points for Core-Shell Aerosol Optics')
1142 99502 Format('Even Number Quadrature Points for Core-Shell Aerosol Optics')
1144 END SUBROUTINE aero_optical_CS
1146 ! ------------------------------------------------------------------
1148 subroutine aero_optical_LW (lamda_in, crefin, Vol, &
1149 dgn, sig, bext, bscat )
1151 ! *** calculate the extinction and scattering coefficients and
1152 ! asymmetry factor for LW radiation.
1153 ! The calling code only uses
1156 ! *** input variables
1157 real, intent(in) :: lamda_in ! wavelengths [micro-m]
1159 complex, intent(in) :: crefin ! complex refractive index
1160 real, intent(in) :: Vol ! modal aerosol volumes [m**3 /m**3]
1161 real, intent(in) :: dgn ! geometric mean diameter
1162 ! for number distribution [ m]
1163 real, intent(in) :: sig ! geometric standard deviation
1166 ! *** output variables
1167 real, intent(out) :: bext ! extinction coefficient [ 1 / m ]
1168 real, intent(out) :: bscat ! scattering coefficient [ 1 / m ]
1171 ! *** internal variables
1172 real, parameter :: pi = 3.14159265359
1174 real :: lamda ! wavelength [ m]
1175 real :: beta_Sc ! aerosol scattering coefficient
1177 real :: beta_Ex ! aerosol extinction coefficients
1178 real :: G ! modal aerosol assymetry factors
1179 real :: VLX, DGX, SIGX, LSIGX
1180 real :: lamdam1 ! 1/ lamda
1181 real :: alphav ! Mie size parameter
1186 ! *** coded 09/08/2004 by Dr. Francis S. Binkowski
1187 ! FSB Modified for RRTMG version December 2009.
1188 ! FSB modified 10/06/2004, 10/12/2004, 10/18/2005
1191 ! FSB Institute for the Environment
1192 ! University of North Carolina at Chapel Hill
1193 ! email: frank_binkowski@unc.edu
1196 ! *** initialize variables
1197 ! lamda = 1.0e-6 * lamda_in ! lamda now in [ m ]
1201 ! lamdam1 = 1.0 / lamda ! 1 / [m]
1202 lamdam1 = 1.0e6 / lamda_in ! 1 / [m]
1209 ! calculate Mie size parameter for volume distribution
1210 ! exp(3.0 * xlnsig*xlnsig) converts dgn to dgv (volume diameter)
1211 alphav = pi * DGX * exp(3.0 * LSIGX * LSIGX) * lamdam1
1212 vfac = VLX * lamdam1
1214 ! FSB Check for valid range of Penndorf application.
1215 if ( alphav .le. 0.3) then
1216 call pennfsbLW(crefin, alphav, LSIGX, beta_EX, beta_Sc)
1219 CALL ghintBH(crefin, alphav, LSIGX, beta_EX, beta_Sc, G, success)
1222 bext = vfac * beta_Ex ! [ 1 / m ]
1223 bscat = vfac * beta_Sc
1225 END SUBROUTINE aero_optical_LW
1227 ! ------------------------------------------------------------------
1228 subroutine ghintBH_2 (crefin,alfv,xlnsig,Qext_GH,Qscat_GH,g_gh, success)
1230 ! *************** REVISED VERSION < NOTE
1231 ! FSB *********** This is the newest (04_14_2012) version of GhintBH
1232 ! this version does the Mie method and calculates the optimum set of
1233 ! set of Gauss-Hermite abscissas and weights.
1234 ! Dr. Francis S. Binkowski, The University of North Carolina
1236 ! FSB this code file now contains all of the necessary subroutines that
1237 ! are called to perform an integral of the Bohren and Huffman
1238 ! Mie codes ( as updated by Prof. Bruce C. Drain of Princeton)
1239 ! calculates the extinction and scattering coefficients
1240 ! normalized by wavelength and total particle volume
1241 ! concentration for a log normal particle distribution
1242 ! with the logarithm of the geometric standard deviation
1243 ! given by xlnsig. The integral of the
1244 ! asymmetry factor g is also calculated.
1245 ! FSB Change 12/20/2011 This code now has a choice of IGH based
1247 ! FBB Changes Simplified code. Eliminated Penndorf code
1248 ! *** Does Gauss-Hermite quadrature of Qext / alfa & Qscat / alfa
1249 ! and asymmetry factor <cos> over log normal distribution using
1254 complex, intent(in) :: crefin ! complex index of refraction
1255 real, intent(in) :: alfv ! Mie parameter for dgv
1256 real, intent(in) :: xlnsig ! log of geometric standard deviation
1257 real, intent(out) :: Qext_GH ! normalized extinction efficiency
1258 real, intent(out) :: Qscat_GH ! normalized scattering efficiency
1259 real, intent(out) :: g_GH ! asymmetry factor <cos>
1260 logical, intent(out) :: success ! flag for successful calculation
1262 real :: nr ! real part of refractive index
1263 real :: aa1 ! see below for definition
1264 real :: alfaip, alfaim ! Mie parameters at abscissas
1266 ! *** these are Qext/alfa and Qscat/alfv at the abscissas
1267 real :: qalfip_e, qalfim_e ! extinction
1268 real :: qalfip_s, qalfim_s ! scattering
1269 real :: gsalfp, gsalfm ! scattering times asymmetry factor
1270 integer :: IGH ! index for GH quadrature
1272 ! FSB define parameters
1273 real, parameter :: pi = 3.14159265
1274 real, parameter :: sqrtpi = 1.772454
1275 real, parameter :: sqrtpi1 = 1.0 / sqrtpi
1276 real, parameter :: sqrt2 = 1.414214
1277 real, parameter :: three_pi_two = 3.0 * pi / 2.0
1278 real, parameter :: const = three_pi_two * sqrtpi1
1281 real :: sum_e,sum_s, xi,wxi,xf
1284 ! Gauss-Hermite abscissas and weights
1285 ! *** the following weights and abscissas are from Abramowitz
1286 ! Stegun, Table 25.10 page 924
1287 ! FSB full precision from Table 25.10
1289 ! FSB ten-point - IGH = 5
1290 real, parameter :: ghxi_10(5) = (/ 0.342901327223705, &
1291 1.036610829789514, &
1292 1.756683649299882, &
1293 2.532731674232790, &
1294 3.436159118837738 /)
1296 real, parameter :: ghwi_10(5) = (/ 6.108626337353e-01, &
1297 2.401386110823e-01, &
1298 3.387439445548e-02, &
1299 1.343645746781e-03, &
1300 7.640432855233e-06 /)
1302 ! FSB six-point - IGH = 3
1303 real, parameter :: ghxi_6(3) = (/ 0.436077411927617, &
1304 1.335849074013597, &
1305 2.350604973674492 /)
1307 real, parameter :: ghwi_6(3) = (/ 7.246295952244e-01, &
1308 1.570673203229e-01, &
1309 4.530009905509e-03 /)
1311 ! FSB two-point - IGH = 1
1312 real, parameter :: ghxi_2(1) = (/ 0.707106781186548 /)
1314 real, parameter :: ghwi_2(1) = (/ 8.862269254528e-01 /)
1316 real :: GHXI(5), GHWI(5) ! weight and abscissas
1317 integer :: NMAX ! number of weights and abscissa
1321 ! FSB now choose IGH. These choices are designed to improve
1322 ! the computational efficiency without sacrificing accuracy.
1326 IGH=3 ! default value; six_point is sufficient generally
1330 if (nr .ge. 1.7) then
1332 IGH = 5 ! more points needed here
1336 if( alfv .gt. 20.0 .or. alfv .lt. 0.5 ) then
1337 IGH = 1 ! in this range fewer points are needed
1345 else if (IGH == 3) then
1352 GHXI(i) = ghxi_10(i)
1353 GHWI(i) = ghwi_10(i)
1355 end if ! set up number of abscissas and weights
1357 ! FSB now start the integration code
1358 aa1 = sqrt2 * xlnsig ! This 1.0 / Sqrt( A ) in derivation of the integral
1359 ! where A = 1.0 / ( 2.0 * xlnsg**2 )
1361 ! Then alpha = alfv * exp[ u / sqrt(A) ]
1362 ! For Gauss-Hermite Quadrature u = xi
1363 ! Therefore, xf = exp( xi / sqrt(A) ),
1364 ! or xf = exp( xi * aa1 )
1369 ! FSB do NMAX calls to the MIE codes
1373 xf = exp( xi * aa1 )
1375 alfaim = alfv / xf ! division cheaper than another exp()
1376 ! *** call subroutine to fetch the effficiencies
1378 call getqext_BH(alfaip,crefin,qalfip_e,qalfip_s, gsalfp, success)
1379 call getqext_BH(alfaim,crefin,qalfim_e,qalfim_s, gsalfm, success)
1381 sum_e = sum_e + wxi * ( qalfip_e + qalfim_e )
1382 sum_s = sum_s + wxi * ( qalfip_s + qalfim_s )
1383 sum_sg = sum_sg + wxi * ( gsalfp + gsalfm )
1387 g_GH = sum_sg / sum_s ! this is <cos>
1388 Qext_GH = const * sum_e !
1389 Qscat_GH = const * sum_s
1391 end subroutine ghintBH_2
1393 ! ------------------------------------------------------------------
1394 subroutine ghintBH_CS_even (RCORE, RSHELL , XX, YY, xlnsig, &
1395 Qext_GH,Qscat_GH, g_gh, success)
1397 ! FSB code for coated-sphere (core-shell) version
1399 ! *************** REVISED VERSION < NOTE
1400 ! FSB *********** This is the newest (04_14_2012) version of ghintBH_CS
1401 ! for the coated-sphere (core-shell) method using BHCOAT
1402 ! this version does the Mie method and calculates the optimum set of
1403 ! set of Gauss-Hermite abscissas and weights.
1404 ! Dr. Francis S. Binkowski, The University of North Carolina
1407 ! FSB this code file now contains all of the necessary subroutines that
1408 ! are called to perform an integral of the Bohren and Huffman
1409 ! Mie codes ( as updated by Prof. Bruce C. Drain of Princeton)
1410 ! calculates the extinction and scattering coefficients
1411 ! normalized by wavelength and total particle volume
1412 ! concentration for a log normal particle distribution
1413 ! with the logarithm of the geometric standard deviation
1414 ! given by xlnsig. The integral of the
1415 ! asymmetry factor g is also calculated.
1416 ! FSB Change 12/20/2011 This code now has a choice of IGH based
1418 ! FBB Changes Simplified code. Eliminated Penndorf code
1419 ! *** Does Gauss-Hermite quadrature of Qext / alfa & Qscat / alfa
1420 ! and asymmetry factor <cos> over log normal distribution using
1424 complex, intent(in) :: RCORE ! refractive index of core
1425 complex, intent(in) :: RSHELL ! refractive index of shell
1426 real, intent(in) :: XX ! Mie parameter for core
1427 real, intent(in) :: YY ! Mie parameter for shell
1428 real, intent(in) :: xlnsig ! log of geometric standard deviation
1429 real, intent(out) :: Qext_GH ! normalized extinction efficiency
1430 real, intent(out) :: Qscat_GH ! normalized scattering efficiency
1431 real, intent(out) :: g_GH ! asymmetry factor <cos>
1432 logical, intent(out) :: success ! flag for successful calculation
1434 real :: nr ! real part of refractive index
1435 real :: aa1 ! see below for definition
1436 real :: XXP, XXM ! Mie parameters at abscissas - CORE
1437 real :: YYP, YYM ! Mie parameters at abscissas - SHELL
1439 ! FSB define parameters
1440 real, parameter :: pi = 3.14159265
1441 real, parameter :: sqrtpi = 1.772454
1442 real, parameter :: sqrtpi1 = 1.0 / sqrtpi
1443 real, parameter :: sqrt2 = 1.414214
1444 real, parameter :: three_pi_two = 3.0 * pi / 2.0
1445 real, parameter :: const = three_pi_two * sqrtpi1
1447 ! *** these are Qext/alfa and Qscat/alfv at the abscissas
1448 real :: qalfip_e, qalfim_e ! extinction
1449 real :: qalfip_s, qalfim_s ! scattering
1450 real :: gsalfp, gsalfm ! scattering times asymmetry factor
1451 integer :: IGH ! index for GH quadrature
1453 real :: sum_e,sum_s, xi,wxi,xf, temp
1456 ! Gauss-Hermite abscissas and weights
1457 ! *** the following weights and abscissas are from Abramowitz
1458 ! Stegun, Table 25.10 page 924
1459 ! FSB full precision from Table 25.10
1461 ! FSB ten-point - IGH = 5
1462 real, parameter :: ghxi_10(5) = (/ 0.342901327223705, &
1463 1.036610829789514, &
1464 1.756683649299882, &
1465 2.532731674232790, &
1466 3.436159118837738 /)
1468 real, parameter :: ghwi_10(5) = (/ 6.108626337353e-01, &
1469 2.401386110823e-01, &
1470 3.387439445548e-02, &
1471 1.343645746781e-03, &
1472 7.640432855233e-06 /)
1474 ! FSB six-point - IGH = 3
1475 real, parameter :: ghxi_6(3) = (/ 0.436077411927617, &
1476 1.335849074013597, &
1477 2.350604973674492 /)
1479 real, parameter :: ghwi_6(3) = (/ 7.246295952244e-01, &
1480 1.570673203229e-01, &
1481 4.530009905509e-03 /)
1483 ! FSB two-point - IGH = 1
1484 real, parameter :: ghxi_2(1) = (/ 0.707106781186548 /)
1486 real, parameter :: ghwi_2(1) = (/ 8.862269254528e-01 /)
1488 real GHXI(5), GHWI(5) ! weight and abscissas
1489 integer NMAX ! number of weights and abscissa
1492 ! FSB now choose IGH. These choices are designed to improve
1493 ! the computational efficiency without sacrificing accuracy.
1497 IGH=3 ! default value; six_point is sufficient generally
1501 if (nr .ge. 1.7) then
1503 IGH = 5 ! more points needed here
1507 if ( XX .gt. 20.0 .or. XX .lt. 0.5 ) then
1508 IGH = 1 ! in this range fewer points are needed
1516 else if (IGH == 3) then
1523 GHXI(i) = ghxi_10(i)
1524 GHWI(i) = ghwi_10(i)
1526 end if ! set up number of abscissas and weights
1528 ! FSB now start the integration code
1529 aa1 = sqrt2 * xlnsig ! This 1.0 / Sqrt( A ) in derivation of the integral
1530 ! where A = 1.0 / ( 2.0 * xlnsg**2 )
1532 ! Then alpha = alfv * exp[ u / sqrt(A) ]
1533 ! For Gauss-Hermite Quadrature u = xi
1534 ! Therefore, xf = exp( xi / sqrt(A) ),
1535 ! or xf = exp( xi * aa1 )
1539 ! FSB do NMAX calls to the MIE codes
1543 xf = exp( xi * aa1 )
1546 XXM = XX * temp ! division cheaper than another exp()
1548 YYM = YY * temp ! division cheaper than another exp()
1549 ! *** call subroutine to fetch the effficiencies
1551 call getqsgBHCS(XXP,YYP,RCORE,RSHELL,qalfip_e,qalfip_s,gsalfp, success)
1552 call getqsgBHCS(XXM,YYM,RCORE,RSHELL,qalfim_e,qalfim_s,gsalfm, success)
1554 sum_e = sum_e + wxi * ( qalfip_e + qalfim_e )
1555 sum_s = sum_s + wxi * ( qalfip_s + qalfim_s )
1556 sum_sg = sum_sg + wxi * ( gsalfp + gsalfm )
1559 g_GH = sum_sg / sum_s ! this is <cos>
1560 Qext_GH = const * sum_e !
1561 Qscat_GH = const * sum_s
1563 end subroutine ghintBH_CS_even
1565 ! ------------------------------------------------------------------
1566 subroutine getqsgBHCS (XX,YY,RRFRL1,RRFRL2,qxtalf,qscalf,qsgalf, success)
1569 real, intent(in) :: XX, YY
1570 real, intent(out) :: qxtalf, qscalf, qsgalf
1571 complex, intent(in) :: RRFRL1,RRFRL2 ! refractive indices Core , Shell
1572 logical, intent(out) :: success ! flag for successful calculation
1574 real :: QEXT, QSCA, QBACK, G_MIE
1576 character (len = 20) :: mystr1, mystr2, mystr3, mystr4
1580 ! if ( (xx * real(RRFRL1) >= 30.0) &
1581 ! .or. (xx * aimag(RRFRL1) >= 30.0) &
1582 ! .or. (yy * aimag(RRFRL2) >= 30.0)) then
1583 ! print *, ' ==d== bhcoat error'
1586 call BHCOAT (XX,YY,RRFRL1,RRFRL2,QEXT,QSCA,QBACK,G_MIE, SUCCESS)
1588 ! if ((trim(mystr1) == ' NaN') .or. &
1589 ! (trim(mystr2) == ' NaN') .or. &
1590 ! (trim(mystr3) == ' NaN') .or. &
1591 ! (trim(mystr4) == ' NaN')) then
1592 ! call BHCOAT (XX,YY,RRFRL1,RRFRL2,QEXT,QSCA,QBACK,G_MIE)
1597 qsgalf = qscalf * G_MIE
1599 END subroutine getqsgBHCS
1601 ! ------------------------------------------------------------------
1602 SUBROUTINE BHCOAT (XX, YY, RRFRL1, RRFRL2, QQEXT, QQSCA, QBACK, GGSCA, SUCCESS)
1604 use complex_number_module
1606 implicit none ! added by FSB
1609 real, intent(in) :: XX,YY ! Defined below
1610 complex, intent(in) :: RRFRL1,RRFRL2 ! Defined below
1611 real, intent(out) :: QQEXT,QQSCA,QBACK ! Defined below
1612 real, intent(out) :: GGSCA ! asymmetry factor <cos> added by FSB
1613 logical,intent(out) :: success
1617 real*8, parameter :: DEL = 1.0D-08
1618 real*8, parameter :: ONE = 1.0D0, TWO = 2.0D0
1619 ! complex*16, save :: II
1620 ! data II/(0.D0,1.D0)/
1621 type(complex_number) :: II
1623 integer :: IFLAG,N,NSTOP
1625 character (len = 128) :: mystr
1627 ! -----------------------------------------------------------
1628 ! del is the inner sphere convergence criterion
1629 ! -----------------------------------------------------------
1631 real*8 :: CHI0Y,CHI1Y,CHIY,PSI0Y,PSI1Y,PSIY,QEXT,RN,QSCA,X,Y,YSTOP,GSCA
1632 real*8 :: TWO_N_M_ONE, TWO_N_P_ONE
1633 real*8 :: RY, RYY, RNRY, RN1, factor
1635 ! complex*16 :: AMESS1,AMESS2,AMESS3,AMESS4,AN,ANCAP,AN1, BN,BNCAP,BN1, BRACK, &
1636 type(complex_number) :: AMESS1,AMESS2,AMESS3,AMESS4,AN,ANCAP,AN1, BN,BNCAP,BN1, BRACK, &
1637 CHI0X2,CHI0Y2,CHI1X2,CHI1Y2,CHIX2,CHIPX2,CHIPY2,CHIY2,CRACK, &
1638 D0X1,D0X2,D0Y2,D1X1,D1X2,D1Y2,DNBAR,GNBAR, &
1639 REFREL,RFREL1,RFREL2, XBACK,XI0Y,XI1Y,XIY, &
1640 X1,X2,Y2,RCX1, RCX2,RCY2, FAC1, FAC2
1642 !***********************************************************************
1643 ! NOTES from Prof. Bruce T. Draine, Princeton University
1644 ! Subroutine BHCOAT calculates Q_ext, Q_sca, Q_back for coated sphere.
1645 ! All bessel functions computed by upward recurrence.
1647 ! XX = 2*PI*RCORE*REFMED/WAVEL
1648 ! YY = 2*PI*RMANT*REFMED/WAVEL
1649 ! RFREL1 = REFCOR/REFMED
1650 ! RFREL2 = REFMAN/REFMED
1651 ! where REFCOR = complex refr.index of core)
1652 ! REFMAN = complex refr.index of mantle)
1653 ! REFMED = real refr.index of medium)
1654 ! RCORE = radius of core
1655 ! RMANT = radius of mantle
1656 ! WAVEL = wavelength of light in ambient medium
1658 ! Routine BHCOAT is taken from Bohren & Huffman (1983)
1659 ! Obtained from C.L.Joseph
1662 ! 92/11/24 (BTD) Explicit declaration of all variables
1663 ! April 30,2012 (FSB) added additional code to optimize
1664 ! run time by finding common terms and replacing multiple
1665 ! divisions by multiplication by a reciprocal.
1666 ! April 09, 2012 code transferred from BTD's BMHMIE to
1667 ! calculate the asymmetry factor by Prof. Francis S. Binkowski of
1668 ! The University of North Carolina at Chapel Hill.
1669 ! April 30,2012 (FSB) added additional code to optimize
1670 ! run time by finding common terms and replacing multiple
1671 ! divisions by multiplication by a reciprocal.
1672 ! July 16, 2010 more optimization by Dr. David Wong (DW) at US EPA
1675 ! Bohren, Craig F. and Donald R. Huffman, Absorption and
1676 ! Scattering of Light by Small Particles, Wiley-Interscience
1677 ! copyright 1983. Paperback Published 1998.
1678 ! This code was originally listed in Appendix B. pp 483-489.
1679 ! As noted above , the original code was subsequently
1680 ! modified by Prof. Bruce T. Draine of Princeton University.
1682 ! FSB The background for this code is discussed in Borhen & Huffman (1983)
1683 ! on pages 181-183 ( Equations 8.2 ) and on pages 483-484.
1684 !***********************************************************************
1690 #if ( RWORDSIZE == 8 )
1691 II = c_set(0.0, 1.0)
1693 II = c_set(0.0D0, 1.0D0)
1696 ! this technique will make the second 4 byte in the 8 byte variable be 0
1697 ! rather than arbitrary digits to increase accuracy
1698 write (mystr, *) xx, yy, real(RRFRL1), aimag(RRFRL1), real(RRFRL2), aimag(RRFRL2)
1699 read (mystr, *) x, y, RFREL1, RFREL2
1705 ! RFREL1%real_part = real(RRFRL1)
1706 ! RFREL1%imag_part = aimag(RRFRL1)
1707 ! RFREL2%real_part = real(RRFRL2)
1708 ! RFREL2%imag_part = aimag(RRFRL2)
1709 x1 = c_mul(x, rfrel1)
1710 x2 = c_mul(x, rfrel2)
1711 y2 = c_mul(y, rfrel2)
1712 RCX1 = c_div(ONE, X1)
1713 RCX2 = c_div(ONE, X2)
1714 RCY2 = c_div(ONE, Y2)
1715 refrel = c_div(rfrel2, rfrel1)
1716 ystop = y + 4.0 * y**0.3333 + 2.0
1717 nstop = INT( ystop )
1719 ! -----------------------------------------------------------
1720 ! series terminated after nstop terms
1721 ! -----------------------------------------------------------
1723 ! initialize variables
1724 d0x1 = c_div(c_cos(x1), c_sin(x1))
1725 d0x2 = c_div(c_cos(x2), c_sin(x2))
1726 d0y2 = c_div(c_cos(y2), c_sin(y2))
1733 xi0y = c_sub(psi0y, c_mul(chi0y, II))
1734 xi1y = c_sub(psi1y, c_mul(chi1y, II))
1736 #if ( RWORDSIZE == 8 )
1737 chi0y2 = c_mul(-1.0, c_SIN(y2))
1739 chi0y2 = c_mul(-1.0d0, c_SIN(y2))
1742 #if ( RWORDSIZE == 8 )
1743 chi0x2 = c_mul(-1.0, c_SIN(x2))
1745 chi0x2 = c_mul(-1.0d0, c_SIN(x2))
1751 #if ( RWORDSIZE == 8 )
1752 xback = c_set(0.0, 0.0)
1754 xback = c_set(0.0d0, 0.0d0)
1759 ! FSB Start main loop
1763 TWO_N_M_ONE = TWO * RN - ONE
1764 TWO_N_P_ONE = TWO * RN + ONE
1765 psiy = (TWO_N_M_ONE)*psi1y*RY - psi0y
1766 chiy = (TWO_N_M_ONE)*chi1y*RY - chi0y
1767 xiy = c_sub(psiy, c_mul(chiy, II))
1768 d1y2 = c_sub(c_div(ONE, c_sub(c_mul(rn, RCY2), d0y2)), c_mul(rn, RCY2))
1770 IF (iflag .eq. 0) THEN
1771 ! *** Calculate inner sphere ancap, bncap
1772 ! and brack and crack
1773 d1x1 = c_sub(c_div(ONE, c_sub(c_mul(rn, RCX1), d0x1)), c_mul(rn, RCX1))
1774 d1x2 = c_sub(c_div(ONE, c_sub(c_mul(rn, RCX2), d0x2)), c_mul(rn, RCX2))
1776 chix2 = c_sub(c_mul(c_mul(TWO*rn - ONE, chi1x2), RCX2), chi0x2)
1777 chiy2 = c_sub(c_mul(c_mul(TWO*rn - ONE, chi1y2), RCY2), chi0y2)
1779 chipx2 = c_sub(chi1x2, c_mul(c_mul(rn, chix2), RCX2))
1780 chipy2 = c_sub(chi1y2, c_mul(c_mul(rn, chiy2), RCY2))
1782 ANCAP = c_sub(c_mul(c_mul(REFREL, D1X1), CHIX2), CHIPX2)
1783 ANCAP = c_mul(ANCAP, c_sub(c_mul(CHIX2, D1X2), CHIPX2))
1784 ANCAP = c_div(c_sub(c_mul(REFREL, D1X1), D1X2), ANCAP)
1786 brack = c_mul(ancap, c_sub(c_mul(chiy2, d1y2), chipy2))
1788 bncap = c_sub(c_mul(refrel, d1x2), d1x1)
1789 bncap = c_div(bncap, c_sub(c_mul(refrel, chipx2), c_mul(d1x1, chix2)))
1790 bncap = c_div(bncap, c_sub(c_mul(chix2, d1x2), chipx2))
1792 crack = c_mul(bncap, c_sub(c_mul(chiy2, d1y2), chipy2))
1793 ! *** calculate convergence test expressions
1795 ! *** see pages 483-485 of Bohren & Huffman for
1797 amess1 = c_mul(brack, chipy2)
1798 amess2 = c_mul(brack, chiy2)
1799 amess3 = c_mul(crack, chipy2)
1800 amess4 = c_mul(crack, chiy2)
1802 ! Now test for convergence for inner sphere
1803 ! All four criteria must be satisfied. See page 484 of B & H
1804 IF (c_ABS(amess1) .LE. del*c_ABS(d1y2) .AND. &
1805 (c_ABS(amess2) .LE. del) .AND. &
1806 (c_ABS(amess3) .LE. del*c_ABS(d1y2)) .AND. &
1807 (c_ABS(amess4) .LE. del) ) THEN
1808 ! convergence for inner sphere
1809 #if ( RWORDSIZE == 8 )
1810 brack = c_set(0.0,0.0)
1811 crack = c_set(0.0,0.0)
1813 brack = c_set(0.0D0,0.0D0)
1814 crack = c_set(0.0D0,0.0D0)
1818 ! no convergence yet
1821 END IF ! test on iflag .eq. 0
1823 ! *** note usage of brack and crack See equations on
1824 ! Page 485 and discussion on pages 486 -487 of B & H
1825 dnbar = c_sub(d1y2, c_mul(brack, chipy2))
1826 dnbar = c_div(dnbar, c_sub(ONE, c_mul(brack, chiy2)))
1827 gnbar = c_sub(d1y2, c_mul(crack, chipy2))
1828 gnbar = c_div(gnbar, c_sub(ONE, c_mul(crack, chiy2)))
1829 !*** Store previous values of an and bn for use
1830 ! in computation of g=<cos(theta)>
1835 ! *** update an and bn
1837 FAC1 = c_add(c_div(dnbar, rfrel2), RNRY)
1839 an = c_sub(c_mul(psiy, FAC1), psi1y)
1840 an = c_div(an, c_sub(c_mul(FAC1, xiy), xi1y))
1841 FAC2 = c_add(c_mul(rfrel2, gnbar), RNRY)
1842 bn = c_sub(c_mul(psiy, FAC2), psi1y)
1843 bn = c_div(bn, c_sub(c_mul(FAC2, xiy), xi1y))
1845 ! *** Calculate sums for qsca, qext, xback
1846 qsca = qsca + (TWO_N_P_ONE) * (c_ABS(an)**2 + c_ABS(bn)**2)
1848 qext = qext + TWO_N_P_ONE * (an%real_part + bn%real_part)
1850 FACTOR = FACTOR * (-1.0D0)
1851 XBACK = c_add(XBACK, c_mul(TWO_N_P_ONE * FACTOR, c_sub(AN, BN)))
1853 ! FSB calculate the sum for the asymmetry factor
1855 GSCA = GSCA + ((TWO_N_P_ONE)/(RN* (RN + ONE)))* &
1856 (an%real_part*bn%real_part + an%imag_part*bn%imag_part)
1860 GSCA = GSCA + (RN - RN1) * &
1861 (AN1%real_part*AN%real_part + AN1%imag_part*AN%imag_part + &
1862 BN1%real_part*BN%real_part + BN1%imag_part*BN%imag_part)
1865 ! continue update for next interation
1870 xi1y = c_sub(psi1y, c_mul(chi1y, II))
1878 END DO ! end of main loop
1880 !*** Have summed sufficient terms.
1881 ! Now compute QQSCA,QQEXT,QBACK,and GSCA
1882 GGSCA = REAL( TWO * GSCA / qsca )
1883 QQSCA = REAL( TWO * qsca * RYY )
1884 QQEXT = REAL( TWO * qext * RYY )
1886 QBACK = 0.5 * real((xback%real_part**2 + xback%imag_part**2) * RYY)
1888 end subroutine BHCOAT
1890 ! ------------------------------------------------------------------
1891 subroutine ghintBH_Odd (INIT, crefin,alfv,xlnsig,Qext_GH,Qscat_GH,g_gh, success )
1893 ! *************** REVISED VERSION < NOTE
1894 ! FSB *********** This is the newest (04_14_2012) version of GhintBH
1895 ! this version does the Mie method and calculates the optimum set of
1896 ! set of Gauss-Hermite abscissas and weights.
1897 ! Dr. Francis S. Binkowski, The University of North Carolina
1899 ! FSB this code file now contains all of the necessary subroutines that
1900 ! are called to perform an integral of the Bohren and Huffman
1901 ! Mie codes ( as updated by Prof. Bruce C. Drain of Princeton)
1902 ! calculates the extinction and scattering coefficients
1903 ! normalized by wavelength and total particle volume
1904 ! concentration for a log normal particle distribution
1905 ! with the logarithm of the geometric standard deviation
1906 ! given by xlnsig. The integral of the
1907 ! asymmetry factor g is also calculated.
1908 ! FSB Change 12/20/2011 This code now has a choice of IGH based
1910 ! FBB Changes Simplified code. Eliminated Penndorf code
1911 ! *** Does Gauss-Hermite quadrature of Qext / alfa & Qscat / alfa
1912 ! and asymmetry factor <cos> over log normal distribution using
1917 logical, intent(INOUT) :: INIT ! initialize number of qudraure points
1918 complex, intent(in) :: crefin ! complex index of refraction
1919 real, intent(in) :: alfv ! Mie parameter for dgv
1920 real, intent(in) :: xlnsig ! log of geometric standard deviation
1921 real, intent(out) :: Qext_GH ! normalized extinction efficiency
1922 real, intent(out) :: Qscat_GH ! normalized scattering efficiency
1923 real, intent(out) :: g_GH ! asymmetry factor <cos>
1924 logical, intent(out) :: success ! flag for successful calculation
1926 real :: nr ! real part of refractive index
1927 real :: aa1 ! see below for definition
1928 real :: alfaip, alfaim ! Mie parameters at abscissas
1930 ! *** these are Qext/alfa and Qscat/alfv at the abscissas
1931 real :: qalfip_e, qalfim_e ! extinction
1932 real :: qalfip_s, qalfim_s ! scattering
1933 real :: gsalfp, gsalfm ! scattering times asymmetry factor
1935 ! FSB define parameters
1936 real, parameter :: pi = 3.14159265
1937 real, parameter :: sqrtpi = 1.772454
1938 real, parameter :: sqrtpi1 = 1.0 / sqrtpi
1939 real, parameter :: sqrt2 = 1.414214
1940 real, parameter :: three_pi_two = 3.0 * pi / 2.0
1941 real, parameter :: const = three_pi_two * sqrtpi1
1944 real :: sum_e,sum_s, xi,wxi,xf
1947 real, allocatable, save :: GHXI(:), GHWI(:) ! weight and abscissas
1948 integer, save :: IGH ! number of weights and abscissa
1949 integer, save :: NMAX ! optimumized number of weights and abscissa
1953 ! FSB now choose IGH. These choices are designed to improve
1954 ! the computational efficiency without sacrificing accuracy.
1958 Select Case( Quadrature_Points )
1960 IGH = Quadrature_Points
1965 NMAX = Max( Int( IGH / 2 ), 0)
1967 If( Allocated( GHXI ) .Or. Allocated( GHWI ) )Then
1972 Allocate( GHXI( NMAX + 1 ), GHWI( NMAX + 1 ) )
1990 If( AERO_UTIL_LOG .GT. 0 )Then
1991 write(AERO_UTIL_LOG,*)'BHMIE: IGH,(NMAX + 1) = ',IGH,(NMAX + 1)
1993 write(AERO_UTIL_LOG,*)'BHMIE: i, GHXI(i), GHWI(i) = ',i, GHXI(i), GHWI(i)
1999 If( .Not. Allocated( GHXI ) .Or. .Not. Allocated( GHWI ) )Then
2003 End If ! set up number of abscissas and weights
2007 ! FSB now start the integration code
2008 aa1 = sqrt2 * xlnsig ! This 1.0 / Sqrt( A ) in derivation of the integral
2009 ! where A = 1.0 / ( 2.0 * xlnsg**2 )
2011 ! Then alpha = alfv * exp[ u / sqrt(A) ]
2012 ! For Gauss-Hermite Quadrature u = xi
2013 ! Therefore, xf = exp( xi / sqrt(A) ),
2014 ! or xf = exp( xi * aa1 )
2016 !start integration at zero point
2021 ! fetch the effficiencies at zero point
2023 call getqext_BH(alfaip,crefin,qalfip_e,qalfip_s, gsalfp, success)
2025 sum_e = wxi * qalfip_e
2026 sum_s = wxi * qalfip_s
2027 sum_sg = wxi * gsalfp
2029 ! FSB do NMAX calls to the MIE codes
2033 xf = exp( xi * aa1 )
2035 alfaim = alfv / xf ! division cheaper than another exp()
2036 ! *** call subroutine to fetch the effficiencies
2038 call getqext_BH(alfaip,crefin,qalfip_e,qalfip_s, gsalfp, success)
2039 call getqext_BH(alfaim,crefin,qalfim_e,qalfim_s, gsalfm, success)
2041 sum_e = sum_e + wxi * ( qalfip_e + qalfim_e )
2042 sum_s = sum_s + wxi * ( qalfip_s + qalfim_s )
2043 sum_sg = sum_sg + wxi * ( gsalfp + gsalfm )
2047 g_GH = sum_sg / sum_s ! this is <cos>
2048 Qext_GH = const * sum_e !
2049 Qscat_GH = const * sum_s
2051 end subroutine ghintBH_Odd
2053 ! ------------------------------------------------------------------
2054 subroutine ghintBH_CS_Odd (INIT, RCORE, RSHELL , XX, YY, xlnsig, &
2055 Qext_GH,Qscat_GH, g_gh, success)
2057 ! FSB code for coated-sphere (core-shell) version
2059 ! *************** REVISED VERSION < NOTE
2060 ! FSB *********** This is the newest (04_14_2012) version of ghintBH_CS
2061 ! for the coated-sphere (core-shell) method using BHCOAT
2062 ! this version does the Mie method and calculates the optimum set of
2063 ! set of Gauss-Hermite abscissas and weights.
2064 ! Dr. Francis S. Binkowski, The University of North Carolina
2067 ! FSB this code file now contains all of the necessary subroutines that
2068 ! are called to perform an integral of the Bohren and Huffman
2069 ! Mie codes ( as updated by Prof. Bruce C. Drain of Princeton)
2070 ! calculates the extinction and scattering coefficients
2071 ! normalized by wavelength and total particle volume
2072 ! concentration for a log normal particle distribution
2073 ! with the logarithm of the geometric standard deviation
2074 ! given by xlnsig. The integral of the
2075 ! asymmetry factor g is also calculated.
2076 ! FSB Change 12/20/2011 This code now has a choice of IGH based
2078 ! FBB Changes Simplified code. Eliminated Penndorf code
2079 ! *** Does Gauss-Hermite quadrature of Qext / alfa & Qscat / alfa
2080 ! and asymmetry factor <cos> over log normal distribution using
2085 logical, intent(inout) :: INIT ! initialize number of qudraure points
2086 complex, intent(in) :: RCORE ! refractive index of core
2087 complex, intent(in) :: RSHELL ! refractive index of shell
2088 real, intent(in) :: XX ! Mie parameter for core
2089 real, intent(in) :: YY ! Mie parameter for shell
2090 real, intent(in) :: xlnsig ! log of geometric standard deviation
2091 real, intent(out) :: Qext_GH ! normalized extinction efficiency
2092 real, intent(out) :: Qscat_GH ! normalized scattering efficiency
2093 real, intent(out) :: g_GH ! asymmetry factor <cos>
2094 logical, intent(out) :: success ! flag for successful calculation
2096 real :: nr ! real part of refractive index
2097 real :: aa1 ! see below for definition
2098 real :: XXP, XXM ! Mie parameters at abscissas - CORE
2099 real :: YYP, YYM ! Mie parameters at abscissas - SHELL
2101 ! FSB define parameters
2102 real, parameter :: pi = 3.14159265
2103 real, parameter :: sqrtpi = 1.772454
2104 real, parameter :: sqrtpi1 = 1.0 / sqrtpi
2105 real, parameter :: sqrt2 = 1.414214
2106 real, parameter :: three_pi_two = 3.0 * pi / 2.0
2107 real, parameter :: const = three_pi_two * sqrtpi1
2109 ! *** these are Qext/alfa and Qscat/alfv at the abscissas
2110 real :: qalfip_e, qalfim_e ! extinction
2111 real :: qalfip_s, qalfim_s ! scattering
2112 real :: gsalfp, gsalfm ! scattering times asymmetry factor
2114 real :: sum_e,sum_s, xi,wxi,xf, temp
2117 real, allocatable, save :: GHXI(:), GHWI(:) ! weight and abscissas
2118 integer, save :: IGH ! number of weights and abscissa
2119 integer, save :: NMAX ! optimized number of weights and abscissa
2122 ! FSB now choose IGH. These choices are designed to improve
2123 ! the computational efficiency without sacrificing accuracy.
2127 Select Case( Quadrature_Points )
2129 IGH = Quadrature_Points
2134 If( Allocated( GHXI ) .Or. Allocated( GHWI ) )Then
2139 NMAX = Max( Int( IGH / 2 ), 0)
2141 Allocate( GHXI( NMAX + 1 ), GHWI( NMAX + 1 ) )
2159 If( AERO_UTIL_LOG .GT. 0 )Then
2160 write(AERO_UTIL_LOG,*)'BHCoat: IGH,(NMAX + 1) = ',IGH,(NMAX + 1)
2162 write(AERO_UTIL_LOG,*)'BHCoat: i, GHXI(i), GHWI(i) = ',i, GHXI(i), GHWI(i)
2169 If( .Not. Allocated( GHXI ) .Or. .Not. Allocated( GHWI ) )Then
2173 End If ! set up number of abscissas and weights
2177 ! FSB now start the integration code
2178 aa1 = sqrt2 * xlnsig ! This 1.0 / Sqrt( A ) in derivation of the integral
2179 ! where A = 1.0 / ( 2.0 * xlnsg**2 )
2181 ! Then alpha = alfv * exp[ u / sqrt(A) ]
2182 ! For Gauss-Hermite Quadrature u = xi
2183 ! Therefore, xf = exp( xi / sqrt(A) ),
2184 ! or xf = exp( xi * aa1 )
2186 !start integration at zero point
2194 ! fetch the effficiencies at zero point
2196 call getqsgBHCS(XXP,YYP,RCORE,RSHELL,qalfip_e,qalfip_s,gsalfp, success)
2198 sum_e = wxi * qalfip_e
2199 sum_s = wxi * qalfip_s
2200 sum_sg = wxi * gsalfp
2202 ! FSB do NMAX calls to the MIE codes
2206 xf = exp( xi * aa1 )
2209 XXM = XX * temp ! division cheaper than another exp()
2211 YYM = YY * temp ! division cheaper than another exp()
2212 ! *** call subroutine to fetch the effficiencies
2214 call getqsgBHCS(XXP,YYP,RCORE,RSHELL,qalfip_e,qalfip_s,gsalfp, success)
2215 call getqsgBHCS(XXM,YYM,RCORE,RSHELL,qalfim_e,qalfim_s,gsalfm, success)
2217 sum_e = sum_e + wxi * ( qalfip_e + qalfim_e )
2218 sum_s = sum_s + wxi * ( qalfip_s + qalfim_s )
2219 sum_sg = sum_sg + wxi * ( gsalfp + gsalfm )
2222 g_GH = sum_sg / sum_s ! this is <cos>
2223 Qext_GH = const * sum_e !
2224 Qscat_GH = const * sum_s
2226 end subroutine ghintBH_CS_Odd
2228 ! ------------------------------------------------------------------
2229 SUBROUTINE BHMIE_FLEXI (X, NMX, NSTOP, REFREL, QQEXT, QQSCA, QBACK, GSCA, SUCCESS)
2231 ! FSB Changed the call vector to return only QEXT, QSCAT QBACK GSCA
2232 ! and ignore NANG, S1 and S2 and all calculations for them
2237 real, intent(in) :: X ! X = pi*particle_diameter / Wavelength
2238 integer, intent(in) :: NMX ! maximum number of terms in Mie series
2239 integer, intent(in) :: NSTOP ! minumum number of terms in Mie series
2240 complex, intent(in) :: REFREL ! refractive index
2242 ! REFREL = (complex refr. index of sphere)/(real index of medium)
2243 ! in the current use the index of refraction of the the medium
2244 ! i taken at 1.0 real.
2248 real, intent(out) :: QQEXT, QQSCA, QBACK, GSCA
2249 logical, intent(out) :: SUCCESS
2251 ! QQEXT Efficiency factor for extinction
2252 ! QQSCA Efficiency factor for scattering
2253 ! QQBACK Efficiency factor for back scatter
2254 ! GSCA asymmetry factor <cos>
2255 ! SUCCESS flag for successful calculation
2257 ! Bohren, Craig F. and Donald R. Huffman, Absorption and
2258 ! Scattering of Light by Small Particles, Wiley-Interscience
2259 ! copyright 1983. Paperback Published 1998.
2261 ! This code was originally listed in Appendix A. pp 477-482.
2262 ! As noted below, the original code was subsequently
2263 ! modified by Prof. Bruce T. Drain of Princetion University.
2264 ! The code was further modified for a specific application
2265 ! in a large three-dimensional code requiring as much
2266 ! computational efficiency as possible.
2267 ! Prof. Francis S. Binkowski of The University of North
2268 ! Carolina at Chapel Hill.
2270 ! Declare parameters:
2271 ! Note: important that MXNANG be consistent with dimension of S1 and S2
2272 ! in calling routine!
2274 integer, parameter :: MXNANG=10, NMXX=150000 ! FSB new limits
2275 integer, parameter :: NANG = 2
2276 real*8, parameter :: PII = 3.1415916536D0
2277 real*8, parameter :: ONE = 1.0D0, TWO = 2.0D0
2278 complex*16, parameter :: COMPLEX_DZERO = (0.0D0,0.0D0)
2279 complex, parameter :: COMPLEX_ZERO = (0.0,0.0)
2283 real*8 :: QSCA, QEXT, DX1, DXX1
2284 real*8 :: CHI,CHI0,CHI1,DX,EN,P,PSI,PSI0,PSI1,XSTOP,YMOD
2285 real*8 :: TWO_N_M_ONE, TWO_N_P_ONE, EN1, FACTOR
2286 complex*16 :: AN,AN1,BN,BN1,DREFRL,XI,XI1,Y, Y1, DREFRL1
2287 complex*16 :: D(NMX)
2288 complex*16 :: FAC1, FAC2
2291 !***********************************************************************
2292 ! Subroutine BHMIE is the Bohren-Huffman Mie scattering subroutine
2293 ! to calculate scattering and absorption by a homogenous isotropic
2297 ! REFREL = (complex refr. index of sphere)/(real index of medium)
2298 ! real refractive index of medium taken as 1.0
2300 ! QEXT = efficiency factor for extinction
2301 ! QSCA = efficiency factor for scattering
2302 ! QBACK = efficiency factor for backscatter
2303 ! see Bohren & Huffman 1983 p. 122
2304 ! GSCA = <cos> asymmetry for scattering
2306 ! Original program taken from Bohren and Huffman (1983), Appendix A
2307 ! Modified by Prof. Bruce T.Draine, Princeton Univ. Obs., 90/10/26
2308 ! in order to compute <cos(theta)>
2309 ! 91/05/07 (BTD): Modified to allow NANG=1
2310 ! 91/08/15 (BTD): Corrected error (failure to initialize P)
2311 ! 91/08/15 (BTD): Modified to enhance vectorizability.
2312 ! 91/08/15 (BTD): Modified to make NANG=2 if called with NANG=1
2313 ! 91/08/15 (BTD): Changed definition of QBACK.
2314 ! 92/01/08 (BTD): Converted to full double precision and double complex
2315 ! eliminated 2 unneed lines of code
2316 ! eliminated redundant variables (e.g. APSI,APSI0)
2317 ! renamed RN -> EN = double precision N
2318 ! Note that DOUBLE COMPLEX and DCMPLX are not part
2319 ! of f77 standard, so this version may not be fully
2320 ! portable. In event that portable version is
2321 ! needed, use src/bhmie_f77.f
2322 ! 93/06/01 (BTD): Changed AMAX1 to generic function MAX
2323 ! FSB April 09,2012 This code was modified by:
2324 ! Prof. Francis S. Binkowski University of North Carolina at
2325 ! Chapel Hill, Institue for the Environment.
2327 ! The modifications were made to enhance computation speed
2328 ! for use in a three-dimensional code. This was done by
2329 ! removing code that calculated angular scattering. The method
2330 ! of calculating QEXT, QBACK was also changed.
2332 !***********************************************************************
2336 ! NANG = 2 ! FSB only this value
2337 ! IF(NANG.GT.MXNANG)STOP'***Error: NANG > MXNANG in bhmie'
2338 ! IF (NANG .LT. 2) NANG = 2
2341 ! FSB Define reciprocals so that divisions can be replaced by multiplications.
2344 DREFRL = DCMPLX( REAL( REFREL ), IMAG( REFREL ) )
2345 DREFRL1 = ONE / DREFRL
2350 !*** Series expansion terminated after NSTOP terms
2351 ! Logarithmic derivatives calculated from NMX on down
2352 ! XSTOP = X + 4.0 * X**0.3333 + 2.0
2353 ! NMX = MAX(XSTOP,YMOD) + 15
2355 ! BTD experiment 91/1/15: add one more term to series and compare results
2356 ! NMX=AMAX1(XSTOP,YMOD)+16
2357 ! test: compute 7001 wavelengths between .0001 and 1000 micron
2358 ! for a=1.0micron SiC grain. When NMX increased by 1, only a single
2359 ! computed number changed (out of 4*7001) and it only changed by 1/8387
2360 ! conclusion: we are indeed retaining enough terms in series!
2364 ! IF (NMX .GT. NMXX) THEN
2365 ! WRITE(6,*)'Error: NMX > NMXX=',NMXX,' for |m|x=',YMOD
2370 ! FSB all code relating to scattering angles is removed out for
2371 ! reasons of efficiency when running in a three-dimensional
2372 ! code. We only need QQSCA, QQEXT, GSCA AND QBACK
2374 !*** Logarithmic derivative D(J) calculated by downward recurrence
2375 ! beginning with initial value (0.,0.)
2377 D(NMX) = COMPLEX_DZERO
2380 EN = REAL( NMX - N + 1, 8 )
2381 ! FSB In the following division by Y has been replaced by
2382 ! multiplication by Y1, the reciprocal of Y.
2383 D(NMX-N) = ( EN * Y1 ) - (ONE / ( D(NMX-N+1) + EN * Y1))
2386 !*** Riccati-Bessel functions with real argument X
2387 ! calculated by upward recurrence
2393 XI1 = DCMPLX(PSI1,-CHI1)
2398 XBACK = COMPLEX_DZERO
2400 ! FSB Start main loop
2404 TWO_N_M_ONE = TWO * EN - ONE
2405 ! for given N, PSI = psi_n CHI = chi_n
2406 ! PSI1 = psi_{n-1} CHI1 = chi_{n-1}
2407 ! PSI0 = psi_{n-2} CHI0 = chi_{n-2}
2408 ! Calculate psi_n and chi_n
2409 PSI = TWO_N_M_ONE * PSI1 * DX1 - PSI0
2410 CHI = TWO_N_M_ONE * CHI1 * DX1 - CHI0
2411 XI = DCMPLX(PSI,-CHI)
2413 !*** Compute AN and BN:
2414 ! FSB Rearrange to get common terms
2415 FAC1 = D(N) * DREFRL1 + EN * DX1
2416 AN = (FAC1) * PSI - PSI1
2417 AN = AN / ( (FAC1 )* XI - XI1 )
2418 FAC2 = ( DREFRL * D(N) + EN * DX1)
2419 BN = ( FAC2) * PSI -PSI1
2420 BN = BN / ((FAC2) * XI - XI1 )
2422 ! FSB calculate sum for QEXT as done by Wiscombe
2424 TWO_N_P_ONE = (TWO * EN + ONE)
2425 QEXT = QEXT + (TWO_N_P_ONE) * (REAL(AN) + REAL(BN) )
2426 QSCA = QSCA + (TWO_N_P_ONE) * ( ABS(AN)**2 + ABS(BN)**2 )
2428 ! FSB calculate XBACK from B & H Page 122
2429 FACTOR = -1.0d0 * FACTOR ! calculate (-1.0 ** N)
2430 XBACK = XBACK + (TWO_N_P_ONE) * factor * (AN - BN)
2432 ! FSB calculate asymmetry factor
2434 GSCA = GSCA + REAL((TWO_N_P_ONE)/(EN * (EN + ONE)) * &
2435 (REAL(AN)*REAL(BN)+IMAG(AN)*IMAG(BN)))
2438 GSCA = GSCA + REAL((EN - EN1) * &
2439 (REAL(AN1)*REAL(AN) + IMAG(AN1)*IMAG(AN) + &
2440 REAL(BN1)*REAL(BN) + IMAG(BN1)*IMAG(BN)))
2443 !*** Store previous values of AN and BN for use in computation of g=<cos(theta)>
2447 ! FSB set up for next iteration
2452 XI1 = DCMPLX(PSI1,-CHI1)
2454 END DO ! main loop on n
2456 !*** Have summed sufficient terms.
2458 ! Now compute QQSCA,QQEXT,QBACK,and GSCA
2459 GSCA = REAL( TWO / QSCA ) * GSCA
2461 ! FSB in the following, divisions by DX * DX has been replaced by
2462 ! multiplication by DXX1 the reciprocal of 1.0 / (DX *DX)
2463 QQSCA = REAL( TWO * QSCA * DXX1 )
2464 QQEXT = REAL( TWO * QEXT * DXX1 )
2465 QBACK = REAL( REAL( 0.5D0 * XBACK * CONJG(XBACK), 8 ) * DXX1 ) ! B&H Page 122
2467 END subroutine BHMIE_FLEXI
2469 END MODULE rrtmg_aero_optical_util_module
2471 ! ------------------------------------------------------------------
2472 ! FSB REvised Mie calculations 02/09/2011
2474 MODULE module_ra_rrtmg_sw_cmaq
2478 !------------------------------------------------------------------
2479 Subroutine get_aerosol_Optics_RRTMG_SW ( ns, nmode,delta_z, INMASS_ws, &
2480 INMASS_in, INMASS_ec, INMASS_ss, &
2481 INMASS_h2o, INDGN, INSIG, &
2482 tauaer, waer, gaer )
2484 !FSB This version switches between BHCOAT to BHMIE depending upon whether
2485 ! EC is present or not. 04/15/2012.
2487 !FSB this version does a core-shell calculation with BHCOAT 04/11/2012
2488 ! This version is set up to be used with RRTMG_SW <<<<<<<<
2489 ! wavelenght is calculated internally
2490 ! FSB This routine calculates the aerosol information ( tauaer, waer,
2491 ! gaer, needed to calculate the solar radiation) The calling
2492 ! program specifies the location ( row, column, layer,
2493 ! layer thicknes, and wave length for the calculation.
2494 ! FSB 02/09/2011 Modifications made to subroutine ghintBH.
2495 ! FSB 04/14/2012 REmoved MODULUS, made changes to ghintBH.
2496 ! Put in option for core-shell (coated-sphere). 2
2498 ! FSB Input variables:
2500 use rrtmg_aero_optical_util_module
2504 integer,intent(in) :: ns ! index for wavelength should be
2505 ! between 1 and 14. <<< RRTMG_SW
2506 integer,intent(in) :: nmode ! should be 3 for WRF/CMAQ calculation
2507 real,intent(in) :: delta_z ! layer thickness [m]
2508 ! FSB mode types for WRF/CMAQ
2510 ! nmode = 2 accumulation
2512 ! FSB modal mass concentration by species [ ug / m**3] NOTE: MKS
2513 real, intent(in) :: INMASS_ws(nmode) ! water soluble
2514 real, intent(in) :: INMASS_in(nmode) ! insolugle
2515 real, intent(in) :: INMASS_ec(nmode) ! elemental carbon or soot like
2516 real, intent(in) :: INMASS_ss(nmode) ! sea salt
2517 real, intent(in) :: INMASS_h2o(nmode) ! water
2518 ! FSB particle size-distribution information
2519 real, intent(in) :: INDGN( nmode) ! geometric mean diameter [ m ] NOTE: MKS
2520 real, intent(in) :: INSIG( nmode) ! geometric standard deviation
2522 !FSB output aerosol radiative properties [dimensionless]
2523 real, intent(out) :: tauaer ! aerosol extinction optical depth
2524 real, intent(out) :: waer ! aerosol single scattering albedo
2525 real, intent(out) :: gaer ! aerosol assymetry parameter
2527 ! FSB Internal variables
2529 real :: NR(nmode), NI(nmode) ! refractive indices
2530 complex :: refcor(nmode), refshell(nmode) ! complex refracive indices
2531 complex :: crefin(nmode) ! complex refractive index
2533 ! FSB special values for EC CORE-shell calculation
2534 real :: DGNSHELL(nmode) ! modal geometric mean diameter [m]
2535 real :: DGNCORE (nmode) ! modal geometric mean diameter [m]
2537 ! FSB Modal volumes [ m**3 / m**3 ]
2538 real :: MVOL_ws(nmode) ! water soluble
2539 real :: MVOL_in(nmode) ! insolugle
2540 real :: MVOL_ec(nmode) ! soot like
2541 real :: MVOL_ss(nmode) !sea salt
2542 real :: MVOL_h2o(nmode) ! water
2543 ! real :: VOL(nmode) ! total modal volume [m** 3 / m**3]
2544 ! FSB special values for EC CORE-shell calculation
2545 real :: VOLCOR(nmode) ! volume of EC core [m** 3 / m**3]
2546 real :: VOLSHELL(nmode) ! volume of shell [m** 3 / m**3]
2548 integer :: m ! loop index
2549 real :: bext ! extinction coefficient [1 / m]
2550 real :: bscat ! scattering coefficient [1 / m]
2551 real :: gfac ! asymmetry factor
2553 real :: bextsum, bscatsum, bsgsum
2555 ! FSB History variables by wavelength and mode
2556 ! real :: bext_wm(ns,nmode)
2557 ! real :: bscat_wm(ns,nmode)
2558 ! real :: gfac_wm(ns,nmode)
2560 real, parameter :: one3rd = 1.0 / 3.0
2561 real :: dfac ! ratio of (volcor/vol) ** one3rd
2562 ! used for calculating the diameter
2567 !...component densities [ g/ cm**3 ] <<<<< cgs
2569 real, parameter :: rhows = 1.8 ! bulk density of water soluble aerosol
2571 real, parameter :: rhoin = 2.2 ! bulk density forinsoluble aerosol
2573 ! real, parameter :: rhoec = 1.7 ! bulk density for soot aerosol
2574 real, parameter :: rhoec = 1.8 ! new value
2576 real, parameter :: rhoh2o = 1.0 ! bulk density of aerosol water
2578 real, parameter :: rhoss = 2.2 ! bulk density of seasalt
2580 ! FSB scale factor for volume calculation
2581 ! 1.0d-12 * [ cm**3 / g] -> [ m** 3 / ug ]
2582 real, parameter :: scalefactor = 1.0e-12
2584 ! FSB scale factor for [1/g] to [1/ug]
2585 real, parameter :: cug2g = 1.0e-06
2587 ! FSB reciprocal component densities[ m ** 3 / ug ]
2589 real, parameter :: rhows1 = scalefactor / rhows ! water soluble aerosol
2591 real, parameter :: rhoin1 = scalefactor / rhoin ! insoluble aerosol
2593 real, parameter :: rhoec1 = scalefactor / rhoec ! soot aerosol
2595 real, parameter :: rhoh2o1 = scalefactor / rhoh2o ! aerosol water
2597 real, parameter :: rhoss1 = scalefactor / rhoss ! seasalt
2599 integer,parameter :: nspint_sw = 14 ! number of spectral intervals for RRTMG_SW
2601 ! FSB Band numbers and wavelengths for RRTMG_SW
2602 integer, parameter :: Band(nspint_sw) = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 /)
2604 real, parameter :: LAMDA_SW(nspint_sw) = (/ 3.4615, 2.7885, 2.325, 2.046, 1.784, &
2605 1.4625, 1.2705, 1.0101, 0.7016, 0.53325, &
2606 0.38815, 0.299, 0.2316, 8.24 /) ! wavelength [ um ]
2608 ! *** refractive indices
2610 ! *** Except as otherwise noted reference values of refractive
2611 ! indices for aerosol particles are from the OPAC Data base.
2612 ! Hess, Koepke, and Schult, Optical properties of
2613 ! aerosols and clouds: The software package OPAC, Bulletan of
2614 ! the American Meteorological Society, Vol 79, No 5,
2615 ! pp 831 - 844, May 1998.
2616 ! OPAC is a downloadable data set of optical properties of
2617 ! 10 aerosol components, 6 water clouds and 3 cirrus clouds
2618 ! at UV, visible and IR wavelengths
2619 ! www.lrz-muenchen.de/~uh234an/www/radaer/opac.htm
2623 real, parameter :: xnreal_ws(nspint_sw) = (/ 1.443, 1.420, 1.420, 1.420, 1.463, 1.510, 1.510, &
2624 1.520, 1.530, 1.530, 1.530, 1.530, 1.530, 1.710 /)
2625 real, parameter :: xnimag_ws(nspint_sw) = (/ 5.718E-3, 1.777E-2, 1.060E-2, 8.368E-3, 1.621E-2, &
2626 2.198E-2, 1.929E-2, 1.564E-2, 7.000E-3, 5.666E-3, &
2627 5.000E-3, 8.440E-3, 3.000E-2, 1.100E-1 /)
2630 real, parameter :: xnreal_ss(nspint_sw) = (/ 1.480, 1.534, 1.437, 1.448, 1.450, 1.462, 1.469, &
2631 1.470, 1.490, 1.500, 1.502, 1.510, 1.510, 1.510 /)
2633 real, parameter :: xnimag_ss(nspint_sw) = (/ 1.758E-3, 7.462E-3, 2.950E-3, 1.276E-3, 7.944E-4, &
2634 5.382E-4, 3.754E-4, 1.498E-4, 2.050E-7, 1.184E-8, &
2635 9.938E-8, 2.060E-6, 5.000E-6, 1.000E-2 /)
2638 real, parameter :: xnreal_in(nspint_sw) = (/ 1.272, 1.168, 1.208, 1.253, 1.329, 1.418, 1.456, &
2639 1.518, 1.530, 1.530, 1.530, 1.530, 1.530, 1.470 /)
2640 real, parameter :: xnimag_in(nspint_sw) = (/ 1.165E-2, 1.073E-2, 8.650E-3, 8.092E-3, 8.000E-3, &
2641 8.000E-3, 8.000E-3, 8.000E-3, 8.000E-3, 8.000E-3, &
2642 8.000E-3, 8.440E-3, 3.000E-2,9.000E-2 /)
2644 ! FSB 02/11/2012 These values are replaced.
2645 ! data xnreal_ec /1.877, 1.832, 1.813, 1.802, 1.791, 1.769, 1.761, &
2646 ! 1.760, 1.750, 1.740, 1.750, 1.738, 1.620, 2.120/
2647 ! data xnimag_ec/ 5.563E-1, 5.273E-1, 5.030E-1, 4.918E-1, 4.814E-1, &
2648 ! 4.585E-1, 4.508E-1, 4.404E-1, 4.300E-1, 4.400E-1, &
2649 ! 4.600E-1, 4.696E-1, 4.500E-1, 5.700E-1/
2651 ! New Refractive indices for EC at RRTMG Wavelengths
2652 ! Source lamda xnreal_ec xnimag_ec
2654 ! 3.4615 2.089 1.070
2655 ! 2.7885 2.014 0.939
2660 ! 1.4625 1.930 0.749
2661 ! 1.2705 1.905 0.737
2662 ! 1.0101 1.870 0.726
2672 ! Bond Personal Communication from Tami Bond
2673 ! B&B Bond, T.C. & R.W. Bergstrom (2006) Light absorption by
2674 ! Carbonaceous Particles: An investigative review,
2675 ! Aerosol Science and Technology. Vol. 40. pp 27-67
2677 ! C&C Chang,H and T.T. Charalmpopoulos (1990) Determination of the
2678 ! wavelength dependence of refractive indices of flame soot,
2679 ! Proceeding of the Royal Society of London A, Vol. 430, pp 577-591.
2682 ! FSB elemental carbon - soot like
2684 real, parameter :: xnreal_ec(nspint_sw) = (/ 2.089, 2.014, 1.962, 1.950, 1.940, 1.930, 1.905, &
2685 1.870, 1.85, 1.85, 1.85, 1.85, 1.85, 2.589 /)
2686 real, parameter :: xnimag_ec(nspint_sw) = (/ 1.070, 0.939, 0.843, 0.784, 0.760, 0.749, 0.737, &
2687 0.726, 0.71, 0.71, 0.71, 0.71, 0.71, 1.771 /)
2690 real, save :: xnreal_h2o(nspint_sw) = (/ 1.408, 1.324, 1.277, 1.302, 1.312, 1.321, 1.323, &
2691 1.327, 1.331, 1.334, 1.340, 1.349, 1.362, 1.260 /)
2692 real, save :: xnimag_h2o(nspint_sw) = (/ 1.420E-2, 1.577E-1, 1.516E-3, 1.159E-3, 2.360E-4, &
2693 1.713E-4, 2.425E-5, 3.125E-6, 3.405E-8, 1.639E-9, &
2694 2.955E-9, 1.635E-8, 3.350E-8, 6.220E-2 /)
2696 ! FSB Begin code ======================================================
2702 ! FSB calculate volumes [ m**3 / m**3 ]
2703 ! FSB the reciprocal densities have been scaled to [ m**3 / ug ]
2705 MVOL_ws(m) = rhows1 * INMASS_ws(m)
2706 MVOL_in(m) = rhoin1 * INMASS_in(m)
2707 MVOL_ec(m) = rhoec1 * INMASS_ec(m)
2708 MVOL_ss(m) = rhoss1 * INMASS_ss(m)
2709 MVOL_h2o(m) = rhoh2o1 * INMASS_h2o(m)
2711 VOLSHELL(m) = MVOL_ws(m) + MVOL_in(m) + MVOL_ss(m) + MVOL_h2o(m)
2712 VOLCOR(m) = MVOL_ec(m)
2713 ! VOL(m) = VOLSHELL(m) + VOLCOR(m) ! VOL is total volume
2715 if ( VOLCOR(m) .gt. 0.0 ) then
2717 ! calculate the ratio of core to shell volume
2718 ! take cube root for scaling the diameter of
2719 ! the core to that of the shell.
2721 ! dfac = ( VOLCOR(m) / VOL(m) ) ** one3rd
2722 dfac = ( VOLCOR(m) / ( VOLSHELL(m) + VOLCOR(m) ) ) ** one3rd
2723 ! dfac = ( VOLCOR(m) / ( VOLSHELL(m) + VOLCOR(m) ) )
2724 ! FSB Set shell and core diameters
2725 DGNSHELL(m) = INDGN(m)
2726 DGNCORE(M) = dfac * INDGN(m)
2727 ! FSB note that VOLSHELL(m) is the total volume when EC is not present
2730 ! internal mixture of non-EC species.
2732 ! modal real refractive index No EC
2733 nr(m) = (MVOL_ws(m) * xnreal_ws(ns) + &
2734 MVOL_in(m) * xnreal_in(ns) + &
2735 MVOL_ss(m) * xnreal_ss(ns) + &
2736 ! MVOL_h2o(m) * xnreal_h2o(ns)) / VOL(m)
2737 MVOL_h2o(m) * xnreal_h2o(ns)) / VOLSHELL(m)
2739 ! modal imaginary refractive index no EC
2740 ni(m) = (MVOL_ws(m) * xnimag_ws(ns) + &
2741 MVOL_in(m) * xnimag_in(ns) + &
2742 MVOL_ss(m) * xnimag_ss(ns) + &
2743 ! MVOL_h2o(m) * xnimag_h2o(ns)) / VOL(m)
2744 MVOL_h2o(m) * xnimag_h2o(ns)) / VOLSHELL(m)
2746 if ( VOLCOR(m) .gt. 0.0) then
2748 ! FSB calculate the complex refractive indices for the CORE and
2749 ! the SHELL for case when and EC core is assumed to exist.
2751 refcor(m) = cmplx( xnreal_ec(ns), xnimag_ec(ns) )
2752 refshell(m) = cmplx(nr(m), ni(m) )
2753 ! FSB do BHCOAT case
2754 CALL aero_optical_CS( LAMDA_SW(ns), refcor(m), refshell(m), &
2755 VOLCOR(m),VOLSHELL(m), DGNCORE(m), &
2756 DGNSHELL(m), INSIG(m), &
2757 bext, bscat, gfac, succesS )
2758 ! else if ( VOL(m) .gt. 0.0) then
2759 else if ( VOLSHELL(m) .gt. 0.0) then
2760 ! FSB do BHMIE case for the case when EC is not present.
2761 crefin(m) = cmplx(nr(m), ni(m) )
2762 ! CALL aero_optical2( LAMDA_SW(ns), crefin(m), VOL(m), &
2763 CALL aero_optical2( LAMDA_SW(ns), crefin(m), VOLSHELL(m), &
2764 INDGN(m), INSIG(m), &
2765 bext, bscat, gfac, success )
2772 ! FSB sum for total values
2773 bextsum = bextsum + bext
2774 bscatsum = bscatsum +bscat
2775 bsgsum = bsgsum + bscat * gfac
2777 ! bext_wm(ns,m) = bext
2778 ! bscat_wm(ns,m) = bscat
2779 ! gfac_wm(ns,m) = gfac
2780 end do ! loop over modes
2782 ! FSB construct output variables
2783 tauaer = bextsum * delta_z
2784 waer = bscatsum / bextsum
2785 gaer = bsgsum / bscatsum
2787 end subroutine get_aerosol_Optics_RRTMG_SW
2789 END MODULE module_ra_rrtmg_sw_cmaq