FV3 Bundle
fv_treat_da_inc_nlm.F90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
2 !> @brief Treat DA increment
3 !> @author Xi.Chen <xi.chen@noaa.gov>
4 !> @date 02/12/2016
5 !
6 ! REVISION HISTORY:
7 ! 02/12/2016 - Initial Version
8 !-------------------------------------------------------------------------------
9 
10 #ifdef OVERLOAD_R4
11 #define _GET_VAR1 get_var1_real
12 #else
13 #define _GET_VAR1 get_var1_double
14 #endif
15 
17 
18  use fms_mod, only: file_exist, read_data, &
19  field_exist, write_version_number
20  use mpp_mod, only: mpp_error, fatal, note, mpp_pe
21  use mpp_domains_mod, only: mpp_get_tile_id, &
22  domain2d, &
24  north, &
25  east
30 
31 #ifndef MAPL_MODE
32  use constants_mod, only: pi=>pi_8, omega, grav, kappa, &
34 #else
36 #endif
37  use fv_arrays_nlm_mod, only: fv_atmos_type, &
38  fv_grid_type, &
41  use fv_grid_utils_nlm_mod, only: ptop_min, g_sum, &
45  use fv_mp_nlm_mod, only: ng, &
46  is_master, &
47  fill_corners, &
48  ydir, &
49  mp_reduce_min, &
50  mp_reduce_max
51 #ifndef MAPL_MODE
52  use sim_nc_nlm_mod, only: open_ncfile, &
53  close_ncfile, &
54  get_ncdim1, &
56  get_var2_real, &
57  get_var3_r4, &
59 #endif
60  implicit none
61  private
62 
63 #ifdef MAPL_MODE
64  real, parameter :: RADIUS = mapl_radius
65  real, parameter :: PI = mapl_pi_r8
66  real, parameter :: RDGAS = mapl_rgas
67  real, parameter :: GRAV = mapl_grav
68  real, parameter :: HLV = mapl_alhl
69  real, parameter :: CP_AIR = mapl_cp
70  real, parameter :: RVGAS = mapl_rvap
71  real, parameter :: OMEGA = mapl_omega
72  real, parameter :: KAPPA = mapl_kappa
73 #endif
74 
75 #ifndef MAPL_MODE
76  public :: read_da_inc
77 #else
78  public :: geos_get_da_increments
79 #endif
80 
81 contains
82 
83  subroutine geos_get_da_increments(Atm, fv_domain, lon,lat,im,jm,km, &
84  u_amb, v_amb, t_amb, dp_amb, q_amb, o3_amb, &
85  u_inc, v_inc, t_inc, dp_inc, q_inc, o3_inc)
86  type(fv_atmos_type), intent(inout) :: Atm(:)
87  type(domain2d), intent(inout) :: fv_domain
88  real, intent(inout) :: lon(im), lat(jm)
89  real, dimension(im,jm,km), intent(inout) :: u_amb, v_amb, t_amb, dp_amb, q_amb, o3_amb
90  real, dimension(Atm(1)%bd%is:Atm(1)%bd%ie,Atm(1)%bd%js:Atm(1)%bd%je,Atm(1)%npz), intent(inout):: &
91  u_inc, v_inc, t_inc, dp_inc, q_inc, o3_inc
92 
93  real, dimension(:,:) , allocatable:: ut_inc, vt_inc
94  real, dimension(:,:,:), allocatable:: ud_inc, vd_inc, ua_inc, va_inc
95 
96  real, allocatable:: pt_c(:,:,:), pt_d(:,:,:)
97  real:: s2c(Atm(1)%bd%is:Atm(1)%bd%ie,Atm(1)%bd%js:Atm(1)%bd%je,4)
98  real:: s2c_c(Atm(1)%bd%is:Atm(1)%bd%ie+1,Atm(1)%bd%js:Atm(1)%bd%je,4)
99  real:: s2c_d(Atm(1)%bd%is:Atm(1)%bd%ie,Atm(1)%bd%js:Atm(1)%bd%je+1,4)
100  integer, dimension(Atm(1)%bd%is:Atm(1)%bd%ie,Atm(1)%bd%js:Atm(1)%bd%je):: &
101  id1, id2, jdc
102  integer, dimension(Atm(1)%bd%is:Atm(1)%bd%ie+1,Atm(1)%bd%js:Atm(1)%bd%je)::&
103  id1_c, id2_c, jdc_c
104  integer, dimension(Atm(1)%bd%is:Atm(1)%bd%ie,Atm(1)%bd%js:Atm(1)%bd%je+1)::&
105  id1_d, id2_d, jdc_d
106  integer, parameter :: update_uv_ghost_cells=1
107  real :: tmp1d(im)
108 
109  integer:: i, j, k, im, jm, km, npz
110  integer:: i1, i2, j1, IMsplit
111  real(kind=R_GRID), dimension(2):: p1, p2, p3
112  real(kind=R_GRID), dimension(3):: e1, e2, ex, ey
113 
114  integer :: is, ie, js, je
115  integer :: isd, ied, jsd, jed
116 
117  is = atm(1)%bd%is
118  ie = atm(1)%bd%ie
119  js = atm(1)%bd%js
120  je = atm(1)%bd%je
121  isd = atm(1)%bd%isd
122  ied = atm(1)%bd%ied
123  jsd = atm(1)%bd%jsd
124  jed = atm(1)%bd%jed
125  npz = atm(1)%npz
126 
127  ! FV3 code wants lon 0:360
128  imsplit = im/2
129  ! Lons
130  tmp1d( 1:imsplit) = lon(imsplit+1:im )
131  tmp1d(imsplit+1:im ) = 2.0*pi + lon( 1:imsplit)
132  lon = tmp1d
133  ! ANA-BKG
134  do k=1,km
135  do j=1,jm
136  ! U
137  tmp1d( 1:imsplit) = u_amb(imsplit+1:im ,j,k)
138  tmp1d(imsplit+1:im ) = u_amb( 1:imsplit,j,k)
139  u_amb(:,j,k) = tmp1d
140  ! V
141  tmp1d( 1:imsplit) = v_amb(imsplit+1:im ,j,k)
142  tmp1d(imsplit+1:im ) = v_amb( 1:imsplit,j,k)
143  v_amb(:,j,k) = tmp1d
144  ! T
145  tmp1d( 1:imsplit) = t_amb(imsplit+1:im ,j,k)
146  tmp1d(imsplit+1:im ) = t_amb( 1:imsplit,j,k)
147  t_amb(:,j,k) = tmp1d
148  ! DP
149  tmp1d( 1:imsplit) = dp_amb(imsplit+1:im ,j,k)
150  tmp1d(imsplit+1:im ) = dp_amb( 1:imsplit,j,k)
151  dp_amb(:,j,k) = tmp1d
152  ! Q
153  tmp1d( 1:imsplit) = q_amb(imsplit+1:im ,j,k)
154  tmp1d(imsplit+1:im ) = q_amb( 1:imsplit,j,k)
155  q_amb(:,j,k) = tmp1d
156  ! O3
157  tmp1d( 1:imsplit) = o3_amb(imsplit+1:im ,j,k)
158  tmp1d(imsplit+1:im ) = o3_amb( 1:imsplit,j,k)
159  o3_amb(:,j,k) = tmp1d
160  enddo
161  enddo
162 
163  ! Initialize lat-lon to Cubed bi-linear interpolation coeff:
164  call remap_coef( is, ie, js, je, isd, ied, jsd, jed, &
165  im, jm, lon, lat, id1, id2, jdc, s2c, &
166  atm(1)%gridstruct%agrid)
167 
168  ! perform increments on scalars
169  call get_inc_on_3d_scalar( t_amb, t_inc)
170  call get_inc_on_3d_scalar(dp_amb,dp_inc)
171  call get_inc_on_3d_scalar( q_amb, q_inc)
172  call get_inc_on_3d_scalar(o3_amb,o3_inc)
173 
174  ! perform increments on winds
175  allocate (ud_inc(isd:ied , jsd:jed+1, km))
176  allocate (vd_inc(isd:ied+1, jsd:jed , km))
177  allocate ( pt_c(isd:ied+1, jsd:jed , 2))
178  allocate ( pt_d(isd:ied , jsd:jed+1, 2))
179  allocate (ut_inc(is :ie+1 , js :je ))
180  allocate (vt_inc(is :ie+1 , js :je ))
181 
182  call get_staggered_grid( &
183  is, ie, js, je, &
184  isd, ied, jsd, jed, &
185  atm(1)%gridstruct%grid, pt_c, pt_d)
186 
187  !------ pt_c part ------
188  ! Initialize lat-lon to Cubed bi-linear interpolation coeff:
189  call remap_coef( is, ie+1, js, je, isd, ied+1, jsd, jed, &
190  im, jm, lon, lat, id1_c, id2_c, jdc_c, s2c_c, &
191  pt_c)
192 
193  do k=1,km
194  do j=js,je
195  do i=is,ie+1
196  i1 = id1_c(i,j)
197  i2 = id2_c(i,j)
198  j1 = jdc_c(i,j)
199  ut_inc(i,j) = s2c_c(i,j,1)*u_amb(i1,j1 ,k) + &
200  s2c_c(i,j,2)*u_amb(i2,j1 ,k) + &
201  s2c_c(i,j,3)*u_amb(i2,j1+1,k) + &
202  s2c_c(i,j,4)*u_amb(i1,j1+1,k)
203  vt_inc(i,j) = s2c_c(i,j,1)*v_amb(i1,j1 ,k) + &
204  s2c_c(i,j,2)*v_amb(i2,j1 ,k) + &
205  s2c_c(i,j,3)*v_amb(i2,j1+1,k) + &
206  s2c_c(i,j,4)*v_amb(i1,j1+1,k)
207  p1(:) = atm(1)%gridstruct%grid(i,j ,1:2)
208  p2(:) = atm(1)%gridstruct%grid(i,j+1,1:2)
209  call mid_pt_sphere(p1, p2, p3)
210  call get_unit_vect2(p1, p2, e2)
211  call get_latlon_vector(p3, ex, ey)
212  vd_inc(i,j,k) = ut_inc(i,j)*inner_prod(e2,ex) + &
213  vt_inc(i,j)*inner_prod(e2,ey)
214  enddo
215  enddo
216  enddo
217 
218  deallocate ( ut_inc, vt_inc )
219 
220  !------ pt_d part ------
221  ! Initialize lat-lon to Cubed bi-linear interpolation coeff:
222  call remap_coef( is, ie, js, je+1, isd, ied, jsd, jed+1, &
223  im, jm, lon, lat, id1_d, id2_d, jdc_d, s2c_d, &
224  pt_d)
225 
226  allocate ( ut_inc(is:ie,js:je+1) )
227  allocate ( vt_inc(is:ie,js:je+1) )
228 
229  do k=1,km
230  do j=js,je+1
231  do i=is,ie
232  i1 = id1_d(i,j)
233  i2 = id2_d(i,j)
234  j1 = jdc_d(i,j)
235  ut_inc(i,j) = s2c_d(i,j,1)*u_amb(i1,j1 ,k) + &
236  s2c_d(i,j,2)*u_amb(i2,j1 ,k) + &
237  s2c_d(i,j,3)*u_amb(i2,j1+1,k) + &
238  s2c_d(i,j,4)*u_amb(i1,j1+1,k)
239  vt_inc(i,j) = s2c_d(i,j,1)*v_amb(i1,j1 ,k) + &
240  s2c_d(i,j,2)*v_amb(i2,j1 ,k) + &
241  s2c_d(i,j,3)*v_amb(i2,j1+1,k) + &
242  s2c_d(i,j,4)*v_amb(i1,j1+1,k)
243  p1(:) = atm(1)%gridstruct%grid(i, j,1:2)
244  p2(:) = atm(1)%gridstruct%grid(i+1,j,1:2)
245  call mid_pt_sphere(p1, p2, p3)
246  call get_unit_vect2(p1, p2, e1)
247  call get_latlon_vector(p3, ex, ey)
248  ud_inc(i,j,k) = ut_inc(i,j)*inner_prod(e1,ex) + &
249  vt_inc(i,j)*inner_prod(e1,ey)
250  enddo
251  enddo
252  enddo
253 
254  deallocate ( ut_inc, vt_inc )
255 
256 #if 0
257  allocate (ua_inc(isd:ied , jsd:jed , km))
258  allocate (va_inc(isd:ied , jsd:jed , km))
259  call cubed_to_latlon(ud_inc, vd_inc, ua_inc, va_inc, atm(1)%gridstruct, &
260  atm(1)%npx, atm(1)%npy, atm(1)%npz, update_uv_ghost_cells, atm(1)%gridstruct%grid_type, &
261  fv_domain, atm(1)%gridstruct%nested, atm(1)%flagstruct%c2l_ord, atm(1)%bd)
262  u_inc(is:ie,js:je,1:npz) = ua_inc(is:ie,js:je,1:npz)
263  v_inc(is:ie,js:je,1:npz) = va_inc(is:ie,js:je,1:npz)
264  deallocate ( ua_inc, va_inc )
265 #else
266  u_inc(is:ie,js:je,1:npz) = ud_inc(is:ie,js:je,1:npz)
267  v_inc(is:ie,js:je,1:npz) = vd_inc(is:ie,js:je,1:npz)
268 #endif
269 
270  !------ winds clean up ------
271  deallocate ( pt_c, pt_d )
272  deallocate ( ud_inc, vd_inc )
273 
274  contains
275  !---------------------------------------------------------------------------
276  subroutine get_inc_on_3d_scalar(amb,inc)
277  real, dimension(1:im, 1:jm, 1:km), intent(in ) :: amb
278  real, dimension(is:ie,js:je,1:km), intent( out) :: inc
279 
280  do k=1,km
281  do j=js,je
282  do i=is,ie
283  i1 = id1(i,j)
284  i2 = id2(i,j)
285  j1 = jdc(i,j)
286  inc(i,j,k) = s2c(i,j,1)*amb(i1,j1 ,k) + &
287  s2c(i,j,2)*amb(i2,j1 ,k) + &
288  s2c(i,j,3)*amb(i2,j1+1,k) + &
289  s2c(i,j,4)*amb(i1,j1+1,k)
290  enddo
291  enddo
292  enddo
293 
294  end subroutine get_inc_on_3d_scalar
295  !---------------------------------------------------------------------------
296  end subroutine geos_get_da_increments
297 
298 #ifndef MAPL_MODE
299  !=============================================================================
300  !> @brief description
301  !> @author Xi.Chen <xi.chen@noaa.gov>
302  !> @date 02/12/2016
303  subroutine read_da_inc(Atm, fv_domain)
304  type(fv_atmos_type), intent(inout) :: atm(:)
305  type(domain2d), intent(inout) :: fv_domain
306  ! local
307  integer :: nq
308 
309  real :: deg2rad
310  character(len=128) :: fname
311  real(kind=4), allocatable:: wk1(:), wk2(:,:), wk3(:,:,:)
312  real(kind=4), allocatable:: wk3_u(:,:,:), wk3_v(:,:,:)
313  real, allocatable:: tp(:,:,:), qp(:,:,:)
314  real, dimension(:,:,:), allocatable:: u_inc, v_inc, ud_inc, vd_inc
315  real, allocatable:: lat(:), lon(:)
316  real, allocatable:: pt_c(:,:,:), pt_d(:,:,:)
317  real:: s2c(atm(1)%bd%is:atm(1)%bd%ie,atm(1)%bd%js:atm(1)%bd%je,4)
318  real:: s2c_c(atm(1)%bd%is:atm(1)%bd%ie+1,atm(1)%bd%js:atm(1)%bd%je,4)
319  real:: s2c_d(atm(1)%bd%is:atm(1)%bd%ie,atm(1)%bd%js:atm(1)%bd%je+1,4)
320  integer, dimension(Atm(1)%bd%is:Atm(1)%bd%ie,Atm(1)%bd%js:Atm(1)%bd%je):: &
321  id1, id2, jdc
322  integer, dimension(Atm(1)%bd%is:Atm(1)%bd%ie+1,Atm(1)%bd%js:Atm(1)%bd%je)::&
323  id1_c, id2_c, jdc_c
324  integer, dimension(Atm(1)%bd%is:Atm(1)%bd%ie,Atm(1)%bd%js:Atm(1)%bd%je+1)::&
325  id1_d, id2_d, jdc_d
326 
327  integer:: i, j, k, im, jm, km, npz, npt
328  integer:: i1, i2, j1, ncid
329  integer:: jbeg, jend
330  integer tsize(3)
331  real(kind=R_GRID), dimension(2):: p1, p2, p3
332  real(kind=R_GRID), dimension(3):: e1, e2, ex, ey
333 
334  logical:: found
335  integer :: is, ie, js, je
336  integer :: isd, ied, jsd, jed
337  integer :: sphum, liq_wat, o3mr
338 
339  is = atm(1)%bd%is
340  ie = atm(1)%bd%ie
341  js = atm(1)%bd%js
342  je = atm(1)%bd%je
343  isd = atm(1)%bd%isd
344  ied = atm(1)%bd%ied
345  jsd = atm(1)%bd%jsd
346  jed = atm(1)%bd%jed
347 
348  deg2rad = pi/180.
349 
350  npz = atm(1)%npz
351 
352  fname = 'INPUT/'//atm(1)%flagstruct%res_latlon_dynamics
353 
354  if( file_exist(fname) ) then
355  call open_ncfile( fname, ncid ) ! open the file
356  call get_ncdim1( ncid, 'lon', tsize(1) )
357  call get_ncdim1( ncid, 'lat', tsize(2) )
358  call get_ncdim1( ncid, 'lev', tsize(3) )
359 
360  im = tsize(1); jm = tsize(2); km = tsize(3)
361 
362  if (km.ne.npz) then
363  if (is_master()) print *, 'km = ', km
364  call mpp_error(fatal, &
365  '==> Error in read_da_inc: km is not equal to npz')
366  endif
367 
368  if(is_master()) write(*,*) fname, ' DA increment dimensions:', tsize
369 
370  allocate ( lon(im) )
371  allocate ( lat(jm) )
372 
373  call _get_var1 (ncid, 'lon', im, lon )
374  call _get_var1 (ncid, 'lat', jm, lat )
375 
376  ! Convert to radian
377  do i=1,im
378  lon(i) = lon(i) * deg2rad ! lon(1) = 0.
379  enddo
380  do j=1,jm
381  lat(j) = lat(j) * deg2rad
382  enddo
383 
384  else
385  call mpp_error(fatal,'==> Error in read_da_inc: Expected file '&
386  //trim(fname)//' for DA increment does not exist')
387  endif
388 
389  ! Initialize lat-lon to Cubed bi-linear interpolation coeff:
390  call remap_coef( is, ie, js, je, isd, ied, jsd, jed, &
391  im, jm, lon, lat, id1, id2, jdc, s2c, &
392  atm(1)%gridstruct%agrid)
393 
394  ! Find bounding latitudes:
395  jbeg = jm-1; jend = 2
396  do j=js,je
397  do i=is,ie
398  j1 = jdc(i,j)
399  jbeg = min(jbeg, j1)
400  jend = max(jend, j1+1)
401  enddo
402  enddo
403 
404  sphum = get_tracer_index(model_atmos, 'sphum')
405  o3mr = get_tracer_index(model_atmos, 'o3mr')
406  liq_wat = get_tracer_index(model_atmos, 'liq_wat')
407 
408  ! perform increments on scalars
409  allocate ( wk3(1:im,jbeg:jend, 1:km) )
410  allocate ( tp(is:ie,js:je,km) )
411 
412  call apply_inc_on_3d_scalar('T_inc',atm(1)%pt)
413  call apply_inc_on_3d_scalar('delp_inc',atm(1)%delp)
414  call apply_inc_on_3d_scalar('sphum_inc',atm(1)%q(:,:,:,sphum))
415  call apply_inc_on_3d_scalar('liq_wat_inc',atm(1)%q(:,:,:,liq_wat))
416  call apply_inc_on_3d_scalar('o3mr_inc',atm(1)%q(:,:,:,o3mr))
417 
418  deallocate ( tp )
419  deallocate ( wk3 )
420 
421  ! perform increments on winds
422  allocate (pt_c(isd:ied+1,jsd:jed ,2))
423  allocate (pt_d(isd:ied ,jsd:jed+1,2))
424  allocate (ud_inc(is:ie , js:je+1, km))
425  allocate (vd_inc(is:ie+1, js:je , km))
426 
427  call get_staggered_grid( &
428  is, ie, js, je, &
429  isd, ied, jsd, jed, &
430  atm(1)%gridstruct%grid, pt_c, pt_d)
431 
432  !------ pt_c part ------
433  ! Initialize lat-lon to Cubed bi-linear interpolation coeff:
434  call remap_coef( is, ie+1, js, je, isd, ied+1, jsd, jed, &
435  im, jm, lon, lat, id1_c, id2_c, jdc_c, s2c_c, &
436  pt_c)
437 
438  ! Find bounding latitudes:
439  jbeg = jm-1; jend = 2
440  do j=js,je
441  do i=is,ie+1
442  j1 = jdc_c(i,j)
443  jbeg = min(jbeg, j1)
444  jend = max(jend, j1+1)
445  enddo
446  enddo
447 
448  allocate ( wk3_u(1:im,jbeg:jend, 1:km) )
449  allocate ( wk3_v(1:im,jbeg:jend, 1:km) )
450  allocate ( u_inc(is:ie+1,js:je,km) )
451  allocate ( v_inc(is:ie+1,js:je,km) )
452 
453  call get_var3_r4( ncid, 'u_inc', 1,im, jbeg,jend, 1,km, wk3_u )
454  call get_var3_r4( ncid, 'v_inc', 1,im, jbeg,jend, 1,km, wk3_v )
455 
456  do k=1,km
457  do j=js,je
458  do i=is,ie+1
459  i1 = id1_c(i,j)
460  i2 = id2_c(i,j)
461  j1 = jdc_c(i,j)
462  u_inc(i,j,k) = s2c_c(i,j,1)*wk3_u(i1,j1 ,k) + &
463  s2c_c(i,j,2)*wk3_u(i2,j1 ,k) + &
464  s2c_c(i,j,3)*wk3_u(i2,j1+1,k) + &
465  s2c_c(i,j,4)*wk3_u(i1,j1+1,k)
466  v_inc(i,j,k) = s2c_c(i,j,1)*wk3_v(i1,j1 ,k) + &
467  s2c_c(i,j,2)*wk3_v(i2,j1 ,k) + &
468  s2c_c(i,j,3)*wk3_v(i2,j1+1,k) + &
469  s2c_c(i,j,4)*wk3_v(i1,j1+1,k)
470  p1(:) = atm(1)%gridstruct%grid(i,j ,1:2)
471  p2(:) = atm(1)%gridstruct%grid(i,j+1,1:2)
472  call mid_pt_sphere(p1, p2, p3)
473  call get_unit_vect2(p1, p2, e2)
474  call get_latlon_vector(p3, ex, ey)
475  vd_inc(i,j,k) = u_inc(i,j,k)*inner_prod(e2,ex) + &
476  v_inc(i,j,k)*inner_prod(e2,ey)
477  atm(1)%v(i,j,k) = atm(1)%v(i,j,k) + vd_inc(i,j,k)
478  enddo
479  enddo
480  enddo
481 
482  deallocate ( u_inc, v_inc )
483  deallocate ( wk3_u, wk3_v )
484 
485  !------ pt_d part ------
486  ! Initialize lat-lon to Cubed bi-linear interpolation coeff:
487  call remap_coef( is, ie, js, je+1, isd, ied, jsd, jed+1, &
488  im, jm, lon, lat, id1_d, id2_d, jdc_d, s2c_d, &
489  pt_d)
490 
491  ! Find bounding latitudes:
492  jbeg = jm-1; jend = 2
493  do j=js,je+1
494  do i=is,ie
495  j1 = jdc_d(i,j)
496  jbeg = min(jbeg, j1)
497  jend = max(jend, j1+1)
498  enddo
499  enddo
500 
501  allocate ( wk3_u(1:im,jbeg:jend, 1:km) )
502  allocate ( wk3_v(1:im,jbeg:jend, 1:km) )
503  allocate ( u_inc(is:ie,js:je+1,km) )
504  allocate ( v_inc(is:ie,js:je+1,km) )
505 
506  call get_var3_r4( ncid, 'u_inc', 1,im, jbeg,jend, 1,km, wk3_u )
507  call get_var3_r4( ncid, 'v_inc', 1,im, jbeg,jend, 1,km, wk3_v )
508 
509  do k=1,km
510  do j=js,je+1
511  do i=is,ie
512  i1 = id1_d(i,j)
513  i2 = id2_d(i,j)
514  j1 = jdc_d(i,j)
515  u_inc(i,j,k) = s2c_d(i,j,1)*wk3_u(i1,j1 ,k) + &
516  s2c_d(i,j,2)*wk3_u(i2,j1 ,k) + &
517  s2c_d(i,j,3)*wk3_u(i2,j1+1,k) + &
518  s2c_d(i,j,4)*wk3_u(i1,j1+1,k)
519  v_inc(i,j,k) = s2c_d(i,j,1)*wk3_v(i1,j1 ,k) + &
520  s2c_d(i,j,2)*wk3_v(i2,j1 ,k) + &
521  s2c_d(i,j,3)*wk3_v(i2,j1+1,k) + &
522  s2c_d(i,j,4)*wk3_v(i1,j1+1,k)
523  p1(:) = atm(1)%gridstruct%grid(i, j,1:2)
524  p2(:) = atm(1)%gridstruct%grid(i+1,j,1:2)
525  call mid_pt_sphere(p1, p2, p3)
526  call get_unit_vect2(p1, p2, e1)
527  call get_latlon_vector(p3, ex, ey)
528  ud_inc(i,j,k) = u_inc(i,j,k)*inner_prod(e1,ex) + &
529  v_inc(i,j,k)*inner_prod(e1,ey)
530  atm(1)%u(i,j,k) = atm(1)%u(i,j,k) + ud_inc(i,j,k)
531  enddo
532  enddo
533  enddo
534 
535  deallocate ( u_inc, v_inc )
536  deallocate ( wk3_u, wk3_v )
537 
538 !rab The following is not necessary as ua/va will be re-calculated during model startup
539 !rab call cubed_to_latlon(Atm(1)%u, Atm(1)%v, Atm(1)%ua, Atm(1)%va, &
540 !rab Atm(1)%gridstruct, Atm(1)%flagstruct%npx, Atm(1)%flagstruct%npy, &
541 !rab Atm(1)%flagstruct%npz, 1, Atm(1)%gridstruct%grid_type, &
542 !rab fv_domain, Atm(1)%gridstruct%nested, &
543 !rab Atm(1)%flagstruct%c2l_ord, Atm(1)%bd)
544 
545  !------ winds clean up ------
546  deallocate ( pt_c, pt_d, ud_inc, vd_inc )
547  !------ all clean up ------
548  deallocate ( lon, lat )
549 
550  contains
551  !---------------------------------------------------------------------------
552  subroutine apply_inc_on_3d_scalar(field_name,var)
553  character(len=*), intent(in) :: field_name
554  real, dimension(isd:ied,jsd:jed,1:km), intent(inout) :: var
555 
556  call get_var3_r4( ncid, field_name, 1,im, jbeg,jend, 1,km, wk3 )
557 
558  do k=1,km
559  do j=js,je
560  do i=is,ie
561  i1 = id1(i,j)
562  i2 = id2(i,j)
563  j1 = jdc(i,j)
564  tp(i,j,k) = s2c(i,j,1)*wk3(i1,j1 ,k) + s2c(i,j,2)*wk3(i2,j1 ,k)+&
565  s2c(i,j,3)*wk3(i2,j1+1,k) + s2c(i,j,4)*wk3(i1,j1+1,k)
566  var(i,j,k) = var(i,j,k)+tp(i,j,k)
567  enddo
568  enddo
569  enddo
570 
571  end subroutine apply_inc_on_3d_scalar
572  !---------------------------------------------------------------------------
573  end subroutine read_da_inc
574 #endif
575 
576  !=============================================================================
577  subroutine remap_coef( is, ie, js, je, isd, ied, jsd, jed, &
578  im, jm, lon, lat, id1, id2, jdc, s2c, agrid )
580  integer, intent(in):: is, ie, js, je, isd, ied, jsd, jed
581  integer, intent(in):: im, jm
582  real, intent(in):: lon(im), lat(jm)
583  real, intent(out):: s2c(is:ie,js:je,4)
584  integer, intent(out), dimension(is:ie,js:je):: id1, id2, jdc
585  real, intent(in):: agrid(isd:ied,jsd:jed,2)
586  ! local:
587  real :: rdlon(im)
588  real :: rdlat(jm)
589  real:: a1, b1
590  integer i,j, i1, i2, jc, i0, j0
591 
592  do i=1,im-1
593  rdlon(i) = 1. / (lon(i+1) - lon(i))
594  enddo
595  rdlon(im) = 1. / (lon(1) + 2.*pi - lon(im))
596 
597  do j=1,jm-1
598  rdlat(j) = 1. / (lat(j+1) - lat(j))
599  enddo
600 
601  ! * Interpolate to cubed sphere cell center
602  do 5000 j=js,je
603 
604  do i=is,ie
605 
606  if ( agrid(i,j,1)>lon(im) ) then
607  i1 = im; i2 = 1
608  a1 = (agrid(i,j,1)-lon(im)) * rdlon(im)
609  elseif ( agrid(i,j,1)<lon(1) ) then
610  i1 = im; i2 = 1
611  a1 = (agrid(i,j,1)+2.*pi-lon(im)) * rdlon(im)
612  else
613  do i0=1,im-1
614  if ( agrid(i,j,1)>=lon(i0) .and. agrid(i,j,1)<=lon(i0+1) ) then
615  i1 = i0; i2 = i0+1
616  a1 = (agrid(i,j,1)-lon(i1)) * rdlon(i0)
617  go to 111
618  endif
619  enddo
620  endif
621 111 continue
622 
623  if ( agrid(i,j,2)<lat(1) ) then
624  jc = 1
625  b1 = 0.
626  elseif ( agrid(i,j,2)>lat(jm) ) then
627  jc = jm-1
628  b1 = 1.
629  else
630  do j0=1,jm-1
631  if ( agrid(i,j,2)>=lat(j0) .and. agrid(i,j,2)<=lat(j0+1) ) then
632  jc = j0
633  b1 = (agrid(i,j,2)-lat(jc)) * rdlat(jc)
634  go to 222
635  endif
636  enddo
637  endif
638 222 continue
639 
640  if ( a1<0.0 .or. a1>1.0 .or. b1<0.0 .or. b1>1.0 ) then
641  write(*,*) 'gid=', mpp_pe(), i,j,a1, b1
642  endif
643 
644  s2c(i,j,1) = (1.-a1) * (1.-b1)
645  s2c(i,j,2) = a1 * (1.-b1)
646  s2c(i,j,3) = a1 * b1
647  s2c(i,j,4) = (1.-a1) * b1
648  id1(i,j) = i1
649  id2(i,j) = i2
650  jdc(i,j) = jc
651  enddo !i-loop
652 5000 continue ! j-loop
653 
654  end subroutine remap_coef
655  !=============================================================================
656  subroutine get_staggered_grid( &
657  is, ie, js, je, &
658  isd, ied, jsd, jed, &
659  pt_b, pt_c, pt_d)
660  integer, intent(in) :: is, ie, js, je, isd, ied, jsd, jed
661  real, dimension(isd:ied+1,jsd:jed+1,2), intent(in) :: pt_b
662  real, dimension(isd:ied+1,jsd:jed ,2), intent(out) :: pt_c
663  real, dimension(isd:ied ,jsd:jed+1,2), intent(out) :: pt_d
664  ! local
665  real(kind=R_GRID), dimension(2):: p1, p2, p3
666  integer :: i, j
667 
668  do j = js,je+1
669  do i = is,ie
670  p1(:) = pt_b(i, j,1:2)
671  p2(:) = pt_b(i+1,j,1:2)
672  call mid_pt_sphere(p1, p2, p3)
673  pt_d(i,j,1:2) = p3(:)
674  enddo
675  enddo
676  do j = js,je
677  do i = is,ie+1
678  p1(:) = pt_b(i,j ,1:2)
679  p2(:) = pt_b(i,j+1,1:2)
680  call mid_pt_sphere(p1, p2, p3)
681  pt_c(i,j,1:2) = p3(:)
682  enddo
683  enddo
684 
685  end subroutine get_staggered_grid
686  !=============================================================================
687 end module fv_treat_da_inc_nlm_mod
688 
Definition: fms.F90:20
real, parameter, public mapl_omega
integer, parameter, public model_atmos
real, parameter, public omega
Rotation rate of the Earth [1/s].
Definition: constants.F90:75
subroutine, public get_unit_vect2(e1, e2, uc)
subroutine, public open_ncfile(iflnm, ncid)
real, parameter, public ptop_min
subroutine, public get_var2_real(ncid, var_name, im, jm, var2)
real(kind=8), parameter, public pi_8
Ratio of circle circumference to diameter [N/A].
Definition: constants.F90:73
subroutine, public get_var1_real(ncid, var1_name, im, var1, var_exist)
real, parameter, public mapl_rvap
subroutine get_inc_on_3d_scalar(amb, inc)
real(kind=mapl_r8), parameter, public mapl_pi_r8
subroutine geos_get_da_increments(Atm, fv_domain, lon, lat, im, jm, km, u_amb, v_amb, t_amb, dp_amb, q_amb, o3_amb, u_inc, v_inc, t_inc, dp_inc, q_inc, o3_inc)
void mid_pt_sphere(const double *p1, const double *p2, double *pm)
Definition: gradient_c2l.c:326
subroutine, public get_var3_r4(ncid, var3_name, is, ie, js, je, ks, ke, var3, time_slice)
real, parameter, public rdgas
Gas constant for dry air [J/kg/deg].
Definition: constants.F90:77
subroutine, public get_number_tracers(model, num_tracers, num_prog, num_diag, num_family)
subroutine remap_coef(is, ie, js, je, isd, ied, jsd, jed, im, jm, lon, lat, id1, id2, jdc, s2c, agrid)
real, parameter, public mapl_cp
subroutine, public cubed_to_latlon(u, v, ua, va, gridstruct, npx, npy, km, mode, grid_type, domain, nested, c2l_ord, bd)
Definition: mpp.F90:39
subroutine get_staggered_grid(is, ie, js, je, isd, ied, jsd, jed, pt_b, pt_c, pt_d)
real, parameter, public mapl_alhl
subroutine apply_inc_on_3d_scalar(field_name, var)
real, parameter, public mapl_kappa
subroutine, public read_da_inc(Atm, fv_domain)
description
int field_exist(const char *file, const char *name)
Definition: read_mosaic.c:69
real, parameter, public rvgas
Gas constant for water vapor [J/kg/deg].
Definition: constants.F90:78
integer, parameter, public ng
real, parameter, public mapl_radius
real, parameter, public cp_air
Specific heat capacity of dry air at constant pressure [J/kg/deg].
Definition: constants.F90:83
integer, parameter, public r_grid
subroutine, public get_latlon_vector(pp, elon, elat)
subroutine, public close_ncfile(ncid)
real, parameter, public grav
Acceleration due to gravity [m/s^2].
Definition: constants.F90:76
real function, public g_sum(domain, p, ifirst, ilast, jfirst, jlast, ngc, area, mode, reproduce)
subroutine, public get_var1_double(ncid, var1_name, im, var1, var_exist)
subroutine, public get_ncdim1(ncid, var1_name, im)
#define max(a, b)
Definition: mosaic_util.h:33
subroutine, public get_tracer_names(model, n, name, longname, units, err_msg)
real, parameter, public mapl_rgas
real, parameter, public mapl_grav
real function, public inner_prod(v1, v2)
#define min(a, b)
Definition: mosaic_util.h:32
integer, parameter fvprc
real, parameter, public kappa
RDGAS / CP_AIR [dimensionless].
Definition: constants.F90:82
real(fp), parameter, public pi