UFO
ufo_gnssroonedvarcheck_setom1_mod.f90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
2 ! (C) Crown copyright Met Office. All rights reserved.
3 ! Refer to COPYRIGHT.txt of this distribution for details.
4 !-------------------------------------------------------------------------------
5 ! Find a solution to the GPSRO inverse problem.
6 !-------------------------------------------------------------------------------
7 
9 
10 use kinds
11 use missing_values_mod
13 
14 private
15 public :: ops_gpsro_setom1
16 
17 contains
18 
19 SUBROUTINE ops_gpsro_setom1 (nobs, &
20  zobs, &
21  yobs, &
22  Rmatrix, &
23  OSigma, &
24  OM1, &
25  OM1_error)
26 
27 USE ufo_utils_mod, ONLY: invertmatrix
28 
29 IMPLICIT NONE
30 
31 ! Subroutine arguments:
32 INTEGER, INTENT(IN) :: nobs
33 REAL(kind_real), INTENT(IN) :: zobs(:)
34 REAL(kind_real), INTENT(IN) :: yobs(:)
35 TYPE (rmatrix_type), INTENT(IN) :: rmatrix
36 REAL(kind_real), INTENT(OUT) :: osigma(:)
37 REAL(kind_real), INTENT(OUT) :: om1(:,:)
38 LOGICAL, INTENT(OUT) :: om1_error
39 
40 ! Local declarations:
41 CHARACTER(len=*), PARAMETER :: routinename = "Ops_GPSRO_setOM1"
42 INTEGER :: n
43 INTEGER :: i
44 INTEGER :: returncode
45 REAL(kind_real) :: frac_err
46 REAL(kind_real) :: omat(nobs,nobs)
47 REAL(kind_real), ALLOCATABLE :: gradient(:)
48 
49 IF (rmatrix % satid <= 0) THEN
50  ! Rmatrix has not been set up
51  om1_error = .true.
52  osigma(:) = 1
53  om1(:,:) = 1
54 ELSE
55  ALLOCATE (gradient(rmatrix % num_heights - 1))
56 
57  DO i = 1, rmatrix % num_heights - 1
58 
59  ! Calculate the gradient of fractional error with height
60 
61  gradient(i) = (rmatrix % frac_err(i + 1) - rmatrix % frac_err(i)) / &
62  (rmatrix % height(i + 1) - rmatrix % height(i))
63 
64  END DO
65 
66  om1_error = .false.
67 
68  ! Initialise covariance matrix
69 
70  omat(:,:) = 0.0
71 
72  ! Calculate the variance values
73 
74  DO n = 1, nobs
75 
76  i = 1
77 
78  DO
79 
80  IF (zobs(n) < rmatrix % height(i + 1) .OR. &
81  i + 1 >= rmatrix % num_heights) THEN
82  EXIT
83  END IF
84 
85  i = i + 1
86 
87  END DO
88 
89  ! Fractional error
90 
91  frac_err = rmatrix % frac_err(i) + &
92  gradient(i) * (zobs(n) - rmatrix % height(i))
93 
94  ! Standard deviation
95 
96  osigma(n) = max(frac_err * yobs(n), rmatrix % min_error)
97 
98  ! Variance
99 
100  omat(n,n) = osigma(n) ** 2
101 
102  END DO
103 
104  ! Calculate the covariances
105 
106  DO n = 1,nobs
107 
108  DO i = n + 1,nobs
109 
110  omat(n,i) = sqrt(omat(n,n) * omat(i,i)) * &
111  exp(-rmatrix % clen * abs(zobs(i) - zobs(n)))
112 
113  omat(i,n) = omat(n,i)
114 
115  END DO
116 
117  END DO
118 
119  ! Invert the matrix
120 
121  CALL invertmatrix (nobs, &
122  nobs, &
123  omat, &
124  returncode)
125 
126  ! Set the inverse
127 
128  om1(:,:) = omat(:,:)
129 
130  IF (returncode /= 0) om1_error = .true.
131 
132  DEALLOCATE (gradient)
133 END IF
134 
135 END SUBROUTINE ops_gpsro_setom1
136 
subroutine, public ops_gpsro_setom1(nobs, zobs, yobs, Rmatrix, OSigma, OM1, OM1_error)
Fortran module for utility routines used in calculating the observation uncertainties,...
Fortran module with various useful routines.
subroutine, public invertmatrix(n, m, a, status, matrix)