FV3 Bundle
qg_goms_mod.F90
Go to the documentation of this file.
1 ! (C) Copyright 2009-2016 ECMWF.
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 ! In applying this licence, ECMWF does not waive the privileges and immunities
6 ! granted to it by virtue of its status as an intergovernmental organisation nor
7 ! does it submit to any jurisdiction.
8 
9 !> Fortran module handling interpolated (to obs locations) model variables
10 
12 
13 use iso_c_binding
14 use qg_locs_mod
15 use qg_vars_mod
16 use kinds
17 
18 implicit none
19 private
20 public :: qg_goms, gom_setup
21 public :: qg_goms_registry
22 
23 ! ------------------------------------------------------------------------------
24 
25 !> Fortran derived type to hold interpolated fields required by the obs operators
26 type :: qg_goms
27  integer :: nobs
28  integer :: nvar
29  integer :: used
30  integer, allocatable :: indx(:)
31  real(kind=kind_real), allocatable :: values(:,:)
32  character(len=1), allocatable :: variables(:)
33  logical :: lalloc
34 end type qg_goms
35 
36 #define LISTED_TYPE qg_goms
37 
38 !> Linked list interface - defines registry_t type
39 #include "oops/util/linkedList_i.f"
40 
41 !> Global registry
42 type(registry_t) :: qg_goms_registry
43 
44 ! ------------------------------------------------------------------------------
45 contains
46 ! ------------------------------------------------------------------------------
47 !> Linked list implementation
48 #include "oops/util/linkedList_c.f"
49 
50 ! ------------------------------------------------------------------------------
51 
52 subroutine c_qg_gom_setup(c_key_self, c_key_locs, c_vars) bind(c,name='qg_gom_setup_f90')
53 implicit none
54 integer(c_int), intent(inout) :: c_key_self
55 integer(c_int), intent(inout) :: c_key_locs
56 integer(c_int), dimension(*), intent(in) :: c_vars !< List of variables
57 
58 type(qg_goms), pointer :: self
59 type(qg_locs), pointer :: locs
60 type(qg_vars) :: vars
61 
62 call qg_goms_registry%init()
63 call qg_goms_registry%add(c_key_self)
64 call qg_goms_registry%get(c_key_self, self)
65 call qg_locs_registry%get(c_key_locs, locs)
66 call qg_vars_create(vars, c_vars)
67 
68 call gom_setup(self, vars, locs%indx)
69 
70 end subroutine c_qg_gom_setup
71 
72 ! ------------------------------------------------------------------------------
73 
74 subroutine c_qg_gom_create(c_key_self) bind(c,name='qg_gom_create_f90')
75 implicit none
76 integer(c_int), intent(inout) :: c_key_self
77 
78 type(qg_goms), pointer :: self
79 call qg_goms_registry%init()
80 call qg_goms_registry%add(c_key_self)
81 call qg_goms_registry%get(c_key_self, self)
82 
83 self%lalloc = .false.
84 
85 end subroutine c_qg_gom_create
86 
87 ! ------------------------------------------------------------------------------
88 
89 subroutine gom_setup(self, vars, kobs)
90 implicit none
91 type(qg_goms), intent(inout) :: self
92 type(qg_vars), intent(in) :: vars
93 integer, intent(in) :: kobs(:)
94 
95 self%nobs=size(kobs)
96 self%nvar=vars%nv
97 self%used=0
98 
99 allocate(self%indx(self%nobs))
100 self%indx(:)=kobs(:)
101 
102 allocate(self%variables(self%nvar))
103 self%variables(:)=vars%fldnames(:)
104 
105 allocate(self%values(self%nvar,self%nobs))
106 
107 self%lalloc = .true.
108 
109 end subroutine gom_setup
110 
111 ! ------------------------------------------------------------------------------
112 
113 subroutine c_qg_gom_delete(c_key_self) bind(c,name='qg_gom_delete_f90')
115 implicit none
116 integer(c_int), intent(inout) :: c_key_self
117 
118 type(qg_goms), pointer :: self
119 
120 call qg_goms_registry%get(c_key_self, self)
121 if (self%lalloc) then
122  deallocate(self%values)
123  deallocate(self%indx)
124  deallocate(self%variables)
125 endif
126 call qg_goms_registry%remove(c_key_self)
127 
128 end subroutine c_qg_gom_delete
129 
130 ! ------------------------------------------------------------------------------
131 
132 subroutine c_qg_gom_assign(c_key_self, c_key_other) bind(c,name='qg_gom_assign_f90')
133 implicit none
134 integer(c_int), intent(in) :: c_key_self
135 integer(c_int), intent(in) :: c_key_other
136 type(qg_goms), pointer :: self
137 type(qg_goms), pointer :: other
138 integer :: jo, jv
139 
140 call qg_goms_registry%get(c_key_self, self)
141 call qg_goms_registry%get(c_key_other, other)
142 
143 self%nobs = other%nobs
144 self%nvar = other%nvar
145 
146 if (.not. self%lalloc) then
147  allocate(self%variables(self%nvar))
148  allocate(self%values(self%nvar,self%nobs))
149  allocate(self%indx(self%nobs))
150  self%lalloc = .true.
151 endif
152 
153 self%variables = other%variables
154 self%values = other%values
155 self%indx = other%indx
156 self%used = other%used
157 
158 end subroutine c_qg_gom_assign
159 
160 ! ------------------------------------------------------------------------------
161 
162 subroutine c_qg_gom_zero(c_key_self) bind(c,name='qg_gom_zero_f90')
163 implicit none
164 integer(c_int), intent(in) :: c_key_self
165 type(qg_goms), pointer :: self
166 call qg_goms_registry%get(c_key_self, self)
167 self%values(:,:)=0.0_kind_real
168 end subroutine c_qg_gom_zero
169 
170 ! ------------------------------------------------------------------------------
171 
172 subroutine c_qg_gom_abs(c_key_self) bind(c,name='qg_gom_abs_f90')
173 implicit none
174 integer(c_int), intent(in) :: c_key_self
175 type(qg_goms), pointer :: self
176 call qg_goms_registry%get(c_key_self, self)
177 self%values(:,:)=abs(self%values(:,:))
178 end subroutine c_qg_gom_abs
179 
180 ! ------------------------------------------------------------------------------
181 
182 subroutine c_qg_gom_random(c_key_self) bind(c,name='qg_gom_random_f90')
184 implicit none
185 integer(c_int), intent(in) :: c_key_self
186 type(qg_goms), pointer :: self
187 call qg_goms_registry%get(c_key_self, self)
188 call random_vector(self%values(:,:))
189 end subroutine c_qg_gom_random
190 
191 ! ------------------------------------------------------------------------------
192 
193 subroutine c_qg_gom_mult(c_key_self, zz) bind(c,name='qg_gom_mult_f90')
194 implicit none
195 integer(c_int), intent(in) :: c_key_self
196 real(c_double), intent(in) :: zz
197 type(qg_goms), pointer :: self
198 integer :: jo, jv
199 
200 call qg_goms_registry%get(c_key_self, self)
201 do jo=1,self%nobs
202  do jv=1,self%nvar
203  self%values(jv,jo) = zz * self%values(jv,jo)
204  enddo
205 enddo
206 
207 end subroutine c_qg_gom_mult
208 
209 ! ------------------------------------------------------------------------------
210 
211 subroutine c_qg_gom_add(c_key_self, c_key_other) bind(c,name='qg_gom_add_f90')
212 implicit none
213 integer(c_int), intent(in) :: c_key_self
214 integer(c_int), intent(in) :: c_key_other
215 type(qg_goms), pointer :: self
216 type(qg_goms), pointer :: other
217 integer :: jo, jv
218 
219 call qg_goms_registry%get(c_key_self, self)
220 call qg_goms_registry%get(c_key_other, other)
221 do jo=1,self%nobs
222  do jv=1,self%nvar
223  self%values(jv,jo) = self%values(jv,jo) + other%values(jv,jo)
224  enddo
225 enddo
226 
227 end subroutine c_qg_gom_add
228 
229 ! ------------------------------------------------------------------------------
230 
231 subroutine c_qg_gom_diff(c_key_self, c_key_other) bind(c,name='qg_gom_diff_f90')
232 implicit none
233 integer(c_int), intent(in) :: c_key_self
234 integer(c_int), intent(in) :: c_key_other
235 type(qg_goms), pointer :: self
236 type(qg_goms), pointer :: other
237 integer :: jo, jv
238 
239 call qg_goms_registry%get(c_key_self, self)
240 call qg_goms_registry%get(c_key_other, other)
241 do jo=1,self%nobs
242  do jv=1,self%nvar
243  self%values(jv,jo) = self%values(jv,jo) - other%values(jv,jo)
244  enddo
245 enddo
246 
247 end subroutine c_qg_gom_diff
248 
249 ! ------------------------------------------------------------------------------
250 !> QG GeoVaLs division Operator
251 
252 subroutine c_qg_gom_divide(c_key_self, c_key_other) bind(c,name='qg_gom_divide_f90')
253 implicit none
254 integer(c_int), intent(in) :: c_key_self
255 integer(c_int), intent(in) :: c_key_other
256 type(qg_goms), pointer :: self
257 type(qg_goms), pointer :: other
258 real(kind_real) :: tol
259 integer :: jloc, jvar, ii
260 
261 call qg_goms_registry%get(c_key_self, self)
262 call qg_goms_registry%get(c_key_other, other)
263 
264 tol = epsilon(tol)
265 ii=0
266 
267 do jvar = 1, self%nvar
268  write(*,*)'qg_gom_divide variable =', trim(self%variables(jvar))
269  do jloc = 1, self%nobs
270  if (abs(other%values(jvar,jloc)) > tol) then
271  write(*,*)'qg_gom_divide self, other = ',self%values(jvar,jloc), other%values(jvar,jloc), &
272  & self%values(jvar,jloc) / other%values(jvar,jloc)
273  self%values(jvar,jloc) = self%values(jvar,jloc) / other%values(jvar,jloc)
274  else
275  write(*,*)'qg_gom_divide self, other = ',self%values(jvar,jloc), other%values(jvar,jloc)
276  self%values(jvar,jloc) = 0.0
277  ii=ii+1
278  endif
279  enddo
280 enddo
281 
282 end subroutine c_qg_gom_divide
283 
284 ! ------------------------------------------------------------------------------
285 
286 subroutine c_qg_gom_rms(c_key_self, rms) bind(c,name='qg_gom_rms_f90')
287 implicit none
288 integer(c_int), intent(in) :: c_key_self
289 real(c_double), intent(inout) :: rms
290 type(qg_goms), pointer :: self
291 integer :: jo, jv
292 
293 call qg_goms_registry%get(c_key_self, self)
294 
295 rms=0.0_kind_real
296 do jo=1,self%nobs
297  do jv=1,self%nvar
298  rms=rms+self%values(jv,jo)**2
299  enddo
300 enddo
301 
302 rms = sqrt(rms/(self%nobs*self%nvar))
303 
304 end subroutine c_qg_gom_rms
305 
306 ! ------------------------------------------------------------------------------
307 
308 subroutine c_qg_gom_dotprod(c_key_self, c_key_other, prod) bind(c,name='qg_gom_dotprod_f90')
309 implicit none
310 integer(c_int), intent(in) :: c_key_self, c_key_other
311 real(c_double), intent(inout) :: prod
312 type(qg_goms), pointer :: self, other
313 integer :: jo, jv
314 
315 call qg_goms_registry%get(c_key_self, self)
316 call qg_goms_registry%get(c_key_other, other)
317 prod=0.0_kind_real
318 do jo=1,self%nobs
319  do jv=1,self%nvar
320  prod=prod+self%values(jv,jo)*other%values(jv,jo)
321  enddo
322 enddo
323 
324 end subroutine c_qg_gom_dotprod
325 
326 ! ------------------------------------------------------------------------------
327 
328 subroutine c_qg_gom_minmaxavg(c_key_self, kobs, pmin, pmax, prms) bind(c,name='qg_gom_minmaxavg_f90')
329 implicit none
330 integer(c_int), intent(in) :: c_key_self
331 integer(c_int), intent(inout) :: kobs
332 real(c_double), intent(inout) :: pmin, pmax, prms
333 type(qg_goms), pointer :: self
334 
335 call qg_goms_registry%get(c_key_self, self)
336 
337 kobs = self%nobs
338 pmin=minval(self%values(:,:))
339 pmax=maxval(self%values(:,:))
340 prms=sqrt(sum(self%values(:,:)**2)/real(self%nobs*self%nvar,kind_real))
341 
342 end subroutine c_qg_gom_minmaxavg
343 
344 ! ------------------------------------------------------------------------------
345 
346 subroutine c_qg_gom_maxloc(c_key_self, mxval, iloc, ivar) bind(c,name='qg_gom_maxloc_f90')
347 implicit none
348 integer(c_int), intent(in) :: c_key_self !< key to GeoVals object
349 real(c_double), intent(inout) :: mxval !< maximum value
350 integer(c_int), intent(inout) :: iloc !< location of maximum value
351 integer(c_int), intent(inout) :: ivar !< variable with maximum value
352 
353 type(qg_goms), pointer :: self
354 integer :: mxloc(2)
355 
356 call qg_goms_registry%get(c_key_self, self)
357 
358 mxval=maxval(self%values(:,:))
359 mxloc=maxloc(self%values(:,:))
360 
361 ivar = mxloc(1)
362 iloc = mxloc(2)
363 
364 end subroutine c_qg_gom_maxloc
365 
366 ! ------------------------------------------------------------------------------
367 
368 subroutine qg_gom_read_file_c(c_key_self, c_conf) bind(c,name='qg_gom_read_file_f90')
369 use config_mod
370 use fckit_log_module, only : fckit_log
371 implicit none
372 integer(c_int), intent(in) :: c_key_self
373 type(c_ptr), intent(in) :: c_conf
374 type(qg_goms), pointer :: self
375 
376 integer, parameter :: iunit=10
377 integer, parameter :: max_string_length=250 ! Yuk!
378 character(len=max_string_length) :: filename, record
379 character(len=4) :: cnx
380 character(len=17) :: fmtn
381 character(len=11) :: fmt1='(X,ES24.16)'
382 integer :: jj, jo, jv
383 
384 call qg_goms_registry%get(c_key_self, self)
385 if (self%lalloc) call abor1_ftn("qg_gom_read_file gom alredy allocated")
386 
387 filename = config_get_string(c_conf,len(filename),"filename")
388 write(record,*)'qg_gom_read_file: opening '//trim(filename)
389 call fckit_log%info(record)
390 open(unit=iunit, file=trim(filename), form='formatted', action='read')
391 
392 read(iunit,*) self%nobs, self%nvar, self%used
393 allocate(self%indx(self%nobs))
394 allocate(self%variables(self%nvar))
395 allocate(self%values(self%nvar,self%nobs))
396 
397 read(iunit,*) self%indx(:)
398 do jv=1,self%nvar
399  read(iunit,*) self%variables(jv)
400 enddo
401 
402 if (self%nvar>9999) call abor1_ftn("Format too small")
403 write(cnx,'(I4)')self%nvar
404 fmtn='('//trim(cnx)//fmt1//')'
405 
406 do jo=1,self%nobs
407  read(iunit,fmtn) (self%values(jj,jo), jj=1,self%nvar)
408 enddo
409 
410 close(iunit)
411 self%lalloc = .true.
412 
413 end subroutine qg_gom_read_file_c
414 
415 ! ------------------------------------------------------------------------------
416 
417 subroutine qg_gom_write_file_c(c_key_self, c_conf) bind(c,name='qg_gom_write_file_f90')
418 use config_mod
419 use fckit_log_module, only : fckit_log
420 implicit none
421 integer(c_int), intent(in) :: c_key_self
422 type(c_ptr), intent(in) :: c_conf
423 type(qg_goms), pointer :: self
424 
425 integer, parameter :: iunit=10
426 integer, parameter :: max_string_length=250 ! Yuk!
427 character(len=max_string_length) :: filename, record
428 character(len=4) :: cnx
429 character(len=17) :: fmtn
430 character(len=11) :: fmt1='(X,ES24.16)'
431 integer :: jj, jo, jv
432 
433 call qg_goms_registry%get(c_key_self, self)
434 if (.not.self%lalloc) call abor1_ftn("qg_gom_write_file gom not allocated")
435 
436 filename = config_get_string(c_conf,len(filename),"filename")
437 write(record,*)'qg_gom_write_file: opening '//trim(filename)
438 call fckit_log%info(record)
439 open(unit=iunit, file=trim(filename), form='formatted', action='write')
440 
441 write(iunit,*) self%nobs, self%nvar, self%used
442 write(iunit,*) self%indx(:)
443 do jv=1,self%nvar
444  write(iunit,*) self%variables(jv)
445 enddo
446 
447 if (self%nvar>9999) call abor1_ftn("Format too small")
448 write(cnx,'(I4)')self%nvar
449 fmtn='('//trim(cnx)//fmt1//')'
450 
451 do jo=1,self%nobs
452  write(iunit,fmtn) (self%values(jj,jo), jj=1,self%nvar)
453 enddo
454 
455 close(iunit)
456 
457 end subroutine qg_gom_write_file_c
458 
459 ! ------------------------------------------------------------------------------
460 !> Initialize a QG GeoVaLs object based on an analytic state
461 !!
462 !! \details **qg_gom_analytic_init_c()** creates a QG GeoVaLs object and fills in
463 !! values based on one of several analytic solutions. For a description of the
464 !! solutions that are currently implemented, see the analytic_init() routine in
465 !! qg_fields.F90. This initialization is intended to be used with the
466 !! **TestStateInterpolation()** test.
467 !!
468 !! \date April, 2018: Created by M. Miesch (JCSDA)
469 !!
470 !! \sa qg::GomQG analytic_init()
471 !!
472 subroutine qg_gom_analytic_init_c(c_key_self, c_key_locs, c_conf) bind(c,name='qg_gom_analytic_init_f90')
473 use config_mod
475 use qg_constants, only : ubar
476 use fckit_log_module, only : fckit_log
477 
478 implicit none
479 integer(c_int), intent(in) :: c_key_self !< key to GeoVaLs object we are creating
480 integer(c_int), intent(in) :: c_key_locs !< key to the F90 Locations object
481 type(c_ptr), intent(in) :: c_conf !< "StateGenerate" configuration
482 
483 type(qg_goms), pointer :: self ! GeoVals object we are creating
484 type(qg_locs), pointer :: locs
485 
486 character(len=30) :: ic
487 character(len=1024) :: buf
488 real(kind_real) :: d1, d2, height(2), klon, klat, kx, ky, kz, xx, yy
489 real(kind_real) :: pi = acos(-1.0_kind_real)
490 real(kind_real) :: p0,u0,v0,x0,w0,t0,phis0,ps0,rho0,hum0,q1,q2,q3,q4
491 real(kind_real) :: lat_range(2),lon_range(2)
492 integer :: iloc, ivar
493 
494 ! Get F90 Locations object
495 call qg_locs_registry%get(c_key_locs, locs)
496 
497 ! The GeoVaLs object should already be allocated and defined.
498 ! We just have to replace the values with the appropriate analytic values
499 
500 call qg_goms_registry%get(c_key_self, self)
501 
502 if (.not. self%lalloc) &
503  call abor1_ftn("qg_gom_analytic init: gom not allocated")
504 
505 ic = config_get_string(c_conf,len(ic),"analytic_init")
506 write(buf,*)'qg_gom_analytic_init: ic '//trim(ic)
507 call fckit_log%info(buf)
508 
509 ! The height is stored in the locations object as the layer number because
510 ! this is what the interp_tl() function currently requires. Here we have
511 ! to convert this to meters in order to use the analytic formulae.
512 ! So, as in the fields analytic_init() routine, set the height to be the
513 ! middle of the corresponding layer.
514 d1 = config_get_real(c_conf,"top_layer_depth")
515 d2 = config_get_real(c_conf,"bottom_layer_depth")
516 height(2) = 0.5_kind_real*d2
517 height(1) = d2 + 0.5_kind_real*d1
518 
519 ! Now loop over locations
520 
521 ! These are only needed for the dcmip initial conditions, which are not currently used for testing,
522 ! the lat range and lon range are hardwired in for now: see qg_geom_mod.F90 for further details
523 lat_range = (/ -28.0_kind_real, 28.0_kind_real /)
524 lon_range = (/ 0.0_kind_real, 107.0_kind_real /)
525 
526 do iloc = 1, locs%nloc
527 
528  ! First get the locations and convert to latitude (rad), longiude (rad) and height (meters)
529  klat = (lat_range(1) + locs%xyz(2,iloc)*(lat_range(2)-lat_range(1)))*pi/180.0_kind_real
530  klon = (lon_range(1) + locs%xyz(1,iloc)*(lon_range(2)-lon_range(1)))*pi/180.0_kind_real
531  kz = height(nint(locs%xyz(3,iloc)))
532 
533  init_option: select case (ic)
534 
535  case ("large-vortices")
536 
537  xx = locs%xyz(1,iloc)
538  yy = locs%xyz(2,iloc)
539  kx = pi
540  ky = 2.0_kind_real * pi
541  u0 = -ky*sin(kx*xx)*cos(ky*yy)
542  v0 = kx*cos(kx*xx)*sin(ky*yy)
543  x0 = sin(kx*xx)*sin(ky*yy) ! streamfunction
544 
545  case ("dcmip-test-1-1")
546 
547  call test1_advection_deformation(klon,klat,p0,kz,1,u0,v0,w0,&
548  t0,phis0,ps0,rho0,hum0,q1,q2,q3,q4)
549 
550  ! Make Nondimensional
551  u0 = u0 / ubar
552  v0 = v0 / ubar
553 
554  case ("dcmip-test-1-2")
555 
556  call test1_advection_hadley(klon,klat,p0,kz,1,u0,v0,w0,&
557  t0,phis0,ps0,rho0,hum0,q1)
558 
559  ! Make Nondimensional
560  u0 = u0 / ubar
561  v0 = v0 / ubar
562 
563  case default
564 
565  write(buf,*) "qg_gom_analytic_init: unknown init = " // ic
566  call fckit_log%error(buf)
567  call abor1_ftn(buf)
568 
569  end select init_option
570 
571  do ivar = 1,self%nvar
572 
573  variable: select case(trim(self%variables(ivar)))
574  case ("u")
575  self%values(ivar,iloc) = u0
576  case ("v")
577  self%values(ivar,iloc) = v0
578  case default
579  self%values(ivar,iloc) = 0.0_kind_real
580  end select variable
581 
582  enddo
583 
584 enddo
585 
586 end subroutine qg_gom_analytic_init_c
587 
588 ! ------------------------------------------------------------------------------
589 
590 end module qg_goms_mod
Fortran derived type to represent QG model variables.
Definition: qg_vars_mod.F90:23
Fortran generic for generating random 1d, 2d and 3d arrays.
subroutine c_qg_gom_mult(c_key_self, zz)
subroutine c_qg_gom_diff(c_key_self, c_key_other)
Fortran derived type to hold interpolated fields required by the obs operators.
Definition: qg_goms_mod.F90:26
type(registry_t), public qg_locs_registry
Linked list interface - defines registry_t type.
Definition: qg_locs_mod.F90:37
subroutine test1_advection_deformation(lon, lat, p, z, zcoords, u, v, w, t, phis, ps, rho, q, q1, q2, q3, q4)
subroutine, public gom_setup(self, vars, kobs)
Definition: qg_goms_mod.F90:90
subroutine c_qg_gom_divide(c_key_self, c_key_other)
QG GeoVaLs division Operator.
Constants for the QG model.
subroutine c_qg_gom_setup(c_key_self, c_key_locs, c_vars)
Linked list implementation.
Definition: qg_goms_mod.F90:53
subroutine c_qg_gom_create(c_key_self)
Definition: qg_goms_mod.F90:75
subroutine qg_gom_analytic_init_c(c_key_self, c_key_locs, c_conf)
Initialize a QG GeoVaLs object based on an analytic state.
subroutine c_qg_gom_random(c_key_self)
subroutine, public qg_vars_create(self, kvars)
Linked list implementation.
Definition: qg_vars_mod.F90:46
Fortran module handling observation locations.
Definition: qg_locs_mod.F90:11
type(registry_t), public qg_goms_registry
Linked list interface - defines registry_t type.
Definition: qg_goms_mod.F90:42
subroutine c_qg_gom_rms(c_key_self, rms)
Fortran module to handle variables for the QG model.
Definition: qg_vars_mod.F90:11
subroutine c_qg_gom_add(c_key_self, c_key_other)
Fortran module for generating random vectors.
subroutine test1_advection_hadley(lon, lat, p, z, zcoords, u, v, w, t, phis, ps, rho, q, q1)
subroutine c_qg_gom_zero(c_key_self)
subroutine qg_gom_read_file_c(c_key_self, c_conf)
subroutine c_qg_gom_maxloc(c_key_self, mxval, iloc, ivar)
Fortran module handling interpolated (to obs locations) model variables.
Definition: qg_goms_mod.F90:11
subroutine qg_gom_write_file_c(c_key_self, c_conf)
subroutine c_qg_gom_minmaxavg(c_key_self, kobs, pmin, pmax, prms)
subroutine c_qg_gom_dotprod(c_key_self, c_key_other, prod)
subroutine c_qg_gom_assign(c_key_self, c_key_other)
subroutine c_qg_gom_delete(c_key_self)
real(kind=kind_real), parameter ubar
typical verlocity (m/s)
subroutine c_qg_gom_abs(c_key_self)