1 !+---+-----------------------------------------------------------------+
2 !..This set of routines facilitates computing radar reflectivity.
3 !.. This module is more library code whereas the individual microphysics
4 !.. schemes contains specific details needed for the final computation,
5 !.. so refer to location within each schemes calling the routine named
6 !.. rayleigh_soak_wetgraupel.
7 !.. The bulk of this code originated from Ulrich Blahak (Germany) and
8 !.. was adapted to WRF by G. Thompson. This version of code is only
9 !.. intended for use when Rayleigh scattering principles dominate and
10 !.. is not intended for wavelengths in which Mie scattering is a
11 !.. significant portion. Therefore, it is well-suited to use with
12 !.. 5 or 10 cm wavelength like USA NEXRAD radars.
13 !.. This code makes some rather simple assumptions about water
14 !.. coating on outside of frozen species (snow/graupel). Fraction of
15 !.. meltwater is simply the ratio of mixing ratio below melting level
16 !.. divided by mixing ratio at level just above highest T>0C. Also,
17 !.. immediately 90% of the melted water exists on the ice's surface
18 !.. and 10% is embedded within ice. No water is "shed" at all in these
19 !.. assumptions. The code is quite slow because it does the reflectivity
20 !.. calculations based on 50 individual size bins of the distributions.
21 !+---+-----------------------------------------------------------------+
23 MODULE module_mp_radar
27 PUBLIC :: rayleigh_soak_wetgraupel
29 PRIVATE :: m_complex_water_ray
30 PRIVATE :: m_complex_ice_maetzler
31 PRIVATE :: m_complex_maxwellgarnett
32 PRIVATE :: get_m_mix_nested
38 INTEGER, PARAMETER, PUBLIC:: nrbins = 50
39 DOUBLE PRECISION, DIMENSION(nrbins+1), PUBLIC:: xxDx
40 DOUBLE PRECISION, DIMENSION(nrbins), PUBLIC:: xxDs,xdts,xxDg,xdtg
41 DOUBLE PRECISION, PARAMETER, PUBLIC:: lamda_radar = 0.10 ! in meters
42 DOUBLE PRECISION, PUBLIC:: K_w, PI5, lamda4
43 COMPLEX*16, PUBLIC:: m_w_0, m_i_0
44 DOUBLE PRECISION, DIMENSION(nrbins+1), PUBLIC:: simpson
45 DOUBLE PRECISION, DIMENSION(3), PARAMETER, PUBLIC:: basis = &
46 (/1.d0/3.d0, 4.d0/3.d0, 1.d0/3.d0/)
47 REAL, DIMENSION(4), PUBLIC:: xcre, xcse, xcge, xcrg, xcsg, xcgg
48 REAL, PUBLIC:: xam_r, xbm_r, xmu_r, xobmr
49 REAL, PUBLIC:: xam_s, xbm_s, xmu_s, xoams, xobms, xocms
50 REAL, PUBLIC:: xam_g, xbm_g, xmu_g, xoamg, xobmg, xocmg
51 REAL, PUBLIC:: xorg2, xosg2, xogg2
53 INTEGER, PARAMETER, PUBLIC:: slen = 20
54 CHARACTER(len=slen), PUBLIC:: &
55 mixingrulestring_s, matrixstring_s, inclusionstring_s, &
56 hoststring_s, hostmatrixstring_s, hostinclusionstring_s, &
57 mixingrulestring_g, matrixstring_g, inclusionstring_g, &
58 hoststring_g, hostmatrixstring_g, hostinclusionstring_g
60 !..Single melting snow/graupel particle 90% meltwater on external sfc
61 DOUBLE PRECISION, PARAMETER:: melt_outside_s = 0.9d0
62 DOUBLE PRECISION, PARAMETER:: melt_outside_g = 0.9d0
64 CHARACTER*256:: radar_debug
68 !+---+-----------------------------------------------------------------+
69 !+---+-----------------------------------------------------------------+
70 !+---+-----------------------------------------------------------------+
76 PI5 = 3.14159*3.14159*3.14159*3.14159*3.14159
77 lamda4 = lamda_radar*lamda_radar*lamda_radar*lamda_radar
78 m_w_0 = m_complex_water_ray (lamda_radar, 0.0d0)
79 m_i_0 = m_complex_ice_maetzler (lamda_radar, 0.0d0)
80 K_w = (ABS( (m_w_0*m_w_0 - 1.0) /(m_w_0*m_w_0 + 2.0) ))**2
86 simpson(n) = simpson(n) + basis(1)
87 simpson(n+1) = simpson(n+1) + basis(2)
88 simpson(n+2) = simpson(n+2) + basis(3)
92 mixingrulestring_s(n:n) = char(0)
93 matrixstring_s(n:n) = char(0)
94 inclusionstring_s(n:n) = char(0)
95 hoststring_s(n:n) = char(0)
96 hostmatrixstring_s(n:n) = char(0)
97 hostinclusionstring_s(n:n) = char(0)
98 mixingrulestring_g(n:n) = char(0)
99 matrixstring_g(n:n) = char(0)
100 inclusionstring_g(n:n) = char(0)
101 hoststring_g(n:n) = char(0)
102 hostmatrixstring_g(n:n) = char(0)
103 hostinclusionstring_g(n:n) = char(0)
106 mixingrulestring_s = 'maxwellgarnett'
108 matrixstring_s = 'water'
109 inclusionstring_s = 'spheroidal'
110 hostmatrixstring_s = 'icewater'
111 hostinclusionstring_s = 'spheroidal'
113 mixingrulestring_g = 'maxwellgarnett'
115 matrixstring_g = 'water'
116 inclusionstring_g = 'spheroidal'
117 hostmatrixstring_g = 'icewater'
118 hostinclusionstring_g = 'spheroidal'
120 !..Create bins of snow (from 100 microns up to 2 cm).
122 xxDx(nrbins+1) = 0.02d0
124 xxDx(n) = DEXP(DFLOAT(n-1)/DFLOAT(nrbins) &
125 *DLOG(xxDx(nrbins+1)/xxDx(1)) +DLOG(xxDx(1)))
128 xxDs(n) = DSQRT(xxDx(n)*xxDx(n+1))
129 xdts(n) = xxDx(n+1) - xxDx(n)
132 !..Create bins of graupel (from 100 microns up to 5 cm).
134 xxDx(nrbins+1) = 0.05d0
136 xxDx(n) = DEXP(DFLOAT(n-1)/DFLOAT(nrbins) &
137 *DLOG(xxDx(nrbins+1)/xxDx(1)) +DLOG(xxDx(1)))
140 xxDg(n) = DSQRT(xxDx(n)*xxDx(n+1))
141 xdtg(n) = xxDx(n+1) - xxDx(n)
145 !..The calling program must set the m(D) relations and gamma shape
146 !.. parameter mu for rain, snow, and graupel. Easily add other types
147 !.. based on the template here. For majority of schemes with simpler
148 !.. exponential number distribution, mu=0.
152 xcre(3) = 1. + xbm_r + xmu_r
153 xcre(4) = 1. + 2.*xbm_r + xmu_r
155 xcrg(n) = WGAMMA(xcre(n))
161 xcse(3) = 1. + xbm_s + xmu_s
162 xcse(4) = 1. + 2.*xbm_s + xmu_s
164 xcsg(n) = WGAMMA(xcse(n))
170 xcge(3) = 1. + xbm_g + xmu_g
171 xcge(4) = 1. + 2.*xbm_g + xmu_g
173 xcgg(n) = WGAMMA(xcge(n))
186 end subroutine radar_init
188 !+---+-----------------------------------------------------------------+
189 !+---+-----------------------------------------------------------------+
191 COMPLEX*16 FUNCTION m_complex_water_ray(lambda,T)
193 ! Complex refractive Index of Water as function of Temperature T
194 ! [deg C] and radar wavelength lambda [m]; valid for
195 ! lambda in [0.001,1.0] m; T in [-10.0,30.0] deg C
199 DOUBLE PRECISION, INTENT(IN):: T,lambda
200 DOUBLE PRECISION:: epsinf,epss,epsr,epsi
201 DOUBLE PRECISION:: alpha,lambdas,sigma,nenner
202 COMPLEX*16, PARAMETER:: i = (0d0,1d0)
203 DOUBLE PRECISION, PARAMETER:: PIx=3.1415926535897932384626434d0
205 epsinf = 5.27137d0 + 0.02164740d0 * T - 0.00131198d0 * T*T
206 epss = 78.54d+0 * (1.0 - 4.579d-3 * (T - 25.0) &
207 + 1.190d-5 * (T - 25.0)*(T - 25.0) &
208 - 2.800d-8 * (T - 25.0)*(T - 25.0)*(T - 25.0))
209 alpha = -16.8129d0/(T+273.16) + 0.0609265d0
210 lambdas = 0.00033836d0 * exp(2513.98d0/(T+273.16)) * 1e-2
212 nenner = 1.d0+2.d0*(lambdas/lambda)**(1d0-alpha)*sin(alpha*PIx*0.5) &
213 + (lambdas/lambda)**(2d0-2d0*alpha)
214 epsr = epsinf + ((epss-epsinf) * ((lambdas/lambda)**(1d0-alpha) &
215 * sin(alpha*PIx*0.5)+1d0)) / nenner
216 epsi = ((epss-epsinf) * ((lambdas/lambda)**(1d0-alpha) &
217 * cos(alpha*PIx*0.5)+0d0)) / nenner &
218 + lambda*1.25664/1.88496
220 m_complex_water_ray = SQRT(CMPLX(epsr,-epsi))
222 END FUNCTION m_complex_water_ray
224 !+---+-----------------------------------------------------------------+
226 COMPLEX*16 FUNCTION m_complex_ice_maetzler(lambda,T)
228 ! complex refractive index of ice as function of Temperature T
229 ! [deg C] and radar wavelength lambda [m]; valid for
230 ! lambda in [0.0001,30] m; T in [-250.0,0.0] C
231 ! Original comment from the Matlab-routine of Prof. Maetzler:
232 ! Function for calculating the relative permittivity of pure ice in
233 ! the microwave region, according to C. Maetzler, "Microwave
234 ! properties of ice and snow", in B. Schmitt et al. (eds.) Solar
235 ! System Ices, Astrophys. and Space Sci. Library, Vol. 227, Kluwer
236 ! Academic Publishers, Dordrecht, pp. 241-257 (1998). Input:
237 ! TK = temperature (K), range 20 to 273.15
238 ! f = frequency in GHz, range 0.01 to 3000
241 DOUBLE PRECISION, INTENT(IN):: T,lambda
242 DOUBLE PRECISION:: f,c,TK,B1,B2,b,deltabeta,betam,beta,theta,alfa
246 f = c / lambda * 1d-9
251 deltabeta = EXP(-10.02 + 0.0364*(TK-273.16))
252 betam = (B1/TK) * ( EXP(b/TK) / ((EXP(b/TK)-1)**2) ) + B2*f*f
253 beta = betam + deltabeta
254 theta = 300. / TK - 1.
255 alfa = (0.00504d0 + 0.0062d0*theta) * EXP(-22.1d0*theta)
256 m_complex_ice_maetzler = 3.1884 + 9.1e-4*(TK-273.16)
257 m_complex_ice_maetzler = m_complex_ice_maetzler &
258 + CMPLX(0.0d0, (alfa/f + beta*f))
259 m_complex_ice_maetzler = SQRT(CONJG(m_complex_ice_maetzler))
261 END FUNCTION m_complex_ice_maetzler
263 !+---+-----------------------------------------------------------------+
265 subroutine rayleigh_soak_wetgraupel (x_g, a_geo, b_geo, fmelt, &
266 meltratio_outside, m_w, m_i, lambda, C_back, &
267 mixingrule,matrix,inclusion, &
268 host,hostmatrix,hostinclusion)
272 DOUBLE PRECISION, INTENT(in):: x_g, a_geo, b_geo, fmelt, lambda, &
274 DOUBLE PRECISION, INTENT(out):: C_back
275 COMPLEX*16, INTENT(in):: m_w, m_i
276 CHARACTER(len=*), INTENT(in):: mixingrule, matrix, inclusion, &
277 host, hostmatrix, hostinclusion
279 COMPLEX*16:: m_core, m_air
280 DOUBLE PRECISION:: D_large, D_g, rhog, x_w, xw_a, fm, fmgrenz, &
281 volg, vg, volair, volice, volwater, &
282 meltratio_outside_grenz, mra
284 DOUBLE PRECISION, PARAMETER:: PIx=3.1415926535897932384626434d0
286 ! refractive index of air:
287 m_air = (1.0d0,0.0d0)
289 ! Limiting the degree of melting --- for safety:
290 fm = DMAX1(DMIN1(fmelt, 1.0d0), 0.0d0)
291 ! Limiting the ratio of (melting on outside)/(melting on inside):
292 mra = DMAX1(DMIN1(meltratio_outside, 1.0d0), 0.0d0)
294 ! ! The relative portion of meltwater melting at outside should increase
295 ! ! from the given input value (between 0 and 1)
296 ! ! to 1 as the degree of melting approaches 1,
297 ! ! so that the melting particle "converges" to a water drop.
298 ! ! Simplest assumption is linear:
299 mra = mra + (1.0d0-mra)*fm
303 D_g = a_geo * x_g**b_geo
305 if (D_g .ge. 1d-12) then
308 rhog = DMAX1(DMIN1(x_g / vg, 900.0d0), 10.0d0)
311 meltratio_outside_grenz = 1.0d0 - rhog / 1000.
313 if (mra .le. meltratio_outside_grenz) then
314 !..In this case, it cannot happen that, during melting, all the
315 !.. air inclusions within the ice particle get filled with
316 !.. meltwater. This only happens at the end of all melting.
317 volg = vg * (1.0d0 - mra * fm)
320 !..In this case, at some melting degree fm, all the air
321 !.. inclusions get filled with meltwater.
322 fmgrenz=(900.0-rhog)/(mra*900.0-rhog+900.0*rhog/1000.)
324 if (fm .le. fmgrenz) then
325 !.. not all air pockets are filled:
326 volg = (1.0 - mra * fm) * vg
328 !..all air pockets are filled with meltwater, now the
329 !.. entire ice sceleton melts homogeneously:
330 volg = (x_g - x_w) / 900.0 + x_w / 1000.
335 D_large = (6.0 / PIx * volg) ** (1./3.)
336 volice = (x_g - x_w) / (volg * 900.0)
337 volwater = x_w / (1000. * volg)
338 volair = 1.0 - volice - volwater
340 !..complex index of refraction for the ice-air-water mixture
342 m_core = get_m_mix_nested (m_air, m_i, m_w, volair, volice, &
343 volwater, mixingrule, host, matrix, inclusion, &
344 hostmatrix, hostinclusion, error)
345 if (error .ne. 0) then
350 !..Rayleigh-backscattering coefficient of melting particle:
351 C_back = (ABS((m_core**2-1.0d0)/(m_core**2+2.0d0)))**2 &
352 * PI5 * D_large**6 / lamda4
358 end subroutine rayleigh_soak_wetgraupel
360 !+---+-----------------------------------------------------------------+
362 complex*16 function get_m_mix_nested (m_a, m_i, m_w, volair, &
363 volice, volwater, mixingrule, host, matrix, &
364 inclusion, hostmatrix, hostinclusion, cumulerror)
368 DOUBLE PRECISION, INTENT(in):: volice, volair, volwater
369 COMPLEX*16, INTENT(in):: m_a, m_i, m_w
370 CHARACTER(len=*), INTENT(in):: mixingrule, host, matrix, &
371 inclusion, hostmatrix, hostinclusion
372 INTEGER, INTENT(out):: cumulerror
374 DOUBLE PRECISION:: vol1, vol2
378 !..Folded: ( (m1 + m2) + m3), where m1,m2,m3 could each be
379 !.. air, ice, or water
382 get_m_mix_nested = CMPLX(1.0d0,0.0d0)
384 if (host .eq. 'air') then
386 if (matrix .eq. 'air') then
387 write(radar_debug,*) 'GET_M_MIX_NESTED: bad matrix: ', matrix
388 CALL wrf_debug(150, radar_debug)
389 cumulerror = cumulerror + 1
391 vol1 = volice / MAX(volice+volwater,1d-10)
393 mtmp = get_m_mix (m_a, m_i, m_w, 0.0d0, vol1, vol2, &
394 mixingrule, matrix, inclusion, error)
395 cumulerror = cumulerror + error
397 if (hostmatrix .eq. 'air') then
398 get_m_mix_nested = get_m_mix (m_a, mtmp, 2.0*m_a, &
399 volair, (1.0d0-volair), 0.0d0, mixingrule, &
400 hostmatrix, hostinclusion, error)
401 cumulerror = cumulerror + error
402 elseif (hostmatrix .eq. 'icewater') then
403 get_m_mix_nested = get_m_mix (m_a, mtmp, 2.0*m_a, &
404 volair, (1.0d0-volair), 0.0d0, mixingrule, &
405 'ice', hostinclusion, error)
406 cumulerror = cumulerror + error
408 write(radar_debug,*) 'GET_M_MIX_NESTED: bad hostmatrix: ', &
410 CALL wrf_debug(150, radar_debug)
411 cumulerror = cumulerror + 1
415 elseif (host .eq. 'ice') then
417 if (matrix .eq. 'ice') then
418 write(radar_debug,*) 'GET_M_MIX_NESTED: bad matrix: ', matrix
419 CALL wrf_debug(150, radar_debug)
420 cumulerror = cumulerror + 1
422 vol1 = volair / MAX(volair+volwater,1d-10)
424 mtmp = get_m_mix (m_a, m_i, m_w, vol1, 0.0d0, vol2, &
425 mixingrule, matrix, inclusion, error)
426 cumulerror = cumulerror + error
428 if (hostmatrix .eq. 'ice') then
429 get_m_mix_nested = get_m_mix (mtmp, m_i, 2.0*m_a, &
430 (1.0d0-volice), volice, 0.0d0, mixingrule, &
431 hostmatrix, hostinclusion, error)
432 cumulerror = cumulerror + error
433 elseif (hostmatrix .eq. 'airwater') then
434 get_m_mix_nested = get_m_mix (mtmp, m_i, 2.0*m_a, &
435 (1.0d0-volice), volice, 0.0d0, mixingrule, &
436 'air', hostinclusion, error)
437 cumulerror = cumulerror + error
439 write(radar_debug,*) 'GET_M_MIX_NESTED: bad hostmatrix: ', &
441 CALL wrf_debug(150, radar_debug)
442 cumulerror = cumulerror + 1
446 elseif (host .eq. 'water') then
448 if (matrix .eq. 'water') then
449 write(radar_debug,*) 'GET_M_MIX_NESTED: bad matrix: ', matrix
450 CALL wrf_debug(150, radar_debug)
451 cumulerror = cumulerror + 1
453 vol1 = volair / MAX(volice+volair,1d-10)
455 mtmp = get_m_mix (m_a, m_i, m_w, vol1, vol2, 0.0d0, &
456 mixingrule, matrix, inclusion, error)
457 cumulerror = cumulerror + error
459 if (hostmatrix .eq. 'water') then
460 get_m_mix_nested = get_m_mix (2*m_a, mtmp, m_w, &
461 0.0d0, (1.0d0-volwater), volwater, mixingrule, &
462 hostmatrix, hostinclusion, error)
463 cumulerror = cumulerror + error
464 elseif (hostmatrix .eq. 'airice') then
465 get_m_mix_nested = get_m_mix (2*m_a, mtmp, m_w, &
466 0.0d0, (1.0d0-volwater), volwater, mixingrule, &
467 'ice', hostinclusion, error)
468 cumulerror = cumulerror + error
470 write(radar_debug,*) 'GET_M_MIX_NESTED: bad hostmatrix: ', &
472 CALL wrf_debug(150, radar_debug)
473 cumulerror = cumulerror + 1
477 elseif (host .eq. 'none') then
479 get_m_mix_nested = get_m_mix (m_a, m_i, m_w, &
480 volair, volice, volwater, mixingrule, &
481 matrix, inclusion, error)
482 cumulerror = cumulerror + error
485 write(radar_debug,*) 'GET_M_MIX_NESTED: unknown matrix: ', host
486 CALL wrf_debug(150, radar_debug)
487 cumulerror = cumulerror + 1
490 IF (cumulerror .ne. 0) THEN
491 write(radar_debug,*) 'GET_M_MIX_NESTED: error encountered'
492 CALL wrf_debug(150, radar_debug)
493 get_m_mix_nested = CMPLX(1.0d0,0.0d0)
496 end function get_m_mix_nested
498 !+---+-----------------------------------------------------------------+
500 COMPLEX*16 FUNCTION get_m_mix (m_a, m_i, m_w, volair, volice, &
501 volwater, mixingrule, matrix, inclusion, error)
505 DOUBLE PRECISION, INTENT(in):: volice, volair, volwater
506 COMPLEX*16, INTENT(in):: m_a, m_i, m_w
507 CHARACTER(len=*), INTENT(in):: mixingrule, matrix, inclusion
508 INTEGER, INTENT(out):: error
511 get_m_mix = CMPLX(1.0d0,0.0d0)
513 if (mixingrule .eq. 'maxwellgarnett') then
514 if (matrix .eq. 'ice') then
515 get_m_mix = m_complex_maxwellgarnett(volice, volair, volwater, &
516 m_i, m_a, m_w, inclusion, error)
517 elseif (matrix .eq. 'water') then
518 get_m_mix = m_complex_maxwellgarnett(volwater, volair, volice, &
519 m_w, m_a, m_i, inclusion, error)
520 elseif (matrix .eq. 'air') then
521 get_m_mix = m_complex_maxwellgarnett(volair, volwater, volice, &
522 m_a, m_w, m_i, inclusion, error)
524 write(radar_debug,*) 'GET_M_MIX: unknown matrix: ', matrix
525 CALL wrf_debug(150, radar_debug)
530 write(radar_debug,*) 'GET_M_MIX: unknown mixingrule: ', mixingrule
531 CALL wrf_debug(150, radar_debug)
535 if (error .ne. 0) then
536 write(radar_debug,*) 'GET_M_MIX: error encountered'
537 CALL wrf_debug(150, radar_debug)
540 END FUNCTION get_m_mix
542 !+---+-----------------------------------------------------------------+
544 COMPLEX*16 FUNCTION m_complex_maxwellgarnett(vol1, vol2, vol3, &
545 m1, m2, m3, inclusion, error)
549 COMPLEX*16 :: m1, m2, m3
550 DOUBLE PRECISION :: vol1, vol2, vol3
551 CHARACTER(len=*) :: inclusion
553 COMPLEX*16 :: beta2, beta3, m1t, m2t, m3t
554 INTEGER, INTENT(out) :: error
558 if (DABS(vol1+vol2+vol3-1.0d0) .gt. 1d-6) then
559 write(radar_debug,*) 'M_COMPLEX_MAXWELLGARNETT: sum of the ', &
560 'partial volume fractions is not 1...ERROR'
561 CALL wrf_debug(150, radar_debug)
562 m_complex_maxwellgarnett=CMPLX(-999.99d0,-999.99d0)
571 if (inclusion .eq. 'spherical') then
572 beta2 = 3.0d0*m1t/(m2t+2.0d0*m1t)
573 beta3 = 3.0d0*m1t/(m3t+2.0d0*m1t)
574 elseif (inclusion .eq. 'spheroidal') then
575 beta2 = 2.0d0*m1t/(m2t-m1t) * (m2t/(m2t-m1t)*LOG(m2t/m1t)-1.0d0)
576 beta3 = 2.0d0*m1t/(m3t-m1t) * (m3t/(m3t-m1t)*LOG(m3t/m1t)-1.0d0)
578 write(radar_debug,*) 'M_COMPLEX_MAXWELLGARNETT: ', &
579 'unknown inclusion: ', inclusion
580 CALL wrf_debug(150, radar_debug)
581 m_complex_maxwellgarnett=DCMPLX(-999.99d0,-999.99d0)
586 m_complex_maxwellgarnett = &
587 SQRT(((1.0d0-vol2-vol3)*m1t + vol2*beta2*m2t + vol3*beta3*m3t) / &
588 (1.0d0-vol2-vol3+vol2*beta2+vol3*beta3))
590 END FUNCTION m_complex_maxwellgarnett
592 !+---+-----------------------------------------------------------------+
593 REAL FUNCTION GAMMLN(XX)
594 ! --- RETURNS THE VALUE LN(GAMMA(XX)) FOR XX > 0.
596 REAL, INTENT(IN):: XX
597 DOUBLE PRECISION, PARAMETER:: STP = 2.5066282746310005D0
598 DOUBLE PRECISION, DIMENSION(6), PARAMETER:: &
599 COF = (/76.18009172947146D0, -86.50532032941677D0, &
600 24.01409824083091D0, -1.231739572450155D0, &
601 .1208650973866179D-2, -.5395239384953D-5/)
602 DOUBLE PRECISION:: SER,TMP,X,Y
608 TMP=(X+0.5D0)*LOG(TMP)-TMP
609 SER=1.000000000190015D0
614 GAMMLN=TMP+LOG(STP*SER/X)
616 ! (C) Copr. 1986-92 Numerical Recipes Software 2.02
617 !+---+-----------------------------------------------------------------+
618 REAL FUNCTION WGAMMA(y)
623 WGAMMA = EXP(GAMMLN(y))
627 !+---+-----------------------------------------------------------------+
628 END MODULE module_mp_radar
629 !+---+-----------------------------------------------------------------+