FV3 Bundle
oobump_mod.F90
Go to the documentation of this file.
1 ! (C) Copyright 2017 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 module for handling generic BUMP
7 
8 module oobump_mod
9 
10 use iso_c_binding
11 use kinds
12 use config_mod
14 use type_bump, only: bump_type
16 
17 implicit none
18 
20  integer :: ngrid !> Number of instances of BUMP
21  type(bump_type),allocatable :: bump(:) !> Instances of BUMP
22 end type oobump_type
23 
24 private
29 
30 ! ------------------------------------------------------------------------------
31 
32 #define LISTED_TYPE oobump_type
33 
34 !> Linked list interface - defines registry_t type
35 #include "oops/util/linkedList_i.f"
36 
37 !> Global registry
38 type(registry_t) :: oobump_registry
39 
40 !-------------------------------------------------------------------------------
41 contains
42 !-------------------------------------------------------------------------------
43 
44 !> Linked list implementation
45 #include "oops/util/linkedList_c.f"
46 
47 ! ------------------------------------------------------------------------------
48 ! C++ interfaces
49 ! ------------------------------------------------------------------------------
50 
51 subroutine create_oobump_c(key, idx, c_conf, ens1_ne, ens1_nsub, ens2_ne, ens2_nsub) bind(c, name='create_oobump_f90')
52 implicit none
53 integer(c_int), intent(inout) :: key
54 integer(c_int), intent(in) :: idx
55 type(c_ptr), intent(in) :: c_conf
56 integer, intent(in) :: ens1_ne
57 integer, intent(in) :: ens1_nsub
58 integer, intent(in) :: ens2_ne
59 integer, intent(in) :: ens2_nsub
60 
61 type(oobump_type), pointer :: self
62 type(unstructured_grid), pointer :: ug
63 
64 ! Initialize BUMP registry
65 call oobump_registry%init()
66 call oobump_registry%add(key)
67 call oobump_registry%get(key, self)
68 
69 ! Get unstructured grid
70 call unstructured_grid_registry%get(idx, ug)
71 
72 ! Create BUMP
73 call create_oobump(self, ug, c_conf, ens1_ne, ens1_nsub, ens2_ne, ens2_nsub)
74 
75 end subroutine create_oobump_c
76 
77 ! ------------------------------------------------------------------------------
78 
79 subroutine delete_oobump_c(key) bind(c, name='delete_oobump_f90')
80 implicit none
81 integer(c_int), intent(inout) :: key
82 
83 type(oobump_type), pointer :: self
84 
85 ! Get BUMP
86 call oobump_registry%get(key, self)
87 
88 ! Delete BUMP
89 call delete_oobump(self)
90 
91 ! Delete registry key
92 call oobump_registry%remove(key)
93 
94 end subroutine delete_oobump_c
95 
96 ! ------------------------------------------------------------------------------
97 
98 subroutine add_oobump_member_c(key, idx, ie, iens) bind(c, name='add_oobump_member_f90')
99 implicit none
100 integer(c_int), intent(in) :: key
101 integer(c_int), intent(in) :: idx
102 integer, intent(in) :: ie
103 integer, intent(in) :: iens
104 
105 type(oobump_type), pointer :: self
106 type(unstructured_grid), pointer :: ug
107 
108 ! Get BUMP
109 call oobump_registry%get(key, self)
110 
111 ! Get unstructured grid
112 call unstructured_grid_registry%get(idx, ug)
113 
114 ! Add BUMP member
115 call add_oobump_member(self, ug, ie, iens)
116 
117 end subroutine add_oobump_member_c
118 
119 ! ------------------------------------------------------------------------------
120 
121 subroutine run_oobump_drivers_c(key) bind(c, name='run_oobump_drivers_f90')
122 implicit none
123 integer(c_int), intent(in) :: key
124 
125 type(oobump_type), pointer :: self
126 
127 ! Get BUMP
128 call oobump_registry%get(key, self)
129 
130 ! Run BUMP drivers
131 call run_oobump_drivers(self)
132 
133 end subroutine run_oobump_drivers_c
134 
135 ! ------------------------------------------------------------------------------
136 
137 subroutine multiply_oobump_vbal_c(key, idx) bind(c, name='multiply_oobump_vbal_f90')
138 implicit none
139 integer(c_int), intent(in) :: key
140 integer(c_int), intent(in) :: idx
141 
142 type(oobump_type), pointer :: self
143 type(unstructured_grid), pointer :: ug
144 
145 ! Get BUMP
146 call oobump_registry%get(key, self)
147 
148 ! Get unstructured grid
149 call unstructured_grid_registry%get(idx, ug)
150 
151 ! Multiply
152 call multiply_oobump_vbal(self, ug)
153 
154 end subroutine multiply_oobump_vbal_c
155 
156 ! ------------------------------------------------------------------------------
157 
158 subroutine multiply_oobump_vbal_inv_c(key, idx) bind(c, name='multiply_oobump_vbal_inv_f90')
159 implicit none
160 integer(c_int), intent(in) :: key
161 integer(c_int), intent(in) :: idx
162 
163 type(oobump_type), pointer :: self
164 type(unstructured_grid), pointer :: ug
165 
166 ! Get BUMP
167 call oobump_registry%get(key, self)
168 
169 ! Get unstructured grid
170 call unstructured_grid_registry%get(idx, ug)
171 
172 ! Multiply
173 call multiply_oobump_vbal_inv(self, ug)
174 
175 end subroutine multiply_oobump_vbal_inv_c
176 
177 ! ------------------------------------------------------------------------------
178 
179 subroutine multiply_oobump_vbal_ad_c(key, idx) bind(c, name='multiply_oobump_vbal_ad_f90')
180 implicit none
181 integer(c_int), intent(in) :: key
182 integer(c_int), intent(in) :: idx
183 
184 type(oobump_type), pointer :: self
185 type(unstructured_grid), pointer :: ug
186 
187 ! Get BUMP
188 call oobump_registry%get(key, self)
189 
190 ! Get unstructured grid
191 call unstructured_grid_registry%get(idx, ug)
192 
193 ! Multiply
194 call multiply_oobump_vbal_ad(self, ug)
195 
196 end subroutine multiply_oobump_vbal_ad_c
197 
198 ! ------------------------------------------------------------------------------
199 
200 subroutine multiply_oobump_vbal_inv_ad_c(key, idx) bind(c, name='multiply_oobump_vbal_inv_ad_f90')
201 implicit none
202 integer(c_int), intent(in) :: key
203 integer(c_int), intent(in) :: idx
204 
205 type(oobump_type), pointer :: self
206 type(unstructured_grid), pointer :: ug
207 
208 ! Get BUMP
209 call oobump_registry%get(key, self)
210 
211 ! Get unstructured grid
212 call unstructured_grid_registry%get(idx, ug)
213 
214 ! Multiply
215 call multiply_oobump_vbal_inv_ad(self, ug)
216 
217 end subroutine multiply_oobump_vbal_inv_ad_c
218 
219 ! ------------------------------------------------------------------------------
220 
221 subroutine multiply_oobump_nicas_c(key, idx) bind(c, name='multiply_oobump_nicas_f90')
222 implicit none
223 integer(c_int), intent(in) :: key
224 integer(c_int), intent(in) :: idx
225 
226 type(oobump_type), pointer :: self
227 type(unstructured_grid), pointer :: ug
228 
229 ! Get BUMP
230 call oobump_registry%get(key, self)
231 
232 ! Get unstructured grid
233 call unstructured_grid_registry%get(idx, ug)
234 
235 ! Multiply
236 call multiply_oobump_nicas(self, ug)
237 
238 end subroutine multiply_oobump_nicas_c
239 
240 ! ------------------------------------------------------------------------------
241 
242 subroutine get_oobump_cv_size_c(key, n) bind(c, name='get_oobump_cv_size_f90')
243 implicit none
244 integer(c_int), intent(in) :: key
245 integer(c_int), intent(out) :: n
246 
247 type(oobump_type), pointer :: self
248 
249 ! Get BUMP
250 call oobump_registry%get(key, self)
251 
252 ! Get control variable size
253 call get_oobump_cv_size(self, n)
254 
255 end subroutine get_oobump_cv_size_c
256 
257 ! ------------------------------------------------------------------------------
258 
259 subroutine multiply_oobump_nicas_sqrt_c(key, cv, idx) bind(c, name='multiply_oobump_nicas_sqrt_f90')
260 implicit none
261 integer(c_int), intent(in) :: key
262 real(c_double), intent(in) :: cv(:)
263 integer(c_int), intent(in) :: idx
264 
265 type(oobump_type), pointer :: self
266 type(unstructured_grid), pointer :: ug
267 
268 ! Get BUMP
269 call oobump_registry%get(key, self)
270 
271 ! Get unstructured grid
272 call unstructured_grid_registry%get(idx, ug)
273 
274 ! Square-root multiply
275 call multiply_oobump_nicas_sqrt(self, cv, ug)
276 
277 end subroutine multiply_oobump_nicas_sqrt_c
278 
279 ! ------------------------------------------------------------------------------
280 
281 subroutine multiply_oobump_nicas_sqrt_ad_c(key, idx, cv) bind(c, name='multiply_oobump_nicas_sqrt_ad_f90')
282 implicit none
283 integer(c_int), intent(in) :: key
284 integer(c_int), intent(in) :: idx
285 real(c_double), intent(inout) :: cv(:)
286 
287 type(oobump_type), pointer :: self
288 type(unstructured_grid), pointer :: ug
289 
290 ! Get BUMP
291 call oobump_registry%get(key, self)
292 
293 ! Get unstructured grid
294 call unstructured_grid_registry%get(idx, ug)
295 
296 ! Square-root multiply
297 call multiply_oobump_nicas_sqrt_ad(self, ug, cv)
298 
299 end subroutine multiply_oobump_nicas_sqrt_ad_c
300 
301 ! ------------------------------------------------------------------------------
302 
303 subroutine get_oobump_param_c(key, nstr, cstr, idx) bind(c, name='get_oobump_param_f90')
304 implicit none
305 integer(c_int), intent(in) :: key
306 integer(c_int), intent(in) :: nstr
307 character(kind=c_char), intent(in) :: cstr(nstr)
308 integer(c_int), intent(in) :: idx
309 
310 type(oobump_type), pointer :: self
311 type(unstructured_grid), pointer :: ug
312 integer :: istr
313 character(len=nstr) :: param
314 
315 ! Get BUMP
316 call oobump_registry%get(key, self)
317 
318 ! Get unstructured grid
319 call unstructured_grid_registry%get(idx, ug)
320 
321 ! Copy string
322 param = ''
323 do istr=1,nstr
324  param = trim(param)//cstr(istr)
325 end do
326 
327 ! Get parameter
328 call get_oobump_param(self, param, ug)
329 
330 end subroutine get_oobump_param_c
331 
332 ! ------------------------------------------------------------------------------
333 
334 subroutine set_oobump_param_c(key, nstr, cstr, idx) bind(c, name='set_oobump_param_f90')
335 implicit none
336 integer(c_int), intent(in) :: key
337 integer(c_int), intent(in) :: nstr
338 character(kind=c_char), intent(in) :: cstr(nstr)
339 integer(c_int), intent(in) :: idx
340 
341 type(oobump_type), pointer :: self
342 type(unstructured_grid), pointer :: ug
343 integer :: istr
344 character(len=nstr) :: param
345 
346 ! Get BUMP
347 call oobump_registry%get(key, self)
348 
349 ! Get unstructured grid
350 call unstructured_grid_registry%get(idx, ug)
351 
352 ! Copy string
353 param = ''
354 do istr=1,nstr
355  param = trim(param)//cstr(istr)
356 end do
357 
358 ! Set parameter
359 call set_oobump_param(self, param, ug)
360 
361 end subroutine set_oobump_param_c
362 
363 ! ------------------------------------------------------------------------------
364 ! End C++ interfaces
365 ! ------------------------------------------------------------------------------
366 
367 subroutine create_oobump(self, ug, c_conf, ens1_ne, ens1_nsub, ens2_ne, ens2_nsub)
369 implicit none
370 type(oobump_type), intent(inout) :: self
371 type(unstructured_grid), intent(in) :: ug
372 type(c_ptr), intent(in) :: c_conf
373 integer, intent(in) :: ens1_ne
374 integer, intent(in) :: ens1_nsub
375 integer, intent(in) :: ens2_ne
376 integer, intent(in) :: ens2_nsub
377 
378 integer :: igrid
379 
380 ! Allocation
381 self%ngrid = ug%ngrid
382 allocate(self%bump(self%ngrid))
383 
384 do igrid=1,self%ngrid
385  ! Initialize namelist
386  call self%bump(igrid)%nam%init
387 
388  ! Read JSON
389  call bump_read_conf(c_conf,self%bump(igrid))
390 
391  ! Online setup
392  call self%bump(igrid)%setup_online(ug%grid(igrid)%nmga,ug%grid(igrid)%nl0,ug%grid(igrid)%nv,ug%grid(igrid)%nts, &
393  & ug%grid(igrid)%lon,ug%grid(igrid)%lat,ug%grid(igrid)%area,ug%grid(igrid)%vunit,ug%grid(igrid)%lmask,ens1_ne=ens1_ne, &
394  & ens1_nsub=ens1_nsub, ens2_ne=ens2_ne, ens2_nsub=ens2_nsub)
395 end do
396 
397 end subroutine create_oobump
398 
399 !-------------------------------------------------------------------------------
400 
401 subroutine bump_read_conf(c_conf,bump)
402 implicit none
403 type(c_ptr), intent(in) :: c_conf
404 type(bump_type), intent(inout) :: bump
405 integer :: iscales,ildwh,ildwv,idir,iv
406 character(len=3) :: iscaleschar,ildwvchar,idirchar,ivchar
407 character(len=6) :: ildwhchar
408 
409 ! Setup from configuration
410 
411 ! general_param
412 if (config_element_exists(c_conf,"datadir")) bump%nam%datadir = config_get_string(c_conf,1024,"datadir")
413 if (config_element_exists(c_conf,"prefix")) bump%nam%prefix = config_get_string(c_conf,1024,"prefix")
414 if (config_element_exists(c_conf,"default_seed")) bump%nam%default_seed = integer_to_logical(config_get_int(c_conf,"default_seed"))
415 
416 ! driver_param
417 if (config_element_exists(c_conf,"method")) bump%nam%method = config_get_string(c_conf,1024,"method")
418 if (config_element_exists(c_conf,"strategy")) bump%nam%strategy = config_get_string(c_conf,1024,"strategy")
419 if (config_element_exists(c_conf,"new_vbal")) bump%nam%new_vbal = integer_to_logical(config_get_int(c_conf,"new_vbal"))
420 if (config_element_exists(c_conf,"load_vbal")) bump%nam%load_vbal = integer_to_logical(config_get_int(c_conf,"load_vbal"))
421 if (config_element_exists(c_conf,"new_hdiag")) bump%nam%new_hdiag = integer_to_logical(config_get_int(c_conf,"new_hdiag"))
422 if (config_element_exists(c_conf,"new_lct")) bump%nam%new_lct = integer_to_logical(config_get_int(c_conf,"new_lct"))
423 if (config_element_exists(c_conf,"load_cmat")) bump%nam%load_cmat = integer_to_logical(config_get_int(c_conf,"load_cmat"))
424 if (config_element_exists(c_conf,"new_nicas")) bump%nam%new_nicas = integer_to_logical(config_get_int(c_conf,"new_nicas"))
425 if (config_element_exists(c_conf,"load_nicas")) bump%nam%load_nicas = integer_to_logical(config_get_int(c_conf,"load_nicas"))
426 if (config_element_exists(c_conf,"new_obsop")) bump%nam%new_obsop = integer_to_logical(config_get_int(c_conf,"new_obsop"))
427 if (config_element_exists(c_conf,"load_obsop")) bump%nam%load_obsop = integer_to_logical(config_get_int(c_conf,"load_obsop"))
428 if (config_element_exists(c_conf,"check_adjoints")) &
429  & bump%nam%check_adjoints = integer_to_logical(config_get_int(c_conf,"check_adjoints"))
430 if (config_element_exists(c_conf,"check_pos_def")) &
431  & bump%nam%check_pos_def = integer_to_logical(config_get_int(c_conf,"check_pos_def"))
432 if (config_element_exists(c_conf,"check_sqrt")) bump%nam%check_sqrt = integer_to_logical(config_get_int(c_conf,"check_sqrt"))
433 if (config_element_exists(c_conf,"check_dirac")) bump%nam%check_dirac = integer_to_logical(config_get_int(c_conf,"check_dirac"))
434 if (config_element_exists(c_conf,"check_randomization")) &
435  & bump%nam%check_randomization = integer_to_logical(config_get_int(c_conf,"check_randomization"))
436 if (config_element_exists(c_conf,"check_consistency")) &
437  & bump%nam%check_consistency = integer_to_logical(config_get_int(c_conf,"check_consistency"))
438 if (config_element_exists(c_conf,"check_optimality")) &
439  & bump%nam%check_optimality = integer_to_logical(config_get_int(c_conf,"check_optimality"))
440 if (config_element_exists(c_conf,"check_obsop")) &
441  & bump%nam%check_obsop = integer_to_logical(config_get_int(c_conf,"check_obsop"))
442 
443 ! sampling_param
444 if (config_element_exists(c_conf,"sam_read")) bump%nam%sam_read = integer_to_logical(config_get_int(c_conf,"sam_read"))
445 if (config_element_exists(c_conf,"sam_write")) bump%nam%sam_write = integer_to_logical(config_get_int(c_conf,"sam_write"))
446 if (config_element_exists(c_conf,"mask_type")) bump%nam%mask_type = config_get_string(c_conf,1024,"mask_type")
447 if (config_element_exists(c_conf,"mask_th")) bump%nam%mask_th = config_get_real(c_conf,"mask_th")
448 if (config_element_exists(c_conf,"mask_check")) bump%nam%mask_check = integer_to_logical(config_get_int(c_conf,"mask_check"))
449 if (config_element_exists(c_conf,"draw_type")) bump%nam%draw_type = config_get_string(c_conf,1024,"draw_type")
450 if (config_element_exists(c_conf,"nc1")) bump%nam%nc1 = config_get_int(c_conf,"nc1")
451 if (config_element_exists(c_conf,"nc2")) bump%nam%nc2 = config_get_int(c_conf,"nc2")
452 if (config_element_exists(c_conf,"ntry")) bump%nam%ntry = config_get_int(c_conf,"ntry")
453 if (config_element_exists(c_conf,"nrep")) bump%nam%nrep = config_get_int(c_conf,"nrep")
454 if (config_element_exists(c_conf,"nc3")) bump%nam%nc3 = config_get_int(c_conf,"nc3")
455 if (config_element_exists(c_conf,"dc")) bump%nam%dc = config_get_real(c_conf,"dc")
456 if (config_element_exists(c_conf,"nl0r")) bump%nam%nl0r = config_get_int(c_conf,"nl0r")
457 
458 ! diag_param
459 if (config_element_exists(c_conf,"ne")) bump%nam%ne = config_get_int(c_conf,"ne")
460 if (config_element_exists(c_conf,"gau_approx")) bump%nam%gau_approx = integer_to_logical(config_get_int(c_conf,"gau_approx"))
461 do iv=1,nvmax*(nvmax-1)/2
462  write(ivchar,'(i3)') iv
463  if (config_element_exists(c_conf,"vbal_block("//trim(adjustl(ivchar))//")")) &
464  & bump%nam%vbal_block(iv) = integer_to_logical(config_get_int(c_conf,"vbal_block("//trim(adjustl(ivchar))//")"))
465 end do
466 if (config_element_exists(c_conf,"vbal_rad")) bump%nam%vbal_rad = config_get_real(c_conf,"vbal_rad")
467 if (config_element_exists(c_conf,"var_diag")) bump%nam%var_diag = integer_to_logical(config_get_int(c_conf,"var_diag"))
468 if (config_element_exists(c_conf,"var_filter")) bump%nam%var_filter = integer_to_logical(config_get_int(c_conf,"var_filter"))
469 if (config_element_exists(c_conf,"var_full")) bump%nam%var_full = integer_to_logical(config_get_int(c_conf,"var_full"))
470 if (config_element_exists(c_conf,"var_niter")) bump%nam%var_niter = config_get_int(c_conf,"var_niter")
471 if (config_element_exists(c_conf,"var_rhflt")) bump%nam%var_rhflt = config_get_real(c_conf,"var_rhflt")
472 if (config_element_exists(c_conf,"local_diag")) bump%nam%local_diag = integer_to_logical(config_get_int(c_conf,"local_diag"))
473 if (config_element_exists(c_conf,"local_rad")) bump%nam%local_rad = config_get_real(c_conf,"local_rad")
474 if (config_element_exists(c_conf,"displ_diag")) bump%nam%displ_diag = integer_to_logical(config_get_int(c_conf,"displ_diag"))
475 if (config_element_exists(c_conf,"displ_rad")) bump%nam%displ_rad = config_get_real(c_conf,"displ_rad")
476 if (config_element_exists(c_conf,"displ_niter")) bump%nam%displ_niter = config_get_int(c_conf,"displ_niter")
477 if (config_element_exists(c_conf,"displ_rhflt")) bump%nam%displ_rhflt = config_get_real(c_conf,"displ_rhflt")
478 if (config_element_exists(c_conf,"displ_tol")) bump%nam%displ_tol = config_get_real(c_conf,"displ_tol")
479 
480 ! fit_param
481 if (config_element_exists(c_conf,"minim_algo")) bump%nam%minim_algo = config_get_string(c_conf,1024,"minim_algo")
482 do iv=0,nvmax
483  write(ivchar,'(i3)') iv
484  if (config_element_exists(c_conf,"double_fit("//trim(adjustl(ivchar))//")")) &
485  & bump%nam%double_fit(iv) = integer_to_logical(config_get_int(c_conf,"double_fit("//trim(adjustl(ivchar))//")"))
486 end do
487 if (config_element_exists(c_conf,"lhomh")) bump%nam%lhomh = integer_to_logical(config_get_int(c_conf,"lhomh"))
488 if (config_element_exists(c_conf,"lhomv")) bump%nam%lhomv = integer_to_logical(config_get_int(c_conf,"lhomv"))
489 if (config_element_exists(c_conf,"rvflt")) bump%nam%rvflt = config_get_real(c_conf,"rvflt")
490 if (config_element_exists(c_conf,"lct_nscales")) bump%nam%lct_nscales = config_get_int(c_conf,"lct_nscales")
491 do iscales=1,nscalesmax
492  write(iscaleschar,'(i3)') iscales
493  if (config_element_exists(c_conf,"lct_diag("//trim(adjustl(iscaleschar))//")")) &
494  & bump%nam%lct_diag(iscales) = integer_to_logical(config_get_int(c_conf,"lct_diag("//trim(adjustl(iscaleschar))//")"))
495 end do
496 
497 ! nicas_param
498 if (config_element_exists(c_conf,"lsqrt")) bump%nam%lsqrt = integer_to_logical(config_get_int(c_conf,"lsqrt"))
499 if (config_element_exists(c_conf,"resol")) bump%nam%resol = config_get_real(c_conf,"resol")
500 if (config_element_exists(c_conf,"fast_sampling")) bump%nam%fast_sampling = integer_to_logical(config_get_int(c_conf, &
501  & "fast_sampling"))
502 if (config_element_exists(c_conf,"nicas_interp")) bump%nam%nicas_interp = config_get_string(c_conf,1024,"nicas_interp")
503 if (config_element_exists(c_conf,"network")) bump%nam%network = integer_to_logical(config_get_int(c_conf,"network"))
504 if (config_element_exists(c_conf,"mpicom")) bump%nam%mpicom = config_get_int(c_conf,"mpicom")
505 if (config_element_exists(c_conf,"advmode")) bump%nam%advmode = config_get_int(c_conf,"advmode")
506 if (config_element_exists(c_conf,"forced_radii")) bump%nam%forced_radii = integer_to_logical(config_get_int(c_conf,"forced_radii"))
507 if (config_element_exists(c_conf,"rh")) bump%nam%rh = config_get_real(c_conf,"rh")
508 if (config_element_exists(c_conf,"rv")) bump%nam%rv = config_get_real(c_conf,"rv")
509 if (config_element_exists(c_conf,"ndir")) bump%nam%ndir = config_get_int(c_conf,"ndir")
510 do idir=1,ndirmax
511  write(idirchar,'(i3)') idir
512  if (config_element_exists(c_conf,"londir("//trim(adjustl(idirchar))//")")) &
513  & bump%nam%londir(idir) = config_get_real(c_conf,"londir("//trim(adjustl(idirchar))//")")
514  if (config_element_exists(c_conf,"latdir("//trim(adjustl(idirchar))//")")) &
515  & bump%nam%latdir(idir) = config_get_real(c_conf,"latdir("//trim(adjustl(idirchar))//")")
516  if (config_element_exists(c_conf,"levdir("//trim(adjustl(idirchar))//")")) &
517  & bump%nam%levdir(idir) = config_get_int(c_conf,"levdir("//trim(adjustl(idirchar))//")")
518  if (config_element_exists(c_conf,"ivdir("//trim(adjustl(idirchar))//")")) &
519  & bump%nam%ivdir(idir) = config_get_int(c_conf,"ivdir("//trim(adjustl(idirchar))//")")
520  if (config_element_exists(c_conf,"itsdir("//trim(adjustl(idirchar))//")")) &
521  & bump%nam%itsdir(idir) = config_get_int(c_conf,"itsdir("//trim(adjustl(idirchar))//")")
522 end do
523 
524 ! output_param
525 if (config_element_exists(c_conf,"nldwh")) bump%nam%nldwh = config_get_int(c_conf,"nldwh")
526 do ildwh=1,nlmax*nc3max
527  write(ildwhchar,'(i6)') ildwh
528  if (config_element_exists(c_conf,"il_ldwh("//trim(adjustl(ildwhchar))//")")) &
529  & bump%nam%il_ldwh(ildwh) = config_get_int(c_conf,"il_ldwh("//trim(adjustl(ildwhchar))//")")
530  if (config_element_exists(c_conf,"ic_ldwh("//trim(adjustl(ildwhchar))//")")) &
531  & bump%nam%ic_ldwh(ildwh) = config_get_int(c_conf,"ic_ldwh("//trim(adjustl(ildwhchar))//")")
532 end do
533 if (config_element_exists(c_conf,"nldwv")) bump%nam%nldwv = config_get_int(c_conf,"nldwv")
534 do ildwv=1,nldwvmax
535  write(ildwvchar,'(i3)') ildwv
536  if (config_element_exists(c_conf,"lon_ldwv("//trim(adjustl(ildwvchar))//")")) &
537  & bump%nam%lon_ldwv(ildwv) = config_get_real(c_conf,"lon_ldwv("//trim(adjustl(ildwvchar))//")")
538  if (config_element_exists(c_conf,"lat_ldwv("//trim(adjustl(ildwvchar))//")")) &
539  & bump%nam%lat_ldwv(ildwv) = config_get_real(c_conf,"lat_ldwv("//trim(adjustl(ildwvchar))//")")
540 end do
541 if (config_element_exists(c_conf,"diag_rhflt")) bump%nam%diag_rhflt = config_get_real(c_conf,"diag_rhflt")
542 if (config_element_exists(c_conf,"diag_interp")) bump%nam%diag_interp = config_get_string(c_conf,1024,"diag_interp")
543 if (config_element_exists(c_conf,"field_io")) bump%nam%field_io = integer_to_logical(config_get_int(c_conf,"field_io"))
544 if (config_element_exists(c_conf,"split_io")) bump%nam%split_io = integer_to_logical(config_get_int(c_conf,"split_io"))
545 if (config_element_exists(c_conf,"grid_output")) bump%nam%grid_output = integer_to_logical(config_get_int(c_conf,"grid_output"))
546 if (config_element_exists(c_conf,"grid_resol")) bump%nam%grid_resol = config_get_real(c_conf,"grid_resol")
547 if (config_element_exists(c_conf,"grid_interp")) bump%nam%grid_interp = config_get_string(c_conf,1024,"grid_interp")
548 
549 end subroutine bump_read_conf
550 
551 !-------------------------------------------------------------------------------
552 
553 logical function integer_to_logical(i)
554 implicit none
555 integer,intent(in) :: i
556 
557 if (i==0) then
558  integer_to_logical = .false.
559 elseif (i==1) then
560  integer_to_logical = .true.
561 else
562  call abor1_ftn('wrong integer in integer_to_logical')
563 end if
564 
565 end function integer_to_logical
566 
567 !-------------------------------------------------------------------------------
568 
569 subroutine delete_oobump(self)
570 implicit none
571 type(oobump_type), intent(inout) :: self
572 integer :: igrid
573 
574 ! Deallocate BUMP
575 if (allocated(self%bump)) then
576  do igrid=1,self%ngrid
577  call self%bump(igrid)%dealloc
578  end do
579  deallocate(self%bump)
580 end if
581 
582 end subroutine delete_oobump
583 
584 !-------------------------------------------------------------------------------
585 
586 subroutine add_oobump_member(self,ug,ie,iens)
587 implicit none
588 type(oobump_type), intent(inout) :: self
589 type(unstructured_grid), intent(inout) :: ug
590 integer, intent(in) :: ie
591 integer, intent(in) :: iens
592 integer :: igrid
593 
594 ! Add member
595 do igrid=1,self%ngrid
596  call self%bump(igrid)%add_member(ug%grid(igrid)%fld,ie,iens)
597 end do
598 
599 end subroutine add_oobump_member
600 
601 !-------------------------------------------------------------------------------
602 
603 subroutine run_oobump_drivers(self)
604 implicit none
605 type(oobump_type), intent(inout) :: self
606 integer :: igrid
607 
608 ! Run BUMP drivers
609 do igrid=1,self%ngrid
610  call self%bump(igrid)%run_drivers
611 end do
612 
613 end subroutine run_oobump_drivers
614 
615 !-------------------------------------------------------------------------------
616 
617 subroutine multiply_oobump_vbal(self,ug)
618 implicit none
619 type(oobump_type), intent(in) :: self
620 type(unstructured_grid), intent(inout) :: ug
621 integer :: igrid
622 
623 ! Apply vertical balance
624 do igrid=1,self%ngrid
625  call self%bump(igrid)%apply_vbal(ug%grid(igrid)%fld)
626 end do
627 
628 end subroutine multiply_oobump_vbal
629 
630 !-------------------------------------------------------------------------------
631 
632 subroutine multiply_oobump_vbal_inv(self,ug)
633 implicit none
634 type(oobump_type), intent(in) :: self
635 type(unstructured_grid), intent(inout) :: ug
636 integer :: igrid
637 
638 ! Apply vertical balance, inverse
639 do igrid=1,self%ngrid
640  call self%bump(igrid)%apply_vbal_inv(ug%grid(igrid)%fld)
641 end do
642 
643 end subroutine multiply_oobump_vbal_inv
644 
645 !-------------------------------------------------------------------------------
646 
647 subroutine multiply_oobump_vbal_ad(self,ug)
648 implicit none
649 type(oobump_type), intent(in) :: self
650 type(unstructured_grid), intent(inout) :: ug
651 integer :: igrid
652 
653 ! Apply vertical balance, adjoint
654 do igrid=1,self%ngrid
655  call self%bump(igrid)%apply_vbal_ad(ug%grid(igrid)%fld)
656 end do
657 
658 end subroutine multiply_oobump_vbal_ad
659 
660 !-------------------------------------------------------------------------------
661 
662 subroutine multiply_oobump_vbal_inv_ad(self,ug)
663 implicit none
664 type(oobump_type), intent(in) :: self
665 type(unstructured_grid), intent(inout) :: ug
666 integer :: igrid
667 
668 ! Apply vertical balance, inverse adjoint
669 do igrid=1,self%ngrid
670  call self%bump(igrid)%apply_vbal_inv_ad(ug%grid(igrid)%fld)
671 end do
672 
673 end subroutine multiply_oobump_vbal_inv_ad
674 
675 !-------------------------------------------------------------------------------
676 
677 subroutine multiply_oobump_nicas(self,ug)
678 implicit none
679 type(oobump_type), intent(in) :: self
680 type(unstructured_grid), intent(inout) :: ug
681 integer :: igrid
682 
683 ! Apply NICAS
684 do igrid=1,self%ngrid
685  call self%bump(igrid)%apply_nicas(ug%grid(igrid)%fld)
686 end do
687 
688 end subroutine multiply_oobump_nicas
689 
690 !-------------------------------------------------------------------------------
691 
692 subroutine get_oobump_cv_size(self,n)
693 implicit none
694 type(oobump_type), intent(in) :: self
695 integer, intent(out) :: n
696 integer :: igrid,nn
697 
698 ! Add control variable sizes for each grid
699 n = 0
700 do igrid=1,self%ngrid
701  call self%bump(igrid)%get_cv_size(nn)
702  n = n+nn
703 end do
704 
705 end subroutine get_oobump_cv_size
706 
707 !-------------------------------------------------------------------------------
708 
709 subroutine multiply_oobump_nicas_sqrt(self,cv,ug)
710 implicit none
711 type(oobump_type), intent(in) :: self
712 real(kind_real), intent(in) :: cv(:)
713 type(unstructured_grid), intent(inout) :: ug
714 integer :: offset,igrid,nn
715 
716 ! Initialization
717 offset = 0
718 
719 do igrid=1,self%ngrid
720  ! Get control variable size for this grid
721  call self%bump(igrid)%get_cv_size(nn)
722 
723  ! Apply NICAS square-root
724  call self%bump(igrid)%apply_nicas_sqrt(cv(offset+1:offset+nn), ug%grid(igrid)%fld)
725 
726  ! Update
727  offset = offset+nn
728 end do
729 
730 end subroutine multiply_oobump_nicas_sqrt
731 
732 !-------------------------------------------------------------------------------
733 
734 subroutine multiply_oobump_nicas_sqrt_ad(self,ug,cv)
735 implicit none
736 type(oobump_type), intent(in) :: self
737 type(unstructured_grid), intent(in) :: ug
738 real(kind_real), intent(inout) :: cv(:)
739 integer :: offset,igrid,nn
740 
741 ! Initialization
742 offset = 0
743 
744 do igrid=1,self%ngrid
745  ! Get control variable size for this grid
746  call self%bump(igrid)%get_cv_size(nn)
747 
748  ! Apply NICAS square-root
749  call self%bump(igrid)%apply_nicas_sqrt_ad(ug%grid(igrid)%fld, cv(offset+1:offset+nn))
750 
751  ! Update
752  offset = offset+nn
753 end do
754 
755 end subroutine multiply_oobump_nicas_sqrt_ad
756 
757 !-------------------------------------------------------------------------------
758 
759 subroutine get_oobump_param(self,param,ug)
760 implicit none
761 type(oobump_type), intent(in) :: self
762 character(len=*), intent(in) :: param
763 type(unstructured_grid), intent(inout) :: ug
764 integer :: igrid
765 
766 ! Get parameter
767 do igrid=1,self%ngrid
768  call self%bump(igrid)%get_parameter(param,ug%grid(igrid)%fld)
769 end do
770 
771 end subroutine get_oobump_param
772 
773 !-------------------------------------------------------------------------------
774 
775 subroutine set_oobump_param(self,param,ug)
776 implicit none
777 type(oobump_type), intent(inout) :: self
778 character(len=*),intent(in) :: param
779 type(unstructured_grid), intent(in) :: ug
780 integer :: igrid
781 
782 ! Set parameter
783 do igrid=1,self%ngrid
784  call self%bump(igrid)%set_parameter(param,ug%grid(igrid)%fld)
785 end do
786 
787 end subroutine set_oobump_param
788 
789 !-------------------------------------------------------------------------------
790 
791 end module oobump_mod
subroutine multiply_oobump_vbal_ad_c(key, idx)
Definition: oobump_mod.F90:180
subroutine, public multiply_oobump_vbal_ad(self, ug)
Definition: oobump_mod.F90:648
subroutine add_oobump_member_c(key, idx, ie, iens)
Definition: oobump_mod.F90:99
subroutine, public multiply_oobump_nicas_sqrt_ad(self, ug, cv)
Definition: oobump_mod.F90:735
subroutine, public multiply_oobump_nicas(self, ug)
Definition: oobump_mod.F90:678
subroutine get_oobump_param(self, param, ug)
Definition: oobump_mod.F90:760
type(registry_t) oobump_registry
Linked list interface - defines registry_t type.
Definition: oobump_mod.F90:38
Fortran module for handling generic BUMP.
Definition: oobump_mod.F90:8
subroutine, public add_oobump_member(self, ug, ie, iens)
Definition: oobump_mod.F90:587
subroutine, public run_oobump_drivers(self)
Definition: oobump_mod.F90:604
subroutine delete_oobump_c(key)
Definition: oobump_mod.F90:80
subroutine, public multiply_oobump_nicas_sqrt(self, cv, ug)
Definition: oobump_mod.F90:710
subroutine multiply_oobump_nicas_sqrt_ad_c(key, idx, cv)
Definition: oobump_mod.F90:282
subroutine multiply_oobump_nicas_sqrt_c(key, cv, idx)
Definition: oobump_mod.F90:260
integer, parameter, public nlmax
Definition: type_nam.F90:23
subroutine, public create_oobump(self, ug, c_conf, ens1_ne, ens1_nsub, ens2_ne, ens2_nsub)
Definition: oobump_mod.F90:368
integer, parameter, public nldwvmax
Definition: type_nam.F90:27
subroutine set_oobump_param(self, param, ug)
Definition: oobump_mod.F90:776
subroutine run_oobump_drivers_c(key)
Definition: oobump_mod.F90:122
subroutine, public multiply_oobump_vbal_inv_ad(self, ug)
Definition: oobump_mod.F90:663
logical function integer_to_logical(i)
Definition: oobump_mod.F90:554
subroutine create_oobump_c(key, idx, c_conf, ens1_ne, ens1_nsub, ens2_ne, ens2_nsub)
Linked list implementation.
Definition: oobump_mod.F90:52
subroutine get_oobump_cv_size_c(key, n)
Definition: oobump_mod.F90:243
subroutine, public get_oobump_cv_size(self, n)
Definition: oobump_mod.F90:693
subroutine, public multiply_oobump_vbal(self, ug)
Definition: oobump_mod.F90:618
type(registry_t), public unstructured_grid_registry
Linked list interface - defines registry_t type.
integer, parameter, public nc3max
Definition: type_nam.F90:24
subroutine, public delete_oobump(self)
Definition: oobump_mod.F90:570
subroutine set_oobump_param_c(key, nstr, cstr, idx)
Definition: oobump_mod.F90:335
integer, parameter, public nvmax
Definition: type_nam.F90:21
integer, parameter, public ndirmax
Definition: type_nam.F90:26
integer, parameter, public nscalesmax
Definition: type_nam.F90:25
subroutine get_oobump_param_c(key, nstr, cstr, idx)
Definition: oobump_mod.F90:304
subroutine multiply_oobump_vbal_c(key, idx)
Definition: oobump_mod.F90:138
subroutine multiply_oobump_vbal_inv_ad_c(key, idx)
Definition: oobump_mod.F90:201
subroutine multiply_oobump_vbal_inv_c(key, idx)
Definition: oobump_mod.F90:159
Fortran module for handling generic unstructured grid.
subroutine, public bump_read_conf(c_conf, bump)
Definition: oobump_mod.F90:402
subroutine multiply_oobump_nicas_c(key, idx)
Definition: oobump_mod.F90:222
subroutine, public multiply_oobump_vbal_inv(self, ug)
Definition: oobump_mod.F90:633