UFO
ufo_gnssro_bendmetoffice_utils_mod.F90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
2 ! (C) British Crown Copyright 2020 Met Office
3 !
4 ! This software is licensed under the terms of the Apache Licence Version 2.0
5 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6 !-------------------------------------------------------------------------------
8 
9 !use iso_c_binding
10 use fckit_log_module, only: fckit_log
11 use kinds, only: kind_real
12 
13 ! Generic routines from elsewhere in jedi
14 use missing_values_mod
15 use ufo_constants_mod, only: &
16  rd, & ! Gas constant for dry air
17  cp, & ! Heat capacity at constant pressure for air
18  rd_over_cp, & ! Ratio of gas constant to heat capacity
19  pref, & ! Reference pressure for calculating exner
20  pi, & ! Something to do with circles...
21  grav, & ! Gravitational field strength
22  ecc, & ! eccentricity
23  k_somig, & ! Somigliana's constant
24  g_equat, & ! equatorial gravity (ms-2)
25  a_earth, & ! semi-major axis of earth (m)
26  flatt, & ! flattening
27  m_ratio, & ! gravity ratio
28  mw_ratio, & ! Ratio of molecular weights of water and dry air
29  c_virtual, & ! Related to mw_ratio
30  n_alpha, & ! Refractivity constant a
31  n_beta ! Refractivity constant b
32 
33 implicit none
34 public :: ops_gpsrocalc_alpha
35 public :: ops_gpsrocalc_nr
36 public :: ops_gpsro_refrac
37 public :: ops_gpsro_geop_geom
38 private
39 
40 contains
41 
42 !-------------------------------------------------------------------------------
43 ! GPSRO 1D bending angle operator.
44 !-------------------------------------------------------------------------------
45 SUBROUTINE ops_gpsrocalc_alpha (nobs, &
46  nlev, &
47  a, &
48  refrac, &
49  nr, &
50  alpha)
51 
52 IMPLICIT NONE
53 
54 ! Subroutine arguments:
55 INTEGER, INTENT(IN) :: nobs ! size of ob. vector
56 INTEGER, INTENT(IN) :: nlev ! no. of refractivity levels
57 REAL(kind_real), INTENT(IN) :: a(nobs) ! observation impact parameters
58 REAL(kind_real), INTENT(IN) :: refrac(nlev) ! refractivity values on model levels
59 REAL(kind_real), INTENT(IN) :: nr(nlev) ! refractive index * radius product
60 REAL(kind_real), INTENT(OUT) :: alpha(nobs) ! bending angle
61 
62 ! Local declarations:
63 CHARACTER(len=*), PARAMETER :: routinename = "Ops_GPSROcalc_alpha"
64 INTEGER :: i
65 INTEGER :: n
66 INTEGER :: ibot
67 INTEGER :: jbot
68 INTEGER :: kbot
69 REAL(kind_real) :: kval(nlev - 1) ! exponential decay rate between levels
70 REAL(kind_real) :: root_2pia
71 REAL(kind_real) :: ref_low ! refractivity at lower level
72 REAL(kind_real) :: nr_low ! impact parameter lower level
73 REAL(kind_real) :: tup
74 REAL(kind_real) :: tlow ! upper/lower bounds to error function
75 REAL(kind_real) :: diff_erf ! error function result
76 REAL(kind_real) :: dalpha ! delta bending angle
77 REAL(kind_real) :: erf_tup
78 REAL(kind_real) :: erf_tlow ! error function of tup and tlow
79 REAL(kind_real) :: t ! int. step in approx. to error function
80 REAL(kind_real), PARAMETER :: a1 = 0.3480242 ! consts used in error function approx.
81 REAL(kind_real), PARAMETER :: a2 = -0.0958798
82 REAL(kind_real), PARAMETER :: a3 = 0.7478556
83 REAL(kind_real), PARAMETER :: p = 0.47047
84 
85 jbot = 1
86 
87 DO
88 
89  IF (refrac(jbot) > 0.0 .AND. nr(jbot) > 0.0) EXIT
90 
91  jbot = jbot + 1
92 
93 END DO
94 
95 !-------------------------------------------------------------------------------
96 ! Calculate lowest usable level (because of superrefraction)
97 !-------------------------------------------------------------------------------
98 
99 kbot = nlev
100 
101 DO i = nlev,jbot + 1,-1
102 
103  ! to avoid large gradients
104  IF ((nr(kbot) - nr(kbot - 1)) < 10.0) EXIT
105 
106  kbot = kbot - 1
107 
108 END DO
109 
110 jbot = max(jbot,kbot)
111 
112 !-------------------------------------------------------------------------------
113 ! Calculate the exponential decay rate between levels
114 !-------------------------------------------------------------------------------
115 
116 DO i = jbot,nlev - 1
117 
118  kval(i) = log(refrac(i) / refrac(i + 1)) / &
119  max(1.0,(nr(i + 1) - nr(i)))
120  kval(i) = max(1.0e-6,kval(i))
121 
122 END DO
123 
124 !-------------------------------------------------------------------------------
125 ! Calculate the bending angle values
126 !-------------------------------------------------------------------------------
127 
128 alpha(:) = missing_value(alpha(1))
129 
130 DO n = 1,nobs
131 
132  IF (a(n) < nr(jbot) .OR. a(n) > nr(nlev)) cycle
133 
134  root_2pia = sqrt(2.0 * pi * a(n))
135 
136  ibot = jbot
137 
138  ! Find bottom state vector level
139  !----------------------------------
140 
141  DO
142  ! check more than 1 metre apart to stop large gradients in K code
143  IF (((nr(ibot + 1) - a(n)) > 1.0) .OR. ibot == nlev - 1) EXIT
144 
145  ibot = ibot + 1
146 
147  END DO
148 
149  ! Initialise bending angle value
150  !-------------------------------
151 
152  alpha(n) = 0.0
153 
154  ! Values of refractivity and impact parameter at lower level
155  !-----------------------------------------------------------
156 !The following line is a compiler directive to avoid bugs with intel compilers
157 !DIR$ NOVECTOR
158  DO i = ibot, nlev - 1
159 
160  IF (i == ibot) THEN
161 
162  ref_low = refrac(ibot) * exp(-kval(ibot) * (a(n) - nr(ibot)))
163  nr_low = a(n)
164 
165  ELSE
166 
167  ref_low = refrac(i)
168  nr_low = nr(i)
169 
170  END IF
171 
172  ! Limits used in the error function
173  !----------------------------------
174 
175  IF (i == nlev - 1) THEN
176 
177  ! Simple extrapolation 100km above the uppermost level
178  !-----------------------------------------------------
179  tup = sqrt(kval(i) * (nr(i + 1) + 1.0e5 - a(n)))
180 
181  ELSE
182 
183  tup = sqrt(kval(i) * (nr(i + 1) - a(n)))
184 
185  END IF
186 
187  tlow = 0.0
188 
189  IF (i > ibot) tlow = sqrt(kval(i) * (nr(i) - a(n)))
190 
191  ! Abramowitz and Stegun approx. to error function
192  !------------------------------------------------
193  t = 1.0 / (1.0 + p * tup)
194  erf_tup = 1.0 - exp(-(tup ** 2)) * (a1 + (a2 + a3 * t) * t) * t
195 
196  t = 1.0 / (1.0 + p * tlow)
197  erf_tlow = 1.0 - exp(-(tlow ** 2)) * (a1 + (a2 + a3 * t) * t) * t
198 
199  diff_erf = erf_tup - erf_tlow
200 
201  dalpha = 1.0e-6 * root_2pia * sqrt(kval(i)) * &
202  ref_low * exp(kval(i) * (nr_low - a(n))) * diff_erf
203 
204  ! Bending angle value
205  !--------------------
206  alpha(n) = alpha(n) + dalpha
207 
208  END DO
209 
210 END DO
211 
212 END SUBROUTINE ops_gpsrocalc_alpha
213 
214 
215 !-------------------------------------------------------------------------------
216 ! (C) Crown copyright Met Office. All rights reserved.
217 ! Refer to COPYRIGHT.txt of this distribution for details.
218 !-------------------------------------------------------------------------------
219 SUBROUTINE ops_gpsrocalc_nr (zb, & ! geopotential heights of model levels
220  nb, & ! number of levels in zb
221  Rad, & ! radius of curvature of earth at observation
222  lat, & ! latitude at observation
223  und, & ! geoid undulation above WGS-84
224  refrac, & ! refractivity of model on model levels
225  nr) ! Calculated model impact parameters
226 
227 IMPLICIT NONE
228 
229 ! Subroutine arguments:
230 INTEGER, INTENT(IN) :: nb ! number of levels in zb
231 REAL(kind_real), INTENT(IN) :: zb(nb) ! geopotential heights on zb levels /m
232 REAL(kind_real), INTENT(IN) :: rad ! local radius of curvature of earth /m
233 REAL(kind_real), INTENT(IN) :: lat ! latitude at observation/ degrees
234 REAL(kind_real), INTENT(IN) :: und ! geoid undulation
235 REAL(kind_real), INTENT(IN) :: refrac(nb) ! refractivity on model levels / N
236 REAL(kind_real), INTENT(OUT) :: nr(nb) ! Calculated model impact parameters
237 
238 ! Local declarations:
239 CHARACTER(len=*), PARAMETER :: routinename = "Ops_GPSROcalc_nr"
240 REAL(kind_real) :: r(nb) ! radius of model levels /m
241 REAL(kind_real) :: z(nb) ! geopotential heights on zb levels /m, local copy of zb
242 INTEGER :: i
243 
244 nr(:) = missing_value(nr(1))
245 
246 !----------------------------------------------
247 ! 1. Convert zb values to geometric altitudes
248 !---------------------------------------------
249 z = zb + und ! approx. convert to geopotential above WGS-84 ellipsoid
250 CALL ops_gpsro_geop_geom (lat, &
251  z)
252 
253 !--------------------------------------------------
254 ! 2. Calculate x =nr, i.e. model impact parameters
255 !--------------------------------------------------
256 
257 r = rad + z
258 
259 DO i = 1,nb
260  IF (zb(i) > 0.0 .AND. refrac(i) > 0.0) THEN
261  nr(i) = (1.0e0 + 1.0e-6 * refrac(i)) * r(i)
262  END IF
263 END DO
264 
265 END SUBROUTINE ops_gpsrocalc_nr
266 
267 
268 !-------------------------------------------------------------------------------
269 ! Convert geopotential height above ellispoid to geometric height on WGS-84
270 ! (ellipsoid). The method for this calculation is available from
271 ! http://mtp.jpl.nasa.gov/notes/altitude/altitude.html.
272 !-------------------------------------------------------------------------------
273 SUBROUTINE ops_gpsro_geop_geom (lat, &
274  z)
275 
276 IMPLICIT NONE
277 
278 ! Subroutine arguments:
279 REAL(kind_real), INTENT(IN) :: lat ! latitude of observation
280 REAL(kind_real), INTENT(INOUT) :: z(:) ! geopotential height in, geometric height out
281 
282 ! Local declarations:
283 CHARACTER(len=*), PARAMETER :: routinename = "Ops_GPSRO_geop_geom"
284 REAL(kind_real) :: r_eff ! effective radius of Earth, formulas from MJ Mahoney (2005)
285 REAL(kind_real) :: g_somig ! Somigliana's equation for normal gravity on the surface of an ellipsoid of revolution
286 REAL(kind_real) :: latrad ! latitude in radians
287 
288 !------------------------
289 ! 1. correct units
290 !-----------------------
291 
292 latrad = lat * (pi / 180.0) !convert latitude from degrees to radians
293 
294 !-------------------------
295 ! 2. Calculate r and g
296 !-------------------------
297 
298 r_eff = a_earth / (1.0 + flatt + m_ratio - 2.0 * flatt * (sin(latrad)) ** 2)
299 
300 g_somig = g_equat * (1.0 + k_somig * (sin(latrad)) ** 2) / (sqrt(1.0 - (ecc ** 2) * (sin(latrad)) ** 2))
301 
302 !-------------------------------------------------------------------
303 ! 3. convert z (in geopotential height) to geometric wrt ellipsoid
304 !-------------------------------------------------------------------
305 
306 z(:) = (r_eff * z(:)) / ((g_somig / grav) * r_eff - z(:))
307 
308 END SUBROUTINE ops_gpsro_geop_geom
309 
310 
311 !-------------------------------------------------------------------------------
312 ! (C) Crown copyright Met Office. All rights reserved.
313 ! Refer to COPYRIGHT.txt of this distribution for details.
314 !-------------------------------------------------------------------------------
315 ! GPSRO refractivity forward operator
316 !-------------------------------------------------------------------------------
317 
318 SUBROUTINE ops_gpsro_refrac (nstate, &
319  nlevP, &
320  nb, &
321  nlevq, &
322  za, &
323  zb, &
324  x, &
325  GPSRO_pseudo_ops, &
326  GPSRO_vert_interp_ops, &
327  refracerr, &
328  refrac, &
329  T, &
330  z_pseudo, &
331  N_pseudo, &
332  nb_pseudo)
333 
334 IMPLICIT NONE
335 
336 ! Subroutine arguments:
337 INTEGER, INTENT(IN) :: nstate ! no. of levels in state vec.
338 INTEGER, INTENT(IN) :: nlevp ! no. of p levels in state vec.
339 INTEGER, INTENT(IN) :: nb ! no. of non-pseudo levs (=nlevq)
340 INTEGER, INTENT(IN) :: nlevq ! no. of theta levels
341 REAL(kind_real), INTENT(IN) :: za(:) ! heights of rho levs
342 REAL(kind_real), INTENT(IN) :: zb(:) ! heights of theta levs
343 REAL(kind_real), INTENT(IN) :: x(:) ! state vector
344 LOGICAL, INTENT(IN) :: gpsro_pseudo_ops
345 LOGICAL, INTENT(IN) :: gpsro_vert_interp_ops
346 LOGICAL, INTENT(OUT) :: refracerr ! refractivity error
347 REAL(kind_real), INTENT(OUT) :: refrac(nb) ! refrac on theta levs
348 REAL(kind_real), INTENT(OUT) :: t(nb) ! Temp. on theta levs
349 REAL(kind_real), ALLOCATABLE, INTENT(OUT), OPTIONAL :: z_pseudo(:) ! height of pseudo levs
350 REAL(kind_real), ALLOCATABLE, INTENT(OUT), OPTIONAL :: n_pseudo(:) ! Ref. on pseudo levs
351 INTEGER, INTENT(OUT), OPTIONAL :: nb_pseudo ! no. of pseudo levs
352 
353 ! Local declarations:
354 integer, parameter :: max_string = 800
355 CHARACTER(len=*), PARAMETER :: routinename = "Ops_GPSRO_refrac"
356 CHARACTER(len=max_string) :: message
357 INTEGER :: i
358 INTEGER :: counter
359 INTEGER :: search_lev ! The vertical level to start searching from to
360  ! find matching temperature-level heights
361 INTEGER :: this_lev ! Matching level to temperature-level height
362 REAL(kind_real) :: p(nlevp)
363 REAL(kind_real) :: exner(nlevp)
364 REAL(kind_real) :: q(nlevq)
365 REAL(kind_real) :: pb(nb)
366 REAL(kind_real) :: tv
367 REAL(kind_real) :: ex_theta
368 REAL(kind_real) :: pwt1
369 REAL(kind_real) :: pwt2
370 REAL(kind_real) :: ndry
371 REAL(kind_real) :: nwet
372 REAL(kind_real), ALLOCATABLE :: p_pseudo(:)
373 REAL(kind_real), ALLOCATABLE :: q_pseudo(:)
374 REAL(kind_real), ALLOCATABLE :: t_pseudo(:)
375 REAL(kind_real) :: gamma
376 REAL(kind_real) :: beta
377 REAL(kind_real) :: c ! continuity constant for hydrostatic pressure
378 LOGICAL :: nonmon
379 LOGICAL :: unphys
380 
381 ! Allocate arrays for pseudo-level processing
382 IF (gpsro_pseudo_ops) THEN
383  nb_pseudo = 2 * nb - 1
384  ALLOCATE (p_pseudo(nb_pseudo))
385  ALLOCATE (q_pseudo(nb_pseudo))
386  ALLOCATE (t_pseudo(nb_pseudo))
387  ALLOCATE (z_pseudo(nb_pseudo))
388  ALLOCATE (n_pseudo(nb_pseudo))
389 END IF
390 
391 ! Set up the P and q vectors from x
392 p(:) = x(1:nlevp)
393 q(:) = x(nlevp + 1:nstate)
394 
395 ! Initialise refractivity arrays to missing Data
396 refrac(:) = missing_value(refrac(1))
397 t(:) = missing_value(t(1))
398 nonmon = .false.
399 unphys = .false.
400 refracerr = .false.
401 
402 DO i = 1, nlevp
403  IF (p(i) == missing_value(p(i))) THEN !pressure missing
404  refracerr = .true.
405  WRITE(message, *) routinename, "Missing value P", i
406  CALL fckit_log % warning(message)
407  EXIT
408  END IF
409 END DO
410 
411 DO i = 1, nlevp-1
412  IF (p(i) - p(i + 1) < 0.0) THEN !or non-monotonic pressure
413  refracerr = .true.
414  nonmon = .true.
415  WRITE(message,*) "Non monotonic", i, p(i), p(i+1)
416  CALL fckit_log % warning(message)
417  EXIT
418  END IF
419 END DO
420 
421 IF (any(p(:) <= 0.0)) THEN !pressure zero or negative
422  refracerr = .true.
423  unphys = .true.
424 END IF
425 
426 IF (any(q(:) < 0.0)) THEN !humidity negative
427  refracerr = .true.
428  unphys = .true.
429 END IF
430 
431 ! only proceed if pressure is valid
432 IF (refracerr) THEN
433  IF (nonmon) THEN
434  CALL fckit_log%warning (routinename // ": GPSRO Pressure non-monotonic")
435  ELSE IF (unphys) THEN
436  CALL fckit_log%warning (routinename // ": GPSRO Pressure <= zero")
437  ELSE
438  CALL fckit_log%warning (routinename // ": GPSRO Pressure missing")
439  END IF
440 ELSE
441 
442  ! Calculate exner on rho levels.
443  exner(:) = (p(:) / pref) ** rd_over_cp
444 
445 ! PRINT*, 'Exner'
446 ! WRITE(*, '(7E18.10)') exner
447 
448  ! Calculate the refractivity on the b levels
449  search_lev = 1
450  DO i = 1, nb
451  ! Search for the first pressure (rho) level which has a height greater than
452  ! the temperature (theta) level being considered. Interpolate the pressure
453  ! to the temperature levels using the level which has been found.
454  DO this_lev = search_lev, nlevp
455  IF (za(this_lev) > zb(i)) THEN
456  EXIT
457  END IF
458  END DO
459  IF (this_lev == 1) THEN
460  ! Calc. pressure pb
461  pb(i) = p(i)
462  CALL fckit_log%warning (routinename // ": Bottom temperature level is below bottom pressure level! Extrapolating!")
463  CALL fckit_log%warning (routinename // ": Results could be very inaccurate")
464  ELSE
465  ! Calc. pressure pb
466  pwt1 = (za(this_lev) - zb(i)) / (za(this_lev) - za(this_lev-1))
467  search_lev = this_lev
468  pwt2 = 1.0 - pwt1
469 
470  ! Calculate the pressure on the theta level.
471  IF (gpsro_vert_interp_ops) THEN
472  ! Assume ln(P) linear with height
473  pb(i) = exp(pwt1 * log(p(this_lev-1)) + pwt2 * log(p(this_lev)))
474  ELSE
475  ! Assume Exner varies linearly with height
476  pb(i) = pref * (pwt1 * (p(this_lev-1) / pref) ** rd_over_cp + pwt2 * &
477  (p(this_lev) / pref) ** rd_over_cp) ** (1.0 / rd_over_cp)
478  END IF
479  END IF
480 
481  ! Calculate the Exner on the theta level.
482  ex_theta = (pb(i) / pref) ** rd_over_cp
483 
484  ! Calculate mean layer Tv (virtual temperature) using ND definition
485  tv = grav * (za(this_lev) - za(this_lev-1)) * ex_theta / &
486  (cp * (exner(this_lev-1) - exner(this_lev)))
487 
488  IF (i > nlevq) THEN
489 
490  t(i) = tv
491 
492  ! No wet component
493 
494  nwet = 0.0
495 
496  ELSE
497 
498  t(i) = tv / (1.0 + c_virtual * q(i))
499 
500  ! Wet component
501 
502  nwet = n_beta * pb(i) * q(i) / (t(i) ** 2 * (mw_ratio + (1.0 - mw_ratio) * q(i)))
503 
504  END IF
505 
506  ndry = n_alpha * pb(i) / t(i)
507 
508  refrac(i) = ndry + nwet
509 
510  END DO
511 
512  ! Do pseudo-level processing
513  IF (gpsro_pseudo_ops) THEN
514  counter = 1
515  DO i = 1, nb_pseudo
516 
517  ! Odd 'i' (i.e. copies of actual model level values)
518  IF (mod(i, 2) > 0) THEN
519  z_pseudo(i) = zb(counter)
520  p_pseudo(i) = pb(counter)
521  q_pseudo(i) = q(counter)
522  t_pseudo(i) = t(counter)
523  counter = counter + 1
524 
525  ! Even 'i' (i.e. intermediate pseudo-levels)
526  ELSE
527  z_pseudo(i) = (zb(counter - 1) + zb(counter)) / 2.0
528 
529  ! Assume exponential variation when humidities are positive
530  IF (min(q(counter - 1), q(counter)) > 0.0) THEN
531  gamma = log(q(counter - 1) / q(counter)) / (zb(counter) - zb(counter - 1))
532  q_pseudo(i) = q(counter - 1) * exp(-gamma * (z_pseudo(i) - z_pseudo(i - 1)))
533 
534  ! Assume linear variation if humidities are -ve
535  ELSE
536  q_pseudo(i) = q(counter - 1) + (q(counter) - q(counter - 1)) / (zb(counter) - &
537  zb(counter - 1)) * (z_pseudo(i) - zb(counter - 1))
538  END IF
539 
540  ! T varies linearly with height
541  beta = (t(counter) - t(counter - 1)) / (zb(counter) - zb(counter - 1))
542  t_pseudo(i) = t(counter - 1) + beta * (z_pseudo(i) - zb(counter - 1))
543 
544  ! Pressure varies to maintain hydrostatic balance
545  IF (abs(t(counter) - t(counter - 1)) > 1.0e-10) THEN
546  c = ((pb(counter) / pb(counter - 1)) * (t(counter) / t(counter - 1)) ** (grav / (rd * beta)) - &
547  1.0) / (zb(counter) - zb(counter - 1))
548  p_pseudo(i) = (pb(counter - 1) * (t_pseudo(i) / t(counter - 1)) ** &
549  (-grav / (rd * beta))) * (1.0 + c * (z_pseudo(i) - zb(counter - 1)))
550  ELSE
551  ! If layer is isothermal, explicitly force P to vary exponentially to avoid singularity
552  p_pseudo(i) = pb(counter - 1) * exp(log(pb(counter) / pb(counter - 1)) * &
553  ((z_pseudo(i) - zb(counter - 1)) / (zb(counter) - zb(counter - 1))))
554  END IF
555  END IF
556  END DO
557 
558  n_pseudo = n_alpha * p_pseudo / t_pseudo + n_beta * p_pseudo * q_pseudo / &
559  (t_pseudo ** 2 * (mw_ratio + (1.0 - mw_ratio) * q_pseudo))
560  END IF
561 
562 END IF
563 
564 IF (gpsro_pseudo_ops) THEN
565  IF (ALLOCATED (p_pseudo)) DEALLOCATE (p_pseudo)
566  IF (ALLOCATED (q_pseudo)) DEALLOCATE (q_pseudo)
567  IF (ALLOCATED (t_pseudo)) DEALLOCATE (t_pseudo)
568 END IF
569 
570 END SUBROUTINE ops_gpsro_refrac
571 
572 !-------------------------------------------------------------------------
ufo_avgkernel_mod::max_string
integer, parameter max_string
Definition: ufo_avgkernel_mod.F90:17
ufo_gnssro_ukmo1d_utils_mod
Definition: ufo_gnssro_bendmetoffice_utils_mod.F90:7
ufo_gnssro_ukmo1d_utils_mod::ops_gpsro_refrac
subroutine, public ops_gpsro_refrac(nstate, nlevP, nb, nlevq, za, zb, x, GPSRO_pseudo_ops, GPSRO_vert_interp_ops, refracerr, refrac, T, z_pseudo, N_pseudo, nb_pseudo)
Definition: ufo_gnssro_bendmetoffice_utils_mod.F90:333
ufo_constants_mod
Definition: ufo_constants_mod.F90:2
ufo_gnssro_ukmo1d_utils_mod::ops_gpsrocalc_alpha
subroutine, public ops_gpsrocalc_alpha(nobs, nlev, a, refrac, nr, alpha)
Definition: ufo_gnssro_bendmetoffice_utils_mod.F90:51
ufo_gnssro_ukmo1d_utils_mod::ops_gpsro_geop_geom
subroutine, public ops_gpsro_geop_geom(lat, z)
Definition: ufo_gnssro_bendmetoffice_utils_mod.F90:275
ufo_constants_mod::rd
real(kind_real), parameter, public rd
Definition: ufo_constants_mod.F90:12
ufo_gnssro_ukmo1d_utils_mod::ops_gpsrocalc_nr
subroutine, public ops_gpsrocalc_nr(zb, nb, Rad, lat, und, refrac, nr)
Definition: ufo_gnssro_bendmetoffice_utils_mod.F90:226