OOPS
qg_getvalues_mod.F90
Go to the documentation of this file.
1 ! (C) Copyright 2020 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 atlas_module, only: atlas_field
9 use datetime_mod
10 use fckit_log_module,only: fckit_log
11 use iso_c_binding
12 use kinds
13 !$ use omp_lib
17 use qg_fields_mod
18 use qg_geom_mod
19 use qg_gom_mod
20 use qg_interp_mod
21 use qg_locs_mod
22 
23 implicit none
24 
25 private
27 
28 ! ------------------------------------------------------------------------------
29 contains
30 ! ------------------------------------------------------------------------------
31 ! Public
32 ! ------------------------------------------------------------------------------
33 !> Interpolation from fields
34 subroutine qg_getvalues_interp(locs,fld,t1,t2,gom)
35 
36 implicit none
37 
38 ! Passed variables
39 type(qg_locs), intent(in) :: locs !< Locations
40 type(qg_fields),intent(in) :: fld !< Fields
41 type(datetime),intent(in) :: t1, t2 !< times
42 type(qg_gom),intent(inout) :: gom !< Interpolated values
43 
44 ! Local variables
45 integer :: jloc
46 real(kind_real),allocatable :: x(:,:,:),q(:,:,:),u(:,:,:),v(:,:,:)
47 real(kind_real), pointer :: lonlat(:,:), z(:)
48 type(atlas_field) :: lonlat_field, z_field
49 
50 ! get locations
51 lonlat_field = locs%lonlat()
52 call lonlat_field%data(lonlat)
53 
54 z_field = locs%altitude()
55 call z_field%data(z)
56 
57 ! Check field
58 call qg_fields_check(fld)
59 
60 ! Allocation
61 allocate(x(fld%geom%nx,fld%geom%ny,fld%geom%nz))
62 allocate(q(fld%geom%nx,fld%geom%ny,fld%geom%nz))
63 allocate(u(fld%geom%nx,fld%geom%ny,fld%geom%nz))
64 allocate(v(fld%geom%nx,fld%geom%ny,fld%geom%nz))
65 
66 ! Get variables
67 if (fld%lq) then
68  q = fld%gfld3d
69 else
70  x = fld%gfld3d
71 endif
72 if (gom%ix /= 0.or.gom%iu /= 0.or.gom%iv /= 0) then
73  if (fld%lq) call convert_q_to_x(fld%geom,q,fld%x_north,fld%x_south,x)
74 endif
75 if (gom%iq /= 0) then
76  if (.not.fld%lq) call convert_x_to_q(fld%geom,x,fld%x_north,fld%x_south,q)
77 endif
78 if (gom%iu /= 0.or.gom%iv /= 0) call convert_x_to_uv(fld%geom,x,fld%x_north,fld%x_south,u,v)
79 
80 !$omp parallel do schedule(static) private(jloc)
81 do jloc=1,locs%nlocs()
82  ! Check if current obs is in this time frame (t1,t2]
83  if (t1 < locs%times(jloc) .and. locs%times(jloc) <= t2) then
84  ! Interpolate variables
85  if (gom%ix /= 0) call qg_interp_trilinear(fld%geom,lonlat(1,jloc),lonlat(2,jloc), &
86  & z(jloc),x,gom%values(gom%ix,jloc))
87  if (gom%iq /= 0) call qg_interp_trilinear(fld%geom,lonlat(1,jloc),lonlat(2,jloc), &
88  & z(jloc),q,gom%values(gom%iq,jloc))
89  if (gom%iu /= 0) call qg_interp_trilinear(fld%geom,lonlat(1,jloc),lonlat(2,jloc), &
90  & z(jloc),u,gom%values(gom%iu,jloc))
91  if (gom%iv /= 0) call qg_interp_trilinear(fld%geom,lonlat(1,jloc),lonlat(2,jloc), &
92  & z(jloc),v,gom%values(gom%iv,jloc))
93  endif
94 enddo
95 !$omp end parallel do
96 
97 call lonlat_field%final()
98 call z_field%final()
99 
100 end subroutine qg_getvalues_interp
101 ! ------------------------------------------------------------------------------
102 !> Interpolation from fields - tangent linear
103 subroutine qg_getvalues_interp_tl(locs,fld,t1,t2,gom)
104 
105 implicit none
106 
107 ! Passed variables
108 type(qg_locs), intent(in) :: locs !< Locations
109 type(qg_fields),intent(in) :: fld !< Fields
110 type(datetime),intent(in) :: t1, t2 !< times
111 type(qg_gom),intent(inout) :: gom !< Interpolated values
112 
113 ! Local variables
114 integer :: jloc
115 real(kind_real),allocatable :: x(:,:,:),q(:,:,:),u(:,:,:),v(:,:,:)
116 real(kind_real), pointer :: lonlat(:,:), z(:)
117 type(atlas_field) :: lonlat_field, z_field
118 
119 ! get locations
120 lonlat_field = locs%lonlat()
121 call lonlat_field%data(lonlat)
122 
123 z_field = locs%altitude()
124 call z_field%data(z)
125 
126 ! Check field
127 call qg_fields_check(fld)
128 
129 ! Allocation
130 allocate(x(fld%geom%nx,fld%geom%ny,fld%geom%nz))
131 allocate(q(fld%geom%nx,fld%geom%ny,fld%geom%nz))
132 allocate(u(fld%geom%nx,fld%geom%ny,fld%geom%nz))
133 allocate(v(fld%geom%nx,fld%geom%ny,fld%geom%nz))
134 
135 ! Get variables
136 if (fld%lq) then
137  q = fld%gfld3d
138 else
139  x = fld%gfld3d
140 endif
141 if (gom%ix /= 0.or.gom%iu /= 0.or.gom%iv /= 0) then
142  if (fld%lq) call convert_q_to_x_tl(fld%geom,q,x)
143 endif
144 if (gom%iq /= 0) then
145  if (.not.fld%lq) call convert_x_to_q_tl(fld%geom,x,q)
146 endif
147 if (gom%iu /= 0.or.gom%iv /= 0) call convert_x_to_uv_tl(fld%geom,x,u,v)
148 
149 !$omp parallel do schedule(static) private(jloc)
150 do jloc=1,locs%nlocs()
151  ! Check if current obs is in this time frame (t1,t2]
152  if (t1 < locs%times(jloc) .and. locs%times(jloc) <= t2) then
153  ! Interpolate variables
154  if (gom%ix /= 0) call qg_interp_trilinear(fld%geom,lonlat(1,jloc),lonlat(2,jloc), &
155  & z(jloc),x,gom%values(gom%ix,jloc))
156  if (gom%iq /= 0) call qg_interp_trilinear(fld%geom,lonlat(1,jloc),lonlat(2,jloc), &
157  & z(jloc),q,gom%values(gom%iq,jloc))
158  if (gom%iu /= 0) call qg_interp_trilinear(fld%geom,lonlat(1,jloc),lonlat(2,jloc), &
159  & z(jloc),u,gom%values(gom%iu,jloc))
160  if (gom%iv /= 0) call qg_interp_trilinear(fld%geom,lonlat(1,jloc),lonlat(2,jloc), &
161  & z(jloc),v,gom%values(gom%iv,jloc))
162  endif
163 enddo
164 !$omp end parallel do
165 
166 call lonlat_field%final()
167 call z_field%final()
168 
169 end subroutine qg_getvalues_interp_tl
170 ! ------------------------------------------------------------------------------
171 !> Interpolation from fields - adjoint
172 subroutine qg_getvalues_interp_ad(locs,fld,t1,t2,gom)
173 
174 implicit none
175 
176 ! Passed variables
177 type(qg_locs), intent(in) :: locs !< Locations
178 type(qg_fields),intent(inout) :: fld !< Fields
179 type(datetime),intent(in) :: t1, t2 !< times
180 type(qg_gom),intent(in) :: gom !< Interpolated values
181 
182 ! Local variables
183 integer :: jloc
184 real(kind_real),allocatable :: x(:,:,:),q(:,:,:),u(:,:,:),v(:,:,:)
185 real(kind_real), pointer :: lonlat(:,:), z(:)
186 type(atlas_field) :: lonlat_field, z_field
187 
188 ! get locations
189 lonlat_field = locs%lonlat()
190 call lonlat_field%data(lonlat)
191 
192 z_field = locs%altitude()
193 call z_field%data(z)
194 
195 ! Check field
196 call qg_fields_check(fld)
197 
198 ! Allocation
199 allocate(x(fld%geom%nx,fld%geom%ny,fld%geom%nz))
200 allocate(q(fld%geom%nx,fld%geom%ny,fld%geom%nz))
201 allocate(u(fld%geom%nx,fld%geom%ny,fld%geom%nz))
202 allocate(v(fld%geom%nx,fld%geom%ny,fld%geom%nz))
203 
204 ! Initialization
205 x = 0.0
206 q = 0.0
207 u = 0.0
208 v = 0.0
209 
210 do jloc=locs%nlocs(),1,-1
211  ! Check if current obs is in this time frame (t1,t2]
212  if (t1 < locs%times(jloc) .and. locs%times(jloc) <= t2) then
213  ! Interpolate variables
214  if (gom%ix /= 0) call qg_interp_trilinear_ad(fld%geom,lonlat(1,jloc),lonlat(2,jloc), &
215  & z(jloc),gom%values(gom%ix,jloc),x)
216  if (gom%iq /= 0) call qg_interp_trilinear_ad(fld%geom,lonlat(1,jloc),lonlat(2,jloc), &
217  & z(jloc),gom%values(gom%iq,jloc),q)
218  if (gom%iu /= 0) call qg_interp_trilinear_ad(fld%geom,lonlat(1,jloc),lonlat(2,jloc), &
219  & z(jloc),gom%values(gom%iu,jloc),u)
220  if (gom%iv /= 0) call qg_interp_trilinear_ad(fld%geom,lonlat(1,jloc),lonlat(2,jloc), &
221  & z(jloc),gom%values(gom%iv,jloc),v)
222  endif
223 enddo
224 
225 ! Get variables
226 if (gom%iu /= 0.or.gom%iv /= 0) call convert_x_to_uv_ad(fld%geom,u,v,x)
227 if (gom%iq /= 0) then
228  if (.not.fld%lq) call convert_x_to_q_ad(fld%geom,q,x)
229 endif
230 if (gom%ix /= 0.or.gom%iu /= 0.or.gom%iv /= 0) then
231  if (fld%lq) call convert_q_to_x_ad(fld%geom,x,q)
232 endif
233 if (fld%lq) then
234  fld%gfld3d = fld%gfld3d+q
235 else
236  fld%gfld3d = fld%gfld3d+x
237 endif
238 
239 call lonlat_field%final()
240 call z_field%final()
241 
242 end subroutine qg_getvalues_interp_ad
243 ! ------------------------------------------------------------------------------
244 end module qg_getvalues_mod
qg_fields_mod
Definition: qg_fields_mod.F90:9
qg_fields_mod::qg_fields
Definition: qg_fields_mod.F90:51
qg_geom_mod
Definition: qg_geom_mod.F90:9
qg_convert_x_to_q_mod
Definition: qg_convert_x_to_q_mod.F90:9
qg_convert_q_to_x_mod::convert_q_to_x_tl
subroutine, public convert_q_to_x_tl(geom, q, x)
Convert potential vorticity to streamfunction - tangent linear.
Definition: qg_convert_q_to_x_mod.F90:86
qg_convert_x_to_q_mod::convert_x_to_q_tl
subroutine, public convert_x_to_q_tl(geom, x, q)
Convert streamfunction to potential vorticity - tangent linear.
Definition: qg_convert_x_to_q_mod.F90:73
qg_interp_mod::qg_interp_trilinear
subroutine, public qg_interp_trilinear(geom, lon, lat, z, gfld3d, val)
Trilinear interpolation.
Definition: qg_interp_mod.F90:29
qg_getvalues_mod
Definition: qg_getvalues_mod.F90:6
qg_convert_q_to_x_mod
Definition: qg_convert_q_to_x_mod.F90:9
qg_locs_mod
Definition: qg_locs_mod.F90:9
qg_locs_mod::qg_locs
Definition: qg_locs_mod.F90:22
qg_gom_mod::qg_gom
Definition: qg_gom_mod.F90:33
qg_interp_mod
Definition: qg_interp_mod.F90:9
qg_convert_x_to_q_mod::convert_x_to_q
subroutine, public convert_x_to_q(geom, x, x_north, x_south, q)
Convert streamfunction to potential vorticity.
Definition: qg_convert_x_to_q_mod.F90:25
qg_convert_x_to_uv_mod::convert_x_to_uv
subroutine, public convert_x_to_uv(geom, x, x_north, x_south, u, v)
Convert streafunction to wind components.
Definition: qg_convert_x_to_uv_mod.F90:23
qg_convert_x_to_q_mod::convert_x_to_q_ad
subroutine, public convert_x_to_q_ad(geom, q, x)
Convert streamfunction to potential vorticity - adjoint.
Definition: qg_convert_x_to_q_mod.F90:107
qg_convert_x_to_uv_mod::convert_x_to_uv_tl
subroutine, public convert_x_to_uv_tl(geom, x, u, v)
Convert streafunction to wind components - tangent Linear.
Definition: qg_convert_x_to_uv_mod.F90:61
qg_getvalues_mod::qg_getvalues_interp_ad
subroutine, public qg_getvalues_interp_ad(locs, fld, t1, t2, gom)
Interpolation from fields - adjoint.
Definition: qg_getvalues_mod.F90:173
qg_getvalues_mod::qg_getvalues_interp_tl
subroutine, public qg_getvalues_interp_tl(locs, fld, t1, t2, gom)
Interpolation from fields - tangent linear.
Definition: qg_getvalues_mod.F90:104
qg_convert_x_to_uv_mod
Definition: qg_convert_x_to_uv_mod.F90:9
qg_interp_mod::qg_interp_trilinear_ad
subroutine, public qg_interp_trilinear_ad(geom, lon, lat, z, val, gfld3d)
Interpolation - adjoint.
Definition: qg_interp_mod.F90:83
qg_fields_mod::qg_fields_check
subroutine, public qg_fields_check(self)
Check fields.
Definition: qg_fields_mod.F90:1429
qg_gom_mod
Definition: qg_gom_mod.F90:9
qg_convert_q_to_x_mod::convert_q_to_x
subroutine, public convert_q_to_x(geom, q, x_north, x_south, x)
Convert potential vorticity to streamfunction.
Definition: qg_convert_q_to_x_mod.F90:25
qg_getvalues_mod::qg_getvalues_interp
subroutine, public qg_getvalues_interp(locs, fld, t1, t2, gom)
Interpolation from fields.
Definition: qg_getvalues_mod.F90:35
qg_convert_x_to_uv_mod::convert_x_to_uv_ad
subroutine, public convert_x_to_uv_ad(geom, u, v, x)
Convert streafunction to wind components - adjoint.
Definition: qg_convert_x_to_uv_mod.F90:96
qg_convert_q_to_x_mod::convert_q_to_x_ad
subroutine, public convert_q_to_x_ad(geom, x, q)
Convert potential vorticity to streamfunction - adjoint.
Definition: qg_convert_q_to_x_mod.F90:133