FV3 Bundle
fv3jedi_getvalues_mod.f90
Go to the documentation of this file.
2 
3 use fckit_mpi_module, only: fckit_mpi_comm, fckit_mpi_sum
4 use type_bump, only: bump_type
5 use ioda_locs_mod, only: ioda_locs
6 use ufo_vars_mod, only: ufo_vars
8 
15 
20 use height_vt_mod
21 
22 implicit none
23 
24 private
26 
27 !This module contains the routines for interfacing with UFO
28 !This is where the GeoVaLs get set for the state and increment.
29 
30 contains
31 
32 ! ------------------------------------------------------------------------------
33 
34 subroutine getvalues(geom, state, locs, vars, gom, traj)
35 
36 implicit none
37 
38 type(fv3jedi_geom), intent(in) :: geom
39 type(fv3jedi_state), intent(in) :: state
40 type(ioda_locs), intent(in) :: locs
41 type(ufo_vars), intent(in) :: vars
42 type(ufo_geovals), intent(inout) :: gom
43 type(fv3jedi_getvalues_traj), optional, target, intent(inout) :: traj
44 
45 character(len=*), parameter :: myname = 'getvalues'
46 
47 type(fckit_mpi_comm) :: f_comm
48 type(bump_type), target :: bump
49 type(bump_type), pointer :: pbump => null()
50 logical, target :: bump_alloc = .false.
51 logical, pointer :: pbump_alloc => null()
52 integer, target, save :: bumpid = 1000
53 integer, pointer :: pbumpid => null()
54 
55 integer :: ii, jj, ji, jvar, jlev, jloc, ngrid, nlocs, nlocsg
56 real(kind=kind_real), allocatable :: mod_state(:,:)
57 real(kind=kind_real), allocatable :: obs_state(:,:)
58 real(kind=kind_real), target, allocatable :: geovale(:,:,:), geovalm(:,:,:)
59 real(kind=kind_real), pointer :: geoval(:,:,:)
60 integer :: nvl
61 logical :: do_interp
62 
63 integer :: isc,iec,jsc,jec,npz,i,j
64 
65 !Local pressure variables
66 real(kind=kind_real), allocatable :: prsi(:,:,:) !Pressure Pa, interfaces
67 real(kind=kind_real), allocatable :: prs (:,:,:) !Pressure Pa, midpoint
68 real(kind=kind_real), allocatable :: logp(:,:,:) !Log(pressue), (Pa) midpoint
69 
70 !Local CRTM moisture variables
71 real(kind=kind_real), allocatable :: ql_ade(:,:,:) !Cloud liq water kgm^2
72 real(kind=kind_real), allocatable :: qi_ade(:,:,:) !Cloud ice water kgm^2
73 real(kind=kind_real), allocatable :: ql_efr(:,:,:) !Cloud effective radius microns
74 real(kind=kind_real), allocatable :: qi_efr(:,:,:) !Cloud effective radium microns
75 real(kind=kind_real), allocatable :: qmr(:,:,:) !Moisture mixing ratio
76 real(kind=kind_real), allocatable :: water_coverage_m(:,:) !Water coverage, model grid
77 
78 !Local CRTM surface variables
79 integer , allocatable :: vegetation_type(:) !Index of vege type | surface(1)%Vegetation_Type
80 integer , allocatable :: land_type(:) !Index of land type | surface(1)%Land_Type
81 integer , allocatable :: soil_type(:) !Index of soil type | surface(1)%Soil_Type
82 real(kind=kind_real), allocatable :: wind_speed(:) !10 meter wind speed m/s | surface(1)%wind_speed
83 real(kind=kind_real), allocatable :: wind_direction(:) !10 meter wind direction degrees | surface(1)%wind_direction
84 real(kind=kind_real), allocatable :: water_coverage(:) !Fraction of water coverage | surface(1)%water_coverage
85 real(kind=kind_real), allocatable :: land_coverage(:) !Fraction of land coverage | surface(1)%land_coverage
86 real(kind=kind_real), allocatable :: ice_coverage(:) !Fraction of ice coverage | surface(1)%ice_coverage
87 real(kind=kind_real), allocatable :: snow_coverage(:) !Fraction of snow coverage | surface(1)%snow_coverage
88 real(kind=kind_real), allocatable :: lai(:) !Leaf area index ! surface(1)%lai
89 real(kind=kind_real), allocatable :: water_temperature(:) !Water temp (K) | surface(1)%water_temperature
90 real(kind=kind_real), allocatable :: land_temperature(:) !Land temp (K) | surface(1)%land_temperature
91 real(kind=kind_real), allocatable :: ice_temperature(:) !Ice temp (K) | surface(1)%ice_temperature
92 real(kind=kind_real), allocatable :: snow_temperature(:) !Snow temp (K) | surface(1)%snow_temperature
93 real(kind=kind_real), allocatable :: soil_moisture_content(:) !Soil moisture content | surface(1)%soil_moisture_content
94 real(kind=kind_real), allocatable :: vegetation_fraction(:) !Vegetation fraction | surface(1)%vegetation_fraction
95 real(kind=kind_real), allocatable :: soil_temperature(:) !Soil temperature | surface(1)%soil_temperature
96 real(kind=kind_real), allocatable :: snow_depth(:) !Snow depth | surface(1)%snow_depth
97 logical, parameter :: use_compress = .true. !Could be a fv3 namelist option?
98 
99 
100 ! Grid convenience
101 ! ----------------
102 isc = geom%isc
103 iec = geom%iec
104 jsc = geom%jsc
105 jec = geom%jec
106 npz = geom%npz
107 
108 ngrid = (iec-isc+1)*(jec-jsc+1)
109 nlocs = locs%nlocs
110 
111 
112 !If no observations can early exit
113 !---------------------------------
114 f_comm = fckit_mpi_comm()
115 call f_comm%allreduce(nlocs,nlocsg,fckit_mpi_sum())
116 if (nlocsg == 0) then
117  if (present(traj)) then
118  traj%lalloc = .true.
119  traj%noobs = .true.
120  endif
121  return
122 endif
123 
124 ! Initialize the interpolation trajectory
125 ! ---------------------------------------
126 if (present(traj)) then
127 
128  pbump => traj%bump
129 
130  if (.not. traj%lalloc) then
131 
132  traj%ngrid = ngrid
133 
134  if (.not.allocated(traj%t)) allocate(traj%t(isc:iec,jsc:jec,1:npz))
135  if (.not.allocated(traj%q)) allocate(traj%q(isc:iec,jsc:jec,1:npz))
136 
137  traj%t = state%t
138  traj%q = state%q
139 
140  pbump_alloc => traj%lalloc
141  pbumpid => traj%bumpid
142 
143  endif
144 
145 else
146 
147  pbump => bump
148  bump_alloc = .false.
149  pbump_alloc => bump_alloc
150  bumpid = bumpid + 1
151  pbumpid => bumpid
152 
153 endif
154 
155 if (.not. pbump_alloc) then
156  call initialize_bump(geom, locs, pbump, pbumpid)
157  pbump_alloc = .true.
158 endif
159 
160 ! Create Buffer for interpolated values
161 ! --------------------------------------
162 allocate(mod_state(ngrid,1))
163 allocate(obs_state(nlocs,1))
164 
165 
166 ! Local GeoVals
167 ! -------------
168 allocate(geovale(isc:iec,jsc:jec,npz+1))
169 allocate(geovalm(isc:iec,jsc:jec,npz))
170 
171 ! Get pressures at edge, center & log center
172 ! ------------------------------------------
173 allocate(prsi(isc:iec,jsc:jec,npz+1))
174 allocate(prs(isc:iec,jsc:jec,npz ))
175 allocate(logp(isc:iec,jsc:jec,npz ))
176 
177 call delp_to_pe_p_logp(geom,state%delp,prsi,prs,logp)
178 
179 ! Get CRTM surface variables
180 ! ----------------------
181 allocate(wind_speed(nlocs))
182 allocate(wind_direction(nlocs))
183 allocate(land_type(nlocs))
184 allocate(vegetation_type(nlocs))
185 allocate(soil_type(nlocs))
186 allocate(water_coverage(nlocs))
187 allocate(land_coverage(nlocs))
188 allocate(ice_coverage(nlocs))
189 allocate(snow_coverage(nlocs))
190 allocate(lai(nlocs))
191 allocate(water_temperature(nlocs))
192 allocate(land_temperature(nlocs))
193 allocate(ice_temperature(nlocs))
194 allocate(snow_temperature(nlocs))
195 allocate(soil_moisture_content(nlocs))
196 allocate(vegetation_fraction(nlocs))
197 allocate(soil_temperature(nlocs))
198 allocate(snow_depth(nlocs))
199 
200 wind_speed = 0.0_kind_real
201 wind_direction = 0.0_kind_real
202 land_type = 0
203 vegetation_type = 0
204 soil_type = 0
205 water_coverage = 0.0_kind_real
206 land_coverage = 0.0_kind_real
207 ice_coverage = 0.0_kind_real
208 snow_coverage = 0.0_kind_real
209 lai = 0.0_kind_real
210 water_temperature = 0.0_kind_real
211 land_temperature = 0.0_kind_real
212 ice_temperature = 0.0_kind_real
213 snow_temperature = 0.0_kind_real
214 soil_moisture_content = 0.0_kind_real
215 vegetation_fraction = 0.0_kind_real
216 soil_temperature = 0.0_kind_real
217 snow_depth = 0.0_kind_real
218 
219 if (state%havecrtmfields) then
220  !TODO only if a radiance
221  call crtm_surface( geom, nlocs, ngrid, locs%lat(:), locs%lon(:), &
222  state%slmsk, state%sheleg, state%tsea, state%vtype, &
223  state%stype, state%vfrac, state%stc, state%smc, state%snwdph, &
224  state%u_srf,state%v_srf,state%f10m, &
225  land_type, vegetation_type, soil_type, water_coverage, land_coverage, ice_coverage, &
226  snow_coverage, lai, water_temperature, land_temperature, ice_temperature, &
227  snow_temperature, soil_moisture_content, vegetation_fraction, soil_temperature, snow_depth, &
228  wind_speed, wind_direction )
229 endif
230 
231 
232 ! Get CRTM moisture variables
233 ! ---------------------------
234 allocate(ql_ade(isc:iec,jsc:jec,npz))
235 allocate(qi_ade(isc:iec,jsc:jec,npz))
236 allocate(ql_efr(isc:iec,jsc:jec,npz))
237 allocate(qi_efr(isc:iec,jsc:jec,npz))
238 allocate(qmr(isc:iec,jsc:jec,npz))
239 allocate(water_coverage_m(isc:iec,jsc:jec))
240 
241 ql_ade = 0.0_kind_real
242 qi_ade = 0.0_kind_real
243 ql_efr = 0.0_kind_real
244 qi_efr = 0.0_kind_real
245 
246 if (state%havecrtmfields) then
247 
248  !TODO Is it water_coverage or sea_coverage fed in here?
249  water_coverage_m = 0.0_kind_real
250  do j = jsc,jec
251  do i = isc,iec
252  if (state%slmsk(i,j) == 0) water_coverage_m(i,j) = 1.0_kind_real
253  enddo
254  enddo
255 
256  call crtm_ade_efr( geom,prsi,state%t,state%delp,water_coverage_m,state%q, &
257  state%ql,state%qi,ql_ade,qi_ade,ql_efr,qi_efr )
258 
259  call crtm_mixratio(geom,state%q,qmr)
260 
261 endif
262 
263 
264 ! Variable transforms and interpolate to obs locations
265 ! ----------------------------------------------------
266 
267 do jvar = 1, vars%nv
268 
269  geovalm = 0.0_kind_real
270  geovale = 0.0_kind_real
271 
272  do_interp = .false.
273 
274  ! Convert to observation variables/units
275  ! --------------------------------------
276  select case (trim(vars%fldnames(jvar)))
277 
278  case ("upper_air_u_component")
279 
280  nvl = npz
281  do_interp = .true.
282  geovalm = state%ua
283  geoval => geovalm
284 
285  case ("upper_air_v_component")
286 
287  nvl = npz
288  do_interp = .true.
289  geovalm = state%va
290  geoval => geovalm
291 
292  case ("temperature")
293 
294  nvl = npz
295  do_interp = .true.
296  geovalm = state%t
297  geoval => geovalm
298 
299  case ("specific_humidity")
300 
301  nvl = npz
302  do_interp = .true.
303  geovalm = state%q
304  geoval => geovalm
305 
306  case ("virtual_temperature")
307 
308  nvl = npz
309  do_interp = .true.
310  call t_to_tv(geom,state%t,state%q,geovalm)
311  geoval => geovalm
312 
313  case ("atmosphere_ln_pressure_coordinate")
314 
315  nvl = npz
316  do_interp = .true.
317  geovalm = log(0.001_kind_real) + logp !to kPa
318  geoval => geovalm
319 
320  case ("humidity_mixing_ratio")
321  nvl = npz
322  do_interp = .true.
323  geovalm = qmr
324  geoval => geovalm
325 
326  case ("air_pressure")
327 
328  nvl = npz
329  do_interp = .true.
330  geovalm = prs / 100.0_kind_real !to hPa
331  geoval => geovalm
332 
333  case ("air_pressure_levels")
334 
335  nvl = npz + 1
336  do_interp = .true.
337  geovale = prsi / 100.0_kind_real !to hPa
338  geoval => geovale
339 
340  case ("geopotential_height")
341 
342  call geop_height(geom,prs,prsi,state%t,state%q,state%phis,use_compress,geovalm)
343  nvl = npz
344  do_interp = .true.
345  geoval => geovalm
346 
347  case ("geopotential_height_levels")
348 
349  call geop_height_levels(geom,prs,prsi,state%t,state%q,state%phis,use_compress,geovale)
350  nvl = npz + 1
351  do_interp = .true.
352  geoval => geovale
353 
354  case ("sfc_geopotential_height")
355 
356  nvl = 1
357  do_interp = .true.
358  geovalm(:,:,1) = state%phis / grav
359  geoval => geovalm
360 
361  case ("mass_concentration_of_ozone_in_air")
362 
363  nvl = npz
364  do_interp = .true.
365  geovalm = state%o3 * constoz
366  geoval => geovalm
367 
368  case ("mass_concentration_of_carbon_dioxide_in_air")
369 
370  nvl = npz
371  do_interp = .true.
372  geovalm = 407.0_kind_real !Just a constant for now
373  geoval => geovalm
374 
375  case ("atmosphere_mass_content_of_cloud_liquid_water")
376 
377  nvl = npz
378  do_interp = .true.
379  geovalm = ql_ade
380  geoval => geovalm
381 
382  case ("atmosphere_mass_content_of_cloud_ice")
383 
384  nvl = npz
385  do_interp = .true.
386  geovalm = qi_ade
387  geoval => geovalm
388 
389  case ("effective_radius_of_cloud_liquid_water_particle")
390 
391  nvl = npz
392  do_interp = .true.
393  geovalm = ql_efr
394  geoval => geovalm
395 
396  case ("effective_radius_of_cloud_ice_particle")
397 
398  nvl = npz
399  do_interp = .true.
400  geovalm = qi_efr
401  geoval => geovalm
402 
403  case ("Water_Fraction")
404 
405  nvl = 1
406  do_interp = .false.
407  obs_state(:,1) = water_coverage
408 
409  case ("Land_Fraction")
410 
411  nvl = 1
412  do_interp = .false.
413  obs_state(:,1) = land_coverage
414 
415  case ("Ice_Fraction")
416 
417  nvl = 1
418  do_interp = .false.
419  obs_state(:,1) = ice_coverage
420 
421  case ("Snow_Fraction")
422 
423  nvl = 1
424  do_interp = .false.
425  obs_state(:,1) = snow_coverage
426 
427  case ("Water_Temperature")
428 
429  nvl = 1
430  do_interp = .false.
431  obs_state(:,1) = water_temperature
432 
433  case ("Land_Temperature")
434 
435  nvl = 1
436  do_interp = .false.
437  obs_state(:,1) = land_temperature
438 
439  case ("Ice_Temperature")
440 
441  nvl = 1
442  do_interp = .false.
443  obs_state(:,1) = ice_temperature
444 
445  case ("Snow_Temperature")
446 
447  nvl = 1
448  do_interp = .false.
449  obs_state(:,1) = snow_temperature
450 
451  case ("Snow_Depth")
452 
453  nvl = 1
454  do_interp = .false.
455  obs_state(:,1) = snow_depth
456 
457  case ("Vegetation_Fraction")
458 
459  nvl = 1
460  do_interp = .false.
461  obs_state(:,1) = vegetation_fraction
462 
463  case ("Sfc_Wind_Speed")
464 
465  nvl = 1
466  do_interp = .false.
467  obs_state(:,1) = wind_speed
468 
469  case ("Sfc_Wind_Direction")
470 
471  nvl = 1
472  do_interp = .false.
473  obs_state(:,1) = wind_direction
474 
475  case ("Lai")
476 
477  nvl = 1
478  do_interp = .false.
479  obs_state(:,1) = lai
480 
481  case ("Soil_Moisture")
482 
483  nvl = 1
484  do_interp = .false.
485  obs_state(:,1) = soil_moisture_content
486 
487  case ("Soil_Temperature")
488 
489  nvl = 1
490  do_interp = .false.
491  obs_state(:,1) = soil_temperature
492 
493  case ("Land_Type_Index")
494 
495  nvl = 1
496  do_interp = .false.
497  obs_state(:,1) = real(land_type,kind_real)
498 
499  case ("Vegetation_Type")
500 
501  nvl = 1
502  do_interp = .false.
503  obs_state(:,1) = real(vegetation_type,kind_real)
504 
505  case ("Soil_Type")
506 
507  nvl = 1
508  do_interp = .false.
509  obs_state(:,1) = real(soil_type,kind_real)
510 
511  case default
512 
513  call abor1_ftn(trim(myname)//"unknown variable")
514 
515  end select
516 
517  ! Allocate geovals%val for this jvars
518  ! -----------------------------------
519  call allocate_geovals_vals(gom,jvar,nvl,jvar==vars%nv)
520 
521 
522  !Run some basic checks on the interpolation
523  !------------------------------------------
524  call getvalues_checks(myname, locs, vars, gom, jvar)
525 
526 
527  ! Find observation location equivlent
528  ! -----------------------------------
529  if (do_interp) then
530  !Perform level-by-level interpolation using BUMP
531  do jlev = 1, nvl
532  ii = 0
533  do jj = jsc, jec
534  do ji = isc, iec
535  ii = ii + 1
536  mod_state(ii, 1) = geoval(ji, jj, jlev)
537  enddo
538  enddo
539  call pbump%apply_obsop(mod_state,obs_state)
540  do jloc = 1,locs%nlocs
541  gom%geovals(jvar)%vals(jlev,locs%indx(jloc)) = obs_state(jloc,1)
542  enddo
543  enddo
544  else
545  do jloc = 1,locs%nlocs
546  gom%geovals(jvar)%vals(nvl,locs%indx(jloc)) = obs_state(jloc,1)
547  enddo
548  endif
549 
550  nullify(geoval)
551 
552 enddo
553 
554 if (.not. present(traj)) then
555  call pbump%dealloc
556 endif
557 
558 nullify(pbump)
559 nullify(pbump_alloc)
560 nullify(pbumpid)
561 
562 ! Deallocate local memory
563 ! -----------------------
564 if (allocated(mod_state )) deallocate(mod_state )
565 if (allocated(obs_state )) deallocate(obs_state )
566 if (allocated(geovale )) deallocate(geovale )
567 if (allocated(geovalm )) deallocate(geovalm )
568 if (allocated(prsi )) deallocate(prsi )
569 if (allocated(prs )) deallocate(prs )
570 if (allocated(logp )) deallocate(logp )
571 if (allocated(wind_speed )) deallocate(wind_speed )
572 if (allocated(wind_direction )) deallocate(wind_direction )
573 if (allocated(land_type )) deallocate(land_type )
574 if (allocated(vegetation_type )) deallocate(vegetation_type )
575 if (allocated(soil_type )) deallocate(soil_type )
576 if (allocated(water_coverage )) deallocate(water_coverage )
577 if (allocated(land_coverage )) deallocate(land_coverage )
578 if (allocated(ice_coverage )) deallocate(ice_coverage )
579 if (allocated(snow_coverage )) deallocate(snow_coverage )
580 if (allocated(lai )) deallocate(lai )
581 if (allocated(water_temperature )) deallocate(water_temperature )
582 if (allocated(land_temperature )) deallocate(land_temperature )
583 if (allocated(ice_temperature )) deallocate(ice_temperature )
584 if (allocated(snow_temperature )) deallocate(snow_temperature )
585 if (allocated(soil_moisture_content)) deallocate(soil_moisture_content)
586 if (allocated(vegetation_fraction )) deallocate(vegetation_fraction )
587 if (allocated(soil_temperature )) deallocate(soil_temperature )
588 if (allocated(snow_depth )) deallocate(snow_depth )
589 if (allocated(ql_ade )) deallocate(ql_ade )
590 if (allocated(qi_ade )) deallocate(qi_ade )
591 if (allocated(ql_efr )) deallocate(ql_efr )
592 if (allocated(qi_efr )) deallocate(qi_efr )
593 if (allocated(qmr )) deallocate(qmr )
594 if (allocated(water_coverage_m )) deallocate(water_coverage_m )
595 
596 end subroutine getvalues
597 
598 ! ------------------------------------------------------------------------------
599 
600 subroutine getvalues_tl(geom, inc, locs, vars, gom, traj)
602 implicit none
603 type(fv3jedi_geom), intent(inout) :: geom
604 type(fv3jedi_increment), intent(in) :: inc
605 type(ioda_locs), intent(in) :: locs
606 type(ufo_vars), intent(in) :: vars
607 type(ufo_geovals), intent(inout) :: gom
608 type(fv3jedi_getvalues_traj), intent(in) :: traj
609 
610 character(len=*), parameter :: myname = 'getvalues_tl'
611 
612 integer :: ii, jj, ji, jvar, jlev, jloc
613 real(kind=kind_real), allocatable :: mod_increment(:,:)
614 real(kind=kind_real), allocatable :: obs_increment(:,:)
615 
616 integer :: nvl
617 real(kind=kind_real), target, allocatable :: geovale(:,:,:), geovalm(:,:,:)
618 real(kind=kind_real), pointer :: geoval(:,:,:)
619 logical :: do_interp
620 
621 integer :: isc, iec, jsc, jec, npz
622 
623 
624 ! Check traj is implemented
625 ! -------------------------
626 if (.not.traj%lalloc) &
627 call abor1_ftn(trim(myname)//" trajectory for this obs op not found")
628 
629 
630 !If no observations can early exit
631 !---------------------------------
632 if (traj%noobs) return
633 
634 
635 ! Grid convenience
636 ! ----------------
637 isc = inc%isc
638 iec = inc%iec
639 jsc = inc%jsc
640 jec = inc%jec
641 npz = inc%npz
642 
643 
644 ! Create Buffer for interpolated values
645 ! --------------------------------------
646 allocate(mod_increment(traj%ngrid,1))
647 allocate(obs_increment(locs%nlocs,1))
648 
649 
650 ! Local GeoVals
651 ! -------------
652 allocate(geovale(isc:iec,jsc:jec,npz+1))
653 allocate(geovalm(isc:iec,jsc:jec,npz))
654 
655 
656 ! Interpolate increment to obs locations using pre-calculated weights
657 ! ----------------------------------------------------------------
658 do jvar = 1, vars%nv
659 
660  geovalm = 0.0_kind_real
661  geovale = 0.0_kind_real
662 
663  do_interp = .false.
664 
665  select case (trim(vars%fldnames(jvar)))
666 
667  case ("upper_air_u_component")
668 
669  nvl = npz
670  do_interp = .true.
671  geovalm = inc%ua
672  geoval => geovalm
673 
674  case ("upper_air_v_component")
675 
676  nvl = npz
677  do_interp = .true.
678  geovalm = inc%va
679  geoval => geovalm
680 
681  case ("temperature")
682 
683  nvl = npz
684  do_interp = .true.
685  geovalm = inc%t
686  geoval => geovalm
687 
688  case ("specific_humidity")
689 
690  nvl = npz
691  do_interp = .true.
692  geovalm = inc%q
693  geoval => geovalm
694 
695  case ("virtual_temperature")
696 
697  nvl = inc%npz
698  do_interp = .true.
699  call t_to_tv_tl(geom, traj%t, inc%t, traj%q, inc%q, geovalm )
700  geoval => geovalm
701 
702  case ("humidity_mixing_ratio")
703 
704  nvl = inc%npz
705  do_interp = .true.
706  call crtm_mixratio_tl(geom, traj%q, inc%q, geovalm)
707  geoval => geovalm
708 
709  case default
710 
711  call abor1_ftn(trim(myname)//"unknown variable")
712 
713  end select
714 
715 
716  ! Allocate geovals%val for this jvars
717  ! -----------------------------------
718  call allocate_geovals_vals(gom,jvar,nvl,jvar==vars%nv)
719 
720 
721  !Run some basic checks on the interpolation
722  !------------------------------------------
723  call getvalues_checks(myname, locs, vars, gom, jvar)
724 
725 
726  ! Find observation location equivlent
727  ! -----------------------------------
728  if (do_interp) then
729  !Perform level-by-level interpolation using BUMP
730  do jlev = 1, nvl
731  ii = 0
732  do jj = jsc, jec
733  do ji = isc, iec
734  ii = ii + 1
735  mod_increment(ii, 1) = geoval(ji, jj, jlev)
736  enddo
737  enddo
738  call traj%bump%apply_obsop(mod_increment,obs_increment)
739  do jloc = 1,locs%nlocs
740  gom%geovals(jvar)%vals(jlev,locs%indx(jloc)) = obs_increment(jloc,1)
741  enddo
742  enddo
743  else
744  do jloc = 1,locs%nlocs
745  gom%geovals(jvar)%vals(nvl,locs%indx(jloc)) = obs_increment(jloc,1)
746  enddo
747  endif
748 
749  nullify(geoval)
750 
751 enddo
752 
753 deallocate(geovalm,geovale)
754 
755 deallocate(mod_increment)
756 deallocate(obs_increment)
757 
758 end subroutine getvalues_tl
759 
760 ! ------------------------------------------------------------------------------
761 
762 subroutine getvalues_ad(geom, inc, locs, vars, gom, traj)
764 implicit none
765 type(fv3jedi_geom), intent(inout) :: geom
766 type(fv3jedi_increment), intent(inout) :: inc
767 type(ioda_locs), intent(in) :: locs
768 type(ufo_vars), intent(in) :: vars
769 type(ufo_geovals), intent(inout) :: gom
770 type(fv3jedi_getvalues_traj), intent(in) :: traj
771 
772 character(len=*), parameter :: myname = 'getvalues_ad'
773 
774 integer :: ii, jj, ji, jvar, jlev, jloc
775 real(kind=kind_real), allocatable :: mod_increment(:,:)
776 real(kind=kind_real), allocatable :: obs_increment(:,:)
777 
778 integer :: nvl
779 real(kind=kind_real), target, allocatable :: geovale(:,:,:), geovalm(:,:,:)
780 real(kind=kind_real), pointer :: geoval(:,:,:)
781 logical :: do_interp
782 
783 integer :: isc, iec, jsc, jec, npz
784 
785 
786 ! Check traj is implemented
787 ! -------------------------
788 if (.not.traj%lalloc) &
789 call abor1_ftn(trim(myname)//" trajectory for this obs op not found")
790 
791 
792 !If no observations can early exit
793 !---------------------------------
794 if (traj%noobs) return
795 
796 
797 ! Grid convenience
798 ! ----------------
799 isc = inc%isc
800 iec = inc%iec
801 jsc = inc%jsc
802 jec = inc%jec
803 npz = inc%npz
804 
805 
806 ! Create Buffer for interpolated values
807 ! --------------------------------------
808 allocate(mod_increment(traj%ngrid,1))
809 allocate(obs_increment(locs%nlocs,1))
810 
811 
812 ! Local GeoVals
813 ! -------------
814 allocate(geovale(isc:iec,jsc:jec,npz+1))
815 allocate(geovalm(isc:iec,jsc:jec,npz))
816 
817 geovale = 0.0_kind_real
818 geovalm = 0.0_kind_real
819 
820 
821 ! Interpolate increment to obs locations using pre-calculated weights
822 ! ----------------------------------------------------------------
823 do jvar = 1, vars%nv
824 
825  ! PART 1, do_interp flag
826  ! ----------------------
827  do_interp = .false.
828 
829  select case (trim(vars%fldnames(jvar)))
830 
831  case ("upper_air_u_component")
832 
833  nvl = npz
834  do_interp = .true.
835  geoval => geovalm
836 
837  case ("upper_air_v_component")
838 
839  nvl = npz
840  do_interp = .true.
841  geoval => geovalm
842 
843  case ("temperature")
844 
845  nvl = npz
846  do_interp = .true.
847  geoval => geovalm
848 
849  case ("specific_humidity")
850 
851  nvl = npz
852  do_interp = .true.
853  geoval => geovalm
854 
855  case ("virtual_temperature")
856 
857  nvl = npz
858  do_interp = .true.
859  geoval => geovalm
860 
861  case ("humidity_mixing_ratio")
862 
863  nvl = npz
864  do_interp = .true.
865  geoval => geovalm
866 
867  case default
868 
869  call abor1_ftn(trim(myname)//"unknown variable")
870 
871  end select
872 
873  !Part 2, apply adjoint of interp
874  !-------------------------------
875  if (do_interp) then
876  !Perform level-by-level interpolation using BUMP
877  do jlev = nvl, 1, -1
878  do jloc = 1,locs%nlocs
879  obs_increment(jloc,1) = gom%geovals(jvar)%vals(jlev,locs%indx(jloc))
880  enddo
881  call traj%bump%apply_obsop_ad(obs_increment,mod_increment)
882  ii = 0
883  do jj = jsc, jec
884  do ji = isc, iec
885  ii = ii + 1
886  geoval(ji, jj, jlev) = mod_increment(ii, 1)
887  enddo
888  enddo
889  enddo
890  else
891  do jloc = 1,locs%nlocs
892  obs_increment(jloc,1) = gom%geovals(jvar)%vals(nvl,locs%indx(jloc))
893  enddo
894  endif
895 
896  !Part 3, back to increment variables
897  !-----------------------------------
898 
899  select case (trim(vars%fldnames(jvar)))
900 
901  case ("upper_air_u_component")
902 
903  inc%ua = geovalm
904 
905  case ("upper_air_v_component")
906 
907  inc%va = geovalm
908 
909  case ("temperature")
910 
911  inc%t = geovalm
912 
913  case ("specific_humidity")
914 
915  inc%q = geovalm
916 
917  case ("virtual_temperature")
918 
919  call t_to_tv_ad(geom, traj%t, inc%t, traj%q, inc%q, geovalm )
920 
921  case ("humidity_mixing_ratio")
922 
923  call crtm_mixratio_ad(geom, traj%q, inc%q, geovalm)
924 
925  case default
926 
927  call abor1_ftn(trim(myname)//"unknown variable")
928 
929  end select
930 
931  geovale = 0.0_kind_real
932  geovalm = 0.0_kind_real
933 
934 enddo
935 
936 deallocate(mod_increment)
937 deallocate(obs_increment)
938 
939 end subroutine getvalues_ad
940 
941 ! ------------------------------------------------------------------------------
942 
943 subroutine allocate_geovals_vals(gom,jvar,gvlev,lastvar)
945 implicit none
946 type(ufo_geovals), intent(inout) :: gom !GeoVaL
947 integer, intent(in) :: jvar !Current variable
948 integer, intent(in) :: gvlev !Number of model levels
949 logical, intent(in) :: lastvar !Logical true if on last var to go into gom
950 
951 if (.not.allocated(gom%geovals(jvar)%vals)) then
952 
953  ! Set number of levels, nobs already set from total locs
954  gom%geovals(jvar)%nval = gvlev
955 
956  ! Allocate %vals
957  allocate(gom%geovals(jvar)%vals(gom%geovals(jvar)%nval,gom%geovals(jvar)%nobs))
958  gom%geovals(jvar)%vals = 0.0_kind_real
959 
960  ! Set flag for internal data arrays having been set
961  if (lastvar) gom%linit = .true.
962 
963 endif
964 
965 end subroutine allocate_geovals_vals
966 
967 ! ------------------------------------------------------------------------------
968 
969 subroutine initialize_bump(geom, locs, bump, bumpid)
971 implicit none
972 
973 !Arguments
974 type(fv3jedi_geom), intent(in) :: geom
975 type(ioda_locs), intent(in) :: locs
976 type(bump_type), intent(inout) :: bump
977 integer, intent(in) :: bumpid
978 
979 !Locals
980 integer :: mod_num
981 real(kind=kind_real), allocatable :: mod_lat(:), mod_lon(:)
982 real(kind=kind_real), allocatable :: area(:),vunit(:,:)
983 logical, allocatable :: lmask(:,:)
984 
985 character(len=5) :: cbumpcount
986 character(len=255) :: bump_nam_prefix
987 
988 type(fckit_mpi_comm) :: f_comm
989 
990 
991 ! Communicator from OOPS
992 ! ----------------------
993 f_comm = fckit_mpi_comm()
994 
995 
996 ! Each bump%nam%prefix must be distinct
997 ! -------------------------------------
998 write(cbumpcount,"(I0.5)") bumpid
999 bump_nam_prefix = 'fv3jedi_bump_data_'//cbumpcount
1000 
1001 !Get the Solution dimensions
1002 !---------------------------
1003 mod_num = (geom%iec - geom%isc + 1) * (geom%jec - geom%jsc + 1)
1004 
1005 
1006 !Calculate interpolation weight using BUMP
1007 !-----------------------------------------
1008 allocate(mod_lat(mod_num))
1009 allocate(mod_lon(mod_num))
1010 mod_lat = reshape( rad2deg*geom%grid_lat(geom%isc:geom%iec, &
1011  geom%jsc:geom%jec), &
1012  [mod_num] )
1013 mod_lon = reshape( rad2deg*geom%grid_lon(geom%isc:geom%iec, &
1014  geom%jsc:geom%jec), &
1015  [mod_num] ) - 180.0_kind_real
1016 
1017 
1018 ! Namelist options
1019 ! ----------------
1020 
1021 !Important namelist options
1022 call bump%nam%init
1023 bump%nam%obsop_interp = 'bilin' ! Interpolation type (bilinear)
1024 
1025 !Less important namelist options (should not be changed)
1026 bump%nam%prefix = trim(bump_nam_prefix) ! Prefix for files output
1027 bump%nam%default_seed = .true.
1028 bump%nam%new_obsop = .true.
1029 
1030 
1031 ! Initialize geometry
1032 ! -------------------
1033 allocate(area(mod_num))
1034 allocate(vunit(mod_num,1))
1035 allocate(lmask(mod_num,1))
1036 area = 1.0 ! Dummy area
1037 vunit = 1.0 ! Dummy vertical unit
1038 lmask = .true. ! Mask
1039 
1040 ! Initialize BUMP
1041 ! ---------------
1042 call bump%setup_online( mod_num,1,1,1,mod_lon,mod_lat,area,vunit,lmask, &
1043  nobs=locs%nlocs,lonobs=locs%lon(:)-180.0_kind_real,latobs=locs%lat(:) )
1044 
1045 !Run BUMP drivers
1046 call bump%run_drivers
1047 
1048 ! Release memory
1049 ! --------------
1050 deallocate(area)
1051 deallocate(vunit)
1052 deallocate(lmask)
1053 deallocate(mod_lat)
1054 deallocate(mod_lon)
1055 
1056 end subroutine initialize_bump
1057 
1058 ! ------------------------------------------------------------------------------
1059 
1060 subroutine getvalues_checks(cop, locs, vars, gom, jvar)
1061 implicit none
1062 character(len=*), intent(in) :: cop
1063 type(ioda_locs), intent(in) :: locs
1064 type(ufo_vars), intent(in) :: vars
1065 type(ufo_geovals), intent(in) :: gom
1066 integer, intent(in) :: jvar
1067 
1068 character(len=255) :: cinfo
1069 
1070 cinfo="fv3jedi_"//trim(cop)//" checks:"
1071 
1072 !Check things are the sizes we expect
1073 !------------------------------------
1074 if( gom%nvar .ne. vars%nv )then
1075  call abor1_ftn(trim(cinfo)//" nvar wrong size")
1076 endif
1077 if( .not. allocated(gom%geovals) )then
1078  call abor1_ftn(trim(cinfo)//" geovals not allocated")
1079 endif
1080 if( size(gom%geovals) .ne. vars%nv )then
1081  call abor1_ftn(trim(cinfo)//" size geovals does not match number of vars from UFo")
1082 endif
1083 if (.not.gom%linit) then
1084 ! call abor1_ftn(trim(cinfo)//" geovals initialization flag not set")
1085 endif
1086 if (.not. allocated(gom%geovals(jvar)%vals)) then
1087  call abor1_ftn(trim(cinfo)//"vals not allocated")
1088 endif
1089 
1090 end subroutine getvalues_checks
1091 
1092 ! ------------------------------------------------------------------------------
1093 
1094 end module fv3jedi_getvalues_mod
Fortran derived type to hold FV3JEDI increment.
subroutine initialize_bump(geom, locs, bump, bumpid)
real(kind=kind_real), parameter, public rad2deg
Fortran derived type to hold observation locations.
subroutine, public delp_to_pe_p_logp(geom, delp, pe, p, logp)
Fortran derived type to hold FV3JEDI state.
Fortran module handling interpolation trajectory for the FV3 model.
subroutine, public getvalues(geom, state, locs, vars, gom, traj)
real(kind=kind_real), parameter, public grav
subroutine, public crtm_mixratio(geom, q, qmr)
subroutine allocate_geovals_vals(gom, jvar, gvlev, lastvar)
Fortran derived type to hold geometry data for the FV3JEDI model.
subroutine, public getvalues_ad(geom, inc, locs, vars, gom, traj)
Variable transforms on moisture variables for fv3-jedi Daniel Holdaway, NASA/JCSDA.
subroutine, public t_to_tv_tl(geom, T, T_tl, q, q_tl, Tv_tl)
Fortran derived type to represent model variables.
subroutine, public geop_height_levels(geom, prs, prsi, T, q, phis, use_compress, gphi)
subroutine, public crtm_ade_efr(geom, p, T, delp, sea_frac, q, ql, qi, ql_ade, qi_ade, ql_efr, qi_efr)
Compute cloud area density and effective radius for the crtm -----------—
Variable transforms on temperature variables for fv3-jedi Daniel Holdaway, NASA/JCSDA.
subroutine, public t_to_tv(geom, T, q, Tv)
subroutine, public crtm_mixratio_ad(geom, q, q_ad, qmr_ad)
subroutine, public getvalues_tl(geom, inc, locs, vars, gom, traj)
subroutine getvalues_checks(cop, locs, vars, gom, jvar)
subroutine, public geop_height(geom, prs, prsi, T, q, phis, use_compress, gph)
type to hold interpolated fields required by the obs operators
Utilities for increment for the FV3JEDI model.
Utilities for state for the FV3JEDI model.
Fortran module handling geometry for the FV3 model.
Variable transforms on pressure variables for fv3-jedi Daniel Holdaway, NASA/JCSDA.
subroutine, public t_to_tv_ad(geom, T, T_ad, q, q_ad, Tv_ad)
real(kind=kind_real), parameter, public constoz
subroutine, public crtm_mixratio_tl(geom, q, q_tl, qmr_tl)
subroutine, public crtm_surface(geom, nobs, ngrid, lats_ob, lons_ob, fld_slmsk, fld_sheleg, fld_tsea, fld_vtype, fld_stype, fld_vfrac, fld_stc, fld_smc, fld_snwdph, fld_u_srf, fld_v_srf, fld_f10m, land_type, vegetation_type, soil_type, water_coverage, land_coverage, ice_coverage, snow_coverage, lai, water_temperature, land_temperature, ice_temperature, snow_temperature, soil_moisture_content, vegetation_fraction, soil_temperature, snow_depth, wind_speed, wind_direction)
Fortran module handling observation locations.
Variable transforms/interpolation for surface variables in fv3-jedi Daniel Holdaway, NASA/JCSDA.
integer, parameter, public kind_real