FV3 Bundle
ufo_conventional_profile_tlad_mod.F90
Go to the documentation of this file.
1 ! (C) Copyright 2017-2018 UCAR
2 !
3 ! This software is licensed under the terms of the Apache Licence Version 2.0
4 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5 
7 
8  use iso_c_binding
9  use kinds
10  use ufo_vars_mod
11  use ufo_geovals_mod
13  use vert_interp_mod
15  use obsspace_mod
16 
17  integer, parameter :: max_string=800
18 
20  private
21  integer :: nval, nobs
22  real(kind_real), allocatable :: wf(:)
23  integer, allocatable :: wi(:)
24  contains
26  procedure :: settraj => conventional_profile_tlad_settraj_
27  procedure :: simobs_tl => conventional_profile_simobs_tl_
28  procedure :: simobs_ad => conventional_profile_simobs_ad_
30 contains
31 
32 ! ------------------------------------------------------------------------------
33 
34  subroutine conventional_profile_tlad_settraj_(self, geovals, obss)
35  implicit none
36  class(ufo_conventional_profile_tlad), intent(inout) :: self
37  type(ufo_geovals), intent(in) :: geovals
38  type(c_ptr), value, intent(in) :: obss
39 
40  character(len=*), parameter :: myname_="ufo_conventional_profile_tlad_settraj"
41  character(max_string) :: err_msg
42 
43  real(kind_real), allocatable :: pressure(:)
44  type(ufo_geoval), pointer :: prsl
45  integer :: iobs, ierr
46 
47  !Check if conventional_profiles in geovals and get it
48  call ufo_geovals_get_var(geovals, var_prsl, prsl, status=ierr)
49  if (ierr/=0) then
50  write(err_msg,*) myname_, trim(var_prsl), ' doesnt exist'
51  call abor1_ftn(err_msg)
52  endif
53 
54  !Make sure nothing already allocated
55  call self%delete()
56 
57  !Keep copy of dimensions
58  self%nval = prsl%nval
59  self%nobs = obsspace_get_nobs(obss)
60 
61  allocate(self%wi(self%nobs))
62  allocate(self%wf(self%nobs))
63 
64  ! observation of pressure (for vertical interpolation)
65  allocate(pressure(self%nobs))
66  call obsspace_get_db(obss, "ObsValue", "air_pressure", pressure)
67 
68  ! compute interpolation weights
69  do iobs = 1, self%nobs
70  call vert_interp_weights(self%nval,log(pressure(iobs)/10.),prsl%vals(:,iobs),self%wi(iobs),self%wf(iobs))
71  enddo
72 
73  self%ltraj = .true.
74  ! cleanup
75  deallocate(pressure)
77 
78 ! ------------------------------------------------------------------------------
79 
80  subroutine conventional_profile_simobs_tl_(self, geovals, hofx, obss)
81  implicit none
82  class(ufo_conventional_profile_tlad), intent(in) :: self
83  type(ufo_geovals), intent(in) :: geovals
84  real(c_double), intent(inout) :: hofx(:)
85  type(c_ptr), value, intent(in) :: obss
86 
87  character(len=*), parameter :: myname_="ufo_conventional_profile_simobs_tl"
88  character(max_string) :: err_msg
89 
90  integer :: iobs,ierr
91  type(ufo_geoval), pointer :: tv_d
92 
93  ! check if trajectory was set
94  if (.not. self%ltraj) then
95  write(err_msg,*) myname_, ' trajectory wasnt set!'
96  call abor1_ftn(err_msg)
97  endif
98 
99  ! check if nobs is consistent in geovals & hofx
100 ! if (geovals%nobs /= hofx%nobs) then
101 ! write(err_msg,*) myname_, ' error: nobs inconsistent!'
102 ! call abor1_ftn(err_msg)
103 ! endif
104 
105  ! check if tv variable is in geovals and get it
106  call ufo_geovals_get_var(geovals, var_tv, tv_d, status=ierr )
107  if (ierr/=0) then
108  write(err_msg,*) myname_, trim(var_tv), ' doesnt exist'
109  call abor1_ftn(err_msg)
110  endif
111 
112  ! tangent linear obs operator (linear)
113  do iobs = 1, geovals%nobs
114  call vert_interp_apply_tl(tv_d%nval, tv_d%vals(:,iobs), hofx(iobs), self%wi(iobs), self%wf(iobs))
115  enddo
116 
117  end subroutine conventional_profile_simobs_tl_
118 
119 ! ------------------------------------------------------------------------------
120 
121  subroutine conventional_profile_simobs_ad_(self, geovals, hofx, obss)
122  implicit none
123  class(ufo_conventional_profile_tlad), intent(in) :: self
124  type(ufo_geovals), intent(inout) :: geovals
125  real(c_double), intent(in) :: hofx(:)
126  type(c_ptr), value, intent(in) :: obss
127 
128  character(len=*), parameter :: myname_="ufo_conventional_profile_simobs_ad"
129  character(max_string) :: err_msg
130 
131  integer :: iobs,ierr
132  type(ufo_geoval), pointer :: tv_d
133 
134  ! check if trajectory was set
135  if (.not. self%ltraj) then
136  write(err_msg,*) myname_, ' trajectory wasnt set!'
137  call abor1_ftn(err_msg)
138  endif
139 
140  ! check if nobs is consistent in geovals & hofx
141 ! if (geovals%nobs /= hofx%nobs) then
142 ! write(err_msg,*) myname_, ' error: nobs inconsistent!'
143 ! call abor1_ftn(err_msg)
144 ! endif
145 
146  ! check if tv variable is in geovals and get it
147  call ufo_geovals_get_var(geovals, var_tv, tv_d, status=ierr)
148  if (ierr/=0) then
149  write(err_msg,*) myname_, trim(var_tv), ' doesnt exist'
150  call abor1_ftn(err_msg)
151  endif
152 
153  ! allocate if not yet allocated
154  if (.not. allocated(tv_d%vals)) then
155  tv_d%nobs = self%nobs
156  tv_d%nval = self%nval
157  allocate(tv_d%vals(tv_d%nval,tv_d%nobs))
158  tv_d%vals = 0.0_kind_real
159  endif
160  if (.not. geovals%linit ) geovals%linit=.true.
161 
162  do iobs = 1, geovals%nobs
163  call vert_interp_apply_ad(tv_d%nval, tv_d%vals(:,iobs), hofx(iobs), self%wi(iobs), self%wf(iobs))
164  enddo
165 
166  end subroutine conventional_profile_simobs_ad_
167 
168 ! ------------------------------------------------------------------------------
169 
170  subroutine conventional_profile_tlad_delete_(self)
171  implicit none
172  class(ufo_conventional_profile_tlad), intent(inout) :: self
173 
174  character(len=*), parameter :: myname_="ufo_conventional_profile_tlad_delete"
175 
176  self%nval = 0
177  if (allocated(self%wi)) deallocate(self%wi)
178  if (allocated(self%wf)) deallocate(self%wf)
179  self%ltraj = .false.
180 
181  end subroutine conventional_profile_tlad_delete_
182 
183 ! ------------------------------------------------------------------------------
184 
subroutine, public ufo_geovals_get_var(self, varname, geoval, status)
integer, parameter max_string
subroutine vert_interp_apply_ad(nlev, fvec_ad, f_ad, wi, wf)
Definition: vert_interp.F90:97
integer function, public obsspace_get_nobs(c_dom)
Return the number of observations.
subroutine vert_interp_apply_tl(nlev, fvec_tl, f_tl, wi, wf)
Definition: vert_interp.F90:82
subroutine conventional_profile_simobs_ad_(self, geovals, hofx, obss)
Fortran module to perform linear interpolation.
Definition: vert_interp.F90:8
character(len=maxvarlen), public var_prsl
type(registry_t), public ufo_geovals_registry
Linked list interface - defines registry_t type.
subroutine conventional_profile_tlad_settraj_(self, geovals, obss)
Fortran interface to ObsSpace.
Definition: obsspace_mod.F90:9
character(len=maxvarlen), public var_tv
subroutine vert_interp_weights(nlev, obl, vec, wi, wf)
Definition: vert_interp.F90:20
subroutine conventional_profile_simobs_tl_(self, geovals, hofx, obss)
subroutine, public delete(self)
Definition: qg_fields.F90:136