33 #define _GET_VAR1 get_var1_real 35 #define _GET_VAR1 get_var1_double 40 use fms_mod
, only: file_exist
41 use mpp_mod
, only: mpp_error, fatal, note, mpp_pe
42 use mpp_domains_mod
, only: domain2d
44 use constants_mod
, only: pi=>pi_8
56 use ipd_typedefs
, only: ipd_init_type, ipd_control_type, &
57 kind_phys => ipd_kind_phys
58 use block_control_mod
, only: block_control_type
60 use tracer_manager_mod
, only: get_tracer_names,get_tracer_index, get_number_tracers
61 use field_manager_mod
, only: model_atmos
66 real,
allocatable::
s2c(:,:,:)
79 real(kind=4),
allocatable::
wk3(:,:,:)
81 real,
allocatable :: ua_inc(:,:,:)
82 real,
allocatable :: va_inc(:,:,:)
83 real,
allocatable :: temp_inc(:,:,:)
84 real,
allocatable :: delp_inc(:,:,:)
85 real,
allocatable :: delz_inc(:,:,:)
86 real,
allocatable :: tracer_inc(:,:,:,:)
89 real,
allocatable :: ua_inc(:,:,:)
90 real,
allocatable :: va_inc(:,:,:)
91 real,
allocatable :: temp_inc(:,:,:)
92 real,
allocatable :: delp_inc(:,:,:)
93 real,
allocatable :: delz_inc(:,:,:)
94 real,
allocatable :: tracer_inc(:,:,:,:)
95 logical :: in_interval = .false.
96 logical :: drymassfixer = .false.
101 real(kind=kind_phys) :: hr1
102 real(kind=kind_phys) :: hr2
103 real(kind=kind_phys) :: wt
104 real(kind=kind_phys) :: wt_normfact
111 type(ipd_control_type),
intent(in) :: ipd_control
113 type(ipd_init_type),
intent(in) :: init_parm
116 character(len=128) :: fname
117 real,
dimension(:,:,:),
allocatable:: u_inc, v_inc
118 real,
allocatable:: lat(:), lon(:),agrid(:,:,:)
119 real(kind=kind_phys) sx,wx,wt,normfact,dtp
121 integer:: i, j, k, nstep, kstep
127 integer,
allocatable :: idt(:)
130 ie =
is + ipd_control%nx-1
132 je =
js + ipd_control%ny-1
133 call get_number_tracers(model_atmos, num_tracers=
ntracers)
147 nfilesall =
size(ipd_control%iau_inc_files)
149 if (is_master()) print*,
'in iau_init',trim(ipd_control%iau_inc_files(1)),ipd_control%iaufhrs(1)
151 if (trim(ipd_control%iau_inc_files(k)) .eq.
'' .or. ipd_control%iaufhrs(k) .lt. 0)
exit 152 if (is_master())
then 153 print *,k,trim(adjustl(ipd_control%iau_inc_files(k)))
157 if (is_master()) print *,
'nfiles = ',
nfiles 163 idt = ipd_control%iaufhrs(2:
nfiles)-ipd_control%iaufhrs(1:
nfiles-1)
165 if (idt(k) .ne. ipd_control%iaufhrs(2)-ipd_control%iaufhrs(1))
then 166 print *,
'forecast intervals in iaufhrs must be constant' 167 call mpp_error (fatal,
' forecast intervals in iaufhrs must be constant')
172 if (is_master()) print *,
'iau interval = ',ipd_control%iau_delthrs,
' hours' 173 dt = (ipd_control%iau_delthrs*3600.)
179 npz = ipd_control%levs
180 fname =
'INPUT/'//trim(ipd_control%iau_inc_files(1))
182 if( file_exist(fname) )
then 189 if (is_master()) print *,
'km = ',
km 190 call mpp_error(fatal, &
191 '==> Error in IAU_initialize: km is not equal to npz')
194 if(is_master())
write(*,*) fname,
' DA increment dimensions:',
im,
jm,
km 199 call _get_var1 (
ncid,
'lon',
im, lon )
200 call _get_var1 (
ncid,
'lat',
jm, lat )
212 call mpp_error(fatal,
'==> Error in IAU_initialize: Expected file '&
213 //trim(fname)//
' for DA increment does not exist')
221 do j = 1,
size(init_parm%xlon,2)
222 do i = 1,
size(init_parm%xlon,1)
224 agrid(
is-1+i,
js-1+j,1)=init_parm%xlon(i,j)
225 agrid(
is-1+i,
js-1+j,2)=init_parm%xlat(i,j)
231 deallocate ( lon, lat,agrid )
249 if (ipd_control%iau_filter_increments)
then 252 nstep = 0.5*ipd_control%iau_delthrs*3600/dtp
257 sx = acos(-1.)*kstep/nstep
258 wx = acos(-1.)*kstep/(nstep+1)
259 if (kstep .ne. 0)
then 260 wt = sin(wx)/wx*sin(sx)/sx
264 normfact = normfact + wt
265 if (is_master()) print *,
'filter wts',k,kstep,wt
267 iau_state%wt_normfact = (2*nstep+1)/normfact
284 iau_data%drymassfixer = ipd_control%iau_drymassfixer
291 type(ipd_control_type),
intent(in) :: ipd_control
293 real(kind=kind_phys) t1,t2,sx,wx,wt,dtp
294 integer n,i,j,k,sphum,kstep,nstep
296 iau_data%in_interval=.false.
301 t1=
iau_state%hr1 - ipd_control%iau_delthrs*0.5
302 t2=
iau_state%hr1 + ipd_control%iau_delthrs*0.5
303 if (ipd_control%iau_filter_increments)
then 310 nstep = 0.5*ipd_control%iau_delthrs*3600/dtp
312 kstep = (ipd_control%fhour-(t1+ipd_control%iau_delthrs*0.5))*3600./dtp
313 if (kstep .ge. -nstep .and. kstep .le. nstep)
then 314 sx = acos(-1.)*kstep/nstep
315 wx = acos(-1.)*kstep/(nstep+1)
316 if (kstep .ne. 0)
then 317 wt = (sin(wx)/wx*sin(sx)/sx)
322 if (is_master()) print *,
'filter wt',kstep,ipd_control%fhour,
iau_state%wt
331 if ( ipd_control%fhour < t1 .or. ipd_control%fhour >= t2 )
then 333 iau_data%in_interval=.false.
336 if (is_master()) print *,
'apply iau forcing',t1,ipd_control%fhour,t2
337 iau_data%in_interval=.true.
344 if (ipd_control%fhour < ipd_control%iaufhrs(1) .or. ipd_control%fhour >= ipd_control%iaufhrs(
nfiles))
then 346 iau_data%in_interval=.false.
348 iau_data%in_interval=.true.
350 if (ipd_control%iaufhrs(k) > ipd_control%fhour)
then 355 if (ipd_control%fhour >=
iau_state%hr2)
then 359 if (is_master()) print *,
'reading next increment file',trim(ipd_control%iau_inc_files(t2))
365 sphum=get_tracer_index(model_atmos,
'sphum')
371 type(ipd_control_type),
intent(in) :: ipd_control
373 real(kind_phys) delt,wt
381 iau_data%ua_inc(i,j,k) =(delt*
iau_state%inc1%ua_inc(i,j,k) + (1.-delt)*
iau_state%inc2%ua_inc(i,j,k))*
rdt*wt
382 iau_data%va_inc(i,j,k) =(delt*
iau_state%inc1%va_inc(i,j,k) + (1.-delt)*
iau_state%inc2%va_inc(i,j,k))*
rdt*wt
383 iau_data%temp_inc(i,j,k) =(delt*
iau_state%inc1%temp_inc(i,j,k) + (1.-delt)*
iau_state%inc2%temp_inc(i,j,k))*
rdt*wt
384 iau_data%delp_inc(i,j,k) =(delt*
iau_state%inc1%delp_inc(i,j,k) + (1.-delt)*
iau_state%inc2%delp_inc(i,j,k))*
rdt*wt
385 iau_data%delz_inc(i,j,k) =(delt*
iau_state%inc1%delz_inc(i,j,k) + (1.-delt)*
iau_state%inc2%delz_inc(i,j,k))*
rdt*wt
387 iau_data%tracer_inc(i,j,k,l) =(delt*
iau_state%inc1%tracer_inc(i,j,k,l) + (1.-delt)*
iau_state%inc2%tracer_inc(i,j,k,l))*
rdt*wt
398 type(ipd_control_type),
intent(in) :: ipd_control
400 real(kind_phys) delt, dt,wt
401 integer i,j,k,l,sphum
403 if (is_master()) print *,
'in setiauforcing',
rdt 407 iau_data%ua_inc(i,j,k) =wt*
iau_state%inc1%ua_inc(i,j,k)*
rdt 408 iau_data%va_inc(i,j,k) =wt*
iau_state%inc1%va_inc(i,j,k)*
rdt 409 iau_data%temp_inc(i,j,k) =wt*
iau_state%inc1%temp_inc(i,j,k)*
rdt 410 iau_data%delp_inc(i,j,k) =wt*
iau_state%inc1%delp_inc(i,j,k)*
rdt 411 iau_data%delz_inc(i,j,k) =wt*
iau_state%inc1%delz_inc(i,j,k)*
rdt 413 iau_data%tracer_inc(i,j,k,l) =wt*
iau_state%inc1%tracer_inc(i,j,k,l)*
rdt 418 sphum=get_tracer_index(model_atmos,
'sphum')
422 type(ipd_control_type),
intent(in) :: ipd_control
424 character(len=*),
intent(in) :: fname
426 real,
dimension(:,:,:),
allocatable:: u_inc, v_inc
428 integer:: i, j, k, l, npz
431 real(kind=R_GRID),
dimension(2):: p1, p2, p3
432 real(kind=R_GRID),
dimension(3):: e1, e2, ex, ey
435 integer :: is, ie, js, je
438 ie = is + ipd_control%nx-1
440 je = js + ipd_control%ny-1
444 npz = ipd_control%levs
446 if( file_exist(fname) )
then 449 call mpp_error(fatal,
'==> Error in read_iau_forcing: Expected file '&
450 //trim(fname)//
' for DA increment does not exist')
454 jbeg =
jm-1; jend = 2
459 jend = max(jend, j1+1)
463 allocate (
wk3(1:
im,jbeg:jend, 1:
km) )
465 call interp_inc(
'T_inc',increments%temp_inc(:,:,:),jbeg,jend)
466 call interp_inc(
'delp_inc',increments%delp_inc(:,:,:),jbeg,jend)
467 call interp_inc(
'delz_inc',increments%delz_inc(:,:,:),jbeg,jend)
468 call interp_inc(
'u_inc',increments%ua_inc(:,:,:),jbeg,jend)
469 call interp_inc(
'v_inc',increments%va_inc(:,:,:),jbeg,jend)
479 subroutine interp_inc(field_name,var,jbeg,jend)
482 character(len=*),
intent(in) :: field_name
483 real,
dimension(is:ie,js:je,1:km),
intent(inout) :: var
484 integer,
intent(in) :: jbeg,jend
485 integer:: i1, i2, j1, k,j,i,ierr
490 if (is_master()) print *,
'warning: no increment for ',trim(field_name),
' found, assuming zero' 499 var(i,j,k) =
s2c(i,j,1)*
wk3(i1,j1 ,k) +
s2c(i,j,2)*
wk3(i2,j1 ,k)+&
real(kind=4), dimension(:,:,:), allocatable wk3
subroutine, public get_var3_r4(ncid, var3_name, is, ie, js, je, ks, ke, var3, time_slice)
The module 'fv_mp_mod' is a single program multiple data (SPMD) parallel decompostion/communication m...
The type 'fv_grid_type' is made up of grid-dependent information from fv_grid_tools and fv_grid_utils...
integer, dimension(:,:), allocatable jdc
character(len=32), dimension(:), allocatable tracer_names
integer, dimension(:,:), allocatable id2
type(iau_state_type) iau_state
subroutine updateiauforcing(IPD_Control, IAU_Data, wt)
integer, parameter, public r_grid
subroutine, public getiauforcing(IPD_Control, IAU_Data)
subroutine, public get_var1_real(ncid, var1_name, im, var1, var_exist)
subroutine read_iau_forcing(IPD_Control, increments, fname)
real, dimension(:,:,:), allocatable s2c
subroutine, public get_var1_double(ncid, var1_name, im, var1, var_exist)
The 'get_var' subroutines read in variables from netcdf files.
incremental analysis update module
subroutine setiauforcing(IPD_Control, IAU_Data, wt)
The module 'fv_arrays' contains the 'fv_atmos_type' and associated datatypes.
subroutine, public iau_initialize(IPD_Control, IAU_Data, Init_parm)
The module 'sim_nc' is a netcdf file reader.
'The module 'tread_da_increment' contains routines for treating the increments of the prognostic vari...
subroutine, public open_ncfile(iflnm, ncid)
integer, dimension(:), allocatable tracer_indicies
integer, dimension(:,:), allocatable id1
subroutine, public remap_coef(is, ie, js, je, isd, ied, jsd, jed, im, jm, lon, lat, id1, id2, jdc, s2c, agrid)
The subroutine 'remap_coef' calculates the coefficients for horizonal regridding. ...
subroutine, public get_ncdim1(ncid, var1_name, im)
subroutine interp_inc(field_name, var, jbeg, jend)
subroutine, public check_var_exists(ncid, var_name, status)
subroutine, public close_ncfile(ncid)