UFO
ufo_insitutemperature_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 
6 !> Fortran insitutemperature module for observation operator
7 
9 
10  use fckit_configuration_module, only: fckit_configuration
11  use iso_c_binding
12  use kinds
13 
15  use ufo_basis_mod, only: ufo_basis
16  use ufo_vars_mod
17  use obsspace_mod
18 
19  implicit none
20  private
21 
22  integer, parameter :: max_string=800
23 
24 !> Fortran derived type for the observation type
25  type, extends(ufo_basis), public :: ufo_insitutemperature
26  private
27  contains
28  procedure :: setup => ufo_insitutemperature_setup
29  procedure :: delete => ufo_insitutemperature_delete
30  procedure :: simobs => ufo_insitutemperature_simobs
31  end type ufo_insitutemperature
32 
33 contains
34 
35 ! ------------------------------------------------------------------------------
36 subroutine ufo_insitutemperature_setup(self, f_conf)
37 implicit none
38 class(ufo_insitutemperature), intent(inout) :: self
39 type(fckit_configuration), intent(in) :: f_conf
40 
41 end subroutine ufo_insitutemperature_setup
42 
43 ! ------------------------------------------------------------------------------
45 implicit none
46 class(ufo_insitutemperature), intent(inout) :: self
47 
48 end subroutine ufo_insitutemperature_delete
49 
50 ! ------------------------------------------------------------------------------
51 subroutine ufo_insitutemperature_simobs(self, geovals, hofx, obss)
55 implicit none
56 class(ufo_insitutemperature), intent(in) :: self
57 type(ufo_geovals), intent(in) :: geovals
58 real(c_double), intent(inout) :: hofx(:)
59 type(c_ptr), value, intent(in) :: obss
60 
61  character(len=*), parameter :: myname_="ufo_insitutemperature_simobs"
62  character(max_string) :: err_msg
63 
64  integer :: iobs, ilev, nlev, nlocs
65  type(ufo_geoval), pointer :: temp, salt, h
66  real (kind_real), allocatable :: depth(:,:)
67  real(kind_real) :: lono, lato, deptho
68  real(kind_real), allocatable :: obs_lon(:)
69  real(kind_real), allocatable :: obs_lat(:)
70  real(kind_real), allocatable :: obs_depth(:)
71  integer :: obss_nlocs
72  real(kind_real) :: wf, tp, sp, prs, max_depth
73  integer :: wi
74 
75  ! check if nlocs is consistent in geovals & hofx
76  if (geovals%nlocs /= size(hofx,1)) then
77  write(err_msg,*) myname_, ' error: nlocs inconsistent!'
78  call abor1_ftn(err_msg)
79  endif
80 
81  ! Associate geoval pointers
82  call ufo_geovals_get_var(geovals, var_ocn_pot_temp, temp)
83  call ufo_geovals_get_var(geovals, var_ocn_salt, salt)
84  call ufo_geovals_get_var(geovals, var_ocn_lay_thick, h)
85 
86  ! Read in obs data
87  obss_nlocs = obsspace_get_nlocs(obss)
88  allocate(obs_lon(obss_nlocs))
89  allocate(obs_lat(obss_nlocs))
90  allocate(obs_depth(obss_nlocs))
91  call obsspace_get_db(obss, "MetaData", "longitude", obs_lon)
92  call obsspace_get_db(obss, "MetaData", "latitude", obs_lat)
93  call obsspace_get_db(obss, "MetaData", "depth", obs_depth)
94 
95  nlev = temp%nval
96  nlocs = temp%nlocs
97  allocate(depth(nlev,nlocs))
98  do iobs = 1,size(hofx,1)
99  !< Depth from layer thickness
100  depth(1,iobs)=0.5*h%vals(1,iobs)
101  do ilev = 2, nlev
102  depth(ilev,iobs)=sum(h%vals(1:ilev-1,iobs))+0.5*h%vals(ilev,iobs)
103  end do
104  end do
105  max_depth=maxval(depth)
106 
107  ! Information for temporary output file
108 
109  hofx = 0.0
110  ! insitu temperature profile obs operator
111  do iobs = 1,size(hofx,1)
112 
113  lono = obs_lon(iobs)
114  lato = obs_lat(iobs)
115  deptho = obs_depth(iobs)
116 
117  !< Interpolation weight
118  call vert_interp_weights(nlev, deptho, depth(:,iobs), wi, wf)
119  if (deptho >= max_depth) then
120  wi=nlev-1
121  wf=0.0
122  end if
123 
124  ! Interpolate temp_p, salt_p to deptho
125  call vert_interp_apply(nlev, temp%vals(:,iobs), tp, wi, wf)
126  call vert_interp_apply(nlev, salt%vals(:,iobs), sp, wi, wf)
127 
128  ! Get insitu temp at model levels and obs location (lono, lato, zo)
129  call insitu_t_nl(hofx(iobs), tp, sp, lono, lato, deptho)
130 
131  enddo
132 
133  deallocate(depth)
134  deallocate(obs_lon)
135  deallocate(obs_lat)
136  deallocate(obs_depth)
137 
138  end subroutine ufo_insitutemperature_simobs
139 
140 end module ufo_insitutemperature_mod
subroutine, public ufo_geovals_get_var(self, varname, geoval)
Fortran insitutemperature module for observation operator.
subroutine ufo_insitutemperature_setup(self, f_conf)
subroutine ufo_insitutemperature_simobs(self, geovals, hofx, obss)
subroutine, public insitu_t_nl(temp_i, temp_p, salt_p, lono, lato, deptho)
character(len=maxvarlen), public var_ocn_pot_temp
character(len=maxvarlen), public var_ocn_salt
character(len=maxvarlen), public var_ocn_lay_thick
Fortran module to perform linear interpolation.
Definition: vert_interp.F90:8
subroutine vert_interp_weights(nlev, obl, vec, wi, wf)
Definition: vert_interp.F90:22
subroutine vert_interp_apply(nlev, fvec, f, wi, wf)
Definition: vert_interp.F90:73
type to hold interpolated field for one variable, one observation
type to hold interpolated fields required by the obs operators
Fortran derived type for the observation type.