diff --git a/Registry/Registry.EM_COMMON b/Registry/Registry.EM_COMMON index cefcbb96de..a26141794f 100644 --- a/Registry/Registry.EM_COMMON +++ b/Registry/Registry.EM_COMMON @@ -1980,6 +1980,8 @@ rconfig integer time_step_fract_num namelist,domains 1 0 rconfig integer time_step_fract_den namelist,domains 1 1 ih "time_step_fract_den" rconfig integer time_step_dfi namelist,domains 1 -1 ih "time_step_dfi" +rconfig real reasonable_time_step_ratio namelist,domains 1 6. ih "reasonable_time_step_ratio" "Any d01, real-data case with a time step ratio larger than this is stopped" + rconfig integer min_time_step namelist,domains max_domains -1 h "min_time_step" rconfig integer min_time_step_den namelist,domains max_domains 0 h "min_time_step denominator" rconfig integer max_time_step namelist,domains max_domains -1 h "max_time_step" diff --git a/dyn_em/start_em.F b/dyn_em/start_em.F index 760a523b7d..5286982518 100644 --- a/dyn_em/start_em.F +++ b/dyn_em/start_em.F @@ -126,6 +126,8 @@ SUBROUTINE start_domain_em ( grid, allowed_to_read & ! CCN for MP=18 initializatio REAL :: ccn_max_val + REAL :: dt_s, dx_km + REAL :: max_mf, max_rot_angle CALL get_ijk_from_grid ( grid , & ids, ide, jds, jde, kds, kde, & @@ -233,23 +235,59 @@ SUBROUTINE start_domain_em ( grid, allowed_to_read & first_trip_for_this_domain = .TRUE. ENDIF - ! Print out the maximum map scale factor on the coarse domain + ! Print out the maximum map scale factor on the coarse domain - IF ( ( first_trip_for_this_domain ) .AND. ( grid%id .EQ. 1 ) .AND. & - ( .NOT. config_flags%polar ) ) THEN - max_mf = grid%msft(its,jts) - DO j=jts,MIN(jde-1,jte) - DO i=its,MIN(ide-1,ite) - max_mf = MAX ( max_mf , grid%msft(i,j) ) - END DO + IF ( ( first_trip_for_this_domain ) .AND. ( grid%id .EQ. 1 ) .AND. & + ( .NOT. config_flags%polar ) ) THEN + max_mf = grid%msft(its,jts) + DO j=jts,MIN(jde-1,jte) + DO i=its,MIN(ide-1,ite) + max_mf = MAX ( max_mf , grid%msft(i,j) ) END DO + END DO #if ( defined(DM_PARALLEL) && ! defined(STUBMPI) ) - max_mf = wrf_dm_max_real ( max_mf ) + max_mf = wrf_dm_max_real ( max_mf ) #endif - WRITE ( a_message , FMT='(A,F5.2,A)' ) 'Max map factor in domain 1 = ',max_mf, & - '. Scale the dt in the model accordingly.' - CALL wrf_message ( a_message ) + WRITE ( a_message , FMT='(A,F5.2,A)' ) 'Max map factor in domain 1 = ',max_mf, & + '. Scale the dt in the model accordingly.' + CALL wrf_message ( a_message ) + END IF + +!----------------------------------------------------------------------- +! Do a gross check on the time step for the most coarse grid (not for +! adaptive time steps. If the value is significantly larger than reasonable, +! then stop immediately. Likely the user made a mistake. +! If the rule of thumb is 6 DX = DT, then anything > 10 is flagged. +! Only look at domain 1, only do this for the firt time into this routine, +! only look at real-data cases (where the map projection is not Cartesian), +! and only look at user-specified time steps (not the adaptive dt option). +!----------------------------------------------------------------------- + IF ( ( grid%id .EQ. 1 ) .AND. & + ( first_trip_for_this_domain ) .AND. & + ( config_flags%map_proj .NE. 0 ) .AND. & + ( .NOT. config_flags%use_adaptive_time_step ) ) THEN + dt_s = REAL(config_flags%time_step) + & + REAL(config_flags%time_step_fract_num) / & + REAL(config_flags%time_step_fract_den) + dx_km = MIN ( config_flags%dx , config_flags%dy ) / 1000. + WRITE (message,*) 'D01: Time step = ',dt_s ,' (s)' + CALL wrf_message ( TRIM(message) ) + WRITE (message,*) 'D01: Grid Distance = ',dx_km ,' (km)' + CALL wrf_message ( TRIM(message) ) + WRITE (message,*) 'D01: Grid Distance Ratio dt/dx = ', dt_s / dx_km, ' (s/km)' + CALL wrf_message ( TRIM(message) ) + WRITE (message,*) 'D01: Ratio Including Maximum Map Factor = ', dt_s / (dx_km / max_mf) , ' (s/km)' + CALL wrf_message ( TRIM(message) ) + WRITE (message,*) 'D01: NML defined reasonable_time_step_ratio = ', config_flags%reasonable_time_step_ratio + CALL wrf_message ( TRIM(message) ) + IF ( dt_s / dx_km > config_flags%reasonable_time_step_ratio ) THEN + CALL wrf_message ( 'The time step is probably too large for this grid distance, reduce it.' ) + WRITE (message, * ) 'If you are sure of your settings, set reasonable_time_step_ratio in namelist.input > ' & + ,dt_s / (dx_km / max_mf) + CALL wrf_message ( TRIM(message) ) + CALL wrf_error_fatal ( '--- ERROR: Time step too large') END IF + END IF if(config_flags%cycling) then ! Clear the buckets for diagnostics at initial time diff --git a/share/input_wrf.F b/share/input_wrf.F index 38a045eab8..6b2562a9ec 100644 --- a/share/input_wrf.F +++ b/share/input_wrf.F @@ -430,6 +430,10 @@ SUBROUTINE input_wrf ( fid , grid , config_flags , switch , ierr ) #if (EM_CORE == 1) + IF ( switch .EQ. input_only ) then + CALL wrf_get_dom_ti_char ( fid , 'SIMULATION_START_DATE' , simulation_start_date , ierr ) + END IF + ! Test to make sure that the grid distances are the right size. CALL wrf_get_dom_ti_real ( fid , 'DX' , dx_compare , 1 , icnt , ierr ) @@ -1140,6 +1144,12 @@ SUBROUTINE input_wrf ( fid , grid , config_flags , switch , ierr ) CALL domain_clock_get( grid, current_time=currtime, & current_timestr=currtimestr ) #if (DA_CORE != 1) + IF ( (switch .EQ. input_only) .and. (grid%id .EQ. 1) .and. (grid%itimestep .EQ. 0) ) THEN + WRITE( wrf_err_message , * ) 'CURRENT DATE = ',TRIM( currtimestr ) + CALL wrf_message ( trim(wrf_err_message) ) + WRITE( wrf_err_message , * ) 'SIMULATION START DATE = ', simulation_start_date(1:19) + CALL wrf_message ( TRIM(wrf_err_message ) ) + END IF ! Don't perform the check for WRFVAR, as we're not passing the right dates ! around CALL domain_clockprint(150, grid, &