From 851dc0736242c49c3b64672b13db96d6a31bb625 Mon Sep 17 00:00:00 2001 From: Dave Gill Date: Tue, 12 Feb 2019 11:39:07 -0700 Subject: [PATCH 1/8] Gross check for d01 timestep TYPE: new feature KEYWORDS: time_step, dx, cfl SOURCE: internal DESCRIPTION OF CHANGES: Problem: Users accidentally forget to change the model time step when adjusting the grid distance. It sometimes takes the model a while to succomb to this ill-chosen value. Solution: The general rule of thumb is dt(s) / dx(km) <= 6. Any ratio > 10 is considered a likely error, and the code gracefully stops. Since the tests require only information from the namelist.input file, the checking takes place in check_a_mundo. LIST OF MODIFIED FILES: M share/module_check_a_mundo.F TESTS CONDUCTED: - [x] With a reasonable time step, the model processes as normal. ``` &domains time_step = 180, dx = 30000, 10000, 3333.33, dy = 30000, 10000, 3333.33, / ``` - [x] With a time step too large, the code immendiately stops. ``` &domains time_step = 330! 180, dx = 30000, 10000, 3333.33, dy = 30000, 10000, 3333.33, / ``` ``` --- ERROR: The time step is too large for this grid distance -------------- FATAL CALLED --------------- FATAL CALLED FROM FILE: LINE: 1773 NOTE: 1 namelist settings are wrong. Please check and reset these options ------------------------------------------- ``` --- share/module_check_a_mundo.F | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/share/module_check_a_mundo.F b/share/module_check_a_mundo.F index fa69562f25..5f53347816 100644 --- a/share/module_check_a_mundo.F +++ b/share/module_check_a_mundo.F @@ -66,6 +66,7 @@ SUBROUTINE check_nml_consistency !END FASDAS ! INTEGER :: count_fatal_error + REAL :: dt_s, dx_km !----------------------------------------------------------------------- ! Set up the WRF Hydro namelist option to allow dynamic allocation of @@ -1726,6 +1727,24 @@ SUBROUTINE check_nml_consistency count_fatal_error = count_fatal_error + 1 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 +! 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. +!----------------------------------------------------------------------- + IF ( .NOT. model_config_rec % use_adaptive_time_step ) THEN + dt_s = REAL(model_config_rec % time_step) + & + REAL(model_config_rec % time_step_fract_num) / & + REAL(model_config_rec % time_step_fract_den) + dx_km = MIN ( model_config_rec % dx(1) , model_config_rec % dy(1) ) / 1000. + IF ( dt_s / dx_km > 10 )THEN + CALL wrf_debug ( 0, '--- ERROR: The time step is too large for this grid distance') + count_fatal_error = count_fatal_error + 1 + END IF + END IF + !----------------------------------------------------------------------- ! Remapping namelist variables for gridded and surface fdda to aux streams 9 and 10. ! Relocated here so that the remappings are after checking the namelist for inconsistencies. From 52b722a119466302a15065e8e25d9dad18610de7 Mon Sep 17 00:00:00 2001 From: Dave Gill Date: Sat, 9 Mar 2019 11:44:56 -0700 Subject: [PATCH 2/8] Move the test from check_a_mundo to start_em, allows map_proj comparison --- Registry/Registry.EM_COMMON | 2 ++ dyn_em/start_em.F | 29 ++++++++++++++++++++++++++++- share/module_check_a_mundo.F | 19 ------------------- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/Registry/Registry.EM_COMMON b/Registry/Registry.EM_COMMON index cefcbb96de..984a38f574 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 10. 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..a2bc0edb07 100644 --- a/dyn_em/start_em.F +++ b/dyn_em/start_em.F @@ -126,6 +126,9 @@ 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, & @@ -153,6 +156,31 @@ SUBROUTINE start_domain_em ( grid, allowed_to_read & CALL wrf_error_fatal ( 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 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). +!----------------------------------------------------------------------- +print *,'dt = ',config_flags%time_step +print *,'dx = ',config_flags%dx + IF ( ( grid%id .EQ. 1 ) .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. + IF ( dt_s / dx_km > config_flags%reasonable_time_step_ratio ) THEN + WRITE (message,*) 'Time step = ',dt_s, ' (s), Grid distance = ',dx_km, ' (km)' + CALL wrf_message ( TRIM(message) ) + CALL wrf_error_fatal ( '--- ERROR: The time step is too large for this grid distance') + END IF + END IF + IF ( config_flags%polar ) THEN !write(0,*)"",__LINE__,' clat ',ips,ipe,jps,jpe !do j = jps,jpe @@ -174,7 +202,6 @@ SUBROUTINE start_domain_em ( grid, allowed_to_read & CALL wrf_message ( TRIM(alloc_err_message) ) CALL wrf_error_fatal ( 'Error allocating entire domain size of 2d array CLAT for global domain' ) END IF - CALL wrf_patch_to_global_real ( grid%clat, clat_glob, grid%domdesc, 'xy', 'xy', & ids, ide, jds, jde, 1, 1, & ims, ime, jms, jme, 1, 1, & diff --git a/share/module_check_a_mundo.F b/share/module_check_a_mundo.F index 5f53347816..fa69562f25 100644 --- a/share/module_check_a_mundo.F +++ b/share/module_check_a_mundo.F @@ -66,7 +66,6 @@ SUBROUTINE check_nml_consistency !END FASDAS ! INTEGER :: count_fatal_error - REAL :: dt_s, dx_km !----------------------------------------------------------------------- ! Set up the WRF Hydro namelist option to allow dynamic allocation of @@ -1727,24 +1726,6 @@ SUBROUTINE check_nml_consistency count_fatal_error = count_fatal_error + 1 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 -! 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. -!----------------------------------------------------------------------- - IF ( .NOT. model_config_rec % use_adaptive_time_step ) THEN - dt_s = REAL(model_config_rec % time_step) + & - REAL(model_config_rec % time_step_fract_num) / & - REAL(model_config_rec % time_step_fract_den) - dx_km = MIN ( model_config_rec % dx(1) , model_config_rec % dy(1) ) / 1000. - IF ( dt_s / dx_km > 10 )THEN - CALL wrf_debug ( 0, '--- ERROR: The time step is too large for this grid distance') - count_fatal_error = count_fatal_error + 1 - END IF - END IF - !----------------------------------------------------------------------- ! Remapping namelist variables for gridded and surface fdda to aux streams 9 and 10. ! Relocated here so that the remappings are after checking the namelist for inconsistencies. From 7a4cb3b8a114cf9cf51c3ede077cb0f13c80c586 Mon Sep 17 00:00:00 2001 From: Dave Gill Date: Sat, 9 Mar 2019 11:55:18 -0700 Subject: [PATCH 3/8] removing debugging prints, oops --- dyn_em/start_em.F | 2 -- 1 file changed, 2 deletions(-) diff --git a/dyn_em/start_em.F b/dyn_em/start_em.F index a2bc0edb07..1b2d340b1c 100644 --- a/dyn_em/start_em.F +++ b/dyn_em/start_em.F @@ -165,8 +165,6 @@ SUBROUTINE start_domain_em ( grid, allowed_to_read & ! projection is not Cartesian), and only look at user-specified time steps ! (not the adaptive dt option). !----------------------------------------------------------------------- -print *,'dt = ',config_flags%time_step -print *,'dx = ',config_flags%dx IF ( ( grid%id .EQ. 1 ) .AND. & ( config_flags%map_proj .NE. 0 ) .AND. & ( .NOT. config_flags%use_adaptive_time_step ) ) THEN From a70169e190324ac6803d71197fba156c3fb5bc7e Mon Sep 17 00:00:00 2001 From: Dave Gill Date: Sat, 9 Mar 2019 11:56:34 -0700 Subject: [PATCH 4/8] replacing blank line that was unintentionally removed --- dyn_em/start_em.F | 1 + 1 file changed, 1 insertion(+) diff --git a/dyn_em/start_em.F b/dyn_em/start_em.F index 1b2d340b1c..27563bb2b2 100644 --- a/dyn_em/start_em.F +++ b/dyn_em/start_em.F @@ -200,6 +200,7 @@ SUBROUTINE start_domain_em ( grid, allowed_to_read & CALL wrf_message ( TRIM(alloc_err_message) ) CALL wrf_error_fatal ( 'Error allocating entire domain size of 2d array CLAT for global domain' ) END IF + CALL wrf_patch_to_global_real ( grid%clat, clat_glob, grid%domdesc, 'xy', 'xy', & ids, ide, jds, jde, 1, 1, & ims, ime, jms, jme, 1, 1, & From 9bb8a8ad018c003157447a864516a1aab6fbb567 Mon Sep 17 00:00:00 2001 From: Dave Gill Date: Sat, 9 Mar 2019 11:57:22 -0700 Subject: [PATCH 5/8] sheesh with the spaces --- dyn_em/start_em.F | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dyn_em/start_em.F b/dyn_em/start_em.F index 27563bb2b2..4a58307c7e 100644 --- a/dyn_em/start_em.F +++ b/dyn_em/start_em.F @@ -200,7 +200,7 @@ SUBROUTINE start_domain_em ( grid, allowed_to_read & CALL wrf_message ( TRIM(alloc_err_message) ) CALL wrf_error_fatal ( 'Error allocating entire domain size of 2d array CLAT for global domain' ) END IF - + CALL wrf_patch_to_global_real ( grid%clat, clat_glob, grid%domdesc, 'xy', 'xy', & ids, ide, jds, jde, 1, 1, & ims, ime, jms, jme, 1, 1, & From cc295f387c2a6c54e71bce32970a37e2f6734862 Mon Sep 17 00:00:00 2001 From: Dave Gill Date: Mon, 11 Mar 2019 17:44:58 -0600 Subject: [PATCH 6/8] Add in prints towards top of printou: dt, dx, and ratio --- dyn_em/start_em.F | 84 +++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/dyn_em/start_em.F b/dyn_em/start_em.F index 4a58307c7e..5286982518 100644 --- a/dyn_em/start_em.F +++ b/dyn_em/start_em.F @@ -128,7 +128,6 @@ SUBROUTINE start_domain_em ( grid, allowed_to_read & REAL :: dt_s, dx_km - REAL :: max_mf, max_rot_angle CALL get_ijk_from_grid ( grid , & ids, ide, jds, jde, kds, kde, & @@ -156,29 +155,6 @@ SUBROUTINE start_domain_em ( grid, allowed_to_read & CALL wrf_error_fatal ( 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 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. & - ( 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. - IF ( dt_s / dx_km > config_flags%reasonable_time_step_ratio ) THEN - WRITE (message,*) 'Time step = ',dt_s, ' (s), Grid distance = ',dx_km, ' (km)' - CALL wrf_message ( TRIM(message) ) - CALL wrf_error_fatal ( '--- ERROR: The time step is too large for this grid distance') - END IF - END IF - IF ( config_flags%polar ) THEN !write(0,*)"",__LINE__,' clat ',ips,ipe,jps,jpe !do j = jps,jpe @@ -259,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 From bf18bb9d029f226d7bf5dd99c0d2ccbba0652c07 Mon Sep 17 00:00:00 2001 From: Dave Gill Date: Tue, 12 Mar 2019 17:09:29 -0600 Subject: [PATCH 7/8] Add date info to the time info at the top of the model print out --- share/input_wrf.F | 10 ++++++++++ 1 file changed, 10 insertions(+) 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, & From 5f7e72f783224da4ea73b2e92cc6b802f9670aa6 Mon Sep 17 00:00:00 2001 From: Dave Gill Date: Tue, 12 Mar 2019 17:15:22 -0600 Subject: [PATCH 8/8] reasonable time step ratio in registry is now 6, not 10 --- Registry/Registry.EM_COMMON | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Registry/Registry.EM_COMMON b/Registry/Registry.EM_COMMON index 984a38f574..a26141794f 100644 --- a/Registry/Registry.EM_COMMON +++ b/Registry/Registry.EM_COMMON @@ -1980,7 +1980,7 @@ 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 10. ih "reasonable_time_step_ratio" "Any d01, real-data case with a time step ratio larger than this is stopped" +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"