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.
100 real(kind=kind_phys) :: hr1
101 real(kind=kind_phys) :: hr2
102 real(kind=kind_phys) :: wt
103 real(kind=kind_phys) :: wt_normfact
110 type(ipd_control_type),
intent(in) :: ipd_control
112 type(ipd_init_type),
intent(in) :: init_parm
115 character(len=128) :: fname
116 real,
dimension(:,:,:),
allocatable:: u_inc, v_inc
117 real,
allocatable:: lat(:), lon(:),agrid(:,:,:)
118 real(kind=kind_phys) sx,wx,wt,normfact,dtp
120 integer:: i, j, k, nstep, kstep
126 integer,
allocatable :: idt(:)
129 ie =
is + ipd_control%nx-1
131 je =
js + ipd_control%ny-1
132 call get_number_tracers(model_atmos, num_tracers=
ntracers)
146 nfilesall =
size(ipd_control%iau_inc_files)
148 if (is_master()) print*,
'in iau_init',trim(ipd_control%iau_inc_files(1)),ipd_control%iaufhrs(1)
150 if (trim(ipd_control%iau_inc_files(k)) .eq.
'' .or. ipd_control%iaufhrs(k) .lt. 0)
exit 151 if (is_master())
then 152 print *,k,trim(adjustl(ipd_control%iau_inc_files(k)))
156 if (is_master()) print *,
'nfiles = ',
nfiles 162 idt = ipd_control%iaufhrs(2:
nfiles)-ipd_control%iaufhrs(1:
nfiles-1)
164 if (idt(k) .ne. ipd_control%iaufhrs(2)-ipd_control%iaufhrs(1))
then 165 print *,
'forecast intervals in iaufhrs must be constant' 166 call mpp_error (fatal,
' forecast intervals in iaufhrs must be constant')
171 if (is_master()) print *,
'iau interval = ',ipd_control%iau_delthrs,
' hours' 172 dt = (ipd_control%iau_delthrs*3600.)
178 npz = ipd_control%levs
179 fname =
'INPUT/'//trim(ipd_control%iau_inc_files(1))
181 if( file_exist(fname) )
then 188 if (is_master()) print *,
'km = ',
km 189 call mpp_error(fatal, &
190 '==> Error in IAU_initialize: km is not equal to npz')
193 if(is_master())
write(*,*) fname,
' DA increment dimensions:',
im,
jm,
km 198 call _get_var1 (
ncid,
'lon',
im, lon )
199 call _get_var1 (
ncid,
'lat',
jm, lat )
211 call mpp_error(fatal,
'==> Error in IAU_initialize: Expected file '&
212 //trim(fname)//
' for DA increment does not exist')
220 do j = 1,
size(init_parm%xlon,2)
221 do i = 1,
size(init_parm%xlon,1)
223 agrid(
is-1+i,
js-1+j,1)=init_parm%xlon(i,j)
224 agrid(
is-1+i,
js-1+j,2)=init_parm%xlat(i,j)
230 deallocate ( lon, lat,agrid )
248 if (ipd_control%iau_filter_increments)
then 251 nstep = 0.5*ipd_control%iau_delthrs*3600/dtp
256 sx = acos(-1.)*kstep/nstep
257 wx = acos(-1.)*kstep/(nstep+1)
258 if (kstep .ne. 0)
then 259 wt = sin(wx)/wx*sin(sx)/sx
263 normfact = normfact + wt
264 if (is_master()) print *,
'filter wts',k,kstep,wt
266 iau_state%wt_normfact = (2*nstep+1)/normfact
289 type(ipd_control_type),
intent(in) :: ipd_control
291 real(kind=kind_phys) t1,t2,sx,wx,wt,dtp
292 integer n,i,j,k,sphum,kstep,nstep
294 iau_data%in_interval=.false.
299 t1=
iau_state%hr1 - ipd_control%iau_delthrs*0.5
300 t2=
iau_state%hr1 + ipd_control%iau_delthrs*0.5
301 if (ipd_control%iau_filter_increments)
then 308 nstep = 0.5*ipd_control%iau_delthrs*3600/dtp
310 kstep = (ipd_control%fhour-(t1+ipd_control%iau_delthrs*0.5))*3600./dtp
311 if (kstep .ge. -nstep .and. kstep .le. nstep)
then 312 sx = acos(-1.)*kstep/nstep
313 wx = acos(-1.)*kstep/(nstep+1)
314 if (kstep .ne. 0)
then 315 wt = (sin(wx)/wx*sin(sx)/sx)
320 if (is_master()) print *,
'filter wt',kstep,ipd_control%fhour,
iau_state%wt
329 if ( ipd_control%fhour < t1 .or. ipd_control%fhour >= t2 )
then 331 iau_data%in_interval=.false.
334 if (is_master()) print *,
'apply iau forcing',t1,ipd_control%fhour,t2
335 iau_data%in_interval=.true.
342 if (ipd_control%fhour < ipd_control%iaufhrs(1) .or. ipd_control%fhour >= ipd_control%iaufhrs(
nfiles))
then 344 iau_data%in_interval=.false.
346 iau_data%in_interval=.true.
348 if (ipd_control%iaufhrs(k) > ipd_control%fhour)
then 353 if (ipd_control%fhour >=
iau_state%hr2)
then 357 if (is_master()) print *,
'reading next increment file',trim(ipd_control%iau_inc_files(t2))
363 sphum=get_tracer_index(model_atmos,
'sphum')
369 type(ipd_control_type),
intent(in) :: ipd_control
370 type(IAU_external_data_type),
intent(inout) :: IAU_Data
371 real(kind_phys) delt,wt
379 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
380 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
381 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
382 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
383 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
385 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
396 type(ipd_control_type),
intent(in) :: ipd_control
397 type(IAU_external_data_type),
intent(inout) :: IAU_Data
398 real(kind_phys) delt, dt,wt
399 integer i,j,k,l,sphum
401 if (is_master()) print *,
'in setiauforcing',
rdt 405 iau_data%ua_inc(i,j,k) =wt*
iau_state%inc1%ua_inc(i,j,k)*
rdt 406 iau_data%va_inc(i,j,k) =wt*
iau_state%inc1%va_inc(i,j,k)*
rdt 407 iau_data%temp_inc(i,j,k) =wt*
iau_state%inc1%temp_inc(i,j,k)*
rdt 408 iau_data%delp_inc(i,j,k) =wt*
iau_state%inc1%delp_inc(i,j,k)*
rdt 409 iau_data%delz_inc(i,j,k) =wt*
iau_state%inc1%delz_inc(i,j,k)*
rdt 411 iau_data%tracer_inc(i,j,k,l) =wt*
iau_state%inc1%tracer_inc(i,j,k,l)*
rdt 416 sphum=get_tracer_index(model_atmos,
'sphum')
420 type(ipd_control_type),
intent(in) :: ipd_control
421 type(iau_internal_data_type),
intent(inout):: increments
422 character(len=*),
intent(in) :: fname
424 real,
dimension(:,:,:),
allocatable:: u_inc, v_inc
426 integer:: i, j, k, l, npz
429 real(kind=R_GRID),
dimension(2):: p1, p2, p3
430 real(kind=R_GRID),
dimension(3):: e1, e2, ex, ey
433 integer :: is, ie, js, je
436 ie = is + ipd_control%nx-1
438 je = js + ipd_control%ny-1
442 npz = ipd_control%levs
444 if( file_exist(fname) )
then 447 call mpp_error(fatal,
'==> Error in read_iau_forcing: Expected file '&
448 //trim(fname)//
' for DA increment does not exist')
452 jbeg =
jm-1; jend = 2
457 jend = max(jend, j1+1)
461 allocate (
wk3(1:
im,jbeg:jend, 1:
km) )
463 call interp_inc(
'T_inc',increments%temp_inc(:,:,:),jbeg,jend)
464 call interp_inc(
'delp_inc',increments%delp_inc(:,:,:),jbeg,jend)
465 call interp_inc(
'delz_inc',increments%delz_inc(:,:,:),jbeg,jend)
466 call interp_inc(
'u_inc',increments%ua_inc(:,:,:),jbeg,jend)
467 call interp_inc(
'v_inc',increments%va_inc(:,:,:),jbeg,jend)
477 subroutine interp_inc(field_name,var,jbeg,jend)
480 character(len=*),
intent(in) :: field_name
481 real,
dimension(is:ie,js:je,1:km),
intent(inout) :: var
482 integer,
intent(in) :: jbeg,jend
483 integer:: i1, i2, j1, k,j,i,ierr
488 if (is_master()) print *,
'warning: no increment for ',trim(field_name),
' found, assuming zero' 497 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, 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)