1 SUBROUTINE dfi_accumulate( grid )
3 USE module_domain, ONLY : domain
5 USE module_driver_constants
8 USE module_model_constants
9 USE module_state_description
18 TYPE(domain) , POINTER :: grid
20 IF ( grid%dfi_opt .EQ. DFI_NODFI .OR. grid%dfi_stage .EQ. DFI_FST ) RETURN
25 hn = grid%hcoeff(grid%itimestep+1)
27 ! accumulate dynamic variables
28 grid%dfi_mu(:,:) = grid%dfi_mu(:,:) + grid%MU_2(:,:) * hn
29 grid%dfi_u(:,:,:) = grid%dfi_u(:,:,:) + grid%u_2(:,:,:) * hn
30 grid%dfi_v(:,:,:) = grid%dfi_v(:,:,:) + grid%v_2(:,:,:) * hn
31 grid%dfi_w(:,:,:) = grid%dfi_w(:,:,:) + grid%w_2(:,:,:) * hn
32 grid%dfi_ww(:,:,:) = grid%dfi_ww(:,:,:) + grid%ww(:,:,:) * hn
33 grid%dfi_t(:,:,:) = grid%dfi_t(:,:,:) + grid%t_2(:,:,:) * hn
34 grid%dfi_phb(:,:,:) = grid%dfi_phb(:,:,:) + grid%phb(:,:,:) * hn
35 grid%dfi_ph0(:,:,:) = grid%dfi_ph0(:,:,:) + grid%ph0(:,:,:) * hn
36 grid%dfi_php(:,:,:) = grid%dfi_php(:,:,:) + grid%php(:,:,:) * hn
37 grid%dfi_p(:,:,:) = grid%dfi_p(:,:,:) + grid%p(:,:,:) * hn
38 grid%dfi_ph(:,:,:) = grid%dfi_ph(:,:,:) + grid%ph_2(:,:,:) * hn
39 grid%dfi_tke(:,:,:) = grid%dfi_tke(:,:,:) + grid%tke_2(:,:,:) * hn
40 grid%dfi_al(:,:,:) = grid%dfi_al(:,:,:) + grid%al(:,:,:) * hn
41 grid%dfi_alt(:,:,:) = grid%dfi_alt(:,:,:) + grid%alt(:,:,:) * hn
42 grid%dfi_pb(:,:,:) = grid%dfi_pb(:,:,:) + grid%pb(:,:,:) * hn
43 ! dfi_savehydmeteors is a namelist parameter, default =0 which means hydrometeor
44 ! and scalar fields will be spinning up in DFI; if dfi_savehydmeteors=1 then
45 ! hydrometeor fields will stay unchanged in DFI, but water vapor mixing ratio
46 ! QV will be modified.
47 IF ( grid%dfi_savehydmeteors .EQ. 0 ) then
48 grid%dfi_moist(:,:,:,:) = grid%dfi_moist(:,:,:,:) + grid%moist(:,:,:,:) * hn
49 grid%dfi_scalar(:,:,:,:) = grid%dfi_scalar(:,:,:,:) + grid%scalar(:,:,:,:) * hn
50 IF ( grid%mp_physics_dfi .NE. NUWRF4ICESCHEME_DFI ) THEN
51 grid%dfi_re_cloud(:,:,:) = grid%dfi_re_cloud(:,:,:) + grid%re_cloud(:,:,:) * hn
52 grid%dfi_re_ice(:,:,:) = grid%dfi_re_ice(:,:,:) + grid%re_ice(:,:,:) * hn
53 grid%dfi_re_snow(:,:,:) = grid%dfi_re_snow(:,:,:) + grid%re_snow(:,:,:) * hn
54 ELSE IF ( grid%mp_physics_dfi .EQ. NUWRF4ICESCHEME_DFI ) THEN
55 grid%dfi_re_cloud_gsfc(:,:,:) = grid%dfi_re_cloud_gsfc(:,:,:) + grid%re_cloud_gsfc(:,:,:) * hn
56 grid%dfi_re_rain_gsfc(:,:,:) = grid%dfi_re_rain_gsfc(:,:,:) + grid%re_rain_gsfc(:,:,:) * hn
57 grid%dfi_re_ice_gsfc(:,:,:) = grid%dfi_re_ice_gsfc(:,:,:) + grid%re_ice_gsfc(:,:,:) * hn
58 grid%dfi_re_snow_gsfc(:,:,:) = grid%dfi_re_snow_gsfc(:,:,:) + grid%re_snow_gsfc(:,:,:) * hn
59 grid%dfi_re_graupel_gsfc(:,:,:) = grid%dfi_re_graupel_gsfc(:,:,:) + grid%re_graupel_gsfc(:,:,:) * hn
60 grid%dfi_re_hail_gsfc(:,:,:) = grid%dfi_re_hail_gsfc(:,:,:) + grid%re_hail_gsfc(:,:,:) * hn
63 grid%dfi_moist(:,:,:,P_QV) = grid%dfi_moist(:,:,:,P_QV) + grid%moist(:,:,:,P_QV) * hn
65 ! IF ( grid%sf_surface_physics .EQ. RUCLSMSCHEME ) then
66 ! grid%dfi_QVG(:,:) = grid%dfi_QVG(:,:) + grid%QVG(:,:) * hn
69 ! accumulate DFI coefficient
70 grid%hcoeff_tot = grid%hcoeff_tot + hn
73 END SUBROUTINE dfi_accumulate
75 SUBROUTINE dfi_bck_init ( grid )
77 USE module_domain, ONLY : domain, head_grid, domain_get_stop_time, domain_get_start_time
79 USE module_state_description
83 TYPE (domain) , POINTER :: grid
88 SUBROUTINE Setup_Timekeeping(grid)
89 USE module_domain, ONLY : domain
90 TYPE (domain), POINTER :: grid
91 END SUBROUTINE Setup_Timekeeping
93 SUBROUTINE dfi_save_arrays(grid)
94 USE module_domain, ONLY : domain
95 TYPE (domain), POINTER :: grid
96 END SUBROUTINE dfi_save_arrays
98 SUBROUTINE dfi_clear_accumulation(grid)
99 USE module_domain, ONLY : domain
100 TYPE (domain), POINTER :: grid
101 END SUBROUTINE dfi_clear_accumulation
103 SUBROUTINE optfil_driver(grid)
104 USE module_domain, ONLY : domain
105 TYPE (domain), POINTER :: grid
106 END SUBROUTINE optfil_driver
108 SUBROUTINE start_domain(grid, allowed_to_read)
109 USE module_domain, ONLY : domain
110 TYPE (domain) :: grid
111 LOGICAL, INTENT(IN) :: allowed_to_read
112 END SUBROUTINE start_domain
115 SUBROUTINE rebalance_driver_dfi (grid)
116 USE module_domain, ONLY : domain
117 TYPE (domain) :: grid
118 END SUBROUTINE rebalance_driver_dfi
123 grid%dfi_stage = DFI_BCK
126 if(grid%cycling) then
127 ! print *,' Rebalancing is on '
128 CALL rebalance_driver_dfi ( grid )
133 IF ( grid%time_step_dfi .gt. 0 ) THEN
134 CALL nl_set_time_step ( 1, -grid%time_step_dfi )
136 CALL nl_set_time_step ( 1, -grid%time_step )
137 CALL nl_set_time_step_fract_num ( 1, -grid%time_step_fract_num )
140 CALL Setup_Timekeeping (grid)
142 !tgs 7apr11 - need to call start_domain here to reset bc initialization for negative dt
143 CALL start_domain ( grid , .TRUE. )
144 !tgs 7apr11 - save arrays should be done after start_domain to get correct grid%p field
145 ! used in computation of initial RH.
146 CALL dfi_save_arrays ( grid )
148 ! set physics options to zero
149 CALL nl_set_mp_physics( grid%id, 0 )
150 CALL nl_set_ra_lw_physics( grid%id, 0 )
151 CALL nl_set_ra_sw_physics( grid%id, 0 )
152 CALL nl_set_sf_surface_physics( grid%id, 0 )
153 CALL nl_set_sf_sfclay_physics( grid%id, 0 )
154 CALL nl_set_sf_urban_physics( grid%id, 0 )
155 CALL nl_set_bl_pbl_physics( grid%id, 0 )
156 CALL nl_set_cu_physics( grid%id, 0 )
157 CALL nl_set_cu_diag( grid%id, 0 )
158 CALL nl_set_damp_opt( grid%id, 0 )
159 CALL nl_set_sst_update( grid%id, 0 )
161 CALL nl_set_sf_ocean_physics( grid%id, 0 )
163 CALL nl_set_fractional_seaice( grid%id, 0 )
164 CALL nl_set_gwd_opt( grid%id, 0 )
165 CALL nl_set_feedback( grid%id, 0 )
168 CALL nl_set_diff_6th_opt( grid%id, 0 )
169 CALL nl_set_constant_bc(1, grid%constant_bc)
170 CALL nl_set_use_adaptive_time_step( grid%id, .false. )
173 #if ( WRF_CHEM == 1 )
174 ! set chemistry option to zero
175 CALL nl_set_chem_opt (grid%id, 0)
176 CALL nl_set_aer_ra_feedback (grid%id, 0)
177 CALL nl_set_io_form_auxinput5 (grid%id, 0)
178 CALL nl_set_io_form_auxinput6 (grid%id, 0)
179 CALL nl_set_io_form_auxinput7 (grid%id, 0)
180 CALL nl_set_io_form_auxinput8 (grid%id, 0)
181 CALL nl_set_io_form_auxinput13 (grid%id, 0)
182 CALL nl_set_io_form_auxinput14 (grid%id, 0)
183 CALL nl_set_io_form_auxinput15 (grid%id, 0)
186 ! set diffusion to zero for backward integration
189 grid%km_opt_dfi = grid%km_opt
190 grid%diff_opt_dfi = grid%diff_opt
191 CALL nl_set_km_opt( grid%id, 1)
192 CALL nl_set_diff_opt( grid%id, 0)
193 CALL nl_set_moist_adv_dfi_opt( grid%id, grid%moist_adv_dfi_opt)
194 CALL nl_set_moist_adv_opt( grid%id,grid%moist_adv_dfi_opt)
197 ! If a request to do pressure level diags, then shut it off
198 ! until we get to the real forecast part of this integration.
201 CALL nl_set_p_lev_diags( grid%id, grid%p_lev_diags_dfi)
204 grid%start_subtime = domain_get_start_time ( grid )
205 grid%stop_subtime = domain_get_stop_time ( grid )
207 CALL WRFU_ClockSet(grid%domain_clock, currTime=grid%start_subtime, rc=rc)
209 !tgs 7apr11 - this call has been moved up
210 ! CALL dfi_save_arrays ( grid )
211 CALL dfi_clear_accumulation( grid )
212 CALL optfil_driver(grid)
214 !tgs need to call start_domain here to reset bc initialization for negative dt
215 CALL start_domain ( grid , .TRUE. )
217 END SUBROUTINE dfi_bck_init
220 SUBROUTINE dfi_fwd_init ( grid )
222 USE module_domain, ONLY : domain, head_grid, domain_get_stop_time, domain_get_start_time
223 USE module_utility, ONLY : WRFU_ClockSet
224 USE module_state_description
228 TYPE (domain) , POINTER :: grid
231 INTEGER n_moist,nm,n_scalar,ns
234 SUBROUTINE Setup_Timekeeping(grid)
235 USE module_domain, ONLY : domain
236 TYPE (domain), POINTER :: grid
237 END SUBROUTINE Setup_Timekeeping
239 SUBROUTINE dfi_save_arrays(grid)
240 USE module_domain, ONLY : domain
241 TYPE (domain), POINTER :: grid
242 END SUBROUTINE dfi_save_arrays
244 SUBROUTINE dfi_clear_accumulation(grid)
245 USE module_domain, ONLY : domain
246 TYPE (domain), POINTER :: grid
247 END SUBROUTINE dfi_clear_accumulation
249 SUBROUTINE optfil_driver(grid)
250 USE module_domain, ONLY : domain
251 TYPE (domain), POINTER :: grid
252 END SUBROUTINE optfil_driver
255 SUBROUTINE rebalance_driver_dfi (grid)
256 USE module_domain, ONLY : domain
257 TYPE (domain) :: grid
258 END SUBROUTINE rebalance_driver_dfi
261 SUBROUTINE start_domain(grid, allowed_to_read)
262 USE module_domain, ONLY : domain
263 TYPE (domain) :: grid
264 LOGICAL, INTENT(IN) :: allowed_to_read
265 END SUBROUTINE start_domain
268 grid%dfi_stage = DFI_FWD
270 ! for Setup_Timekeeping to use when setting the clock
272 IF ( grid%time_step_dfi .gt. 0 ) THEN
273 CALL nl_set_time_step ( grid%id, grid%time_step_dfi )
276 CALL nl_get_time_step( grid%id, grid%time_step )
277 CALL nl_get_time_step_fract_num( grid%id, grid%time_step_fract_num )
279 grid%time_step = abs(grid%time_step)
280 CALL nl_set_time_step( grid%id, grid%time_step )
282 grid%time_step_fract_num = abs(grid%time_step_fract_num)
283 CALL nl_set_time_step_fract_num( grid%id, grid%time_step_fract_num )
290 ! reset physics options to normal
291 CALL nl_set_mp_physics( grid%id, grid%mp_physics)
292 CALL nl_set_ra_lw_physics( grid%id, grid%ra_lw_physics)
293 CALL nl_set_ra_sw_physics( grid%id, grid%ra_sw_physics)
294 CALL nl_set_sf_surface_physics( grid%id, grid%sf_surface_physics)
295 CALL nl_set_sf_sfclay_physics( grid%id, grid%sf_sfclay_physics)
296 CALL nl_set_sf_urban_physics( grid%id, grid%sf_urban_physics)
297 CALL nl_set_bl_pbl_physics( grid%id, grid%bl_pbl_physics)
298 CALL nl_set_cu_physics( grid%id, grid%cu_physics)
299 CALL nl_set_cu_diag( grid%id, grid%cu_diag )
300 CALL nl_set_damp_opt( grid%id, grid%damp_opt)
301 CALL nl_set_sst_update( grid%id, 0)
303 CALL nl_set_sf_ocean_physics( grid%id, 0)
305 CALL nl_set_fractional_seaice( grid%id, grid%fractional_seaice)
306 CALL nl_set_gwd_opt( grid%id, grid%gwd_opt)
307 CALL nl_set_feedback( grid%id, 0 )
309 CALL nl_set_diff_6th_opt( grid%id, grid%diff_6th_opt)
310 CALL nl_set_use_adaptive_time_step( grid%id, .false. )
312 CALL nl_set_constant_bc(grid%id, grid%constant_bc)
316 !#if ( WRF_CHEM == 1 )
317 ! ! reset chem option to normal
318 ! CALL nl_set_chem_opt( grid%id, grid%chem_opt)
319 ! CALL nl_set_aer_ra_feedback (grid%id, grid%aer_ra_feedback)
323 ! reset km_opt to normal
324 grid%km_opt = grid%km_opt_dfi
325 grid%diff_opt = grid%diff_opt_dfi
326 CALL nl_set_km_opt( grid%id, grid%km_opt_dfi)
327 CALL nl_set_diff_opt( grid%id, grid%diff_opt_dfi)
328 CALL nl_set_moist_adv_opt( grid%id, grid%moist_adv_opt)
332 CALL Setup_Timekeeping (grid)
333 grid%start_subtime = domain_get_start_time ( head_grid )
334 grid%stop_subtime = domain_get_stop_time ( head_grid )
336 CALL WRFU_ClockSet(grid%domain_clock, currTime=grid%start_subtime, rc=rc)
338 IF ( grid%dfi_opt .EQ. DFI_DFL ) THEN
339 CALL dfi_save_arrays ( grid )
341 CALL dfi_clear_accumulation( grid )
342 CALL optfil_driver(grid)
344 !tgs need to call it here to reset bc initialization for positive time_step
345 CALL start_domain ( grid , .TRUE. )
347 !tgs After start_domain moist and scalar arrays are fully dimentioned,
348 !and initial values should be restored here if grid%dfi_savehydmeteors .EQ. 1:
349 IF ( grid%dfi_savehydmeteors .EQ. 1 ) then
350 ! print *,'FWD n_moist,PARAM_FIRST_SCALAR,P_QV,P_QC,P_QR,P_QI,P_QS,P_QG', &
351 ! n_moist,PARAM_FIRST_SCALAR,P_QV,P_QC,P_QR,P_QI,P_QS,P_QG
352 ! print *,'FWD num_scalar,P_QNC,P_QNI,P_QNR,P_QNWFA,P_QNIFA',P_QNC,P_QNI,P_QNR,P_QNWFA,P_QNIFA
354 DO nm=PARAM_FIRST_SCALAR+1,n_moist
355 grid%moist(:,:,:,nm)=grid%dfi_moist(:,:,:,nm)
357 grid%scalar(:,:,:,:) = grid%dfi_scalar(:,:,:,:)
360 END SUBROUTINE dfi_fwd_init
362 SUBROUTINE dfi_fst_init ( grid )
364 USE module_domain, ONLY : domain, domain_get_stop_time, domain_get_start_time
365 USE module_state_description
369 TYPE (domain) , POINTER :: grid
370 CHARACTER (LEN=80) :: wrf_error_message
374 SUBROUTINE Setup_Timekeeping(grid)
375 USE module_domain, ONLY : domain
376 TYPE (domain), POINTER :: grid
377 END SUBROUTINE Setup_Timekeeping
379 SUBROUTINE dfi_save_arrays(grid)
380 USE module_domain, ONLY : domain
381 TYPE (domain), POINTER :: grid
382 END SUBROUTINE dfi_save_arrays
384 SUBROUTINE dfi_clear_accumulation(grid)
385 USE module_domain, ONLY : domain
386 TYPE (domain), POINTER :: grid
387 END SUBROUTINE dfi_clear_accumulation
389 SUBROUTINE optfil_driver(grid)
390 USE module_domain, ONLY : domain
391 TYPE (domain), POINTER :: grid
392 END SUBROUTINE optfil_driver
395 SUBROUTINE rebalance_driver_dfi (grid)
396 USE module_domain, ONLY : domain
397 TYPE (domain) :: grid
398 END SUBROUTINE rebalance_driver_dfi
401 SUBROUTINE start_domain(grid, allowed_to_read)
402 USE module_domain, ONLY : domain
403 TYPE (domain) :: grid
404 LOGICAL, INTENT(IN) :: allowed_to_read
405 END SUBROUTINE start_domain
408 grid%dfi_stage = DFI_FST
410 ! reset time_step to normal and adaptive_time_step
411 CALL nl_set_time_step( grid%id, grid%time_step )
414 grid%xtime=0. ! BUG: This will probably not work for all DFI options
415 ! only use adaptive time stepping for forecast
417 if (grid%id == 1) then
418 CALL nl_set_use_adaptive_time_step( 1, grid%use_adaptive_time_step )
420 CALL nl_set_sst_update( grid%id, grid%sst_update)
421 CALL nl_set_sf_ocean_physics( grid%id, grid%sf_ocean_physics)
423 CALL nl_set_constant_bc(grid%id, .false.)
425 CALL nl_set_feedback( grid%id, grid%feedback )
427 #if ( WRF_CHEM == 1 )
428 ! reset chem option to normal
429 CALL nl_set_chem_opt( grid%id, grid%chem_opt)
430 CALL nl_set_aer_ra_feedback (grid%id, grid%aer_ra_feedback)
431 CALL nl_set_io_form_auxinput5 (grid%id, grid%io_form_auxinput5)
432 CALL nl_set_io_form_auxinput6 (grid%id, grid%io_form_auxinput6)
433 CALL nl_set_io_form_auxinput7 (grid%id, grid%io_form_auxinput7)
434 CALL nl_set_io_form_auxinput8 (grid%id, grid%io_form_auxinput8)
435 CALL nl_set_io_form_auxinput13(grid%id, grid%io_form_auxinput13)
436 CALL nl_set_io_form_auxinput14(grid%id, grid%io_form_auxinput14)
437 CALL nl_set_io_form_auxinput15(grid%id, grid%io_form_auxinput15)
439 ! This resets the open file handles associated with the chemistry
440 ! auxinputs. It may be a good idea to do this with other auxinputs as well.
441 ! A better fix than the below may be to never assign the file handles to begin
442 ! with when running DFI.
444 grid%auxinput5_oid = 0
445 grid%auxinput6_oid = 0
446 grid%auxinput7_oid = 0
447 grid%auxinput8_oid = 0
448 grid%auxinput12_oid = 0
449 grid%auxinput13_oid = 0
450 grid%auxinput14_oid = 0
451 grid%auxinput15_oid = 0
455 ! reset pressure level diags to normal
456 CALL nl_set_p_lev_diags ( grid%id, grid%p_lev_diags)
460 CALL Setup_Timekeeping (grid)
461 grid%start_subtime = domain_get_start_time ( grid )
462 grid%stop_subtime = domain_get_stop_time ( grid )
464 CALL start_domain ( grid , .TRUE. )
466 END SUBROUTINE dfi_fst_init
469 SUBROUTINE dfi_write_initialized_state( grid )
472 USE module_domain, ONLY : domain, head_grid
474 USE module_configure, ONLY : grid_config_rec_type, model_config_rec
478 TYPE (domain) , POINTER :: grid
480 CHARACTER (LEN=80) :: wrf_error_message
481 CHARACTER (LEN=256) :: rstname
482 CHARACTER (LEN=132) :: message
484 TYPE (grid_config_rec_type) :: config_flags
486 CALL model_to_grid_config_rec ( grid%id , model_config_rec , config_flags )
488 WRITE (wrf_err_message,'(A,I4)') 'Writing out initialized model state'
489 CALL wrf_message(TRIM(wrf_err_message))
491 WRITE (rstname,'(A,I2.2)')'wrfinput_initialized_d',grid%id
492 CALL open_w_dataset ( fid, TRIM(rstname), grid, config_flags, output_input, "DATASET=INPUT", ierr )
493 IF ( ierr .NE. 0 ) THEN
494 WRITE( message , '("program wrf: error opening ",A," for writing")') TRIM(rstname)
495 CALL WRF_ERROR_FATAL ( message )
497 CALL output_input ( fid, grid, config_flags, ierr )
498 CALL close_dataset ( fid, config_flags, "DATASET=INPUT" )
500 END SUBROUTINE dfi_write_initialized_state
502 SUBROUTINE tdfi_write_analyzed_state ( grid )
505 USE module_domain, ONLY : domain, head_grid
507 USE module_configure, ONLY : grid_config_rec_type, model_config_rec
511 TYPE (domain) , POINTER :: grid
513 CHARACTER (LEN=80) :: wrf_error_message
514 CHARACTER (LEN=256) :: rstname
515 CHARACTER (LEN=132) :: message
517 TYPE (grid_config_rec_type) :: config_flags
519 CALL model_to_grid_config_rec ( grid%id , model_config_rec , config_flags )
521 rstname = 'wrfout_analyzed_d01'
522 CALL open_w_dataset ( fid, TRIM(rstname),grid, config_flags, output_input, "DATASET=INPUT", ierr )
523 IF ( ierr .NE. 0 ) THEN
524 WRITE( message , '("program wrf: error opening ",A," for writing")') TRIM(rstname)
525 CALL WRF_ERROR_FATAL ( message )
527 CALL output_input ( fid, grid, config_flags, ierr )
528 CALL close_dataset ( fid, config_flags, "DATASET=INPUT" )
530 END SUBROUTINE tdfi_write_analyzed_state
533 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
534 ! DFI array reset group of functions
535 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
537 SUBROUTINE wrf_dfi_array_reset ( )
539 USE module_domain, ONLY : domain, head_grid, set_current_grid_ptr
544 RECURSIVE SUBROUTINE dfi_array_reset_recurse(grid)
545 USE module_domain, ONLY : domain
546 TYPE (domain), POINTER :: grid
547 END SUBROUTINE dfi_array_reset_recurse
550 ! Copy filtered arrays back into state arrays in grid structure, and
551 ! restore original land surface fields
553 CALL dfi_array_reset_recurse(head_grid)
555 CALL set_current_grid_ptr( head_grid )
557 END SUBROUTINE wrf_dfi_array_reset
559 SUBROUTINE dfi_array_reset( grid )
561 USE module_domain, ONLY : domain
562 ! USE module_configure
563 ! USE module_driver_constants
566 USE module_model_constants
567 USE module_state_description
571 INTEGER :: its, ite, jts, jte, kts, kte, &
573 INTEGER :: n_moist, nm, n_scalar, ns
576 TYPE(domain) , POINTER :: grid
579 ! real p1000mb,eps,svp1,svp2,svp3,svpt0
581 ! parameter (p1000mb = 1.e+05, eps=0.622,svp1=0.6112,svp3=29.65,svpt0=273.15)
582 parameter (eps=0.622)
583 integer nsoil , ncount
584 REAL es,qs,pol,tx,temp,pres,rslf,rsif
588 nsoil = grid%num_soil_layers
590 IF ( grid%dfi_opt .EQ. DFI_NODFI ) RETURN
593 ! Set dynamic variables
594 ! divide by total DFI coefficient
597 grid%MU_2(:,:) = grid%dfi_mu(:,:) / grid%hcoeff_tot
598 grid%u_2(:,:,:) = grid%dfi_u(:,:,:) / grid%hcoeff_tot
599 grid%v_2(:,:,:) = grid%dfi_v(:,:,:) / grid%hcoeff_tot
600 grid%w_2(:,:,:) = grid%dfi_w(:,:,:) / grid%hcoeff_tot
601 grid%ww(:,:,:) = grid%dfi_ww(:,:,:) / grid%hcoeff_tot
602 grid%t_2(:,:,:) = grid%dfi_t(:,:,:) / grid%hcoeff_tot
603 grid%phb(:,:,:) = grid%dfi_phb(:,:,:) / grid%hcoeff_tot
604 grid%ph0(:,:,:) = grid%dfi_ph0(:,:,:) / grid%hcoeff_tot
605 grid%php(:,:,:) = grid%dfi_php(:,:,:) / grid%hcoeff_tot
606 grid%p(:,:,:) = grid%dfi_p(:,:,:) / grid%hcoeff_tot
607 grid%ph_2(:,:,:) = grid%dfi_ph(:,:,:) / grid%hcoeff_tot
608 grid%tke_2(:,:,:) = grid%dfi_tke(:,:,:) / grid%hcoeff_tot
609 grid%al(:,:,:) = grid%dfi_al(:,:,:) / grid%hcoeff_tot
610 grid%alt(:,:,:) = grid%dfi_alt(:,:,:) / grid%hcoeff_tot
611 grid%pb(:,:,:) = grid%dfi_pb(:,:,:) / grid%hcoeff_tot
612 IF ( grid%dfi_savehydmeteors .EQ. 0 ) then
613 ! print *,'Normal DFI'
614 grid%moist(:,:,:,:) = max(0.,grid%dfi_moist(:,:,:,:) / grid%hcoeff_tot)
615 grid%scalar(:,:,:,:) = max(0.,grid%dfi_scalar(:,:,:,:) / grid%hcoeff_tot)
616 IF ( grid%mp_physics_dfi .NE. NUWRF4ICESCHEME_DFI ) THEN
617 grid%re_cloud(:,:,:) = max(0.,grid%dfi_re_cloud(:,:,:) / grid%hcoeff_tot)
618 grid%re_ice(:,:,:) = max(0.,grid%dfi_re_ice(:,:,:) / grid%hcoeff_tot)
619 grid%re_snow(:,:,:) = max(0.,grid%dfi_re_snow(:,:,:) / grid%hcoeff_tot)
621 ELSE IF ( grid%mp_physics_dfi .EQ. NUWRF4ICESCHEME_DFI ) THEN
622 grid%re_cloud_gsfc(:,:,:) = max(0.,grid%dfi_re_cloud_gsfc(:,:,:) / grid%hcoeff_tot)
623 grid%re_rain_gsfc(:,:,:) = max(0.,grid%dfi_re_rain_gsfc(:,:,:) / grid%hcoeff_tot)
624 grid%re_ice_gsfc(:,:,:) = max(0.,grid%dfi_re_ice_gsfc(:,:,:) / grid%hcoeff_tot)
625 grid%re_snow_gsfc(:,:,:) = max(0.,grid%dfi_re_snow_gsfc(:,:,:) / grid%hcoeff_tot)
626 grid%re_graupel_gsfc(:,:,:) = max(0.,grid%dfi_re_graupel_gsfc(:,:,:) / grid%hcoeff_tot)
627 grid%re_hail_gsfc(:,:,:) = max(0.,grid%dfi_re_hail_gsfc(:,:,:) / grid%hcoeff_tot)
631 ! print *,'In dfi_array_reset, QV comp, dfi_save_hydrometeors=1'
632 grid%moist(:,:,:,P_QV) = max(0.,grid%dfi_moist(:,:,:,P_QV) / grid%hcoeff_tot)
634 if ( grid%sf_surface_physics .EQ. RUCLSMSCHEME ) then
635 ! grid%qvg(:,:) = grid%dfi_qvg(:,:) / grid%hcoeff_tot
638 IF ( grid%dfi_savehydmeteors .EQ. 1 ) then
639 ! print *,'restore initial surface fields'
640 ! restore initial fields
641 grid%SNOW (:,:) = grid%dfi_SNOW (:,:)
642 grid%SNOWH (:,:) = grid%dfi_SNOWH (:,:)
643 grid%SNOWC (:,:) = grid%dfi_SNOWC (:,:)
644 grid%CANWAT(:,:) = grid%dfi_CANWAT(:,:)
645 grid%TSK (:,:) = grid%dfi_TSK (:,:)
647 grid%TSLB (:,:,:) = grid%dfi_TSLB (:,:,:)
648 grid%SMOIS (:,:,:) = grid%dfi_SMOIS (:,:,:)
649 IF ( grid%sf_surface_physics .EQ. RUCLSMSCHEME ) then
650 grid%QVG (:,:) = grid%dfi_QVG (:,:)
651 grid%TSNAV (:,:) = grid%dfi_TSNAV (:,:)
652 grid%SOILT1(:,:) = grid%dfi_SOILT1(:,:)
653 grid%SMFR3D(:,:,:) = grid%dfi_SMFR3D (:,:,:)
654 grid%KEEPFR3DFLAG(:,:,:) = grid%dfi_KEEPFR3DFLAG(:,:,:)
658 ! print *, 'take into account DFI snowfall'
659 ! restore initial fields
660 its = grid%sp31 ; ite = grid%ep31 ;
661 jts = grid%sp33 ; jte = grid%ep33 ;
665 grid%SNOW (i,j) = max(grid%SNOW (i,j),grid%dfi_SNOW (i,j))
666 grid%SNOWH (i,j) = max(grid%SNOWH (i,j),grid%dfi_SNOWH (i,j))
667 grid%SNOWC (i,j) = max(grid%SNOWC (i,j),grid%dfi_SNOWC (i,j))
668 grid%CANWAT(i,j) = max(grid%CANWAT(i,j),grid%dfi_CANWAT(i,j))
669 IF(grid%SNOWC (i,j) .eq.0.) then
670 grid%TSK (i,j) = grid%dfi_TSK (i,j)
672 grid%TSLB (i,k,j) = grid%dfi_TSLB (i,k,j)
673 grid%SMOIS (i,k,j) = grid%dfi_SMOIS (i,k,j)
674 IF ( grid%sf_surface_physics .EQ. RUCLSMSCHEME ) then
675 grid%KEEPFR3DFLAG(i,k,j) = grid%dfi_KEEPFR3DFLAG(i,k,j)
676 grid%SMFR3D(i,k,j) = grid%dfi_SMFR3D (i,k,j)
679 IF ( grid%sf_surface_physics .EQ. RUCLSMSCHEME ) then
680 grid%QVG (i,j) = grid%dfi_QVG (i,j)
681 grid%TSNAV (i,j) = grid%dfi_TSNAV (i,j)
682 grid%SOILT1(i,j) = grid%dfi_SOILT1(i,j)
691 ! restore analized hydrometeor and scalar fileds
692 IF ( grid%dfi_savehydmeteors .EQ. 1 ) then
693 ! print *,'In dfi_array_reset - restore initial hydrometeors'
694 ! grid%moist(:,:,:,:) = grid%dfi_moist(:,:,:,:) !tgs
696 if (grid%dfi_stage .EQ. DFI_BCK) then
697 !tgs - backward integration changed only QV
699 n_scalar = PARAM_FIRST_SCALAR - 1
701 DO nm=PARAM_FIRST_SCALAR+1,n_moist
702 grid%moist(:,:,:,nm)=grid%dfi_moist(:,:,:,nm)
704 grid%scalar(:,:,:,:) = grid%dfi_scalar(:,:,:,:)
706 if(grid%dfi_stage .EQ. DFI_FWD) then
707 !tgs change QV to restore initial RH field after the diabatic DFI
708 its = grid%sp31 ; ite = grid%ep31 ;
709 kts = grid%sp32 ; kte = grid%ep32 ;
710 jts = grid%sp33 ; jte = grid%ep33 ;
714 if ( grid%use_theta_m .EQ. 1 ) then
715 temp = (grid%t_2(i,k,j)+t0) / (1. + R_v/R_d*grid%moist(i,k,j,P_Qv)) * &
716 ( (grid%p(i,k,j)+grid%pb(i,k,j))/p1000mb ) ** (r_d / Cp)
718 temp = (grid%t_2(i,k,j)+t0) * &
719 ( (grid%p(i,k,j)+grid%pb(i,k,j))/p1000mb ) ** (r_d / Cp)
721 pres = grid%p(i,k,j)+grid%pb(i,k,j)
722 !tgs rslf - function to compute qs from Thompson microphysics
723 qs = rslf(pres, temp)
725 ! if(i.eq. 464 .and. j.eq. 212 .and. k.eq.6) then
726 ! print *,'temp,pres,qs-thomp',temp,pres,qs
728 !! es=svp1*10.*EXP(svp2*(temp-svpt0)/(temp-svp3))
729 !! qs=0.622*es/(pres/100.-es)
731 ! if(i.eq. 464 .and. j.eq. 212 .and. k.eq.6) then
732 ! print *,'temp,pres,qs-wrf',temp,pres,qs
735 POL = 0.99999683 + TX*(-0.90826951E-02 + &
736 TX*(0.78736169E-04 + TX*(-0.61117958E-06 + &
737 TX*(0.43884187E-08 + TX*(-0.29883885E-10 + &
738 TX*(0.21874425E-12 + TX*(-0.17892321E-14 + &
739 TX*(0.11112018E-16 + TX*(-0.30994571E-19)))))))))
741 !! qs = 0.62197*es / (pres/100. - es*0.37803)
742 ! if(i.eq. 464 .and. j.eq. 212 .and. k.eq.6) then
743 ! print *,'temp,pres,qs-ruc',temp,pres,qs
746 ! if(i.eq. 464 .and. j.eq. 212 .and. k.eq.6) then
747 ! print *,'before grid%moist (i,k,j,P_QV),grid%dfi_rh(i,k,j)', &
748 ! grid%moist(i,k,j,P_QV),grid%dfi_rh(i,k,j)
751 ! Ensure that saturated points going into DFI remain saturated after DFI
752 IF(grid%dfi_rh(i,k,j) == 1. ) then
753 grid%moist (i,k,j,P_QV) = MAX(grid%moist (i,k,j,P_QV),grid%dfi_rh(i,k,j)*QS)
756 ! if(i.eq. 464 .and. j.eq. 212 .and. k.eq.6) then
757 ! print *,'after grid%moist (i,k,j,P_QV)', &
758 ! grid%moist(i,k,j,P_QV)
763 ! print *,'QV reset to saturation at ncount= ',ncount
765 !tgs need to call rebalance here again after hydrometeor and QV reset
766 ! print *,' Rebalancing is on '
767 CALL rebalance_driver_dfi ( grid )
773 END SUBROUTINE dfi_array_reset
775 SUBROUTINE optfil_driver( grid )
777 USE module_domain, ONLY : domain
779 ! USE module_wrf_error
781 ! USE module_date_time
782 ! USE module_configure
783 USE module_state_description
784 USE module_model_constants
788 TYPE (domain) , POINTER :: grid
791 integer :: nstep2, nstepmax, rundfi, i, rc,hr,min,sec
793 real :: timestep, tauc
794 TYPE(WRFU_TimeInterval) :: run_interval
797 timestep=abs(grid%dt)
798 run_interval = grid%stop_subtime - grid%start_subtime
799 CALL WRFU_TimeGet(grid%start_subtime, YY=yr, dayofYear=jday, H=hr, M=min, S=sec, rc=rc)
800 CALL WRFU_TimeGet(grid%stop_subtime, YY=yr, dayofYear=jday, H=hr, M=min, S=sec, rc=rc)
802 CALL WRFU_TimeIntervalGet( run_interval, S=rundfi, rc=rc )
805 nstep2= ceiling((1.0 + real(rundfi)/timestep) / 2.0)
807 ! nstep2 is equal to a half of timesteps per initialization period,
808 ! should not exceed nstepmax
810 tauc = real(grid%dfi_cutoff_seconds)
812 ! Get DFI coefficient
814 IF ( grid%dfi_nfilter < 0 .OR. grid%dfi_nfilter > 8 ) THEN
815 write(mess,*) 'Invalid filter specified in namelist.'
816 call wrf_message(mess)
818 call dfcoef(nstep2-1, grid%dt, tauc, grid%dfi_nfilter, grid%hcoeff)
821 IF ( MOD(int(1.0 + real(rundfi)/timestep),2) /= 0 ) THEN
823 grid%hcoeff(2*nstep2-i) = grid%hcoeff(i)
827 grid%hcoeff(2*nstep2-i+1) = grid%hcoeff(i)
831 END SUBROUTINE optfil_driver
834 SUBROUTINE dfi_clear_accumulation( grid )
836 USE module_domain, ONLY : domain
837 ! USE module_configure
838 ! USE module_driver_constants
841 ! USE module_model_constants
842 USE module_state_description
847 TYPE(domain) , POINTER :: grid
850 grid%dfi_mu(:,:) = 0.
851 grid%dfi_u(:,:,:) = 0.
852 grid%dfi_v(:,:,:) = 0.
853 grid%dfi_w(:,:,:) = 0.
854 grid%dfi_ww(:,:,:) = 0.
855 grid%dfi_t(:,:,:) = 0.
856 grid%dfi_phb(:,:,:) = 0.
857 grid%dfi_ph0(:,:,:) = 0.
858 grid%dfi_php(:,:,:) = 0.
859 grid%dfi_p(:,:,:) = 0.
860 grid%dfi_ph(:,:,:) = 0.
861 grid%dfi_tke(:,:,:) = 0.
862 grid%dfi_al(:,:,:) = 0.
863 grid%dfi_alt(:,:,:) = 0.
864 grid%dfi_pb(:,:,:) = 0.
865 IF ( grid%dfi_savehydmeteors .EQ. 0 ) then
866 ! print *,'normal DFI'
867 grid%dfi_moist(:,:,:,:) = 0.
868 grid%dfi_scalar(:,:,:,:) = 0.
869 IF ( grid%mp_physics_dfi .NE. NUWRF4ICESCHEME_DFI ) THEN
870 grid%re_cloud(:,:,:) = 0.
871 grid%re_ice(:,:,:) = 0.
872 grid%re_snow(:,:,:) = 0.
874 ELSE IF ( grid%mp_physics_dfi .EQ. NUWRF4ICESCHEME_DFI ) THEN
875 grid%re_cloud_gsfc(:,:,:) = 0.
876 grid%re_rain_gsfc(:,:,:) = 0.
877 grid%re_ice_gsfc(:,:,:) = 0.
878 grid%re_snow_gsfc(:,:,:) = 0.
879 grid%re_graupel_gsfc(:,:,:) = 0.
880 grid%re_hail_gsfc(:,:,:) = 0.
884 ! print *,'In dfi_clear_accumulation, clear dfi_QV - dfi_savehydmeteors=1'
885 grid%dfi_moist(:,:,:,P_QV) = 0.
887 if ( grid%sf_surface_physics .EQ. RUCLSMSCHEME ) then
888 ! grid%dfi_qvg(:,:) = 0.
893 grid%hcoeff_tot = 0.0
895 END SUBROUTINE dfi_clear_accumulation
898 SUBROUTINE dfi_save_arrays( grid )
900 USE module_domain, ONLY : domain
901 ! USE module_configure
902 ! USE module_driver_constants
905 USE module_model_constants
906 USE module_state_description
910 INTEGER :: its, ite, jts, jte, kts, kte, &
914 TYPE(domain) , POINTER :: grid
917 REAL es,qs,pol,tx,temp,pres,rslf
920 ! save surface 2-D fields
921 grid%dfi_SNOW(:,:) = grid%SNOW(:,:)
922 grid%dfi_SNOWH(:,:) = grid%SNOWH(:,:)
923 grid%dfi_SNOWC(:,:) = grid%SNOWC(:,:)
924 grid%dfi_CANWAT(:,:) = grid%CANWAT(:,:)
925 grid%dfi_TSK(:,:) = grid%TSK(:,:)
928 grid%dfi_TSLB(:,:,:) = grid%TSLB(:,:,:)
929 grid%dfi_SMOIS(:,:,:) = grid%SMOIS(:,:,:)
930 ! RUC LSM only, need conditional
931 IF ( grid%sf_surface_physics .EQ. RUCLSMSCHEME ) then
932 grid%dfi_QVG(:,:) = grid%QVG(:,:)
933 grid%dfi_SOILT1(:,:) = grid%SOILT1(:,:)
934 ! use this array to save initial mu_2
935 ! grid%dfi_TSNAV(:,:) = (grid%c1h(k)*grid%mu_2(:,:))
936 grid%dfi_TSNAV(:,:) = grid%TSNAV(:,:)
937 grid%dfi_SMFR3D(:,:,:) = grid%SMFR3D(:,:,:)
938 grid%dfi_KEEPFR3DFLAG(:,:,:) = grid%KEEPFR3DFLAG(:,:,:)
943 ! save hydrometeor and scalar fields
944 IF ( grid%dfi_savehydmeteors .EQ. 1 ) then !tgs
945 ! print *,'In dfi_save_arrays - save initial hydrometeors'
946 ! print *,'SAVE n_moist,PARAM_FIRST_SCALAR,P_QV,P_QC,P_QR,P_QI,P_QS,P_QG', &
947 ! n_moist,PARAM_FIRST_SCALAR,P_QV,P_QC,P_QR,P_QI,P_QS,P_QG
949 DO nm=PARAM_FIRST_SCALAR+1,n_moist
950 grid%dfi_moist(:,:,:,nm)=max(0.,grid%moist(:,:,:,nm))
952 grid%dfi_scalar(:,:,:,:) = max(0.,grid%scalar(:,:,:,:))
955 if(grid%dfi_stage .EQ. DFI_BCK) then
956 ! compute initial RH field to be reintroduced after the diabatic DFI
957 its = grid%sp31 ; ite = grid%ep31 ;
958 kts = grid%sp32 ; kte = grid%ep32 ;
959 jts = grid%sp33 ; jte = grid%ep33 ;
963 if ( grid%use_theta_m .EQ. 1 ) then
964 temp = (grid%t_2(i,k,j)+t0) / (1. + R_v/R_d*grid%moist(i,k,j,P_Qv)) * &
965 ( (grid%p(i,k,j)+grid%pb(i,k,j))/p1000mb ) ** (r_d / Cp)
967 temp = (grid%t_2(i,k,j)+t0) * &
968 ( (grid%p(i,k,j)+grid%pb(i,k,j))/p1000mb ) ** (r_d / Cp)
970 pres = grid%p(i,k,j)+grid%pb(i,k,j)
971 !tgs rslf - function to compute qs from Thompson microphysics
972 qs = rslf(pres, temp)
973 ! if(i.eq. 464 .and. j.eq. 212 .and. k.eq.6) then
974 ! print *,'temp,pres,qs-thomp',temp,pres,qs
977 !! es=svp1*10.*EXP(svp2*(temp-svpt0)/(temp-svp3))
978 !! qs=0.622*es/(pres/100.-es)
980 ! if(i.eq. 464 .and. j.eq. 212 .and. k.eq.6) then
981 ! print *,'temp,pres,qs-wrf',temp,pres,qs
984 POL = 0.99999683 + TX*(-0.90826951E-02 + &
985 TX*(0.78736169E-04 + TX*(-0.61117958E-06 + &
986 TX*(0.43884187E-08 + TX*(-0.29883885E-10 + &
987 TX*(0.21874425E-12 + TX*(-0.17892321E-14 + &
988 TX*(0.11112018E-16 + TX*(-0.30994571E-19)))))))))
990 !! qs = 0.62197*es / (pres/100. - es*0.37803)
991 ! if(i.eq. 464 .and. j.eq. 212 .and. k.eq.6) then
992 ! print *,'temp,pres,qs-ruc',temp,pres,qs
995 grid%dfi_rh (i,k,j) = MIN(1.,MAX(0.,grid%moist(i,k,j,P_QV)/qs))
996 ! if(i.eq. 464 .and. j.eq. 212 .and. k.eq.6) then
997 ! print *,'temp,pres,qs,grid%moist (i,k,j,P_QV),grid%dfi_rh (i,k,j)',temp,pres,qs, &
998 ! grid%moist(i,k,j,P_QV),grid%dfi_rh (i,k,j)
1001 !tgs saturation check for points with water or ice clouds
1002 IF ((grid%moist (i,k,j,P_QC) .GT. 1.e-6 .or. &
1003 grid%moist (i,k,j,P_QI) .GT. 1.e-6) .and. &
1004 grid%dfi_rh (i,k,j) .lt. 1.) THEN
1005 grid%dfi_rh (i,k,j)=1.
1015 END SUBROUTINE dfi_save_arrays
1018 SUBROUTINE dfcoef (NSTEPS,DT,TAUC,NFILT,H)
1020 ! calculate filter weights with selected window.
1022 ! peter lynch and xiang-yu huang
1024 ! ref: see hamming, r.w., 1989: digital filters,
1025 ! prentice-hall international. 3rd edition.
1027 ! input: nsteps - number of timesteps
1028 ! forward or backward.
1029 ! dt - time step in seconds.
1030 ! tauc - cut-off period in seconds.
1031 ! nfilt - indicator for selected filter.
1033 ! output: h - array(0:nsteps) with the
1034 ! required filter weights
1036 !------------------------------------------------------------
1040 integer, intent(in) :: nsteps, nfilt
1041 real , intent(in) :: dt, tauc
1042 real, intent(out) :: h(1:nsteps+1)
1047 real :: pi, omegac, x, window, deltat
1048 real :: hh(0:nsteps)
1053 ! windows are defined by a call and held in hh.
1055 if ( nfilt .eq. -1) call debug (nsteps,h)
1057 IF ( NFILT .EQ. 0 ) CALL UNIFORM (NSTEPS,HH)
1058 #if ( WRFPLUS == 1 )
1059 IF ( NFILT .EQ. 1 ) CALL LANCZOS_ (NSTEPS,HH)
1061 IF ( NFILT .EQ. 1 ) CALL LANCZOS (NSTEPS,HH)
1063 IF ( NFILT .EQ. 2 ) CALL HAMMING (NSTEPS,HH)
1064 IF ( NFILT .EQ. 3 ) CALL BLACKMAN (NSTEPS,HH)
1065 IF ( NFILT .EQ. 4 ) CALL KAISER (NSTEPS,HH)
1066 IF ( NFILT .EQ. 5 ) CALL POTTER2 (NSTEPS,HH)
1067 IF ( NFILT .EQ. 6 ) CALL DOLPHWIN (NSTEPS,HH)
1069 IF ( NFILT .LE. 6 ) THEN ! sinc-windowed filters
1071 ! calculate the cutoff frequency
1076 IF ( N .EQ. 0 ) THEN
1077 X = (OMEGAC*DELTAT/PI)
1079 X = SIN(N*OMEGAC*DELTAT)/(N*PI)
1084 ! normalize the sums to be unity
1085 CALL NORMLZ(HH,NSTEPS)
1088 H(N+1) = HH(NSTEPS-N)
1091 ELSE IF ( NFILT .EQ. 7 ) THEN ! dolph filter
1093 CALL DOLPH(DT,TAUC,NSTEPS,H)
1095 ELSE IF ( NFILT .EQ. 8 ) THEN ! 2nd order, 2nd type quick start filter (RHO)
1097 CALL RHOFIL(DT,TAUC,2,NSTEPS*2,2,H,NSTEPS)
1103 END SUBROUTINE dfcoef
1106 SUBROUTINE NORMLZ(HH,NMAX)
1108 ! normalize the sum of hh to be unity
1112 integer, intent(in) :: nmax
1113 real , dimension(0:nmax), intent(out) :: hh
1121 SUMHH = SUMHH + 2*HH(N)
1129 END subroutine normlz
1132 subroutine debug(nsteps, ww)
1136 integer, intent(in) :: nsteps
1137 real , dimension(0:nsteps), intent(out) :: ww
1148 end subroutine debug
1151 SUBROUTINE UNIFORM(NSTEPS,WW)
1153 ! define uniform or rectangular window function.
1157 integer, intent(in) :: nsteps
1158 real , dimension(0:nsteps), intent(out) :: ww
1168 END subroutine uniform
1171 #if ( WRFPLUS == 1 )
1172 SUBROUTINE LANCZOS_(NSTEPS,WW)
1174 SUBROUTINE LANCZOS(NSTEPS,WW)
1177 ! define (genaralised) lanczos window function.
1181 integer, parameter :: nmax = 1000
1182 integer, intent(in) :: nsteps
1183 real , dimension(0:nmax), intent(out) :: ww
1185 real :: power, pi, w
1187 ! (for the usual lanczos window, power = 1 )
1192 IF ( N .EQ. 0 ) THEN
1195 W = SIN(N*PI/(NSTEPS+1)) / ( N*PI/(NSTEPS+1))
1202 #if ( WRFPLUS == 1 )
1203 END SUBROUTINE lanczos_
1205 END SUBROUTINE lanczos
1209 SUBROUTINE HAMMING(NSTEPS,WW)
1211 ! define (genaralised) hamming window function.
1215 integer, intent(in) :: nsteps
1216 real, dimension(0:nsteps) :: ww
1218 real :: alpha, pi, w
1220 ! (for the usual hamming window, alpha=0.54,
1221 ! for the hann window, alpha=0.50).
1226 IF ( N .EQ. 0 ) THEN
1229 W = ALPHA + (1-ALPHA)*COS(N*PI/(NSTEPS))
1236 END SUBROUTINE hamming
1239 SUBROUTINE BLACKMAN(NSTEPS,WW)
1241 ! define blackman window function.
1245 integer, intent(in) :: nsteps
1246 real, dimension(0:nsteps) :: ww
1253 IF ( N .EQ. 0 ) THEN
1256 W = 0.42 + 0.50*COS( N*PI/(NSTEPS)) &
1257 + 0.08*COS(2*N*PI/(NSTEPS))
1264 END SUBROUTINE blackman
1267 SUBROUTINE KAISER(NSTEPS,WW)
1269 ! define kaiser window function.
1273 real, external :: bessi0
1275 integer, intent(in) :: nsteps
1276 real, dimension(0:nsteps) :: ww
1278 real :: alpha, xi0a, xn, as
1282 XI0A = BESSI0(ALPHA)
1285 AS = ALPHA*SQRT(1.-(XN/NSTEPS)**2)
1286 WW(N) = BESSI0(AS) / XI0A
1291 END SUBROUTINE kaiser
1294 REAL FUNCTION BESSI0(X)
1296 ! from numerical recipes (press, et al.)
1301 real(8) :: P1 = 1.0d0
1302 real(8) :: P2 = 3.5156230D0
1303 real(8) :: P3 = 3.0899424D0
1304 real(8) :: P4 = 1.2067492D0
1305 real(8) :: P5 = 0.2659732D0
1306 real(8) :: P6 = 0.360768D-1
1307 real(8) :: P7 = 0.45813D-2
1309 real*8 :: Q1 = 0.39894228D0
1310 real*8 :: Q2 = 0.1328592D-1
1311 real*8 :: Q3 = 0.225319D-2
1312 real*8 :: Q4 = -0.157565D-2
1313 real*8 :: Q5 = 0.916281D-2
1314 real*8 :: Q6 = -0.2057706D-1
1315 real*8 :: Q7 = 0.2635537D-1
1316 real*8 :: Q8 = -0.1647633D-1
1317 real*8 :: Q9 = 0.392377D-2
1322 IF (ABS(X).LT.3.75) THEN
1324 BESSI0=P1+Y*(P2+Y*(P3+Y*(P4+Y*(P5+Y*(P6+Y*P7)))))
1328 BESSI0=(EXP(AX)/SQRT(AX))*(Q1+Y*(Q2+Y*(Q3+Y*(Q4 &
1329 +Y*(Q5+Y*(Q6+Y*(Q7+Y*(Q8+Y*Q9))))))))
1336 SUBROUTINE POTTER2(NSTEPS,WW)
1338 ! define potter window function.
1339 ! modified to fall off over twice the range.
1343 integer, intent(in) :: nsteps
1344 real, dimension(0:nsteps),intent(out) :: ww
1346 real :: ck, sum, arg
1349 real, dimension(0:3) :: d
1362 IF (N.EQ.NSTEPS) CK = 0.5
1363 ARG = PI*FLOAT(N)/FLOAT(NSTEPS)
1364 !min--- modification in next statement
1366 !min--- end of modification
1369 SUM = SUM + 2.*D(IP)*COS(ARG*FLOAT(IP))
1376 END SUBROUTINE potter2
1379 SUBROUTINE dolphwin(m, window)
1381 ! calculation of dolph-chebyshev window or, for short,
1382 ! dolph window, using the expression in the reference:
1384 ! antoniou, andreas, 1993: digital filters: analysis,
1385 ! design and applications. mcgraw-hill, inc., 689pp.
1387 ! the dolph window is optimal in the following sense:
1388 ! for a given main-lobe width, the stop-band attenuation
1389 ! is minimal; for a given stop-band level, the main-lobe
1392 ! it is possible to specify either the ripple-ratio r
1393 ! or the stop-band edge thetas.
1398 INTEGER, INTENT(IN) :: m
1399 REAL, DIMENSION(0:M), INTENT(OUT) :: window
1402 REAL, DIMENSION(0:2*M) :: t
1403 REAL, DIMENSION(0:M) :: w, time
1404 REAL :: pi, thetas, x0, term1, term2, rr, r, db, sum, arg
1405 INTEGER :: n, nm1, nt, i
1412 X0 = 1/COS(THETAS/2)
1414 TERM1 = (X0 + SQRT(X0**2-1))**(FLOAT(N-1))
1415 TERM2 = (X0 - SQRT(X0**2-1))**(FLOAT(N-1))
1416 RR = 0.5*(TERM1+TERM2)
1419 WRITE(*,'(1X,''DOLPH: M,N='',2I8)')M,N
1420 WRITE(*,'(1X,''DOLPH: THETAS (STOP-BAND EDGE)='',F10.3)')THETAS
1421 WRITE(*,'(1X,''DOLPH: R,DB='',2F10.3)')R, DB
1426 ARG = X0*COS(I*PI/N)
1427 CALL CHEBY(T,NM1,ARG)
1429 TERM2 = COS(2*NT*PI*I/N)
1430 SUM = SUM + 2*TERM1*TERM2
1436 ! fill up the array for return
1443 END SUBROUTINE dolphwin
1446 SUBROUTINE dolph(deltat, taus, m, window)
1448 ! calculation of dolph-chebyshev window or, for short,
1449 ! dolph window, using the expression in the reference:
1451 ! antoniou, andreas, 1993: digital filters: analysis,
1452 ! design and applications. mcgraw-hill, inc., 689pp.
1454 ! the dolph window is optimal in the following sense:
1455 ! for a given main-lobe width, the stop-band attenuation
1456 ! is minimal; for a given stop-band level, the main-lobe
1462 INTEGER, INTENT(IN) :: m
1463 REAL, DIMENSION(0:M), INTENT(OUT) :: window
1464 REAL, INTENT(IN) :: deltat, taus
1467 integer, PARAMETER :: NMAX = 5000
1468 REAL, dimension(0:NMAX) :: t, w, time
1469 real, dimension(0:2*nmax) :: w2
1470 INTEGER :: NPRPE=0 ! no of pe
1473 real :: pi, thetas, x0, term1, term2, rr, r,db, sum, arg, sumw
1474 integer :: n, nm1, i, nt
1478 WRITE (mes,'(A,F8.2,A,F10.2)') 'In dolph, deltat = ',deltat,' taus = ',taus
1479 CALL wrf_message(TRIM(mes))
1484 THETAS = 2*PI*ABS(DELTAT/TAUS)
1485 X0 = 1/COS(THETAS/2)
1486 TERM1 = (X0 + SQRT(X0**2-1))**(FLOAT(N-1))
1487 TERM2 = (X0 - SQRT(X0**2-1))**(FLOAT(N-1))
1488 RR = 0.5*(TERM1+TERM2)
1492 WRITE (mes,'(A,2I8)') 'In dolph: M,N = ', M,N
1493 CALL wrf_message(TRIM(mes))
1494 WRITE (mes,'(A,F10.3)') 'In dolph: THETAS (STOP-BAND EDGE) = ', thetas
1495 CALL wrf_message(TRIM(mes))
1496 WRITE (mes,'(A,2F10.3)') 'In dolph: R,DB = ', R,DB
1497 CALL wrf_message(TRIM(mes))
1502 ARG = X0*COS(I*PI/N)
1503 CALL CHEBY(T,NM1,ARG)
1505 TERM2 = COS(2*NT*PI*I/N)
1506 SUM = SUM + R*2*TERM1*TERM2
1510 WRITE (mes,'(A,F10.6,2x,E17.7)') 'In dolph: TIME, W = ', TIME(NT), W(NT)
1511 CALL wrf_message(TRIM(mes))
1513 ! fill in the negative-time values by symmetry.
1519 ! fill up the array for return
1522 SUMW = SUMW + W2(NT)
1524 WRITE (mes,'(A,F10.4)') 'In dolph: SUM OF WEIGHTS W2 = ', sumw
1525 CALL wrf_message(TRIM(mes))
1533 END SUBROUTINE dolph
1536 SUBROUTINE cheby(t, n, x)
1538 ! calculate all chebyshev polynomials up to order n
1539 ! for the argument value x.
1541 ! reference: numerical recipes, page 184, recurrence
1542 ! t_n(x) = 2xt_{n-1}(x) - t_{n-2}(x) , n>=2.
1547 INTEGER, INTENT(IN) :: n
1548 REAL, INTENT(IN) :: x
1549 REAL, DIMENSION(0:N) :: t
1557 T(NN) = 2*X*T(NN-1) - T(NN-2)
1562 END SUBROUTINE cheby
1565 SUBROUTINE rhofil(dt, tauc, norder, nstep, ictype, frow, nosize)
1567 ! RHO = recurssive high order.
1569 ! This routine calculates and returns the
1570 ! Last Row, FROW, of the FILTER matrix.
1573 ! DT : Time Step in seconds
1574 ! TAUC : Cut-off period (hours)
1575 ! NORDER : Order of QS Filter
1576 ! NSTEP : Number of step/Size of row.
1577 ! ICTYPE : Initial Conditions
1578 ! NOSIZE : Max. side of FROW.
1581 ! ACOEF : X-coefficients of filter
1582 ! BCOEF : Y-coefficients of filter
1583 ! FILTER : Filter Matrix.
1585 ! Output Parameters:
1586 ! FROW : Last Row of Filter Matrix.
1588 ! Note: Two types of initial conditions are permitted.
1589 ! ICTYPE = 1 : Order increasing each row to NORDER.
1590 ! ICTYPE = 2 : Order fixed at NORDER throughout.
1592 ! DOUBLE PRECISION USED THROUGHOUT.
1594 IMPLICIT DOUBLE PRECISION (A-H,O-Z)
1596 DOUBLE PRECISION MUC
1598 ! N.B. Single Precision for List Parameters.
1599 REAL, intent(in) :: DT,TAUC
1601 ! Space for the last row of FILTER.
1602 integer, intent(in) :: norder, nstep, ictype, nosize
1603 REAL , dimension(0:nosize), intent(out):: FROW
1605 ! Arrays for rho filter.
1606 integer, PARAMETER :: NOMAX=100
1607 real , dimension(0:NOMAX) :: acoef, bcoef
1608 real , dimension(0:NOMAX,0:NOMAX) :: filter
1610 real , dimension(0:NOMAX) :: alpha, beta
1618 ! Filtering Parameters (derived).
1619 THETAC = 2*PI*DTT/(TAUC)
1635 ! Fill up the Filter Matrix.
1638 ! Get the coefficients of the Filter.
1639 IF ( ICTYPE.eq.2 ) THEN
1640 CALL RHOCOF(NORDER,NOMAX,MUC, ACOEF,BCOEF)
1645 IF ( ICTYPE.eq.1 ) THEN
1646 NORD = MIN(NROW,NORDER)
1647 IF ( NORD.le.NORDER) THEN
1648 CALL RHOCOF(NORD,NOMAX,MUC, ACOEF,BCOEF)
1653 ALPHA(K) = ACOEF(NROW-K)
1654 IF(K.lt.NROW) BETA(K) = BCOEF(NROW-K)
1657 ! Correction for terms of negative index.
1658 IF ( ICTYPE.eq.2 ) THEN
1659 IF ( NROW.lt.NORDER ) THEN
1662 CN = CN + (ACOEF(NN)+BCOEF(NN))
1664 ALPHA(0) = ALPHA(0) + CN
1668 ! Check sum of ALPHAs and BETAs = 1
1671 SUMAB = SUMAB + ALPHA(NN)
1672 IF(NN.lt.NROW) SUMAB = SUMAB + BETA(NN)
1678 SUMBF = SUMBF + BETA(LL)*FILTER(LL,KK)
1680 FILTER(NROW,KK) = ALPHA(KK)+SUMBF
1682 FILTER(NROW,NROW) = ALPHA(NROW)
1684 ! Check sum of row elements = 1
1687 SUMROW = SUMROW + FILTER(NROW,NN)
1693 FROW(NC) = FILTER(NSTEP,NC)
1698 END SUBROUTINE rhofil
1701 SUBROUTINE rhocof(nord, nomax, muc, ca, cb)
1703 ! Get the coefficients of the RHO Filter
1705 ! IMPLICIT DOUBLE PRECISION (A-H,O-Z)
1709 integer, intent(in) :: nord, nomax
1710 real, dimension(0:nomax) :: ca, cb
1713 double precision, external :: cnr
1718 DOUBLE PRECISION :: MUC, ZN
1719 DOUBLE PRECISION :: pi, root2, rn, sigma, gain, sumcof
1726 SIGMA = 1./( SQRT(2.**RN-1.) )
1728 GAIN = (MUC*SIGMA/(1+MUC*SIGMA))**NORD
1729 ZN = (1-MUC*SIGMA)/(1+MUC*SIGMA)
1732 CA(NN) = CNR(NORD,NN)*GAIN
1733 IF(NN.gt.0) CB(NN) = -CNR(NORD,NN)*(-ZN)**NN
1736 ! Check sum of coefficients = 1
1739 SUMCOF = SUMCOF + CA(NN)
1740 IF(NN.gt.0) SUMCOF = SUMCOF + CB(NN)
1745 END SUBROUTINE RHOCOF
1748 DOUBLE PRECISION FUNCTION cnr(n,r)
1750 ! Binomial Coefficient (n,r).
1752 ! IMPLICIT DOUBLE PRECISION(C,X)
1756 INTEGER , intent(in) :: n, R
1760 DOUBLE PRECISION :: coeff, xn, xr, xk
1771 COEFF = COEFF * ( (XN-XR+XK)/XK )
1780 SUBROUTINE optfil (grid,NH,DELTAT,NHMAX)
1781 !----------------------------------------------------------------------
1783 ! SUBROUTINE optfil (NH,DELTAT,TAUP,TAUS,LPRINT, &
1786 ! - Huang and Lynch optimal filter
1787 ! Monthly Weather Review, Feb 1993
1788 !----------------------------------------------------------
1789 ! Input Parameters in List:
1790 ! NH : Half-length of the Filter
1791 ! DELTAT : Time-step (in seconds).
1792 ! TAUP : Period of pass-band edge (hours).
1793 ! TAUS : Period of stop-band edge (hours).
1794 ! LPRINT : Logical switch for messages.
1795 ! NHMAX : Maximum permitted Half-length.
1797 ! Output Parameters in List:
1798 ! H : Impulse Response.
1799 ! DP : Deviation in pass-band (db)
1800 ! DS : Deviation in stop-band (db)
1801 !----------------------------------------------------------
1803 USE module_domain, ONLY : domain
1805 TYPE(domain) , POINTER :: grid
1807 REAL,DIMENSION( 20) :: EDGE
1808 REAL,DIMENSION( 10) :: FX, WTX, DEVIAT
1809 REAL,DIMENSION(2*NHMAX+1) :: H
1811 REAL, INTENT (IN) :: DELTAT
1812 INTEGER, INTENT (IN) :: NH, NHMAX
1825 print *,' start optfil, NFILT=', nfilt
1828 ! 930325 PL & XYH : the upper limit is changed from 64 to 128.
1829 IF(NFILT.LE.0 .OR. NFILT.GT.128 ) THEN
1831 CALL wrf_error_fatal (' Sorry, error 1 in call to OPTFIL ')
1834 ! The following four should always be the same.
1840 ! calculate transition frequencies.
1842 FS = DT/(TAUS*3600.)
1843 FP = DT/(TAUP*3600.)
1845 ! print *,' FS too large in OPTFIL '
1846 CALL wrf_error_fatal (' FS too large in OPTFIL ')
1850 ! print *, ' FP too small in OPTFIL '
1851 CALL wrf_error_fatal (' FP too small in OPTFIL ')
1855 ! Relative Weights in pass- and stop-bands.
1859 !CC NOTE: (FP,FC,FS) is an arithmetic progression, so
1860 !CC (1/FS,1/FC,1/FP) is a harmonic one.
1861 !CC TAUP = 1/( (1/TAUC)-(1/DTAU) )
1862 !CC TAUS = 1/( (1/TAUC)+(1/DTAU) )
1863 !CC TAUC : Cut-off Period (hours).
1864 !CC DTAU : Transition half-width (hours).
1865 !CC FC = 1/TAUC ; DF = 1/DTAU
1866 !CC FP = FC - DF : FS = FC + DF
1869 TAUC = 2./((1/TAUS)+(1/TAUP))
1870 DTAU = 2./((1/TAUS)-(1/TAUP))
1871 FC = DT/(TAUC*3600.)
1872 DF = DT/(DTAU*3600.)
1873 WRITE(6,*) ' DT ' , dt
1874 WRITE(6,*) ' TAUS, TAUP ' , TAUS,TAUP
1875 WRITE(6,*) ' TAUC, DTAU ' , TAUC,DTAU
1876 WRITE(6,*) ' FP, FS ' , FP, FS
1877 WRITE(6,*) ' FC, DF ' , FC, DF
1878 WRITE(6,*) ' WTS, WTP ' , WTS, WTP
1881 ! Fill the control vectors for MCCPAR
1891 CALL MCCPAR(NFILT,JTYPE,NBANDS,LPRINT,LGRID, &
1892 EDGE,FX,WTX,DEVIAT, h )
1894 ! Save the deviations in the pass- and stop-bands.
1898 ! Fill out the array H (only first half filled in MCCPAR).
1899 IF(MOD(NFILT,2).EQ.0) THEN
1905 H(NFILT+1-nn) = h(nn)
1908 ! normalize the sums to be unity
1913 print *,'SUMH =', sumh
1921 ! print *,'HCOEFF(n) ', grid%hcoeff
1923 END SUBROUTINE optfil
1926 SUBROUTINE MCCPAR (NFILT,JTYPE,NBANDS,LPRINT,LGRID, &
1927 EDGE,FX,WTX,DEVIAT,h )
1929 ! PROGRAM FOR THE DESIGN OF LINEAR PHASE FINITE IMPULSE
1930 ! REPONSE (FIR) FILTERS USING THE REMEZ EXCHANGE ALGORITHM
1932 !************************************************************
1933 !* Reference: McClellan, J.H., T.W. Parks and L.R.Rabiner, *
1934 !* 1973: A computer program for designing *
1935 !* optimum FIR linear phase digital filters. *
1936 !* IEEE Trans. on Audio and Electroacoustics, *
1937 !* Vol AU-21, No. 6, 506-526. *
1938 !************************************************************
1940 ! THREE TYPES OF FILTERS ARE INCLUDED -- BANDPASS FILTERS
1941 ! DIFFERENTIATORS, AND HILBERT TRANSFORM FILTERS
1943 !---------------------------------------------------------------
1945 ! COMMON /x3x/ PI2,AD,DEV,X,Y,GRID,DES,WT,ALPHA,IEXT,NFCNS,NGRID
1946 DIMENSION IEXT(66),AD(66),ALPHA(66),X(66),Y(66)
1948 DIMENSION DES(1045),GRID(1045),WT(1045)
1949 DIMENSION EDGE(20),FX(10),WTX(10),DEVIAT(10)
1950 DOUBLE PRECISION PI2,PI
1951 DOUBLE PRECISION AD,DEV,X,Y
1954 PI = 3.141592653589793
1955 PI2 = 6.283185307179586
1962 ! PROGRAM INPUT SECTION
1964 !CC READ(5,*) NFILT,JTYPE,NBANDS,JPRINT,LGRID
1966 IF(NFILT.GT.NFMAX.OR.NFILT.LT.3) THEN
1967 CALL wrf_error_fatal (' **** ERROR IN INPUT DATA ****' )
1969 IF(NBANDS.LE.0) NBANDS = 1
1973 IF(LGRID.LE.0) LGRID = 16
1975 !cc READ(5,*) (EDGE(J),J=1,JB)
1976 !cc READ(5,*) (FX(J),J=1,NBANDS)
1977 !cc READ(5,*) (WTX(J),J=1,NBANDS)
1979 CALL wrf_error_fatal (' **** ERROR IN INPUT DATA ****' )
1982 IF(JTYPE.EQ.1) NEG = 0
1986 IF(NODD.EQ.1.AND.NEG.EQ.0) NFCNS = NFCNS+1
1993 IF(NEG.EQ.0) GOTO 135
1994 IF(EDGE(1).LT.DELF) GRID(1) = DELF
2004 DES(J) = EFF(TEMP,FX,WTX,LBAND,JTYPE)
2005 WT(J) = WATE(TEMP,FX,WTX,LBAND,JTYPE)
2008 IF(GRID(J).GT.FUP) GOTO 150
2011 DES(J-1) = EFF(FUP,FX,WTX,LBAND,JTYPE)
2012 WT(J-1) = WATE(FUP,FX,WTX,LBAND,JTYPE)
2015 IF(LBAND.GT.NBANDS) GOTO 160
2019 IF(NEG.NE.NODD) GOTO 165
2020 IF(GRID(NGRID).GT.(0.5-DELF)) NGRID = NGRID-1
2026 170 IF(NODD.EQ.1) GOTO 200
2028 CHANGE = DCOS(PI*GRID(J))
2029 DES(J) = DES(J)/CHANGE
2030 WT(J) = WT(J)*CHANGE
2033 180 IF(NODD.EQ.1) GOTO 190
2035 CHANGE = DSIN(PI*GRID(J))
2036 DES(J) = DES(J)/CHANGE
2037 WT(J) = WT(J)*CHANGE
2040 190 DO 195 J =1,NGRID
2041 CHANGE = DSIN(PI2*GRID(J))
2042 DES(J) = DES(J)/CHANGE
2043 WT(J) = WT(J)*CHANGE
2048 200 TEMP = FLOAT(NGRID-1)/FLOAT(NFCNS)
2050 IEXT(J) = (J-1)*TEMP+1
2052 IEXT(NFCNS+1) = NGRID
2056 ! CALL THE REMEZ EXCHANGE ALGORITHM TO DO THE APPROXIMATION PROBLEM
2058 CALL REMEZ(EDGE,NBANDS,PI2,AD,DEV,X,Y,GRID,DES,WT,ALPHA,IEXT,NFCNS,NGRID)
2060 ! CALCULATE THE IMPULSE RESPONSE
2063 300 IF(NODD.EQ.0) GOTO 310
2065 H(J) = 0.5*ALPHA(NZ-J)
2069 310 H(1) = 0.25*ALPHA(NFCNS)
2071 H(J) = 0.25*(ALPHA(NZ-J)+ALPHA(NFCNS+2-J))
2073 H(NFCNS) = 0.5*ALPHA(1)+0.25*ALPHA(2)
2075 320 IF(NODD.EQ.0) GOTO 330
2076 H(1) = 0.25*ALPHA(NFCNS)
2077 H(2) = 0.25*ALPHA(NM1)
2079 H(J) = 0.25*(ALPHA(NZ-J)-ALPHA(NFCNS+3-J))
2081 H(NFCNS) = 0.5*ALPHA(1)-0.25*ALPHA(3)
2084 330 H(1) = 0.25*ALPHA(NFCNS)
2086 H(J) = 0.25*(ALPHA(NZ-J)-ALPHA(NFCNS+2-J))
2088 H(NFCNS) = 0.5*ALPHA(1)-0.25*ALPHA(2)
2090 ! PROGRAM OUTPUT SECTION
2096 print *, '****************************************************'
2097 print *, 'FINITE IMPULSE RESPONSE (FIR)'
2098 print *, 'LINEAR PHASE DIGITAL FILTER DESIGN'
2099 print *, 'REMEZ EXCHANGE ALGORITHM'
2101 IF(JTYPE.EQ.1) WRITE(6,365)
2102 365 FORMAT(25X,'BANDPASS FILTER'/)
2104 IF(JTYPE.EQ.2) WRITE(6,370)
2105 370 FORMAT(25X,'DIFFERENTIATOR '/)
2107 IF(JTYPE.EQ.3) WRITE(6,375)
2108 375 FORMAT(25X,'HILBERT TRANSFORMER '/)
2111 378 FORMAT(15X,'FILTER LENGTH =',I3/)
2114 380 FORMAT(15X,'***** IMPULSE RESPONSE *****')
2118 IF(NEG.EQ.0) WRITE(6,382) J,H(J),K
2119 IF(NEG.EQ.1) WRITE(6,383) J,H(J),K
2121 382 FORMAT(20X,'H(',I3,') = ',E15.8,' = H(',I4,')')
2122 383 FORMAT(20X,'H(',I3,') = ',E15.8,' = -H(',I4,')')
2124 IF(NEG.EQ.1.AND.NODD.EQ.1) WRITE(6,384) NZ
2125 384 FORMAT(20X,'H(',I3,') = 0.0')
2129 IF(KUP.GT.NBANDS) KUP = NBANDS
2131 WRITE(6,385) (J,J=K,KUP)
2132 385 FORMAT(24X,4('BAND',I3,8X))
2133 WRITE(6,390) (EDGE(2*J-1),J=K,KUP)
2134 390 FORMAT(2X,'LOWER BAND EDGE',5F15.8)
2135 WRITE(6,395) (EDGE(2*J),J=K,KUP)
2136 395 FORMAT(2X,'UPPER BAND EDGE',5F15.8)
2137 IF(JTYPE.NE.2) WRITE(6,400) (FX(J),J=K,KUP)
2138 400 FORMAT(2X,'DESIRED VALUE',2X,5F15.8)
2139 IF(JTYPE.EQ.2) WRITE(6,405) (FX(J),J=K,KUP)
2140 405 FORMAT(2X,'DESIRED SLOPE',2X,5F15.8)
2141 WRITE(6,410) (WTX(J),J=K,KUP)
2142 410 FORMAT(2X,'WEIGHTING',6X,5F15.8)
2144 DEVIAT(J) = DEV/WTX(J)
2146 WRITE(6,425) (DEVIAT(J),J=K,KUP)
2147 425 FORMAT(2X,'DEVIATION',6X,5F15.8)
2148 IF(JTYPE.NE.1) GOTO 450
2150 DEVIAT(J) = 20.0*ALOG10(DEVIAT(J))
2152 WRITE(6,435) (DEVIAT(J),J=K,KUP)
2153 435 FORMAT(2X,'DEVIATION IN DB',5F15.8)
2155 print *, 'EXTREMAL FREQUENCIES'
2156 WRITE(6,455) (GRID(IEXT(J)),J=1,NZ)
2157 455 FORMAT((2X,5F15.7))
2159 460 FORMAT(1X,70(1H*))
2163 !CC IF(NFILT.NE.0) GOTO 100 ! removal of re-run loop.
2165 END SUBROUTINE mccpar
2168 FUNCTION EFF(TEMP,FX,WTX,LBAND,JTYPE)
2169 DIMENSION FX(5),WTX(5)
2170 IF(JTYPE.EQ.2) GOTO 1
2173 1 EFF = FX(LBAND)*TEMP
2177 FUNCTION WATE(TEMP,FX,WTX,LBAND,JTYPE)
2178 DIMENSION FX(5),WTX(5)
2179 IF(JTYPE.EQ.2) GOTO 1
2182 1 IF(FX(LBAND).LT.0.0001) GOTO 2
2183 WATE = WTX(LBAND)/TEMP
2190 !! WRITE(6,*)' **** ERROR IN INPUT DATA ****'
2191 ! CALL wrf_error_fatal (' **** ERROR IN INPUT DATA ****' )
2192 ! END SUBROUTINE error
2195 SUBROUTINE REMEZ(EDGE,NBANDS,PI2,AD,DEV,X,Y,GRID,DES,WT,ALPHA,IEXT,NFCNS,NGRID)
2196 ! THIS SUBROUTINE IMPLEMENTS THE REMEZ EXCHANGE ALGORITHM
2197 ! FOR THE WEIGHTED CHEBCHEV APPROXIMATION OF A CONTINUOUS
2198 ! FUNCTION WITH A SUM OF COSINES. INPUTS TO THE SUBROUTINE
2199 ! ARE A DENSE GRID WHICH REPLACES THE FREQUENCY AXIS, THE
2200 ! DESIRED FUNCTION ON THIS GRID, THE WEIGHT FUNCTION ON THE
2201 ! GRID, THE NUMBER OF COSINES, AND THE INITIAL GUESS OF THE
2202 ! EXTREMAL FREQUENCIES. THE PROGRAM MINIMIZES THE CHEBYSHEV
2203 ! ERROR BY DETERMINING THE BEST LOCATION OF THE EXTREMAL
2204 ! FREQUENCIES (POINTS OF MAXIMUM ERROR) AND THEN CALCULATES
2205 ! THE COEFFICIENTS OF THE BEST APPROXIMATION.
2207 ! COMMON /x3x/ PI2,AD,DEV,X,Y,GRID,DES,WT,ALPHA,IEXT,NFCNS,NGRID
2209 DIMENSION IEXT(66),AD(66),ALPHA(66),X(66),Y(66)
2210 DIMENSION DES(1045),GRID(1045),WT(1045)
2211 DIMENSION A(66),P(65),Q(65)
2212 DOUBLE PRECISION PI2,DNUM,DDEN,DTEMP,A,P,Q
2213 DOUBLE PRECISION AD,DEV,X,Y
2214 DOUBLE PRECISION, EXTERNAL :: D, GEE
2216 ! THE PROGRAM ALLOWS A MAXIMUM NUMBER OF ITERATIONS OF 25
2226 IF(NITER.GT.ITRMAX) GO TO 400
2229 DTEMP=DCOS(DTEMP*PI2)
2233 120 AD(J)=D(J,NZ,JET,X)
2246 IF(DEV.GT.0.0) NU=-1
2254 IF(DEV.GE.DEVL) GO TO 150
2255 WRITE(6,*) ' ******** FAILURE TO CONVERGE *********** '
2256 WRITE(6,*) ' PROBABLE CAUSE IS MACHINE ROUNDING ERROR '
2257 WRITE(6,*) ' THE IMPULSE RESPONSE MAY BE CORRECT '
2258 WRITE(6,*) ' CHECK WITH A FREQUENCY RESPONSE '
2259 WRITE(6,*) ' **************************************** '
2269 ! SEARCH FOR THE EXTERMAL FREQUENCIES OF THE BEST
2272 200 IF(J.EQ.NZZ) YNZ=COMP
2273 IF(J.GE.NZZ) GO TO 300
2279 IF(L.GE.KUP) GO TO 220
2280 ERR=GEE(L,NZ,GRID,PI2,X,Y,AD)
2281 ERR=(ERR-DES(L))*WT(L)
2283 IF(DTEMP.LE.0.0) GO TO 220
2286 IF(L.GE.KUP) GO TO 215
2287 ERR=GEE(L,NZ,GRID,PI2,X,Y,AD)
2288 ERR=(ERR-DES(L))*WT(L)
2290 IF(DTEMP.LE.0.0) GO TO 215
2300 IF(L.LE.KLOW) GO TO 250
2301 ERR=GEE(L,NZ,GRID,PI2,X,Y,AD)
2302 ERR=(ERR-DES(L))*WT(L)
2304 IF(DTEMP.GT.0.0) GO TO 230
2305 IF(JCHNGE.LE.0) GO TO 225
2309 IF(L.LE.KLOW) GO TO 240
2310 ERR=GEE(L,NZ,GRID,PI2,X,Y,AD)
2311 ERR=(ERR-DES(L))*WT(L)
2313 IF(DTEMP.LE.0.0) GO TO 240
2322 IF(JCHNGE.GT.0) GO TO 215
2324 IF(L.GE.KUP) GO TO 260
2325 ERR=GEE(L,NZ,GRID,PI2,X,Y,AD)
2326 ERR=(ERR-DES(L))*WT(L)
2328 IF(DTEMP.LE.0.0) GO TO 255
2334 300 IF(J.GT.NZZ) GO TO 320
2335 IF(K1.GT.IEXT(1)) K1=IEXT(1)
2336 IF(KNZ.LT.IEXT(NZ)) KNZ=IEXT(NZ)
2344 IF(L.GE.KUP) GO TO 315
2345 ERR=GEE(L,NZ,GRID,PI2,X,Y,AD)
2346 ERR=(ERR-DES(L))*WT(L)
2348 IF(DTEMP.LE.0.0) GO TO 310
2354 320 IF(LUCK.GT.9) GO TO 350
2355 IF(COMP.GT.Y1) Y1=COMP
2362 IF(L.LE.KLOW) GO TO 340
2363 ERR=GEE(L,NZ,GRID,PI2,X,Y,AD)
2364 ERR=(ERR-DES(L))*WT(L)
2366 IF(DTEMP.LE.0.0) GO TO 330
2371 340 IF(LUCK.EQ.6) GO TO 370
2373 345 IEXT(NZZ-J)=IEXT(NZ-J)
2378 360 IEXT(J)=IEXT(J+1)
2381 370 IF(JCHNGE.GT.0) GO TO 100
2383 ! CALCULATION OF THE COEFFICIENTS OF THE BEST APPROXIMATION
2384 ! USING THE INVERSE DISCRETE FOURIER TRANSFORM.
2395 IF(EDGE(1).EQ.0.0.AND.EDGE(2*NBANDS).EQ.0.5) KKK=1
2396 IF(NFCNS.LE.3) KKK=1
2397 IF(KKK.EQ.1) GO TO 405
2398 DTEMP=DCOS(PI2*GRID(1))
2399 DNUM=DCOS(PI2*GRID(NGRID))
2401 BB=-(DTEMP+DNUM)/(DTEMP-DNUM)
2406 IF(KKK.EQ.1) GO TO 410
2408 ! original : FT=ARCOS(XT)/PI2
2411 IF(XT.GT.XE) GO TO 420
2412 IF((XE-XT).LT.FSH) GO TO 415
2417 420 IF((XT-XE).LT.FSH) GO TO 415
2419 A(J)=GEE(1,NZ,GRID,PI2,X,Y,AD)
2428 IF(NM1.LT.1) GO TO 505
2430 500 DTEMP=DTEMP+A(K+1)*DCOS(DNUM*K)
2431 505 DTEMP=2.0*DTEMP+A(1)
2434 550 ALPHA(J)=2*ALPHA(J)/CN
2435 ALPHA(1)=ALPHA(1)/CN
2436 IF(KKK.EQ.1) GO TO 545
2437 P(1)=2.0*ALPHA(NFCNS)*BB+ALPHA(NM1)
2438 P(2)=2.0*AA*ALPHA(NFCNS)
2439 Q(1)=ALPHA(NFCNS-2)-ALPHA(NFCNS)
2441 IF(J.LT.NM1) GO TO 515
2448 520 P(K)=2.0*BB*A(K)
2449 P(2)=P(2)+A(1)*2.0*AA
2452 525 P(K)=P(K)+Q(K)+AA*A(K+1)
2455 530 P(K)=P(K)+AA*A(K-1)
2456 IF(J.EQ.NM1) GO TO 540
2459 Q(1)=Q(1)+ALPHA(NFCNS-1-J)
2464 IF(NFCNS.GT.3) RETURN
2467 END SUBROUTINE remez
2469 DOUBLE PRECISION FUNCTION D(K,N,M,X)
2470 ! COMMON /x3x/ PI2,AD,DEV,X,Y,GRID,DES,WT,ALPHA,IEXT,NFCNS,NGRID
2471 DIMENSION IEXT(66),AD(66),ALPHA(66),X(66),Y(66)
2472 DIMENSION DES(1045),GRID(1045),WT(1045)
2473 DOUBLE PRECISION AD,DEV,X,Y
2475 DOUBLE PRECISION PI2
2481 1 D = 2.0*D*(Q-X(J))
2488 DOUBLE PRECISION FUNCTION GEE(K,N,GRID,PI2,X,Y,AD)
2489 ! COMMON /x3x/ PI2,AD,DEV,X,Y,GRID,DES,WT,ALPHA,IEXT,NFCNS,NGRID
2490 DIMENSION IEXT(66),AD(66),ALPHA(66),X(66),Y(66)
2491 DIMENSION DES(1045),GRID(1045),WT(1045)
2492 DOUBLE PRECISION AD,DEV,X,Y
2493 DOUBLE PRECISION P,C,D,XF
2494 DOUBLE PRECISION PI2
2508 !+---+-----------------------------------------------------------------+
2509 ! THIS FUNCTION CALCULATES THE LIQUID SATURATION VAPOR MIXING RATIO AS
2510 ! A FUNCTION OF TEMPERATURE AND PRESSURE in Thompson microphysics
2513 REAL FUNCTION RSLF(P,T)
2516 REAL, INTENT(IN):: P, T
2518 REAL, PARAMETER:: C0= .611583699E03
2519 REAL, PARAMETER:: C1= .444606896E02
2520 REAL, PARAMETER:: C2= .143177157E01
2521 REAL, PARAMETER:: C3= .264224321E-1
2522 REAL, PARAMETER:: C4= .299291081E-3
2523 REAL, PARAMETER:: C5= .203154182E-5
2524 REAL, PARAMETER:: C6= .702620698E-8
2525 REAL, PARAMETER:: C7= .379534310E-11
2526 REAL, PARAMETER:: C8=-.321582393E-13
2528 X=MAX(-80.,T-273.16)
2530 ! ESL=612.2*EXP(17.67*X/(T-29.65))
2531 ESL=C0+X*(C1+X*(C2+X*(C3+X*(C4+X*(C5+X*(C6+X*(C7+X*C8)))))))
2532 RSLF=.622*ESL/(P-ESL)
2535 !+---+-----------------------------------------------------------------+
2536 ! THIS FUNCTION CALCULATES THE ICE SATURATION VAPOR MIXING RATIO AS A
2537 ! FUNCTION OF TEMPERATURE AND PRESSURE
2539 REAL FUNCTION RSIF(P,T)
2542 REAL, INTENT(IN):: P, T
2544 REAL, PARAMETER:: C0= .609868993E03
2545 REAL, PARAMETER:: C1= .499320233E02
2546 REAL, PARAMETER:: C2= .184672631E01
2547 REAL, PARAMETER:: C3= .402737184E-1
2548 REAL, PARAMETER:: C4= .565392987E-3
2549 REAL, PARAMETER:: C5= .521693933E-5
2550 REAL, PARAMETER:: C6= .307839583E-7
2551 REAL, PARAMETER:: C7= .105785160E-9
2552 REAL, PARAMETER:: C8= .161444444E-12
2554 X=MAX(-80.,T-273.16)
2555 ESI=C0+X*(C1+X*(C2+X*(C3+X*(C4+X*(C5+X*(C6+X*(C7+X*C8)))))))
2556 RSIF=.622*ESI/(P-ESI)
2559 ! ; Source: Murphy and Koop, Review of the vapour pressure of ice and
2560 ! supercooled water for atmospheric applications, Q. J. R.
2561 ! Meteorol. Soc (2005), 131, pp. 1539-1565.
2562 ! ESI = EXP(9.550426 - 5723.265/T + 3.53068*ALOG(T) - 0.00728332*T)
2565 !+---+-----------------------------------------------------------------+
2568 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2569 ! DFI startfwd group of functions
2570 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2572 SUBROUTINE wrf_dfi_startfwd_init ( )
2574 USE module_domain, ONLY : domain, head_grid, domain_get_stop_time, domain_get_start_time, set_current_grid_ptr
2580 SUBROUTINE dfi_startfwd_init_recurse(grid)
2581 USE module_domain, ONLY : domain
2582 TYPE (domain), POINTER :: grid
2583 END SUBROUTINE dfi_startfwd_init_recurse
2586 ! Now, setup all nests
2588 CALL dfi_startfwd_init_recurse(head_grid)
2590 CALL set_current_grid_ptr( head_grid )
2592 END SUBROUTINE wrf_dfi_startfwd_init
2595 RECURSIVE SUBROUTINE dfi_startfwd_init_recurse(grid)
2597 USE module_domain, ONLY : domain, head_grid, domain_get_stop_time, domain_get_start_time, max_nests, set_current_grid_ptr
2602 SUBROUTINE dfi_startfwd_init(grid)
2603 USE module_domain, ONLY : domain
2604 TYPE (domain), POINTER :: grid
2605 END SUBROUTINE dfi_startfwd_init
2609 TYPE (domain), POINTER :: grid
2610 TYPE (domain), POINTER :: grid_ptr
2614 DO WHILE ( ASSOCIATED( grid_ptr ) )
2616 ! Assure that time-step is set back to positive
2617 ! for this forward step.
2619 grid_ptr%dt = abs(grid_ptr%dt)
2620 grid_ptr%time_step = abs(grid_ptr%time_step)
2621 CALL set_current_grid_ptr( grid_ptr )
2622 CALL dfi_startfwd_init( grid_ptr )
2623 DO kid = 1, max_nests
2624 IF ( ASSOCIATED( grid_ptr%nests(kid)%ptr ) ) THEN
2625 CALL dfi_startfwd_init_recurse(grid_ptr%nests(kid)%ptr)
2628 grid_ptr => grid_ptr%sibling
2631 END SUBROUTINE dfi_startfwd_init_recurse
2634 SUBROUTINE dfi_startfwd_init ( grid )
2636 USE module_domain, ONLY : domain, head_grid, domain_get_stop_time, domain_get_start_time
2638 USE module_state_description
2642 TYPE (domain) , POINTER :: grid
2646 SUBROUTINE Setup_Timekeeping(grid)
2647 USE module_domain, ONLY : domain
2648 TYPE (domain), POINTER :: grid
2649 END SUBROUTINE Setup_Timekeeping
2653 grid%dfi_stage = DFI_STARTFWD
2656 ! No need for adaptive time-step
2657 CALL nl_set_use_adaptive_time_step( grid%id, .false. )
2660 CALL Setup_Timekeeping (grid)
2661 grid%start_subtime = domain_get_start_time ( head_grid )
2662 grid%stop_subtime = domain_get_stop_time ( head_grid )
2664 CALL WRFU_ClockSet(grid%domain_clock, currTime=grid%start_subtime, rc=rc)
2666 END SUBROUTINE dfi_startfwd_init
2668 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2669 ! DFI startbck group of functions
2670 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2672 SUBROUTINE wrf_dfi_startbck_init ( )
2674 USE module_domain, ONLY : domain, head_grid, domain_get_stop_time, domain_get_start_time, set_current_grid_ptr
2680 SUBROUTINE dfi_startbck_init_recurse(grid)
2681 USE module_domain, ONLY : domain
2682 TYPE (domain), POINTER :: grid
2683 END SUBROUTINE dfi_startbck_init_recurse
2686 ! Now, setup all nests
2688 CALL dfi_startbck_init_recurse(head_grid)
2690 CALL set_current_grid_ptr( head_grid )
2692 END SUBROUTINE wrf_dfi_startbck_init
2695 RECURSIVE SUBROUTINE dfi_startbck_init_recurse(grid)
2697 USE module_domain, ONLY : domain, head_grid, domain_get_stop_time, domain_get_start_time, max_nests, set_current_grid_ptr
2702 SUBROUTINE dfi_startbck_init(grid)
2703 USE module_domain, ONLY : domain
2704 TYPE (domain), POINTER :: grid
2705 END SUBROUTINE dfi_startbck_init
2709 TYPE (domain), POINTER :: grid
2710 TYPE (domain), POINTER :: grid_ptr
2714 DO WHILE ( ASSOCIATED( grid_ptr ) )
2716 ! Assure that time-step is set back to positive
2717 ! for this forward step.
2719 grid_ptr%dt = abs(grid_ptr%dt)
2720 grid_ptr%time_step = abs(grid_ptr%time_step)
2721 CALL set_current_grid_ptr( grid_ptr )
2722 CALL dfi_startbck_init( grid_ptr )
2723 DO kid = 1, max_nests
2724 IF ( ASSOCIATED( grid_ptr%nests(kid)%ptr ) ) THEN
2725 CALL dfi_startbck_init_recurse(grid_ptr%nests(kid)%ptr)
2728 grid_ptr => grid_ptr%sibling
2731 END SUBROUTINE dfi_startbck_init_recurse
2734 SUBROUTINE dfi_startbck_init ( grid )
2736 USE module_domain, ONLY : domain, head_grid, domain_get_stop_time, domain_get_start_time
2738 USE module_state_description
2742 TYPE (domain) , POINTER :: grid
2746 SUBROUTINE Setup_Timekeeping(grid)
2747 USE module_domain, ONLY : domain
2748 TYPE (domain), POINTER :: grid
2749 END SUBROUTINE Setup_Timekeeping
2753 grid%dfi_stage = DFI_STARTBCK
2755 ! set physics options to zero
2756 CALL nl_set_mp_physics( grid%id, 0 )
2757 CALL nl_set_ra_lw_physics( grid%id, 0 )
2758 CALL nl_set_ra_sw_physics( grid%id, 0 )
2759 CALL nl_set_sf_surface_physics( grid%id, 0 )
2760 CALL nl_set_sf_sfclay_physics( grid%id, 0 )
2761 CALL nl_set_sf_urban_physics( grid%id, 0 )
2762 CALL nl_set_bl_pbl_physics( grid%id, 0 )
2763 CALL nl_set_cu_physics( grid%id, 0 )
2764 CALL nl_set_cu_diag( grid%id, 0 )
2765 CALL nl_set_damp_opt( grid%id, 0 )
2766 CALL nl_set_sst_update( grid%id, 0 )
2768 CALL nl_set_sf_ocean_physics( grid%id, 0 )
2770 CALL nl_set_gwd_opt( grid%id, 0 )
2772 CALL nl_set_diff_6th_opt( grid%id, 0 )
2773 CALL nl_set_use_adaptive_time_step( grid%id, .false. )
2775 CALL nl_set_feedback( grid%id, 0 )
2778 CALL nl_set_constant_bc( grid%id, head_grid%constant_bc)
2781 #if ( WRF_CHEM == 1 )
2782 ! set chemistry option to zero
2783 CALL nl_set_chem_opt (grid%id, 0)
2784 CALL nl_set_aer_ra_feedback (grid%id, 0)
2785 CALL nl_set_io_form_auxinput5 (grid%id, 0)
2786 CALL nl_set_io_form_auxinput6 (grid%id, 0)
2787 CALL nl_set_io_form_auxinput7 (grid%id, 0)
2788 CALL nl_set_io_form_auxinput8 (grid%id, 0)
2789 CALL nl_set_io_form_auxinput13 (grid%id, 0)
2790 CALL nl_set_io_form_auxinput14 (grid%id, 0)
2791 CALL nl_set_io_form_auxinput15 (grid%id, 0)
2795 ! set diffusion to zero for backward integration
2796 grid%km_opt_dfi = grid%km_opt
2797 grid%diff_opt_dfi = grid%diff_opt
2798 CALL nl_set_km_opt( grid%id, grid%km_opt_dfi)
2799 CALL nl_set_diff_opt( grid%id, grid%diff_opt_dfi)
2800 CALL nl_set_moist_adv_dfi_opt( grid%id, grid%moist_adv_dfi_opt)
2801 CALL nl_set_moist_adv_opt( grid%id,grid%moist_adv_dfi_opt)
2804 ! If a request to do pressure level diags, then shut it off
2805 ! until we get to the real forecast part of this integration.
2808 CALL nl_set_p_lev_diags( grid%id, grid%p_lev_diags_dfi)
2811 !tgs need to call start_domain here to reset bc initialization for
2812 ! negative dt, but only for outer domain.
2813 if (grid%id == 1) then
2814 CALL start_domain ( grid , .TRUE. )
2817 ! Call wrf_run to advance forward 1 step
2820 CALL nl_set_time_step ( grid%id, -grid%time_step )
2822 CALL Setup_Timekeeping (grid)
2824 grid%start_subtime = domain_get_start_time ( grid )
2825 grid%stop_subtime = domain_get_stop_time ( grid )
2827 CALL WRFU_ClockSet(grid%domain_clock, currTime=grid%start_subtime, rc=rc)
2829 END SUBROUTINE dfi_startbck_init
2832 SUBROUTINE wrf_dfi_bck_init ( )
2834 USE module_domain, ONLY : domain, head_grid, domain_get_stop_time, domain_get_start_time
2836 USE module_state_description
2841 SUBROUTINE dfi_bck_init_recurse(grid)
2842 USE module_domain, ONLY : domain
2843 TYPE (domain), POINTER :: grid
2844 END SUBROUTINE dfi_bck_init_recurse
2847 ! We can only call dfi_bck_init for the head_grid
2848 ! since nests have not been instantiated at this point,
2849 ! so, dfi_bck_init will need to be called for each
2850 ! nest from integrate.
2851 CALL dfi_bck_init_recurse(head_grid)
2853 END SUBROUTINE wrf_dfi_bck_init
2855 RECURSIVE SUBROUTINE dfi_bck_init_recurse(grid)
2857 USE module_domain, ONLY : domain, domain_get_stop_time, domain_get_start_time, max_nests, set_current_grid_ptr
2862 SUBROUTINE dfi_bck_init(grid)
2863 USE module_domain, ONLY : domain
2864 TYPE (domain), POINTER :: grid
2865 END SUBROUTINE dfi_bck_init
2869 TYPE (domain), POINTER :: grid
2870 TYPE (domain), POINTER :: grid_ptr
2874 DO WHILE ( ASSOCIATED( grid_ptr ) )
2876 ! Assure that time-step is set back to positive
2877 ! for this forward step.
2879 grid_ptr%dt = abs(grid_ptr%dt)
2880 grid_ptr%time_step = abs(grid_ptr%time_step)
2881 CALL set_current_grid_ptr( grid_ptr )
2882 CALL dfi_bck_init( grid_ptr )
2883 DO kid = 1, max_nests
2884 IF ( ASSOCIATED( grid_ptr%nests(kid)%ptr ) ) THEN
2885 CALL dfi_bck_init_recurse(grid_ptr%nests(kid)%ptr)
2888 grid_ptr => grid_ptr%sibling
2891 END SUBROUTINE dfi_bck_init_recurse
2893 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2894 ! DFI forward initialization group of functions
2895 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2897 SUBROUTINE wrf_dfi_fwd_init ( )
2899 USE module_domain, ONLY : domain, head_grid, domain_get_stop_time, domain_get_start_time, set_current_grid_ptr
2905 SUBROUTINE dfi_fwd_init_recurse(grid)
2906 USE module_domain, ONLY : domain
2907 TYPE (domain), POINTER :: grid
2908 END SUBROUTINE dfi_fwd_init_recurse
2911 ! Now, setup all nests
2913 CALL dfi_fwd_init_recurse(head_grid)
2915 CALL set_current_grid_ptr( head_grid )
2917 END SUBROUTINE wrf_dfi_fwd_init
2919 RECURSIVE SUBROUTINE dfi_fwd_init_recurse(grid)
2921 USE module_domain, ONLY : domain, head_grid, domain_get_stop_time, domain_get_start_time, max_nests, set_current_grid_ptr
2926 SUBROUTINE dfi_fwd_init(grid)
2927 USE module_domain, ONLY : domain
2928 TYPE (domain), POINTER :: grid
2929 END SUBROUTINE dfi_fwd_init
2933 TYPE (domain), POINTER :: grid
2934 TYPE (domain), POINTER :: grid_ptr
2938 DO WHILE ( ASSOCIATED( grid_ptr ) )
2940 ! Assure that time-step is set back to positive
2941 ! for this forward step.
2943 grid_ptr%dt = abs(grid_ptr%dt)
2944 grid_ptr%time_step = abs(grid_ptr%time_step)
2945 CALL set_current_grid_ptr( grid_ptr )
2946 CALL dfi_fwd_init( grid_ptr )
2947 DO kid = 1, max_nests
2948 IF ( ASSOCIATED( grid_ptr%nests(kid)%ptr ) ) THEN
2949 CALL dfi_fwd_init_recurse(grid_ptr%nests(kid)%ptr)
2952 grid_ptr => grid_ptr%sibling
2955 END SUBROUTINE dfi_fwd_init_recurse
2957 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2958 ! DFI forecast initialization group of functions
2959 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2961 SUBROUTINE wrf_dfi_fst_init ( )
2963 USE module_domain, ONLY : domain, head_grid, domain_get_stop_time, domain_get_start_time, set_current_grid_ptr
2969 SUBROUTINE dfi_fst_init_recurse(grid)
2970 USE module_domain, ONLY : domain
2971 TYPE (domain), POINTER :: grid
2972 END SUBROUTINE dfi_fst_init_recurse
2975 ! Now, setup all nests
2977 CALL dfi_fst_init_recurse(head_grid)
2979 CALL set_current_grid_ptr( head_grid )
2981 END SUBROUTINE wrf_dfi_fst_init
2983 RECURSIVE SUBROUTINE dfi_fst_init_recurse ( grid )
2985 USE module_domain, ONLY : domain, domain_get_stop_time, domain_get_start_time, max_nests, set_current_grid_ptr
2990 SUBROUTINE dfi_fst_init(grid)
2991 USE module_domain, ONLY : domain
2992 TYPE (domain), POINTER :: grid
2993 END SUBROUTINE dfi_fst_init
2997 TYPE (domain), POINTER :: grid
2998 TYPE (domain), POINTER :: grid_ptr
3002 DO WHILE ( ASSOCIATED( grid_ptr ) )
3004 ! Assure that time-step is set back to positive
3005 ! for this forward step.
3007 grid_ptr%dt = abs(grid_ptr%dt)
3008 grid_ptr%time_step = abs(grid_ptr%time_step)
3009 CALL set_current_grid_ptr( grid_ptr )
3010 CALL dfi_fst_init( grid_ptr )
3011 DO kid = 1, max_nests
3012 IF ( ASSOCIATED( grid_ptr%nests(kid)%ptr ) ) THEN
3013 CALL dfi_fst_init_recurse(grid_ptr%nests(kid)%ptr)
3016 grid_ptr => grid_ptr%sibling
3019 END SUBROUTINE dfi_fst_init_recurse
3021 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3022 ! DFI write initialization group of functions
3023 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3025 SUBROUTINE wrf_dfi_write_initialized_state( )
3027 USE module_domain, ONLY : domain, head_grid
3030 SUBROUTINE dfi_write_initialized_state_recurse(grid)
3031 USE module_domain, ONLY : domain
3032 TYPE (domain), POINTER :: grid
3033 END SUBROUTINE dfi_write_initialized_state_recurse
3036 ! Now, setup all nests
3038 CALL dfi_write_initialized_state_recurse(head_grid)
3040 END SUBROUTINE wrf_dfi_write_initialized_state
3042 RECURSIVE SUBROUTINE dfi_write_initialized_state_recurse( grid )
3044 USE module_domain, ONLY : domain, max_nests
3049 SUBROUTINE dfi_write_initialized_state( grid )
3050 USE module_domain, ONLY : domain
3051 TYPE (domain), POINTER :: grid
3052 END SUBROUTINE dfi_write_initialized_state
3056 TYPE (domain), POINTER :: grid
3057 TYPE (domain), POINTER :: grid_ptr
3061 DO WHILE ( ASSOCIATED( grid_ptr ) )
3063 ! Assure that time-step is set back to positive
3064 ! for this forward step.
3066 CALL dfi_write_initialized_state( grid_ptr )
3067 DO kid = 1, max_nests
3068 IF ( ASSOCIATED( grid_ptr%nests(kid)%ptr ) ) THEN
3069 CALL dfi_write_initialized_state_recurse(grid_ptr%nests(kid)%ptr)
3072 grid_ptr => grid_ptr%sibling
3075 END SUBROUTINE dfi_write_initialized_state_recurse
3077 SUBROUTINE wrf_tdfi_write_analyzed_state( )
3079 USE module_domain, ONLY : domain, head_grid
3082 SUBROUTINE tdfi_write_analyzed_state_recurse(grid)
3083 USE module_domain, ONLY : domain
3084 TYPE (domain), POINTER :: grid
3085 END SUBROUTINE tdfi_write_analyzed_state_recurse
3088 ! Now, setup all nests
3090 CALL tdfi_write_analyzed_state_recurse(head_grid)
3092 END SUBROUTINE wrf_tdfi_write_analyzed_state
3094 RECURSIVE SUBROUTINE tdfi_write_analyzed_state_recurse( grid )
3096 USE module_domain, ONLY : domain, max_nests
3101 SUBROUTINE tdfi_write_analyzed_state( grid )
3102 USE module_domain, ONLY : domain
3103 TYPE (domain), POINTER :: grid
3104 END SUBROUTINE tdfi_write_analyzed_state
3108 TYPE (domain), POINTER :: grid
3109 TYPE (domain), POINTER :: grid_ptr
3113 DO WHILE ( ASSOCIATED( grid_ptr ) )
3115 ! Assure that time-step is set back to positive
3116 ! for this forward step.
3118 CALL tdfi_write_analyzed_state( grid_ptr )
3119 DO kid = 1, max_nests
3120 IF ( ASSOCIATED( grid_ptr%nests(kid)%ptr ) ) THEN
3121 CALL tdfi_write_analyzed_state_recurse(grid_ptr%nests(kid)%ptr)
3124 grid_ptr => grid_ptr%sibling
3127 END SUBROUTINE tdfi_write_analyzed_state_recurse
3129 RECURSIVE SUBROUTINE dfi_array_reset_recurse(grid)
3131 USE module_domain, ONLY : domain, max_nests, set_current_grid_ptr
3136 SUBROUTINE dfi_array_reset(grid)
3137 USE module_domain, ONLY : domain
3138 TYPE (domain), POINTER :: grid
3139 END SUBROUTINE dfi_array_reset
3143 TYPE (domain), POINTER :: grid
3144 TYPE (domain), POINTER :: grid_ptr
3148 DO WHILE ( ASSOCIATED( grid_ptr ) )
3149 CALL set_current_grid_ptr( grid_ptr )
3150 CALL dfi_array_reset( grid_ptr )
3151 DO kid = 1, max_nests
3152 IF ( ASSOCIATED( grid_ptr%nests(kid)%ptr ) ) THEN
3153 CALL dfi_array_reset_recurse(grid_ptr%nests(kid)%ptr)
3156 grid_ptr => grid_ptr%sibling
3159 END SUBROUTINE dfi_array_reset_recurse
3161 !-------------------------------------------------------------------
3164 SUBROUTINE rebalance_driver_dfi ( grid )
3166 USE module_domain, ONLY : domain
3170 TYPE (domain) :: grid
3172 CALL rebalance_dfi( grid &
3174 #include "actual_new_args.inc"
3178 END SUBROUTINE rebalance_driver_dfi
3180 !---------------------------------------------------------------------
3182 SUBROUTINE rebalance_dfi ( grid &
3184 #include "dummy_new_args.inc"
3187 USE module_domain, ONLY : domain
3189 USE module_state_description
3190 USE module_model_constants
3191 USE module_driver_constants
3194 USE module_comm_dm, ONLY : &
3195 HALO_EM_INIT_1_sub &
3196 ,HALO_EM_INIT_2_sub &
3197 ,HALO_EM_INIT_3_sub &
3198 ,HALO_EM_INIT_4_sub &
3205 TYPE (domain) :: grid
3207 #include "dummy_new_decl.inc"
3209 REAL :: p_surf , pd_surf, p_surf_int , pb_int , ht_hold
3210 REAL :: qvf , qvf1 , qvf2, qtot
3211 REAL :: pfu, pfd, phm
3212 REAL :: z0, z1, z2, w1, w2
3214 ! Local domain indices and counters.
3219 ids, ide, jds, jde, kds, kde, &
3220 ims, ime, jms, jme, kms, kme, &
3221 its, ite, jts, jte, kts, kte, &
3222 ips, ipe, jps, jpe, kps, kpe, &
3223 i, j, k, kk, ispe, ktf
3225 SELECT CASE ( model_data_order )
3226 CASE ( DATA_ORDER_ZXY )
3227 kds = grid%sd31 ; kde = grid%ed31 ;
3228 ids = grid%sd32 ; ide = grid%ed32 ;
3229 jds = grid%sd33 ; jde = grid%ed33 ;
3231 kms = grid%sm31 ; kme = grid%em31 ;
3232 ims = grid%sm32 ; ime = grid%em32 ;
3233 jms = grid%sm33 ; jme = grid%em33 ;
3235 kts = grid%sp31 ; kte = grid%ep31 ; ! note that tile is entire patch
3236 its = grid%sp32 ; ite = grid%ep32 ; ! note that tile is entire patch
3237 jts = grid%sp33 ; jte = grid%ep33 ; ! note that tile is entire patch
3239 CASE ( DATA_ORDER_XYZ )
3240 ids = grid%sd31 ; ide = grid%ed31 ;
3241 jds = grid%sd32 ; jde = grid%ed32 ;
3242 kds = grid%sd33 ; kde = grid%ed33 ;
3244 ims = grid%sm31 ; ime = grid%em31 ;
3245 jms = grid%sm32 ; jme = grid%em32 ;
3246 kms = grid%sm33 ; kme = grid%em33 ;
3248 its = grid%sp31 ; ite = grid%ep31 ; ! note that tile is entire patch
3249 jts = grid%sp32 ; jte = grid%ep32 ; ! note that tile is entire patch
3250 kts = grid%sp33 ; kte = grid%ep33 ; ! note that tile is entire patch
3252 CASE ( DATA_ORDER_XZY )
3253 ids = grid%sd31 ; ide = grid%ed31 ;
3254 kds = grid%sd32 ; kde = grid%ed32 ;
3255 jds = grid%sd33 ; jde = grid%ed33 ;
3257 ims = grid%sm31 ; ime = grid%em31 ;
3258 kms = grid%sm32 ; kme = grid%em32 ;
3259 jms = grid%sm33 ; jme = grid%em33 ;
3261 its = grid%sp31 ; ite = grid%ep31 ; ! note that tile is entire patch
3262 kts = grid%sp32 ; kte = grid%ep32 ; ! note that tile is entire patch
3263 jts = grid%sp33 ; jte = grid%ep33 ; ! note that tile is entire patch
3271 grid%ph_2(i,1,j) = 0.
3275 ! Base state potential temperature and inverse density (alpha = 1/rho) from
3276 ! the half eta levels and the base-profile surface pressure. Compute 1/rho
3277 ! from equation of state. The potential temperature is a perturbation from t0.
3280 ! n_moist = num_moist-1
3282 ! print *,'n_moist,PARAM_FIRST_SCALAR',n_moist,PARAM_FIRST_SCALAR
3284 DO j = jts, MIN(jte,jde-1)
3285 DO i = its, MIN(ite,ide-1)
3287 ! Integrate the hydrostatic equation (from the RHS of the bigstep vertical momentum
3288 ! equation) down from the top to get the pressure perturbation. First get the pressure
3289 ! perturbation, moisture, and inverse density (total and perturbation) at the top-most level.
3294 DO ispe=PARAM_FIRST_SCALAR,n_moist
3295 qtot = qtot + 0.5*(moist(i,kk,j,ispe)+moist(i,kk,j,ispe))
3300 grid%p(i,kk,j) = - 0.5*((grid%c1f(k)*grid%Mu_2(i,j))+qvf1*(grid%c1f(k)*grid%Mub(i,j)+grid%c2f(k)))/grid%rdnw(kk)/qvf2
3301 if ( grid%use_theta_m .EQ. 1 ) then
3304 qvf = 1.+rvovrd*moist(i,kk,j,P_QV)
3306 grid%alt(i,kk,j) = (r_d/p1000mb)*(grid%t_2(i,kk,j)+t0)*qvf* &
3307 (((grid%p(i,kk,j)+grid%pb(i,kk,j))/p1000mb)**cvpm)
3308 grid%al(i,kk,j) = grid%alt(i,kk,j) - grid%alb(i,kk,j)
3309 grid%p_hyd(i,kk,j) = grid%p(i,kk,j) + grid%pb(i,kk,j)
3311 ! Now, integrate down the column to compute the pressure perturbation, and diagnose the two
3312 ! inverse density fields (total and perturbation).
3317 DO ispe=PARAM_FIRST_SCALAR,n_moist
3318 qtot = qtot + 0.5*( moist(i,kk ,j,ispe) + moist(i,kk+1,j,ispe) )
3322 grid%p(i,kk,j) = grid%p(i,kk+1,j) - ((grid%c1f(k)*grid%Mu_2(i,j)) + &
3323 qvf1*(grid%c1f(k)*grid%Mub(i,j)+grid%c2f(k)))/qvf2/grid%rdn(kk+1)
3324 if ( grid%use_theta_m .EQ. 1 ) then
3327 qvf = 1.+rvovrd*moist(i,kk,j,P_QV)
3329 grid%alt(i,kk,j) = (r_d/p1000mb)*(grid%t_2(i,kk,j)+t0)*qvf* &
3330 (((grid%p(i,kk,j)+grid%pb(i,kk,j))/p1000mb)**cvpm)
3331 grid%al(i,kk,j) = grid%alt(i,kk,j) - grid%alb(i,kk,j)
3332 grid%p_hyd(i,kk,j) = grid%p(i,kk,j) + grid%pb(i,kk,j)
3335 ! This is the hydrostatic equation used in the model after the small timesteps. In
3336 ! the model, grid%al (inverse density) is computed from the geopotential.
3338 IF (grid%hypsometric_opt == 1) THEN
3341 grid%ph_2(i,kk,j) = grid%ph_2(i,kk-1,j) - &
3342 grid%dnw(kk-1) * ( ((grid%c1h(k)*grid%mub(i,j)+grid%c2h(k))+(grid%c1h(k)*grid%mu_2(i,j)))*grid%al(i,kk-1,j) &
3343 + (grid%c1h(k)*grid%mu_2(i,j))*grid%alb(i,kk-1,j) )
3344 grid%ph0(i,kk,j) = grid%ph_2(i,kk,j) + grid%phb(i,kk,j)
3346 ELSE IF (grid%hypsometric_opt == 2) THEN
3347 ! Alternative hydrostatic eq.: dZ = -al*p*dLOG(p), where p is
3349 ! Note that al*p approximates Rd*T and dLOG(p) does z.
3350 ! Here T varies mostly linear with z, the first-order
3351 ! integration produces better result.
3353 grid%ph_2(i,1,j) = grid%phb(i,1,j)
3355 pfu = grid%c3f(k )*(grid%MUB(i,j)+grid%MU_2(i,j)) + grid%c4f(k ) + grid%p_top
3356 pfd = grid%c3f(k-1)*(grid%MUB(i,j)+grid%MU_2(i,j)) + grid%c4f(k-1) + grid%p_top
3357 phm = grid%c3h(k-1)*(grid%MUB(i,j)+grid%MU_2(i,j)) + grid%c4h(k-1) + grid%p_top
3358 grid%ph_2(i,k,j) = grid%ph_2(i,k-1,j) + grid%alt(i,k-1,j)*phm*LOG(pfd/pfu)
3362 grid%ph_2(i,k,j) = grid%ph_2(i,k,j) - grid%phb(i,k,j)
3366 grid%ph0(i,k,j) = grid%ph_2(i,k,j) + grid%phb(i,k,j)
3370 ! update surface pressure PSFC:
3371 z0 = grid%ph0(i,1,j)/g
3372 z1 = 0.5*(grid%ph0(i,1,j)+grid%ph0(i,2,j))/g
3373 z2 = 0.5*(grid%ph0(i,2,j)+grid%ph0(i,3,j))/g
3374 w1 = (z0 - z2)/(z1 - z2)
3376 grid%psfc(i,j) = w1*(grid%p(i,1,j)+grid%pb(i,1,j))+w2*(grid%p(i,2,j)+grid%pb(i,2,j))
3381 ips = its ; ipe = ite ; jps = jts ; jpe = jte ; kps = kts ; kpe = kte
3383 # include "HALO_EM_INIT_1.inc"
3384 # include "HALO_EM_INIT_2.inc"
3385 # include "HALO_EM_INIT_3.inc"
3386 # include "HALO_EM_INIT_4.inc"
3387 # include "HALO_EM_INIT_5.inc"
3389 END SUBROUTINE rebalance_dfi
3392 !---------------------------------------------------------------------