UFO
ufo_gnssro_bndnbam_util_mod.F90
Go to the documentation of this file.
1 !
2 ! This software is licensed under the terms of the Apache Licence Version 2.0
3 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
4 
5 !> Fortran module of Gnssro NBAM (NCEP's Bending Angle Method) operator
6 
8  use fckit_log_module, only: fckit_log
9  use kinds
10  use missing_values_mod
12  use vert_interp_mod
16 
17  implicit none
19  private
20 
21  contains
22 ! ------------------------------------------------------------------------------
24  obsLat, obsGeoid, obsLocR, obsImpP, &
25  grids, ngrd, &
26  nlev, nlevExt, nlevAdd, nlevCheck, &
27  radius,ref,refIndex,refXrad, &
28  bendingAngle)
29 ! -------------------------------------------------------------------------------
30  character(len=*), parameter :: myname = "ufo_gnssro_bndnbam_simobs_single"
31 
32  real(kind_real), intent(out) :: bendingangle
33 
34  integer, intent(in) :: nlev
35  integer, intent(in) :: nlevext
36  integer, intent(in) :: nlevadd
37  integer, intent(in) :: nlevcheck
38  integer, intent(in) :: ngrd
39  real(kind_real), intent(in) :: obslat, obsgeoid, obslocr, obsimpp ! obsspace
40  real(kind_real), intent(in) :: grids(ngrd)
41 
42  real(kind_real), intent(in) :: radius(nlev)
43  real(kind_real), intent(in) :: refindex(nlev)
44  real(kind_real), intent(inout) :: ref(nlevext)
45  real(kind_real), intent(inout) :: refxrad(0:nlevext+1)
46  real(kind_real) :: lagconst(3,nlevext)
47 
48  real(kind_real) :: sindx
49  real(kind_real) :: obsimph
50  integer :: k, igrd, indx
51  real(kind_real) :: d_refxrad
52  real(kind_real) :: w4(4), dw4(4)
53  real(kind_real) :: bndintgd
54  real(kind_real) :: rnlevext
55  real(kind_real) :: derivref_s(ngrd)
56  real(kind_real) :: refxrad_s(ngrd)
57 
58 !------------------------------------------------------------
59 ! Extend atmosphere above interface level nlev
60  d_refxrad = refxrad(nlev) - refxrad(nlev-1)
61  do k = 1, nlevadd
62  refxrad(nlev+k)=refxrad(nlev)+ k*d_refxrad ! extended x_i
63  ref(nlev+k)=ref(nlev+k-1)**2/ref(nlev+k-2) ! exended N_i
64  end do
65 
66  refxrad(0)=refxrad(3)
67  refxrad(nlevext+1)=refxrad(nlevext-2)
68  do k = 1,nlevext
69  call lag_interp_const(lagconst(:,k),refxrad(k-1:k+1),3)
70  enddo
71 
72 ! integrate on a new set of equally-spaced vertical grid
73  derivref_s = zero
74  grids_loop: do igrd =1,ngrd
75  refxrad_s(igrd)=sqrt(grids(igrd)**2 + obsimpp**2) !x_s^2=s^2+a^2
76  call get_coordinate_value(refxrad_s(igrd), sindx,refxrad(1:nlevext),nlevext,"increasing")
77  rnlevext = float(nlevext)
78 
79  if (sindx > zero .and. sindx < rnlevext) then !obs inside the new grid
80  indx=sindx
81 ! Compute derivative at new grids (dN/ds) using Lagrange interpolators
82  call lag_interp_smthweights(refxrad(indx-1:indx+2),refxrad_s(igrd),&
83  lagconst(:,indx),lagconst(:,indx+1), &
84  w4,dw4,4)
85  if (indx==1) then
86  w4(4)=w4(4)+w4(1); w4(1:3)=w4(2:4);w4(4)=zero
87  dw4(4)=dw4(4)+dw4(1);dw4(1:3)=dw4(2:4);dw4(4)=zero
88  indx=indx+1
89  endif
90  if (indx==nlevext-1) then
91  w4(1)=w4(1)+w4(4); w4(2:4)=w4(1:3);w4(1)=zero
92  dw4(1)=dw4(1)+dw4(4); dw4(2:4)=dw4(1:3);dw4(1)=zero
93  indx=indx-1
94  endif
95 
96  derivref_s(igrd)=dot_product(dw4,ref(indx-1:indx+2)) !derivative dN/dx_s
97  derivref_s(igrd)=max(zero,abs(derivref_s(igrd)))
98 
99  else
100  return
101  endif !obs in new grid
102  end do grids_loop
103 
104 ! bending angle (radians)
105  bendingangle = ds*derivref_s(1)/refxrad_s(1)
106  do igrd = 2,ngrd
107  bndintgd = ds*derivref_s(igrd)/refxrad_s(igrd)
108  bendingangle = bendingangle + two*bndintgd
109  end do
110  bendingangle=r1em6 * obsimpp * bendingangle
111 
113 ! ------------------------------------------------------------------------------
real(kind_real), parameter, public ds
real(kind_real), parameter, public r1em6
subroutine, public get_coordinate_value(fin, fout, x, nx, flag)
Fortran module to prepare for Lagrange polynomial interpolation. based on GSI: lagmod....
Definition: lag_interp.F90:4
subroutine, public lag_interp_const(q, x, n)
Definition: lag_interp.F90:24
subroutine, public lag_interp_smthweights(x, xt, aq, bq, w, dw, n)
Definition: lag_interp.F90:174
Fortran module of Gnssro NBAM (NCEP's Bending Angle Method) operator.
subroutine, public ufo_gnssro_bndnbam_simobs_single(obsLat, obsGeoid, obsLocR, obsImpP, grids, ngrd, nlev, nlevExt, nlevAdd, nlevCheck, radius, ref, refIndex, refXrad, bendingAngle)
Fortran module to perform linear interpolation.
Definition: vert_interp.F90:8