PageRenderTime 52ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/wrfv2_fire/main/nup_em.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 915 lines | 491 code | 151 blank | 273 comment | 13 complexity | ee6c0b3f4153c1d40f0e2ead8765fb72 MD5 | raw file
Possible License(s): AGPL-1.0
  1. !WRF:DRIVER_LAYER:MAIN
  2. !
  3. ! "Nest up" program in WRFV2.
  4. !
  5. ! Description:
  6. !
  7. ! The nest up (nup.exe) program reads from wrfout_d02_<date> files for
  8. ! the nest and generates wrfout_d01_<date> files for the same periods as
  9. ! are in the input files. The fields in the output are the fields in the
  10. ! input for state variables that have 'h' and 'u' in the I/O string of
  11. ! the Registry. In other words, these are the fields that are normally
  12. ! fed back from nest->parent during 2-way nesting. It will read and
  13. ! output over multiple files of nest data and generate an equivalent
  14. ! number of files of parent data. The dimensions of the fields in the
  15. ! output are the size of the nest fields divided by the nesting ratio.
  16. !
  17. ! Source file: main/nup_em.F
  18. !
  19. ! Compile with WRF: compile em_real
  20. !
  21. ! Resulting executable:
  22. !
  23. ! main/nup.exe
  24. ! -and-
  25. ! symbolic link in test/em_real/nup.exe
  26. !
  27. ! Run as: nup.exe (no arguments)
  28. !
  29. ! Namelist information:
  30. !
  31. ! Nup.exe uses the same namelist as a nested run of the wrf.exe.
  32. ! Important settings are:
  33. !
  34. ! &time_control
  35. !
  36. ! start_* <start time information for both domains>
  37. ! end_* <start time information for both domains>
  38. ! history_interval <interval between frames in input/output files>
  39. ! frames_per_outfile <number of frames in input/output files>
  40. ! io_form_history <2 for NetCDF>
  41. !
  42. ! &domains
  43. ! ...
  44. ! max_dom <number of domains; must be 2>
  45. ! e_we <col 2 is size of nested grid in west-east>
  46. ! <col 1 is ignored in the namelist>
  47. ! e_sn <col 2 is size of nested grid in south-north>
  48. ! <col 1 is ignored in the namelist>
  49. ! parent_grid_ratio <col 2 is nesting ratio in both dims>
  50. ! feedback <must be 1>
  51. ! smooth_option <recommend 0>
  52. !
  53. ! &physics
  54. ! <all options in this section should be the same
  55. ! as the run that generated the nest data>
  56. !
  57. ! created: JM 2006 01 25
  58. PROGRAM nup_em
  59. USE module_machine
  60. USE module_domain, ONLY : domain, wrfu_timeinterval, alloc_and_configure_domain, &
  61. domain_clock_set, domain_get_current_time, domain_get_stop_time, head_grid, &
  62. domain_clock_get, domain_clockadvance
  63. USE module_domain_type, ONLY : program_name
  64. USE module_streams
  65. USE module_initialize_real, only : wrfu_initialize
  66. USE module_integrate
  67. USE module_driver_constants
  68. USE module_configure, only : grid_config_rec_type, model_config_rec
  69. USE module_io_domain
  70. USE module_utility
  71. USE module_timing
  72. USE module_wrf_error
  73. #ifdef DM_PARALLEL
  74. USE module_dm
  75. #endif
  76. ! USE read_util_module
  77. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  78. !new for bc
  79. USE module_bc
  80. USE module_big_step_utilities_em
  81. USE module_get_file_names
  82. #ifdef WRF_CHEM
  83. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  84. ! for chemistry
  85. USE module_input_chem_data
  86. ! USE module_input_chem_bioemiss
  87. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  88. #endif
  89. IMPLICIT NONE
  90. ! interface
  91. INTERFACE
  92. ! mediation-supplied
  93. SUBROUTINE med_read_wrf_chem_bioemiss ( grid , config_flags)
  94. USE module_domain
  95. TYPE (domain) grid
  96. TYPE (grid_config_rec_type) config_flags
  97. END SUBROUTINE med_read_wrf_chem_bioemiss
  98. SUBROUTINE nup ( parent_grid , nested_grid, in_id, out_id, newly_opened )
  99. USE module_domain
  100. TYPE (domain), POINTER :: parent_grid, nested_grid
  101. INTEGER, INTENT(IN) :: in_id, out_id ! io units
  102. LOGICAL, INTENT(IN) :: newly_opened ! whether to add global metadata
  103. END SUBROUTINE nup
  104. END INTERFACE
  105. TYPE(WRFU_TimeInterval) :: RingInterval
  106. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  107. !new for bc
  108. INTEGER :: ids , ide , jds , jde , kds , kde
  109. INTEGER :: ims , ime , jms , jme , kms , kme
  110. INTEGER :: ips , ipe , jps , jpe , kps , kpe
  111. INTEGER :: its , ite , jts , jte , kts , kte
  112. INTEGER :: ijds , ijde , spec_bdy_width
  113. INTEGER :: i , j , k
  114. INTEGER :: time_loop_max , time_loop
  115. INTEGER :: total_time_sec , file_counter
  116. INTEGER :: julyr , julday , iswater , map_proj
  117. INTEGER :: icnt
  118. REAL :: dt , new_bdy_frq
  119. REAL :: gmt , cen_lat , cen_lon , dx , dy , truelat1 , truelat2 , moad_cen_lat , stand_lon
  120. REAL , DIMENSION(:,:,:) , ALLOCATABLE :: ubdy3dtemp1 , vbdy3dtemp1 , tbdy3dtemp1 , pbdy3dtemp1 , qbdy3dtemp1
  121. REAL , DIMENSION(:,:,:) , ALLOCATABLE :: mbdy2dtemp1
  122. REAL , DIMENSION(:,:,:) , ALLOCATABLE :: ubdy3dtemp2 , vbdy3dtemp2 , tbdy3dtemp2 , pbdy3dtemp2 , qbdy3dtemp2
  123. REAL , DIMENSION(:,:,:) , ALLOCATABLE :: mbdy2dtemp2
  124. CHARACTER(LEN=19) :: start_timestr , current_timestr , end_timestr, timestr
  125. CHARACTER(LEN=19) :: stopTimeStr
  126. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  127. INTEGER :: num_veg_cat , num_soil_top_cat , num_soil_bot_cat
  128. REAL :: time
  129. INTEGER :: rc
  130. INTEGER :: loop , levels_to_process
  131. INTEGER , PARAMETER :: max_sanity_file_loop = 100
  132. TYPE (domain) , POINTER :: keep_grid, grid_ptr, null_domain, parent_grid , nested_grid
  133. TYPE (domain) :: dummy
  134. TYPE (grid_config_rec_type) :: config_flags
  135. INTEGER :: number_at_same_level
  136. INTEGER :: time_step_begin_restart
  137. INTEGER :: max_dom , domain_id , fid , fido, fidb , idum1 , idum2 , ierr
  138. INTEGER :: status_next_var
  139. INTEGER :: debug_level
  140. LOGICAL :: newly_opened
  141. CHARACTER (LEN=19) :: date_string
  142. #ifdef DM_PARALLEL
  143. INTEGER :: nbytes
  144. INTEGER, PARAMETER :: configbuflen = 4* CONFIG_BUF_LEN
  145. INTEGER :: configbuf( configbuflen )
  146. LOGICAL , EXTERNAL :: wrf_dm_on_monitor
  147. #endif
  148. INTEGER :: idsi, in_id, out_id
  149. INTEGER :: e_sn, e_we, pgr
  150. CHARACTER (LEN=80) :: inpname , outname , bdyname
  151. CHARACTER (LEN=80) :: si_inpname
  152. CHARACTER *19 :: temp19
  153. CHARACTER *24 :: temp24 , temp24b
  154. CHARACTER *132 :: fname
  155. CHARACTER(len=24) :: start_date_hold
  156. CHARACTER (LEN=80) :: message
  157. integer :: ii
  158. #include "version_decl"
  159. ! Interface block for routine that passes pointers and needs to know that they
  160. ! are receiving pointers.
  161. INTERFACE
  162. SUBROUTINE med_feedback_domain ( parent_grid , nested_grid )
  163. USE module_domain
  164. USE module_configure
  165. TYPE(domain), POINTER :: parent_grid , nested_grid
  166. END SUBROUTINE med_feedback_domain
  167. SUBROUTINE Setup_Timekeeping( parent_grid )
  168. USE module_domain
  169. TYPE(domain), POINTER :: parent_grid
  170. END SUBROUTINE Setup_Timekeeping
  171. END INTERFACE
  172. ! Define the name of this program (program_name defined in module_domain)
  173. program_name = "NUP_EM " // TRIM(release_version) // " PREPROCESSOR"
  174. #ifdef DM_PARALLEL
  175. CALL disable_quilting
  176. #endif
  177. ! Initialize the modules used by the WRF system. Many of the CALLs made from the
  178. ! init_modules routine are NO-OPs. Typical initializations are: the size of a
  179. ! REAL, setting the file handles to a pre-use value, defining moisture and
  180. ! chemistry indices, etc.
  181. CALL init_modules(1) ! Phase 1 returns after MPI_INIT() (if it is called)
  182. #ifdef NO_LEAP_CALENDAR
  183. CALL WRFU_Initialize( defaultCalKind=WRFU_CAL_NOLEAP, rc=rc )
  184. #else
  185. CALL WRFU_Initialize( defaultCalKind=WRFU_CAL_GREGORIAN, rc=rc )
  186. #endif
  187. CALL init_modules(2) ! Phase 2 resumes after MPI_INIT() (if it is called)
  188. ! Get the NAMELIST data. This is handled in the initial_config routine. All of the
  189. ! NAMELIST input variables are assigned to the model_config_rec structure. Below,
  190. ! note for parallel processing, only the monitor processor handles the raw Fortran
  191. ! I/O, and then broadcasts the info to each of the other nodes.
  192. #ifdef DM_PARALLEL
  193. IF ( wrf_dm_on_monitor() ) THEN
  194. CALL initial_config
  195. ENDIF
  196. CALL get_config_as_buffer( configbuf, configbuflen, nbytes )
  197. CALL wrf_dm_bcast_bytes( configbuf, nbytes )
  198. CALL set_config_as_buffer( configbuf, configbuflen )
  199. CALL wrf_dm_initialize
  200. #else
  201. CALL initial_config
  202. #endif
  203. ! And here is an instance of using the information in the NAMELIST.
  204. CALL nl_get_debug_level ( 1, debug_level )
  205. CALL set_wrf_debug_level ( debug_level )
  206. ! set the specified boundary to zero so the feedback goes all the way
  207. ! to the edge of the coarse domain
  208. CALL nl_set_spec_zone( 1, 0 )
  209. ! Allocated and configure the mother domain. Since we are in the nesting down
  210. ! mode, we know a) we got a nest, and b) we only got 1 nest.
  211. NULLIFY( null_domain )
  212. !!!! set up the parent grid (for nup_em, this is the grid we do output from)
  213. CALL nl_set_shw( 1, 0 )
  214. CALL nl_set_shw( 2, 0 )
  215. CALL nl_set_i_parent_start( 2, 1 )
  216. CALL nl_set_j_parent_start( 2, 1 )
  217. CALL nl_get_e_we( 2, e_we )
  218. CALL nl_get_e_sn( 2, e_sn )
  219. CALL nl_get_parent_grid_ratio( 2, pgr )
  220. ! parent grid must cover the entire nest, which is always dimensioned a factor of 3 + 1
  221. ! so add two here temporarily, then remove later after nest is allocated.
  222. e_we = e_we / pgr + 2
  223. e_sn = e_sn / pgr + 2
  224. CALL nl_set_e_we( 1, e_we )
  225. CALL nl_set_e_sn( 1, e_sn )
  226. CALL wrf_message ( program_name )
  227. CALL wrf_debug ( 100 , 'nup_em: calling alloc_and_configure_domain coarse ' )
  228. CALL alloc_and_configure_domain ( domain_id = 1 , &
  229. grid = head_grid , &
  230. parent = null_domain , &
  231. kid = -1 )
  232. parent_grid => head_grid
  233. ! Set up time initializations.
  234. CALL Setup_Timekeeping ( parent_grid )
  235. CALL domain_clock_set( head_grid, &
  236. time_step_seconds=model_config_rec%interval_seconds )
  237. CALL model_to_grid_config_rec ( parent_grid%id , model_config_rec , config_flags )
  238. CALL set_scalar_indices_from_config ( parent_grid%id , idum1, idum2 )
  239. !!!! set up the fine grid (for nup_em, this is the grid we do input into)
  240. CALL wrf_message ( program_name )
  241. CALL wrf_debug ( 100 , 'wrf: calling alloc_and_configure_domain fine ' )
  242. CALL alloc_and_configure_domain ( domain_id = 2 , &
  243. grid = nested_grid , &
  244. parent = parent_grid , &
  245. kid = 1 )
  246. ! now that the nest is allocated, pinch off the extra two rows/columns of the parent
  247. ! note the IKJ assumption here.
  248. parent_grid%ed31 = parent_grid%ed31 - 2
  249. parent_grid%ed33 = parent_grid%ed33 - 2
  250. CALL nl_set_e_we( 1, e_we-2 )
  251. CALL nl_set_e_sn( 1, e_sn-2 )
  252. write(0,*)'after alloc_and_configure_domain ',associated(nested_grid%intermediate_grid)
  253. CALL model_to_grid_config_rec ( nested_grid%id , model_config_rec , config_flags )
  254. CALL set_scalar_indices_from_config ( nested_grid%id , idum1, idum2 )
  255. ! Set up time initializations for the fine grid.
  256. CALL Setup_Timekeeping ( nested_grid )
  257. ! Adjust the time step on the clock so that it's the same as the history interval
  258. CALL WRFU_AlarmGet( nested_grid%alarms(HISTORY_ALARM), RingInterval=RingInterval )
  259. CALL WRFU_ClockSet( nested_grid%domain_clock, TimeStep=RingInterval, rc=rc )
  260. CALL WRFU_ClockSet( parent_grid%domain_clock, TimeStep=RingInterval, rc=rc )
  261. ! Get and store the history interval from the fine grid; use for time loop
  262. ! Initialize the I/O for WRF.
  263. CALL init_wrfio
  264. ! Some of the configuration values may have been modified from the initial READ
  265. ! of the NAMELIST, so we re-broadcast the configuration records.
  266. #ifdef DM_PARALLEL
  267. CALL get_config_as_buffer( configbuf, configbuflen, nbytes )
  268. CALL wrf_dm_bcast_bytes( configbuf, nbytes )
  269. CALL set_config_as_buffer( configbuf, configbuflen )
  270. #endif
  271. ! Open the input data (wrfout_d01_xxxxxx) for reading.
  272. in_id = 0
  273. out_id = 0
  274. main_loop : DO WHILE ( domain_get_current_time(nested_grid) .LT. domain_get_stop_time(nested_grid) )
  275. IF( WRFU_AlarmIsRinging( nested_grid%alarms( HISTORY_ALARM ), rc=rc ) ) THEN
  276. CALL domain_clock_get( nested_grid, current_timestr=timestr )
  277. newly_opened = .FALSE.
  278. IF ( in_id.EQ. 0 ) THEN
  279. CALL model_to_grid_config_rec ( nested_grid%id , model_config_rec , config_flags )
  280. CALL construct_filename2a ( fname , config_flags%history_outname , nested_grid%id , 2 , timestr )
  281. CALL open_r_dataset ( in_id, TRIM(fname), nested_grid , &
  282. config_flags , 'DATASET=HISTORY' , ierr )
  283. IF ( ierr .NE. 0 ) THEN
  284. WRITE(message,*)'Failed to open ',TRIM(fname),' for reading. '
  285. CALL wrf_message(message)
  286. EXIT main_loop
  287. ENDIF
  288. CALL model_to_grid_config_rec ( parent_grid%id , model_config_rec , config_flags )
  289. CALL construct_filename2a ( fname , config_flags%history_outname , parent_grid%id , 2 , timestr )
  290. CALL open_w_dataset ( out_id, TRIM(fname), parent_grid , &
  291. config_flags , output_history, 'DATASET=HISTORY' , ierr )
  292. IF ( ierr .NE. 0 ) THEN
  293. WRITE(message,*)'Failed to open ',TRIM(fname),' for writing. '
  294. CALL wrf_message(message)
  295. EXIT main_loop
  296. ENDIF
  297. newly_opened = .TRUE.
  298. ENDIF
  299. CALL model_to_grid_config_rec ( nested_grid%id , model_config_rec , config_flags )
  300. CALL input_history ( in_id, nested_grid , config_flags , ierr )
  301. IF ( ierr .NE. 0 ) THEN
  302. WRITE(message,*)'Unable to read time ',timestr
  303. CALL wrf_message(message)
  304. EXIT main_loop
  305. ENDIF
  306. !
  307. CALL nup ( nested_grid , parent_grid, in_id, out_id, newly_opened )
  308. !
  309. CALL model_to_grid_config_rec ( parent_grid%id , model_config_rec , config_flags )
  310. CALL output_history ( out_id, parent_grid , config_flags , ierr )
  311. IF ( ierr .NE. 0 ) THEN
  312. WRITE(message,*)'Unable to write time ',timestr
  313. CALL wrf_message(message)
  314. EXIT main_loop
  315. ENDIF
  316. nested_grid%nframes(history_only) = nested_grid%nframes(history_only) + 1
  317. IF ( nested_grid%nframes(history_only) >= config_flags%frames_per_outfile ) THEN
  318. CALL model_to_grid_config_rec ( nested_grid%id , model_config_rec , config_flags )
  319. CALL close_dataset ( in_id , config_flags , "DATASET=HISTORY" )
  320. CALL model_to_grid_config_rec ( parent_grid%id , model_config_rec , config_flags )
  321. CALL close_dataset ( out_id , config_flags , "DATASET=HISTORY" )
  322. in_id = 0
  323. out_id = 0
  324. nested_grid%nframes(history_only) = 0
  325. ENDIF
  326. CALL WRFU_AlarmRingerOff( nested_grid%alarms( HISTORY_ALARM ), rc=rc )
  327. ENDIF
  328. CALL domain_clockadvance( nested_grid )
  329. CALL domain_clockadvance( parent_grid )
  330. ENDDO main_loop
  331. CALL model_to_grid_config_rec ( parent_grid%id , model_config_rec , config_flags )
  332. CALL med_shutdown_io ( parent_grid , config_flags )
  333. CALL wrf_debug ( 0 , 'nup_em: SUCCESS COMPLETE NUP_EM INIT' )
  334. ! CALL wrf_shutdown
  335. CALL WRFU_Finalize( rc=rc )
  336. END PROGRAM nup_em
  337. SUBROUTINE nup ( nested_grid, parent_grid , in_id, out_id, newly_opened )
  338. USE module_domain
  339. USE module_io_domain
  340. USE module_utility
  341. USE module_timing
  342. USE module_wrf_error
  343. !
  344. IMPLICIT NONE
  345. ! Args
  346. TYPE(domain), POINTER :: parent_grid, nested_grid
  347. INTEGER, INTENT(IN) :: in_id, out_id ! io descriptors
  348. LOGICAL, INTENT(IN) :: newly_opened ! whether to add global metadata
  349. ! Local
  350. INTEGER :: julyr , julday , iswater , map_proj
  351. INTEGER :: icnt, ierr
  352. REAL :: dt , new_bdy_frq
  353. REAL :: gmt , cen_lat , cen_lon , dx , dy , truelat1 , truelat2 , moad_cen_lat , stand_lon
  354. REAL , DIMENSION(:,:,:) , ALLOCATABLE :: ubdy3dtemp1 , vbdy3dtemp1 , tbdy3dtemp1 , pbdy3dtemp1 , qbdy3dtemp1
  355. REAL , DIMENSION(:,:,:) , ALLOCATABLE :: mbdy2dtemp1
  356. REAL , DIMENSION(:,:,:) , ALLOCATABLE :: ubdy3dtemp2 , vbdy3dtemp2 , tbdy3dtemp2 , pbdy3dtemp2 , qbdy3dtemp2
  357. REAL , DIMENSION(:,:,:) , ALLOCATABLE :: mbdy2dtemp2
  358. INTEGER :: ids , ide , jds , jde , kds , kde
  359. INTEGER :: ims , ime , jms , jme , kms , kme
  360. INTEGER :: ips , ipe , jps , jpe , kps , kpe
  361. INTEGER :: its , ite , jts , jte , kts , kte
  362. INTERFACE
  363. SUBROUTINE med_feedback_domain ( parent_grid , nested_grid )
  364. USE module_domain
  365. USE module_configure
  366. TYPE(domain), POINTER :: parent_grid , nested_grid
  367. END SUBROUTINE med_feedback_domain
  368. SUBROUTINE med_interp_domain ( parent_grid , nested_grid )
  369. USE module_domain
  370. USE module_configure
  371. TYPE(domain), POINTER :: parent_grid , nested_grid
  372. END SUBROUTINE med_interp_domain
  373. END INTERFACE
  374. IF ( newly_opened ) THEN
  375. CALL wrf_get_dom_ti_integer ( in_id , 'MAP_PROJ' , map_proj , 1 , icnt , ierr )
  376. CALL wrf_get_dom_ti_real ( in_id , 'DX' , dx , 1 , icnt , ierr )
  377. CALL wrf_get_dom_ti_real ( in_id , 'DY' , dy , 1 , icnt , ierr )
  378. CALL wrf_get_dom_ti_real ( in_id , 'CEN_LAT' , cen_lat , 1 , icnt , ierr )
  379. CALL wrf_get_dom_ti_real ( in_id , 'CEN_LON' , cen_lon , 1 , icnt , ierr )
  380. CALL wrf_get_dom_ti_real ( in_id , 'TRUELAT1' , truelat1 , 1 , icnt , ierr )
  381. CALL wrf_get_dom_ti_real ( in_id , 'TRUELAT2' , truelat2 , 1 , icnt , ierr )
  382. CALL wrf_get_dom_ti_real ( in_id , 'MOAD_CEN_LAT' , moad_cen_lat , 1 , icnt , ierr )
  383. CALL wrf_get_dom_ti_real ( in_id , 'STAND_LON' , stand_lon , 1 , icnt , ierr )
  384. ! CALL wrf_get_dom_ti_real ( in_id , 'GMT' , gmt , 1 , icnt , ierr )
  385. ! CALL wrf_get_dom_ti_integer ( in_id , 'JULYR' , julyr , 1 , icnt , ierr )
  386. ! CALL wrf_get_dom_ti_integer ( in_id , 'JULDAY' , julday , 1 , icnt , ierr )
  387. CALL wrf_get_dom_ti_integer ( in_id , 'ISWATER' , iswater , 1 , icnt , ierr )
  388. ENDIF
  389. parent_grid%fnm = nested_grid%fnm
  390. parent_grid%fnp = nested_grid%fnp
  391. parent_grid%rdnw = nested_grid%rdnw
  392. parent_grid%rdn = nested_grid%rdn
  393. parent_grid%dnw = nested_grid%dnw
  394. parent_grid%dn = nested_grid%dn
  395. parent_grid%znu = nested_grid%znu
  396. parent_grid%znw = nested_grid%znw
  397. parent_grid%zs = nested_grid%zs
  398. parent_grid%dzs = nested_grid%dzs
  399. parent_grid%p_top = nested_grid%p_top
  400. parent_grid%rdx = nested_grid%rdx * 3.
  401. parent_grid%rdy = nested_grid%rdy * 3.
  402. parent_grid%resm = nested_grid%resm
  403. parent_grid%zetatop = nested_grid%zetatop
  404. parent_grid%cf1 = nested_grid%cf1
  405. parent_grid%cf2 = nested_grid%cf2
  406. parent_grid%cf3 = nested_grid%cf3
  407. parent_grid%cfn = nested_grid%cfn
  408. parent_grid%cfn1 = nested_grid%cfn1
  409. #ifdef WRF_CHEM
  410. parent_grid%chem_opt = nested_grid%chem_opt
  411. parent_grid%chem_in_opt = nested_grid%chem_in_opt
  412. #endif
  413. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  414. ! Various sizes that we need to be concerned about.
  415. ids = parent_grid%sd31
  416. ide = parent_grid%ed31
  417. kds = parent_grid%sd32
  418. kde = parent_grid%ed32
  419. jds = parent_grid%sd33
  420. jde = parent_grid%ed33
  421. ims = parent_grid%sm31
  422. ime = parent_grid%em31
  423. kms = parent_grid%sm32
  424. kme = parent_grid%em32
  425. jms = parent_grid%sm33
  426. jme = parent_grid%em33
  427. ips = parent_grid%sp31
  428. ipe = parent_grid%ep31
  429. kps = parent_grid%sp32
  430. kpe = parent_grid%ep32
  431. jps = parent_grid%sp33
  432. jpe = parent_grid%ep33
  433. nested_grid%imask_nostag = 1
  434. nested_grid%imask_xstag = 1
  435. nested_grid%imask_ystag = 1
  436. nested_grid%imask_xystag = 1
  437. ! Interpolate from nested_grid back onto parent_grid
  438. CALL med_feedback_domain ( parent_grid , nested_grid )
  439. parent_grid%ht_int = parent_grid%ht
  440. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  441. #if 0
  442. CALL construct_filename2( si_inpname , 'wrf_real_input_em' , parent_grid%id , 2 , start_date_char )
  443. CALL wrf_debug ( 100 , 'med_sidata_input: calling open_r_dataset for ' // TRIM(si_inpname) )
  444. CALL model_to_grid_config_rec ( parent_grid%id , model_config_rec , config_flags )
  445. CALL open_r_dataset ( idsi, TRIM(si_inpname) , parent_grid , config_flags , "DATASET=INPUT", ierr )
  446. IF ( ierr .NE. 0 ) THEN
  447. CALL wrf_error_fatal( 'real: error opening wrf_real_input_em for reading: ' // TRIM (si_inpname) )
  448. END IF
  449. ! Input data.
  450. CALL wrf_debug ( 100 , 'nup_em: calling input_aux_model_input2' )
  451. CALL input_aux_model_input2 ( idsi , parent_grid , config_flags , ierr )
  452. parent_grid%ht_input = parent_grid%ht
  453. ! Close this fine grid static input file.
  454. CALL wrf_debug ( 100 , 'nup_em: closing fine grid static input' )
  455. CALL close_dataset ( idsi , config_flags , "DATASET=INPUT" )
  456. ! We need a parent grid landuse in the interpolation. So we need to generate
  457. ! that field now.
  458. IF ( ( parent_grid%ivgtyp(ips,jps) .GT. 0 ) .AND. &
  459. ( parent_grid%isltyp(ips,jps) .GT. 0 ) ) THEN
  460. DO j = jps, MIN(jde-1,jpe)
  461. DO i = ips, MIN(ide-1,ipe)
  462. parent_grid% vegcat(i,j) = parent_grid%ivgtyp(i,j)
  463. parent_grid%soilcat(i,j) = parent_grid%isltyp(i,j)
  464. END DO
  465. END DO
  466. ELSE IF ( ( parent_grid% vegcat(ips,jps) .GT. 0.5 ) .AND. &
  467. ( parent_grid%soilcat(ips,jps) .GT. 0.5 ) ) THEN
  468. DO j = jps, MIN(jde-1,jpe)
  469. DO i = ips, MIN(ide-1,ipe)
  470. parent_grid%ivgtyp(i,j) = NINT(parent_grid% vegcat(i,j))
  471. parent_grid%isltyp(i,j) = NINT(parent_grid%soilcat(i,j))
  472. END DO
  473. END DO
  474. ELSE
  475. num_veg_cat = SIZE ( parent_grid%landusef , DIM=2 )
  476. num_soil_top_cat = SIZE ( parent_grid%soilctop , DIM=2 )
  477. num_soil_bot_cat = SIZE ( parent_grid%soilcbot , DIM=2 )
  478. CALL land_percentages ( parent_grid%xland , &
  479. parent_grid%landusef , parent_grid%soilctop , parent_grid%soilcbot , &
  480. parent_grid%isltyp , parent_grid%ivgtyp , &
  481. num_veg_cat , num_soil_top_cat , num_soil_bot_cat , &
  482. ids , ide , jds , jde , kds , kde , &
  483. ims , ime , jms , jme , kms , kme , &
  484. ips , ipe , jps , jpe , kps , kpe , &
  485. model_config_rec%iswater(parent_grid%id) )
  486. END IF
  487. DO j = jps, MIN(jde-1,jpe)
  488. DO i = ips, MIN(ide-1,ipe)
  489. parent_grid%lu_index(i,j) = parent_grid%ivgtyp(i,j)
  490. END DO
  491. END DO
  492. CALL check_consistency ( parent_grid%ivgtyp , parent_grid%isltyp , parent_grid%landmask , &
  493. ids , ide , jds , jde , kds , kde , &
  494. ims , ime , jms , jme , kms , kme , &
  495. ips , ipe , jps , jpe , kps , kpe , &
  496. model_config_rec%iswater(parent_grid%id) )
  497. CALL check_consistency2( parent_grid%ivgtyp , parent_grid%isltyp , parent_grid%landmask , &
  498. parent_grid%tmn , parent_grid%tsk , parent_grid%sst , parent_grid%xland , &
  499. parent_grid%tslb , parent_grid%smois , parent_grid%sh2o , &
  500. config_flags%num_soil_layers , parent_grid%id , &
  501. ids , ide , jds , jde , kds , kde , &
  502. ims , ime , jms , jme , kms , kme , &
  503. ips , ipe , jps , jpe , kps , kpe , &
  504. model_config_rec%iswater(parent_grid%id) )
  505. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  506. ! We have 2 terrain elevations. One is from input and the other is from the
  507. ! the horizontal interpolation.
  508. parent_grid%ht_fine = parent_grid%ht_input
  509. parent_grid%ht = parent_grid%ht_int
  510. ! We have both the interpolated fields and the higher-resolution static fields. From these
  511. ! the rebalancing is now done. Note also that the field parent_grid%ht is now from the
  512. ! fine grid input file (after this call is completed).
  513. CALL rebalance_driver ( parent_grid )
  514. ! Different things happen during the different time loops:
  515. ! first loop - write wrfinput file, close data set, copy files to holder arrays
  516. ! middle loops - diff 3d/2d arrays, compute and output bc
  517. ! last loop - diff 3d/2d arrays, compute and output bc, write wrfbdy file, close wrfbdy file
  518. ! Set the time info.
  519. print *,'current_date = ',current_date
  520. CALL domain_clock_set( parent_grid, &
  521. current_timestr=current_date(1:19) )
  522. !
  523. ! SEP Put in chemistry data
  524. !
  525. #ifdef WRF_CHEM
  526. IF( parent_grid%chem_opt .NE. 0 ) then
  527. IF( parent_grid%chem_in_opt .EQ. 0 ) then
  528. ! Read the chemistry data from a previous wrf forecast (wrfout file)
  529. ! Generate chemistry data from a idealized vertical profile
  530. message = 'STARTING WITH BACKGROUND CHEMISTRY '
  531. CALL wrf_message ( message )
  532. CALL input_chem_profile ( parent_grid )
  533. message = 'READING BEIS3.11 EMISSIONS DATA'
  534. CALL wrf_message ( message )
  535. CALL med_read_wrf_chem_bioemiss ( parent_grid , config_flags)
  536. ELSE
  537. message = 'RUNNING WITHOUT CHEMISTRY INITIALIZATION'
  538. CALL wrf_message ( message )
  539. ENDIF
  540. ENDIF
  541. #endif
  542. #endif
  543. ! Output the first time period of the data.
  544. IF ( newly_opened ) THEN
  545. CALL wrf_put_dom_ti_integer ( out_id , 'MAP_PROJ' , map_proj , 1 , ierr )
  546. ! CALL wrf_put_dom_ti_real ( out_id , 'DX' , dx , 1 , ierr )
  547. ! CALL wrf_put_dom_ti_real ( out_id , 'DY' , dy , 1 , ierr )
  548. CALL wrf_put_dom_ti_real ( out_id , 'CEN_LAT' , cen_lat , 1 , ierr )
  549. CALL wrf_put_dom_ti_real ( out_id , 'CEN_LON' , cen_lon , 1 , ierr )
  550. CALL wrf_put_dom_ti_real ( out_id , 'TRUELAT1' , truelat1 , 1 , ierr )
  551. CALL wrf_put_dom_ti_real ( out_id , 'TRUELAT2' , truelat2 , 1 , ierr )
  552. CALL wrf_put_dom_ti_real ( out_id , 'MOAD_CEN_LAT' , moad_cen_lat , 1 , ierr )
  553. CALL wrf_put_dom_ti_real ( out_id , 'STAND_LON' , stand_lon , 1 , ierr )
  554. CALL wrf_put_dom_ti_integer ( out_id , 'ISWATER' , iswater , 1 , ierr )
  555. CALL wrf_put_dom_ti_real ( out_id , 'GMT' , gmt , 1 , ierr )
  556. CALL wrf_put_dom_ti_integer ( out_id , 'JULYR' , julyr , 1 , ierr )
  557. CALL wrf_put_dom_ti_integer ( out_id , 'JULDAY' , julday , 1 , ierr )
  558. ENDIF
  559. END SUBROUTINE nup
  560. SUBROUTINE land_percentages ( xland , &
  561. landuse_frac , soil_top_cat , soil_bot_cat , &
  562. isltyp , ivgtyp , &
  563. num_veg_cat , num_soil_top_cat , num_soil_bot_cat , &
  564. ids , ide , jds , jde , kds , kde , &
  565. ims , ime , jms , jme , kms , kme , &
  566. its , ite , jts , jte , kts , kte , &
  567. iswater )
  568. USE module_soil_pre
  569. IMPLICIT NONE
  570. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  571. ims , ime , jms , jme , kms , kme , &
  572. its , ite , jts , jte , kts , kte , &
  573. iswater
  574. INTEGER , INTENT(IN) :: num_veg_cat , num_soil_top_cat , num_soil_bot_cat
  575. REAL , DIMENSION(ims:ime,1:num_veg_cat,jms:jme) , INTENT(INOUT):: landuse_frac
  576. REAL , DIMENSION(ims:ime,1:num_soil_top_cat,jms:jme) , INTENT(IN):: soil_top_cat
  577. REAL , DIMENSION(ims:ime,1:num_soil_bot_cat,jms:jme) , INTENT(IN):: soil_bot_cat
  578. INTEGER , DIMENSION(ims:ime,jms:jme), INTENT(OUT) :: isltyp , ivgtyp
  579. REAL , DIMENSION(ims:ime,jms:jme) , INTENT(OUT) :: xland
  580. CALL process_percent_cat_new ( xland , &
  581. landuse_frac , soil_top_cat , soil_bot_cat , &
  582. isltyp , ivgtyp , &
  583. num_veg_cat , num_soil_top_cat , num_soil_bot_cat , &
  584. ids , ide , jds , jde , kds , kde , &
  585. ims , ime , jms , jme , kms , kme , &
  586. its , ite , jts , jte , kts , kte , &
  587. iswater )
  588. END SUBROUTINE land_percentages
  589. SUBROUTINE check_consistency ( ivgtyp , isltyp , landmask , &
  590. ids , ide , jds , jde , kds , kde , &
  591. ims , ime , jms , jme , kms , kme , &
  592. its , ite , jts , jte , kts , kte , &
  593. iswater )
  594. IMPLICIT NONE
  595. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  596. ims , ime , jms , jme , kms , kme , &
  597. its , ite , jts , jte , kts , kte , &
  598. iswater
  599. INTEGER , DIMENSION(ims:ime,jms:jme), INTENT(INOUT) :: isltyp , ivgtyp
  600. REAL , DIMENSION(ims:ime,jms:jme), INTENT(INOUT) :: landmask
  601. LOGICAL :: oops
  602. INTEGER :: oops_count , i , j
  603. oops = .FALSE.
  604. oops_count = 0
  605. DO j = jts, MIN(jde-1,jte)
  606. DO i = its, MIN(ide-1,ite)
  607. IF ( ( ( landmask(i,j) .LT. 0.5 ) .AND. ( ivgtyp(i,j) .NE. iswater ) ) .OR. &
  608. ( ( landmask(i,j) .GT. 0.5 ) .AND. ( ivgtyp(i,j) .EQ. iswater ) ) ) THEN
  609. print *,'mismatch in landmask and veg type'
  610. print *,'i,j=',i,j, ' landmask =',NINT(landmask(i,j)),' ivgtyp=',ivgtyp(i,j)
  611. oops = .TRUE.
  612. oops_count = oops_count + 1
  613. landmask(i,j) = 0
  614. ivgtyp(i,j)=16
  615. isltyp(i,j)=14
  616. END IF
  617. END DO
  618. END DO
  619. IF ( oops ) THEN
  620. CALL wrf_debug( 0, 'mismatch in check_consistency, turned to water points, be careful' )
  621. END IF
  622. END SUBROUTINE check_consistency
  623. SUBROUTINE check_consistency2( ivgtyp , isltyp , landmask , &
  624. tmn , tsk , sst , xland , &
  625. tslb , smois , sh2o , &
  626. num_soil_layers , id , &
  627. ids , ide , jds , jde , kds , kde , &
  628. ims , ime , jms , jme , kms , kme , &
  629. its , ite , jts , jte , kts , kte , &
  630. iswater )
  631. USE module_configure
  632. USE module_optional_input
  633. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  634. ims , ime , jms , jme , kms , kme , &
  635. its , ite , jts , jte , kts , kte
  636. INTEGER , INTENT(IN) :: num_soil_layers , id
  637. INTEGER , DIMENSION(ims:ime,jms:jme) :: ivgtyp , isltyp
  638. REAL , DIMENSION(ims:ime,jms:jme) :: landmask , tmn , tsk , sst , xland
  639. REAL , DIMENSION(ims:ime,num_soil_layers,jms:jme) :: tslb , smois , sh2o
  640. INTEGER :: oops1 , oops2
  641. INTEGER :: i , j , k
  642. fix_tsk_tmn : SELECT CASE ( model_config_rec%sf_surface_physics(id) )
  643. CASE ( SLABSCHEME , LSMSCHEME , RUCLSMSCHEME )
  644. DO j = jts, MIN(jde-1,jte)
  645. DO i = its, MIN(ide-1,ite)
  646. IF ( ( landmask(i,j) .LT. 0.5 ) .AND. ( flag_sst .EQ. 1 ) ) THEN
  647. tmn(i,j) = sst(i,j)
  648. tsk(i,j) = sst(i,j)
  649. ELSE IF ( landmask(i,j) .LT. 0.5 ) THEN
  650. tmn(i,j) = tsk(i,j)
  651. END IF
  652. END DO
  653. END DO
  654. END SELECT fix_tsk_tmn
  655. ! Is the TSK reasonable?
  656. DO j = jts, MIN(jde-1,jte)
  657. DO i = its, MIN(ide-1,ite)
  658. IF ( tsk(i,j) .LT. 170 .or. tsk(i,j) .GT. 400. ) THEN
  659. print *,'error in the TSK'
  660. print *,'i,j=',i,j
  661. print *,'landmask=',landmask(i,j)
  662. print *,'tsk, sst, tmn=',tsk(i,j),sst(i,j),tmn(i,j)
  663. if(tmn(i,j).gt.170. .and. tmn(i,j).lt.400.)then
  664. tsk(i,j)=tmn(i,j)
  665. else if(sst(i,j).gt.170. .and. sst(i,j).lt.400.)then
  666. tsk(i,j)=sst(i,j)
  667. else
  668. CALL wrf_error_fatal ( 'TSK unreasonable' )
  669. end if
  670. END IF
  671. END DO
  672. END DO
  673. ! Is the TMN reasonable?
  674. DO j = jts, MIN(jde-1,jte)
  675. DO i = its, MIN(ide-1,ite)
  676. IF ( ( ( tmn(i,j) .LT. 170. ) .OR. ( tmn(i,j) .GT. 400. ) ) .AND. ( landmask(i,j) .GT. 0.5 ) ) THEN
  677. print *,'error in the TMN'
  678. print *,'i,j=',i,j
  679. print *,'landmask=',landmask(i,j)
  680. print *,'tsk, sst, tmn=',tsk(i,j),sst(i,j),tmn(i,j)
  681. if(tsk(i,j).gt.170. .and. tsk(i,j).lt.400.)then
  682. tmn(i,j)=tsk(i,j)
  683. else if(sst(i,j).gt.170. .and. sst(i,j).lt.400.)then
  684. tmn(i,j)=sst(i,j)
  685. else
  686. CALL wrf_error_fatal ( 'TMN unreasonable' )
  687. endif
  688. END IF
  689. END DO
  690. END DO
  691. ! Is the TSLB reasonable?
  692. DO j = jts, MIN(jde-1,jte)
  693. DO i = its, MIN(ide-1,ite)
  694. IF ( ( ( tslb(i,1,j) .LT. 170. ) .OR. ( tslb(i,1,j) .GT. 400. ) ) .AND. ( landmask(i,j) .GT. 0.5 ) ) THEN
  695. print *,'error in the TSLB'
  696. print *,'i,j=',i,j
  697. print *,'landmask=',landmask(i,j)
  698. print *,'tsk, sst, tmn=',tsk(i,j),sst(i,j),tmn(i,j)
  699. print *,'tslb = ',tslb(i,:,j)
  700. print *,'old smois = ',smois(i,:,j)
  701. DO l = 1 , num_soil_layers
  702. sh2o(i,l,j) = 0.0
  703. END DO
  704. DO l = 1 , num_soil_layers
  705. smois(i,l,j) = 0.3
  706. END DO
  707. if(tsk(i,j).gt.170. .and. tsk(i,j).lt.400.)then
  708. DO l = 1 , num_soil_layers
  709. tslb(i,l,j)=tsk(i,j)
  710. END DO
  711. else if(sst(i,j).gt.170. .and. sst(i,j).lt.400.)then
  712. DO l = 1 , num_soil_layers
  713. tslb(i,l,j)=sst(i,j)
  714. END DO
  715. else if(tmn(i,j).gt.170. .and. tmn(i,j).lt.400.)then
  716. DO l = 1 , num_soil_layers
  717. tslb(i,l,j)=tmn(i,j)
  718. END DO
  719. else
  720. CALL wrf_error_fatal ( 'TSLB unreasonable' )
  721. endif
  722. END IF
  723. END DO
  724. END DO
  725. ! Let us make sure (again) that the landmask and the veg/soil categories match.
  726. oops1=0
  727. oops2=0
  728. DO j = jts, MIN(jde-1,jte)
  729. DO i = its, MIN(ide-1,ite)
  730. IF ( ( ( landmask(i,j) .LT. 0.5 ) .AND. ( ivgtyp(i,j) .NE. iswater .OR. isltyp(i,j) .NE. 14 ) ) .OR. &
  731. ( ( landmask(i,j) .GT. 0.5 ) .AND. ( ivgtyp(i,j) .EQ. iswater .OR. isltyp(i,j) .EQ. 14 ) ) ) THEN
  732. IF ( tslb(i,1,j) .GT. 1. ) THEN
  733. oops1=oops1+1
  734. ivgtyp(i,j) = 5
  735. isltyp(i,j) = 8
  736. landmask(i,j) = 1
  737. xland(i,j) = 1
  738. ELSE IF ( sst(i,j) .GT. 1. ) THEN
  739. oops2=oops2+1
  740. ivgtyp(i,j) = iswater
  741. isltyp(i,j) = 14
  742. landmask(i,j) = 0
  743. xland(i,j) = 2
  744. ELSE
  745. print *,'the landmask and soil/veg cats do not match'
  746. print *,'i,j=',i,j
  747. print *,'landmask=',landmask(i,j)
  748. print *,'ivgtyp=',ivgtyp(i,j)
  749. print *,'isltyp=',isltyp(i,j)
  750. print *,'iswater=', iswater
  751. print *,'tslb=',tslb(i,:,j)
  752. print *,'sst=',sst(i,j)
  753. CALL wrf_error_fatal ( 'mismatch_landmask_ivgtyp' )
  754. END IF
  755. END IF
  756. END DO
  757. END DO
  758. if (oops1.gt.0) then
  759. print *,'points artificially set to land : ',oops1
  760. endif
  761. if(oops2.gt.0) then
  762. print *,'points artificially set to water: ',oops2
  763. endif
  764. END SUBROUTINE check_consistency2