1 ! Create an initial data set for the WRF model based on real data. This
2 ! program is specifically set up for the Eulerian, mass-based coordinate.
5 USE module_domain, ONLY : domain, alloc_and_configure_domain, &
6 domain_clock_set, head_grid, program_name, domain_clockprint, &
9 USE module_initialize_real, ONLY : wrfu_initialize
10 USE module_driver_constants
11 USE module_configure, ONLY : grid_config_rec_type, model_config_rec, &
12 initial_config, get_config_as_buffer, set_config_as_buffer
14 USE module_state_description, ONLY: tconly
16 USE module_dm, ONLY: wrf_dm_initialize
18 #ifdef NO_LEAP_CALENDAR
19 USE module_symbols_util, ONLY: wrfu_cal_noleap
21 USE module_symbols_util, ONLY: wrfu_cal_gregorian
23 USE module_utility, ONLY : WRFU_finalize
30 INTEGER :: loop , levels_to_process , debug_level
33 TYPE(domain) , POINTER :: null_domain
34 TYPE(domain) , POINTER :: grid , another_grid
35 TYPE(domain) , POINTER :: grid_ptr , grid_ptr2
36 TYPE (grid_config_rec_type) :: config_flags
37 INTEGER :: number_at_same_level
38 INTEGER :: myproc, nproc
40 INTEGER :: max_dom, domain_id , grid_id , parent_id , parent_id1 , id
41 INTEGER :: e_we , e_sn , i_parent_start , j_parent_start
42 INTEGER :: idum1, idum2
45 INTEGER, PARAMETER :: configbuflen = 4* CONFIG_BUF_LEN
46 INTEGER :: configbuf( configbuflen )
47 LOGICAL , EXTERNAL :: wrf_dm_on_monitor
51 INTEGER :: ids , ide , jds , jde , kds , kde
52 INTEGER :: ims , ime , jms , jme , kms , kme
53 INTEGER :: ips , ipe , jps , jpe , kps , kpe
54 INTEGER :: ijds , ijde , spec_bdy_width
55 INTEGER :: i , j , k , idts, rc
56 INTEGER :: sibling_count , parent_id_hold , dom_loop
58 CHARACTER (LEN=80) :: message
59 CHARACTER(LEN=256) :: some_string
61 INTEGER :: start_year , start_month , start_day , start_hour , start_minute , start_second
62 INTEGER :: end_year , end_month , end_day , end_hour , end_minute , end_second
63 INTEGER :: interval_seconds , real_data_init_type
64 INTEGER :: time_loop_max , time_loop, bogus_id, storm
66 real :: latc_loc(max_bogus),lonc_loc(max_bogus),vmax(max_bogus),rmax(max_bogus)
69 SUBROUTINE Setup_Timekeeping( grid )
70 USE module_domain, ONLY : domain
71 TYPE(domain), POINTER :: grid
72 END SUBROUTINE Setup_Timekeeping
75 #include "version_decl"
76 #include "commit_decl"
78 ! Define the name of this program (program_name defined in module_domain)
80 program_name = "TC_EM " // TRIM(release_version) // " PREPROCESSOR"
82 ! The TC bogus algorithm assumes that the user defines a central point, and then
83 ! allows the program to remove a typhoon based on a distance in km. This is
84 ! implemented on a single processor only.
89 ! Initialize the modules used by the WRF system. Many of the CALLs made from the
90 ! init_modules routine are NO-OPs. Typical initializations are: the size of a
91 ! REAL, setting the file handles to a pre-use value, defining moisture and
92 ! chemistry indices, etc.
94 CALL wrf_debug ( 100 , 'real_em: calling init_modules ' )
95 CALL init_modules(1) ! Phase 1 returns after MPI_INIT() (if it is called)
96 #ifdef NO_LEAP_CALENDAR
97 CALL WRFU_Initialize( defaultCalKind=WRFU_CAL_NOLEAP, rc=rc )
99 CALL WRFU_Initialize( defaultCalKind=WRFU_CAL_GREGORIAN, rc=rc )
101 CALL init_modules(2) ! Phase 2 resumes after MPI_INIT() (if it is called)
103 #if defined( DM_PARALLEL ) && !defined( STUBMPI )
104 IF ( wrf_dm_on_monitor () ) THEN
105 CALL wrf_get_myproc (myproc)
106 CALL wrf_get_nproc (nproc)
107 IF ( nproc .GT. 1 ) THEN
108 WRITE (some_string,*) 'My MPI processor number = ',myproc
109 CALL wrf_debug ( 0 , TRIM(some_string) )
110 WRITE (some_string,*) 'Total MPI requested tasks = ',nproc
111 CALL wrf_debug ( 0 , TRIM(some_string) )
112 CALL wrf_error_fatal( 'MPI TC bogus must run with a single processor only, re-run with num procs set to 1' )
118 ! The configuration switches mostly come from the NAMELIST input.
121 IF ( wrf_dm_on_monitor() ) THEN
124 CALL get_config_as_buffer( configbuf, configbuflen, nbytes )
125 CALL wrf_dm_bcast_bytes( configbuf, nbytes )
126 CALL set_config_as_buffer( configbuf, configbuflen )
127 CALL wrf_dm_initialize
133 CALL nl_get_debug_level ( 1, debug_level )
134 CALL set_wrf_debug_level ( debug_level )
136 CALL wrf_message ( program_name )
137 CALL wrf_message ( commit_version )
139 ! There are variables in the Registry that are only required for the real
140 ! program, fields that come from the WPS package. We define the run-time
141 ! flag that says to allocate space for these input-from-WPS-only arrays.
143 CALL nl_set_use_wps_input ( 1 , TCONLY )
145 ! Allocate the space for the mother of all domains.
147 NULLIFY( null_domain )
148 CALL wrf_debug ( 100 , 'real_em: calling alloc_and_configure_domain ' )
149 CALL alloc_and_configure_domain ( domain_id = 1 , &
151 parent = null_domain , &
155 CALL nl_get_max_dom ( 1 , max_dom )
157 IF ( model_config_rec%interval_seconds .LE. 0 ) THEN
158 CALL wrf_error_fatal( 'namelist value for interval_seconds must be > 0')
161 all_domains : DO domain_id = 1 , max_dom
163 IF ( ( model_config_rec%input_from_file(domain_id) ) .OR. &
164 ( domain_id .EQ. 1 ) ) THEN
166 CALL Setup_Timekeeping ( grid )
167 CALL set_current_grid_ptr( grid )
168 CALL domain_clockprint ( 150, grid, &
169 'DEBUG real: clock after Setup_Timekeeping,' )
170 CALL domain_clock_set( grid, &
171 time_step_seconds=model_config_rec%interval_seconds )
172 CALL domain_clockprint ( 150, grid, &
173 'DEBUG real: clock after timeStep set,' )
176 CALL wrf_debug ( 100 , 'tc_em: calling set_scalar_indices_from_config ' )
177 CALL set_scalar_indices_from_config ( grid%id , idum1, idum2 )
179 !This is goofy but we need to loop through the number of storms to get
180 !the namelist variables for the tc_bogus. But then we need to
181 !call model_to_grid_config_rec with the grid%id = to 1 in order to
182 !reset to the correct information.
183 CALL wrf_debug ( 100 , 'tc_em: calling model_to_grid_config_rec ' )
188 CALL model_to_grid_config_rec ( grid%id , model_config_rec , config_flags )
189 lonc_loc(1) = config_flags%lonc_loc
190 latc_loc(1) = config_flags%latc_loc
191 vmax(1) = config_flags%vmax_meters_per_second
192 rmax(1) = config_flags%rmax
193 rankine_lid = config_flags%rankine_lid
194 do storm = 2,config_flags%num_storm
196 CALL model_to_grid_config_rec ( bogus_id , model_config_rec , config_flags )
197 lonc_loc(storm) = config_flags%lonc_loc
198 latc_loc(storm) = config_flags%latc_loc
199 vmax(storm) = config_flags%vmax_meters_per_second
200 rmax(storm) = config_flags%rmax
201 ! print *,"in loop ",storm,lonc_loc(storm),latc_loc(storm),vmax(storm),rmax(storm)
203 CALL model_to_grid_config_rec ( grid%id , model_config_rec , config_flags )
205 ! Initialize the WRF IO: open files, init file handles, etc.
207 CALL wrf_debug ( 100 , 'tc_em: calling init_wrfio' )
210 ! Some of the configuration values may have been modified from the initial READ
211 ! of the NAMELIST, so we re-broadcast the configuration records.
214 CALL wrf_debug ( 100 , 'tc_em: re-broadcast the configuration records' )
215 CALL get_config_as_buffer( configbuf, configbuflen, nbytes )
216 CALL wrf_dm_bcast_bytes( configbuf, nbytes )
217 CALL set_config_as_buffer( configbuf, configbuflen )
220 ! No looping in this layer.
222 CALL wrf_debug ( 100 , 'calling tc_med_sidata_input' )
223 CALL tc_med_sidata_input ( grid , config_flags, latc_loc, lonc_loc, &
224 vmax,rmax,rankine_lid)
225 CALL wrf_debug ( 100 , 'backfrom tc_med_sidata_input' )
233 CALL set_current_grid_ptr( head_grid )
237 CALL wrf_debug ( 0 , 'tc_em: SUCCESS COMPLETE TC BOGUS' )
241 CALL WRFU_Finalize( rc=rc )
247 !-----------------------------------------------------------------
248 SUBROUTINE tc_med_sidata_input ( grid , config_flags, latc_loc, lonc_loc, &
249 vmax, rmax,rankine_lid)
255 USE module_bc_time_utilities
256 USE module_optional_input
266 SUBROUTINE start_domain ( grid , allowed_to_read ) ! comes from module_start in appropriate dyn_ directory
269 LOGICAL, INTENT(IN) :: allowed_to_read
270 END SUBROUTINE start_domain
275 TYPE (grid_config_rec_type) :: config_flags
277 INTEGER :: time_step_begin_restart
278 INTEGER :: idsi , ierr , myproc, internal_time_loop,iflag
279 ! Declarations for the netcdf routines.
282 CHARACTER (LEN=256) :: si_inpname
283 CHARACTER (LEN=80) :: message
285 CHARACTER(LEN=19) :: start_date_char , end_date_char , current_date_char , next_date_char
286 CHARACTER(LEN=8) :: flag_name
288 INTEGER :: time_loop_max , loop, rc,icnt,itmp
289 INTEGER :: julyr , julday ,metndims, metnvars, metngatts, nunlimdimid,rcode
292 real :: latc_loc(max_bogus), lonc_loc(max_bogus)
293 real :: vmax(max_bogus),rmax(max_bogus),rankine_lid
295 grid%input_from_file = .true.
296 grid%input_from_file = .false.
298 CALL tc_compute_si_start ( model_config_rec%start_year (grid%id) , &
299 model_config_rec%start_month (grid%id) , &
300 model_config_rec%start_day (grid%id) , &
301 model_config_rec%start_hour (grid%id) , &
302 model_config_rec%start_minute(grid%id) , &
303 model_config_rec%start_second(grid%id) , &
304 model_config_rec%interval_seconds , &
305 model_config_rec%real_data_init_type , &
308 end_date_char = start_date_char
309 IF ( end_date_char .LT. start_date_char ) THEN
310 CALL wrf_error_fatal( 'Ending date in namelist ' // end_date_char // ' prior to beginning date ' // start_date_char )
312 print *,"the start date char ",start_date_char
313 print *,"the end date char ",end_date_char
316 ! Override stop time with value computed above.
317 CALL domain_clock_set( grid, stop_timestr=end_date_char )
319 ! TBH: for now, turn off stop time and let it run data-driven
320 CALL WRFU_ClockStopTimeDisable( grid%domain_clock, rc=rc )
321 CALL wrf_check_error( WRFU_SUCCESS, rc, &
322 'WRFU_ClockStopTimeDisable(grid%domain_clock) FAILED', &
325 CALL domain_clockprint ( 150, grid, &
326 'DEBUG med_sidata_input: clock after stopTime set,' )
328 ! Here we define the initial time to process, for later use by the code.
330 current_date_char = start_date_char
331 start_date = start_date_char // '.0000'
332 current_date = start_date
334 CALL nl_set_bdyfrq ( grid%id , REAL(model_config_rec%interval_seconds) )
338 DO loop = 1 , time_loop_max
340 internal_time_loop = loop
341 IF ( ( grid%id .GT. 1 ) .AND. ( loop .GT. 1 ) .AND. &
342 ( model_config_rec%grid_fdda(grid%id) .EQ. 0 ) .AND. &
343 ( model_config_rec%sst_update .EQ. 0 ) ) EXIT
346 print *,'-----------------------------------------------------------------------------'
348 print '(A,I2,A,A,A,I4,A,I4)' , &
349 ' Domain ',grid%id,': Current date being processed: ',current_date, ', which is loop #',loop,' out of ',time_loop_max
351 ! After current_date has been set, fill in the julgmt stuff.
353 CALL geth_julgmt ( config_flags%julyr , config_flags%julday , config_flags%gmt )
355 print *,'configflags%julyr, %julday, %gmt:',config_flags%julyr, config_flags%julday, config_flags%gmt
356 ! Now that the specific Julian info is available, save these in the model config record.
358 CALL nl_set_gmt (grid%id, config_flags%gmt)
359 CALL nl_set_julyr (grid%id, config_flags%julyr)
360 CALL nl_set_julday (grid%id, config_flags%julday)
362 ! Open the input file for tc stuff. Either the "new" one or the "old" one. The "new" one could have
363 ! a suffix for the type of the data format. Check to see if either is around.
366 WRITE ( wrf_err_message , FMT='(A,A)' )'med_sidata_input: calling open_r_dataset for ', &
367 TRIM(config_flags%auxinput1_inname)
368 CALL wrf_debug ( 100 , wrf_err_message )
369 IF ( config_flags%auxinput1_inname(1:8) .NE. 'wrf_real' ) THEN
370 CALL construct_filename4a( si_inpname , config_flags%auxinput1_inname , grid%id , 2 , &
371 current_date_char , config_flags%io_form_auxinput1 )
373 CALL construct_filename2a( si_inpname , config_flags%auxinput1_inname , grid%id , 2 , &
376 CALL open_r_dataset ( idsi, TRIM(si_inpname) , grid , config_flags , "DATASET=AUXINPUT1", ierr )
377 IF ( ierr .NE. 0 ) THEN
378 CALL wrf_error_fatal( 'error opening ' // TRIM(si_inpname) // &
379 ' for input; bad date in namelist or file not in directory' )
384 CALL wrf_debug ( 100 , 'med_sidata_input: calling input_auxinput1' )
385 CALL input_auxinput1 ( idsi , grid , config_flags , ierr )
386 WRITE ( wrf_err_message , FMT='(A,I10,A)' ) 'Timing for input ',NINT(t4-t3) ,' s.'
387 CALL wrf_debug( 0, wrf_err_message )
389 ! Possible optional SI input. This sets flags used by init_domain.
392 CALL wrf_debug ( 100 , 'med_sidata_input: calling init_module_optional_input' )
393 CALL init_module_optional_input ( grid , config_flags )
394 CALL wrf_debug ( 100 , 'med_sidata_input: calling optional_input' )
395 CALL optional_input ( grid , idsi , config_flags )
397 !Here we check the flags yet again. The flags are checked in optional_input but
398 !the grid% flags are not set.
399 flag_name(1:8) = 'SM000010'
400 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
401 IF ( ierr .EQ. 0 ) THEN
402 grid%flag_sm000010 = 1
405 flag_name(1:8) = 'SM010040'
406 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
407 IF ( ierr .EQ. 0 ) THEN
408 grid%flag_sm010040 = 1
411 flag_name(1:8) = 'SM040100'
412 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
413 IF ( ierr .EQ. 0 ) THEN
414 grid%flag_sm040100 = itmp
418 flag_name(1:8) = 'SM100200'
419 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
420 IF ( ierr .EQ. 0 ) THEN
421 grid%flag_sm100200 = itmp
424 ! flag_name(1:8) = 'SM010200'
425 ! CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
426 ! IF ( ierr .EQ. 0 ) THEN
427 ! config_flags%flag_sm010200 = itmp
428 ! print *,"found the flag_sm010200 "
431 !Now the soil temperature flags
432 flag_name(1:8) = 'ST000010'
433 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
434 IF ( ierr .EQ. 0 ) THEN
435 grid%flag_st000010 = 1
439 flag_name(1:8) = 'ST010040'
440 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
441 IF ( ierr .EQ. 0 ) THEN
442 grid%flag_st010040 = 1
445 flag_name(1:8) = 'ST040100'
446 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
447 IF ( ierr .EQ. 0 ) THEN
448 grid%flag_st040100 = 1
452 flag_name(1:8) = 'ST100200'
453 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
454 IF ( ierr .EQ. 0 ) THEN
455 grid%flag_st100200 = 1
458 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_SOIL_LAYERS', itmp, 1, icnt, ierr )
459 IF ( ierr .EQ. 0 ) THEN
460 grid%flag_soil_layers = 1
466 CALL close_dataset ( idsi , config_flags , "DATASET=AUXINPUT1" )
469 ! Possible optional SI input. This sets flags used by init_domain.
470 ! We need to call the optional input routines to get the flags that
471 ! are in the metgrid output file so they can be put in the tc bogus
472 ! output file for real to read.
474 already_been_here = .FALSE.
475 CALL model_to_grid_config_rec ( grid%id , model_config_rec , config_flags )
480 CALL assemble_output ( grid , config_flags , loop , time_loop_max, current_date_char, &
481 latc_loc, lonc_loc, vmax, rmax, rankine_lid,si_inpname)
483 WRITE ( wrf_err_message , FMT='(A,I10,A)' ) 'Timing for output ',NINT(t4-t3) ,' s.'
484 CALL wrf_debug( 0, wrf_err_message )
486 WRITE ( wrf_err_message , FMT='(A,I4,A,I10,A)' ) 'Timing for loop # ',loop,' = ',NINT(t2-t1) ,' s.'
487 CALL wrf_debug( 0, wrf_err_message )
492 END SUBROUTINE tc_med_sidata_input
495 !-------------------------------------------------------------------------------------
496 SUBROUTINE tc_compute_si_start( &
497 start_year , start_month , start_day , start_hour , start_minute , start_second , &
498 interval_seconds , real_data_init_type , &
505 INTEGER :: start_year , start_month , start_day , start_hour , start_minute , start_second
506 INTEGER :: end_year , end_month , end_day , end_hour , end_minute , end_second
507 INTEGER :: interval_seconds , real_data_init_type
508 INTEGER :: time_loop_max , time_loop
510 CHARACTER(LEN=19) :: current_date_char , start_date_char , end_date_char , next_date_char
513 WRITE ( start_date_char , FMT = '(I4.4,"-",I5.5,"_",I2.2,":",I2.2,":",I2.2)' ) &
514 start_year,start_day,start_hour,start_minute,start_second
516 WRITE ( start_date_char , FMT = '(I4.4,"-",I2.2,"-",I2.2,"_",I2.2,":",I2.2,":",I2.2)' ) &
517 start_year,start_month,start_day,start_hour,start_minute,start_second
521 END SUBROUTINE tc_compute_si_start
523 !-----------------------------------------------------------------------
524 SUBROUTINE assemble_output ( grid , config_flags , loop , time_loop_max,current_date_char, &
525 latc_loc, lonc_loc,vmax,rmax,rankine_lid,si_inpname)
527 USE module_big_step_utilities_em
536 TYPE (grid_config_rec_type) :: config_flags
538 INTEGER , INTENT(IN) :: loop , time_loop_max
540 !These values are in the name list and are avaiable from
541 !from the config_flags.
542 real :: vmax(max_bogus),vmax_ratio,rankine_lid
543 real :: rmax(max_bogus),stand_lon,cen_lat,ptop_in_pa
544 real :: latc_loc(max_bogus),lonc_loc(max_bogus)
546 INTEGER :: ijds , ijde , spec_bdy_width
547 INTEGER :: i , j , k , idts,map_proj,remove_only,storms
549 INTEGER :: id1 , interval_seconds , ierr, rc, sst_update, grid_fdda
550 INTEGER , SAVE :: id, id2, id4
551 CHARACTER (LEN=256) :: tcoutname , bdyname,si_inpname
552 CHARACTER(LEN= 4) :: loop_char
553 CHARACTER(LEN=19) :: current_date_char
555 character *19 :: temp19
556 character *24 :: temp24 , temp24b
558 real::t1,t2,truelat1,truelat2
561 ! Boundary width, scalar value.
563 spec_bdy_width = model_config_rec%spec_bdy_width
564 interval_seconds = model_config_rec%interval_seconds
565 sst_update = model_config_rec%sst_update
566 grid_fdda = model_config_rec%grid_fdda(grid%id)
567 truelat1 = config_flags%truelat1
568 truelat2 = config_flags%truelat2
570 stand_lon = config_flags%stand_lon
571 cen_lat = config_flags%cen_lat
572 map_proj = config_flags%map_proj
574 vmax_ratio = config_flags%vmax_ratio
575 ptop_in_pa = config_flags%p_top_requested
577 if(config_flags%remove_storm) then
581 storms = config_flags%num_storm
582 print *,"number of storms ",config_flags%num_storm
583 call tc_bogus(cen_lat,stand_lon,map_proj,truelat1,truelat2, &
584 grid%dx,grid%e_we,grid%e_sn,grid%num_metgrid_levels,ptop_in_pa, &
585 rankine_lid,latc_loc,lonc_loc,vmax,vmax_ratio,rmax,remove_only, &
590 ! Open the tc bogused output file. cd
591 CALL construct_filename4a( tcoutname , config_flags%auxinput1_outname , grid%id , 2 , &
592 current_date_char , config_flags%io_form_auxinput1 )
594 print *,"outfile name from construct filename ",tcoutname
595 CALL open_w_dataset ( id1, TRIM(tcoutname) , grid , config_flags ,output_auxinput1,"DATASET=AUXINPUT1",ierr )
596 IF ( ierr .NE. 0 ) THEN
597 CALL wrf_error_fatal( 'tc_em: error opening tc bogus file for writing' )
599 CALL output_auxinput1( id1, grid , config_flags , ierr )
600 CALL close_dataset ( id1 , config_flags , "DATASET=AUXINPUT1" )
603 END SUBROUTINE assemble_output
605 !----------------------------------------------------------------------------------------------
607 SUBROUTINE tc_bogus(centerlat,stdlon,nproj,truelat1,truelat2,dsm,ew,ns,nz,ptop_in_pa, &
608 rankine_lid,latc_loc,lonc_loc,vmax,vmax_ratio,rmax,remove_only, &
611 !!Original Author Dave Gill. Modified by Sherrie Fredrick
612 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
613 !These are read in from the netcdf file.
614 !centerlat The center latitude from the global attributes in the netcdf file.
615 !stdlon The center longitude from the global attributes in the netcdf file.
616 !nproj The map projection from the global attributes in the netcdf file.
617 !dsm The spacing in meters from the global attributes in the netcdf file.
618 !ew The west_east_stag from the dimensions in the netcdf file..
619 !ns The south_north_stag from the dimensions in the netcdf file. .
620 !nz The number of metgrid levels from the dimensions in the netcdf file.
622 !ptop_in_pa This is part of the namelist.input file under the &domains section.
624 !These values are part of the namelist.input file under the &tc section specifically
625 !for the tc bogus code.
626 !NOTES: There can be up to five bogus storms. The variable max_bogus is set in
627 !the WRF subroutine called module_driver_constants.F in the ./WRFV3/frame directory.
629 !latc_loc The center latitude of the bogus strorm. This is an array dimensioned max_bogus.
631 !lonc_loc The center longitude of the bogus strorm. This is an array dimensioned max_bogus.
633 !vmax The max vortex in meters/second it comes from the namelist entry.
634 ! This is an array dimensioned max_bogus.
636 !vmax_ratio This comes from the namelist entry.
638 !rmax The maximum radius this comes from the namelist entry.
639 ! This is an array dimensioned max_bogus
641 !remove_only If this is set to true in the namelist.input file a value of 0.1
642 ! is automatically assigned to vmax.
644 !rankine_lid This comes from the namelist entry. It can be used to determine
645 ! what model levels the bogus storm affects.
647 !storms The number of bogus storms.
649 !grid This is a Fortran structure which holds all of the field data values
650 ! for the netcdf that was read in.
651 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
654 !module_llxy resides in the share directory.
656 !This is for the large structure (grid)
666 real :: centerlat,stdlon,conef,truelat1,truelat2,dsm,dx,rankine_lid
667 real :: latc_loc(max_bogus),lonc_loc(max_bogus),vmax(max_bogus),vmax_ratio,rmax(max_bogus)
669 real :: press(ew-1,nz,ns-1),rhmx(nz), vwgt(nz),old_slp(ew-1,ns-1)
670 real, dimension(:,:,:) , allocatable :: u11,v11,t11,rh11,phi11
671 real, dimension(:,:,:) , allocatable :: u1 , v1 , t1 , rh1 , phi1
672 real, dimension(ew-1,ns-1) :: lond,terrain,cor,pslx
675 !The map scale factors.
676 real, dimension(ew,ns-1) :: msfu !The mapscale factor for the ew wind staggered grid
677 real, dimension(ew-1,ns) :: msfv !The mapscale factor for the ns wind staggered grid
678 real, dimension(ew-1,ns-1) :: msfm !The mapscale factor for the unstaggered grid.
684 real :: r_search,r_vor,beta,devps,humidity_max
685 real :: devpc,const,r_vor2,cnst,alphar,epsilon,vormx , rad , sum_q
686 real :: avg_q ,q_old,ror,q_new,dph,dphx0
687 real :: rh_max,min_RH_value,ps
688 integer :: vert_variation
689 integer :: i,k,j,kx,remove_only
690 integer :: k00,kfrm ,kto ,k85,n_iter,ew_mvc,ns_mvc,nct,itr
691 integer :: strmci(nz), strmcj(nz)
692 real :: disx,disy,alpha,degran,pie,rovcp,cp
693 REAL :: rho,pprm,phip0,x0,y0,vmx,xico,xjco,xicn,xjcn,p85,xlo,rconst,ew_gcntr,ns_gcntr
694 real :: ptop_in_pa,themax,themin
695 real :: latinc,loninc
696 real :: rtemp,colat0,colat
697 REAL :: q1(ew-1,nz,ns-1), psi1(ew-1,nz,ns-1)
699 ! This is the entire map projection enchilada.
700 TYPE(proj_info) :: proj
705 ! These values are read in from the data set.
706 real :: knowni,knownj
709 REAL utcr(ew,nz,ns-1), vtcr(ew-1,nz,ns)
710 REAL utcp(ew,nz,ns-1), vtcp(ew-1,nz,ns)
711 REAL psitc(ew-1,nz,ns-1), psiv(nz)
712 REAL vortc(ew-1,nz,ns-1), vorv(nz)
713 REAL tptc(ew-1,nz,ns-1)
714 REAL phiptc(ew-1,nz,ns-1)
717 REAL uuwork(nz), vvwork(nz), temp2(ew,ns)
718 REAL vort(ew-1,nz,ns-1), div(ew-1,nz,ns-1)
719 REAL vortsv(ew-1,nz,ns-1)
720 REAL theta(ew-1,nz,ns-1), t_reduce(ew-1,nz,ns-1)
721 REAL ug(ew,nz,ns-1), vg(ew-1,nz,ns), vorg(ew-1,nz,ns-1)
722 REAL delpx(ew-1,ns-1)
724 !subroutines for relaxation
725 REAL outold(ew-1,ns-1)
726 REAL rd(ew-1,ns-1), ff(ew-1,ns-1)
727 REAL tmp1(ew-1,ns-1), tmp2(ew-1,ns-1)
730 REAL , DIMENSION (ew-1,nz,ns-1) :: t0, t00, rh0, q0, phi0, psi0, chi
733 REAL , DIMENSION (ew-1,nz,ns-1) :: psipos, tpos, psi ,phipos, phip
736 REAL u2(ew,nz,ns-1), v2(ew-1,nz,ns)
737 REAL t2(ew-1,nz,ns-1),z2(ew-1,nz,ns-1)
738 REAL phi2(ew-1,nz,ns-1),rh2(ew-1,nz,ns-1)
740 print *,"the dimensions: north-south = ",ns," east-west =",ew
741 IF (nproj .EQ. 1) THEN
743 print *,"Lambert Conformal projection"
744 ELSE IF (nproj .EQ. 2) THEN
746 ELSE IF (nproj .EQ. 3) THEN
748 print *,"A mercator projection"
754 pie = 3.141592653589793
772 if(remove_only .eq. 1) then
778 ! Set up initializations for map projection so that the lat/lon
779 ! of the tropical storm can be put into model (i,j) space. This needs to be done once per
780 ! map projection definition. Since this is the domain that we are "GOING TO", it is a once
781 ! per regridder requirement. If the user somehow ends up calling this routine for several
782 ! time periods, there is no problemos, just a bit of overhead with redundant calls.
785 lat1 = grid%xlat_gc(1,1)
786 lon1 = grid%xlong_gc(1,1)
787 IF( jproj .EQ. 'ME' )THEN
788 IF ( lon1 .LT. -180. ) lon1 = lon1 + 360.
789 IF ( lon1 .GT. 180. ) lon1 = lon1 - 360.
790 IF ( stdlon .LT. -180. ) stdlon = stdlon + 360.
791 IF ( stdlon .GT. 180. ) stdlon = stdlon - 360.
792 CALL map_set ( proj_merc, proj, lat1, lon1, lat1, lon1, knowni, knownj, dx, &
793 latinc,loninc,stdlon , truelat1 , truelat2)
795 ELSE IF ( jproj .EQ. 'LC' ) THEN
796 if((truelat1 .eq. 0.0) .and. (truelat2 .eq. 0.0)) then
797 print *,"Truelat1 and Truelat2 are both 0"
800 CALL map_set (proj_lc,proj, lat1, lon1, lat1, lon1, knowni, knownj, dx, &
801 latinc,loninc,stdlon , truelat1 , truelat2)
803 ELSE IF ( jproj .EQ. 'ST' ) THEN
805 CALL map_set ( proj_ps,proj,lat1, lon1, lat1, lon1, knowni, knownj, dx, &
806 latinc,loninc,stdlon , truelat1 , truelat2)
809 ! Load the pressure array.
814 press(i,k,j) = grid%p_gc(i,k,j)*0.01
820 ! Initialize the vertical profiles for humidity and weighting.
821 !The ptop variable will be read in from the namelist
822 IF ( ( ptop_in_pa .EQ. 40000. ) .OR. ( ptop_in_pa .EQ. 60000. ) ) THEN
823 PRINT '(A)','Hold on pardner, your value for PTOP is gonna cause problems for the TC bogus option.'
824 PRINT '(A)','Make it higher up than 400 mb.'
825 STOP 'ptop_woes_for_tc_bogus'
828 IF ( vert_variation .EQ. 1 ) THEN
830 IF ( press(1,k,1) .GT. 400. ) THEN
831 rhmx(k) = humidity_max
833 rhmx(k) = humidity_max * MAX( 0.1 , (press(1,k,1) - ptop_in_pa/100.)/(400.-ptop_in_pa/100.) )
836 IF ( press(1,k,1) .GT. 600. ) THEN
838 ELSE IF ( press(1,k,1) .LE. 100. ) THEN
841 vwgt(k) = MAX ( 0.0001 , (press(1,k,1)-ptop_in_pa/100.)/(600.-ptop_in_pa/100.) )
845 ELSE IF ( vert_variation .EQ. 2 ) THEN
846 IF ( kx .eq. 24 ) THEN
847 rhmx = (/ 95., 95., 95., 95., 95., 95., 95., 95., &
848 95., 95., 95., 95., 95., 90., 85., 80., 75., &
849 70., 66., 60., 39., 10., 10., 10./)
850 vwgt = (/ 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 0.9850, &
851 0.9680, 0.9500, 0.9290, 0.9060, 0.8810, 0.8500, 0.7580, 0.6500, 0.5100, &
852 0.3500, 0.2120, 0.0500, 0.0270, 0.0001, 0.0001, 0.0001/)
854 PRINT '(A)','Number of vertical levels assumed to be 24 for AFWA TC bogus option'
855 STOP 'AFWA_TC_BOGUS_LEVEL_ERROR'
859 !Remember that ns = the north south staggered. This is one more than the ns mass point grid.
860 ! ew = the east west staggered. This is one more than the ew mass point grid.
863 !Put the U and V into the new arrays.
864 !Remember that the WRF ordering is ew,vert level,ns
865 !Vorticity and Divergence calculatins are done on
866 !the staggered grids so the winds are not destaggered
867 allocate(u11 (1:ew, 1:nz, 1:ns-1))
868 allocate(u1 (1:ew, 1:nz, 1:ns-1))
869 allocate(v11 (1:ew-1, 1:nz, 1:ns))
870 allocate(v1 (1:ew-1, 1:nz, 1:ns))
874 u11(i,k,j) = grid%u_gc(i,k,j)
875 u1(i,k,j) = grid%u_gc(i,k,j)
876 msfu(i,j) = grid%msfu(i,j) !map scale factor on the U staggered grid
885 v11(i,k,j) = grid%v_gc(i,k,j)
886 v1(i,k,j) = grid%v_gc(i,k,j)
887 msfv(i,j) = grid%msfv(i,j) !map scale factor on the V staggered grid
893 !Put the temperature, relative humidity and height fields
894 !into arrays. Save the initial fields also.
895 !These arrays are on the WRF mass points
896 allocate(t11 (1:ew-1, 1:nz, 1:ns-1))
897 allocate(t1 (1:ew-1, 1:nz, 1:ns-1))
898 allocate(rh11 (1:ew-1, 1:nz, 1:ns-1))
899 allocate(rh1 (1:ew-1, 1:nz, 1:ns-1))
900 allocate(phi11(1:ew-1, 1:nz, 1:ns-1))
901 allocate(phi1 (1:ew-1, 1:nz, 1:ns-1))
905 t11(i,k,j) = grid%t_gc(i,k,j)
906 t1(i,k,j) = grid%t_gc(i,k,j)
907 rh11(i,k,j) = grid%rh_gc(i,k,j)
908 rh1(i,k,j) = grid%rh_gc(i,k,j)
909 msfm(i,j) = grid%msft(i,j)
911 phi11(i,k,j) = grid%ht_gc(i,j)
912 phi1(i,k,j) = grid%ht_gc(i,j) * 9.81
914 phi11(i,k,j) = grid%ght_gc(i,k,j)
915 phi1(i,k,j) = grid%ght_gc(i,k,j) * 9.81
922 !The terrain soil height is from ght at level 1
925 pslx(i,j) = grid%pslv_gc(i,j) * 0.01
926 cor(i,j) = grid%f(i,j) !coreolous
927 lond(i,j) = grid%xlong_gc(i,j)
928 terrain(i,j) = grid%ht_gc(i,j)
929 old_slp(i,j) = grid%pslv_gc(i,j)
935 ! Loop over the number of storms to process.
938 all_storms : DO nstrm=1,storms
941 !Make sure the user has defined the rmax variable
942 if(rmax(nstrm) .eq. -999.) then
943 print *,"Please enter a value for rmax in the namelist"
954 IF ( press(1,k,1) .GE. p85 ) THEN
961 ! Parameters for max wind
967 !latc_loc and lonc_loc come in from the namelist.
968 !These x0 and y0 points are relative to the mass points.
969 CALL latlon_to_ij ( proj , latc_loc(nstrm) , lonc_loc(nstrm) , x0 , y0 )
970 IF ( ( x0 .LT. 1. ) .OR. ( x0 .GT. REAL(ew-1) ) .OR. &
971 ( y0 .LT. 1. ) .OR. ( y0 .GT. REAL(ns-1) ) ) THEN
972 PRINT '(A,I3,A,A,A)',' Storm position is outside the computational domain.'
973 PRINT '(A,2F6.2,A)' ,' Storm postion: (x,y) = ',x0,y0,'.'
978 ! Bogus vortex specifications, vmax (m/s); rmax (m);
979 vmx = vmax(nstrm) * vmax_ratio
981 IF ( latc_loc(nstrm) .LT. 0. ) THEN
985 IF ( vmax(nstrm) .LE. 0. ) THEN
986 vmx = SQRT( 2.*(1-beta)*ABS(phip0) )
989 ew_gcntr = x0 !ew center grid location
990 ns_gcntr = y0 !ns center grid location
991 !For right now we are adding 0.5 to the grid location this
992 !makes the output of the wrf tc_bogus scheme analogous to the
993 !ouput of the MM5 tc_bogus scheme.
1001 PRINT '(/,A,I3,A,A,A)' ,'---> TC: Processing storm number= ',nstrm
1002 PRINT '(A,F6.2,A,F7.2,A)' ,' Storm center lat= ',latc_loc(nstrm),' lon= ',lonc_loc(nstrm),'.'
1003 PRINT '(A,2F6.2,A)' ,' Storm center grid position (x,y)= ',ew_gcntr,ns_gcntr,'.'
1004 PRINT '(A,F5.2,F9.2,A)' ,' Storm max wind (m/s) and max radius (m)= ',vmx,rmax(nstrm),'.'
1005 PRINT '(A,F5.2,A)' ,' Estimated central press dev (mb)= ',devpc,'.'
1008 ! Initialize storm center to (1,1)
1015 ! Define complete field of bogus storm
1016 !Note dx is spacing in meters.
1017 !The output arrays from the rankine subroutine vvwork,uuwork,psiv and vorv
1018 !are defined on the WRF mass points.
1021 print *,"nstrm ",rmax(nstrm),ew_gcntr,ns_gcntr
1024 disx = REAL(i) - ew_gcntr
1025 disy = REAL(j) - ns_gcntr
1026 CALL rankine(disx,disy,dx,kx,vwgt,rmax(nstrm),vmx,uuwork,vvwork,psiv,vorv)
1028 utcp(i,k,j) = uuwork(k)
1029 vtcp(i,k,j) = vvwork(k)
1030 psitc(i,k,j) = psiv(k)
1031 vortc(i,k,j) = vorv(k)
1035 call stagger_rankine_winds(utcp,vtcp,ew,ns,nz)
1040 ! dave Rotate wind to map proj, on the correct staggering
1043 xlo = stdlon-grid%xlong_u(i,j)
1044 IF ( xlo .GT. 180.)xlo = xlo-360.
1045 IF ( xlo .LT.-180.)xlo = xlo+360.
1047 alpha = xlo*conef*degran*SIGN(1.,centerlat)
1049 utcr(i,k,j) = (vtcp(i-1,k,j)+vtcp(i,k,j)+vtcp(i,k,j+1)+vtcp(i-1,k,j+1))/4 *SIN(alpha)+utcp(i,k,j)*COS(alpha)
1050 if(utcr(i,k,j) .gt. 300.) then
1051 print *,i,k,j,"a very bad value of utcr"
1061 xlo = stdlon-grid%xlong_v(i,j)
1062 IF ( xlo .GT. 180.)xlo = xlo-360.
1063 IF ( xlo .LT.-180.)xlo = xlo+360.
1065 alpha = xlo*conef*degran*SIGN(1.,centerlat)
1067 vtcr(i,k,j) = vtcp(i,k,j)*COS(alpha)-(utcp(i,k,j-1)+utcp(i+1,k,j-1)+utcp(i+1,k,j)+utcp(i,k,j))/4*SIN(alpha)
1068 if(vtcr(i,k,j) .gt. 300.) then
1069 print *,i,k,j,"a very bad value of vtcr"
1077 !Fill in UTCR's along the left and right side.
1079 utcr(1,:,j) = utcr(2,:,j)
1080 utcr(ew,:,j) = utcr(ew-1,:,j)
1083 !Fill in V's along the bottom and top.
1085 vtcr(i,:,1) = vtcr(i,:,2)
1086 vtcr(i,:,ns) = vtcr(i,:,ns-1)
1090 ! Compute vorticity of FG. This is the vorticity of the original winds
1091 ! on the staggered grid. The vorticity and divergence are defined at
1092 ! the mass points when done.
1093 CALL vor(u1,v1,msfu,msfv,msfm,ew,ns,kx,dx,vort)
1096 ! Compute divergence of FG
1097 CALL diverg(u1,v1,msfu,msfv,msfm,ew,ns,kx,dx,div)
1100 ! Compute mixing ratio of FG
1101 CALL mxratprs(rh1,t1,press*100.,ew,ns,kx,q1,min_RH_value)
1102 q1(:,1,:) = q1(:,2,:)
1105 ! Compute initial streamfunction - PSI1
1110 ! Solve for streamfunction.
1114 ff(i,j) = vort(i,k,j)
1119 CALL relax(tmp1,ff,rd,ew,ns,dx,epsilon,alphar)
1122 psi1(i,k,j) = tmp1(i,j)
1128 DO k=1,kx !start of the k loop
1129 IF ( latc_loc(nstrm) .GE. 0. ) THEN
1140 rad = SQRT((REAL(i)-ew_gcntr)**2.+(REAL(j)-ns_gcntr)**2.)*dx
1141 IF ( rad .LE. r_search ) THEN
1142 IF ( latc_loc(nstrm) .GE. 0. ) THEN
1143 IF ( vortsv(i,k,j) .GT. vormx ) THEN
1144 vormx = vortsv(i,k,j)
1148 ELSE IF (latc_loc(nstrm) .LT. 0. ) THEN
1149 IF ( vortsv(i,k,j) .LT. vormx ) THEN
1150 vormx = vortsv(i,k,j)
1164 rad = SQRT(REAL((i-ew_mvc)**2.+(j-ns_mvc)**2.))*dx
1165 IF ( rad .GT. r_vor ) THEN
1177 rad = SQRT(REAL(i-ew_mvc)**2.+REAL(j-ns_mvc)**2.)*dx
1178 IF ( (rad .LT. r_vor2).AND.(rad .GE. 0.8*r_vor2) ) THEN
1179 sum_q = sum_q + q0(i,k,j)
1184 avg_q = sum_q/MAX(REAL(nct),1.)
1189 rad = SQRT(REAL(i-ew_mvc)**2.+REAL(j-ns_mvc)**2.)*dx
1190 IF ( rad .LT. r_vor2 ) THEN
1192 q_new = ((1.-ror)*avg_q) + (ror*q_old)
1197 END DO !end of itr loop
1198 END DO !of the k loop
1201 ! Compute divergent wind (chi) at the mass points
1205 ff(i,j) = div(i,k,j)
1211 CALL relax(tmp1,ff,rd,ew,ns,dx,epsilon,alphar)
1214 chi(i,k,j) = tmp1(i,j)
1217 END DO !of the k loop for divergent winds
1221 ! Compute background streamfunction (PSI0) and perturbation field (PSI)
1222 ! print *,"perturbation field (PSI) relax three"
1231 CALL relax(tmp1,ff,rd,ew,ns,dx,epsilon,alphar)
1234 psi(i,k,j)=tmp1(i,j)
1240 !We can now calculate the final wind fields.
1241 call final_ew_velocity(u2,u1,chi,psi,utcr,dx,ew,ns,nz)
1242 call final_ns_velocity(v2,v1,chi,psi,vtcr,dx,ew,ns,nz)
1247 psi0(i,k,j) = psi1(i,k,j)-psi(i,k,j)
1255 psipos(i,k,j)=psi(i,k,j)
1261 ! Geostrophic vorticity.
1262 !We calculate the ug and vg on the wrf U and V staggered grids
1263 !since this is where the vorticity subroutine expects them.
1265 CALL geowind(phi1,ew,ns,kx,dx,ug,vg)
1266 CALL vor(ug,vg,msfu,msfv,msfm,ew,ns,kx,dx,vorg)
1274 rad = SQRT(REAL(i-ew_mvc)**2.+REAL(j-ns_mvc)**2.)*dx
1275 IF ( rad .GT. r_vor ) THEN
1285 ff(i,j) = vorg(i,k,j)
1290 CALL relax(tmp1,ff,rd,ew,ns,dx,epsilon,alphar)
1293 phip(i,k,j) = tmp1(i,j)
1299 ! Background geopotential.
1303 phi0(i,k,j) = phi1(i,k,j) - phip(i,k,j)
1309 ! Background temperature
1314 tpos(i,k,j) = (-1./rconst)*(phip(i,k+1,j)-phip(i,k,j ))/LOG(press(i,k+1,j)/press(i,k,j))
1315 ELSE IF ( k .EQ. kx ) THEN
1316 tpos(i,k,j) = (-1./rconst)*(phip(i,k ,j)-phip(i,k-1,j))/LOG(press(i,k,j )/press(i,k-1,j))
1318 tpos(i,k,j) = (-1./rconst)*(phip(i,k+1,j)-phip(i,k-1,j))/LOG(press(i,k+1,j)/press(i,k-1,j))
1320 t0(i,k,j) = t1(i,k,j)-tpos(i,k,j)
1321 t00(i,k,j) = t0(i,k,j)
1322 if(t0(i,k,j) .gt. 400) then
1323 print *,"interesting temperature ",t0(i,k,j)," at ",i,j,k
1331 CALL qvtorh (q0,t0,press*100.,k00,ew,ns,kx,rh0,min_RH_value)
1332 call final_RH(rh2,rh0,rhmx,strmci,strmcj,rmax(nstrm),ew,ns,nz,k00,dx,ew_gcntr,ns_gcntr,r_vor2)
1340 theta(i,k,j) = t1(i,k,j)*(1000./press(i,k,j))**rovcp
1346 ew_mvc = strmci(k00)
1347 ns_mvc = strmcj(k00)
1351 rad = SQRT(REAL(i-ew_mvc)**2.+REAL(j-ns_mvc)**2.)*dx
1352 IF ( rad .LT. r_vor2 ) THEN
1353 t_reduce(i,k,j) = theta(i,k85,j)-0.03*(press(i,k,j)-press(i,k85,j))
1354 t0(i,k,j) = t00(i,k,j)*(rad/r_vor2) + (((press(i,k,j)/1000.)**rovcp)*t_reduce(i,k,j))*(1.-(rad/r_vor2))
1360 ! Geopotential perturbation
1364 tmp1(i,j)=psitc(i,k,j)
1367 CALL balance(cor,tmp1,ew,ns,dx,outold)
1375 CALL relax (tmp1,ff,rd,ew,ns,dx,epsilon,alphar)
1378 phiptc(i,k,j) = tmp1(i,j)
1384 ! New geopotential field.
1388 phi2(i,k,j) = phi0(i,k,j) + phiptc(i,k,j)
1394 ! New temperature field.
1399 tptc(i,k,j)=(-1./rconst)*(phiptc(i,k+1,j)-phiptc(i,k,j ))/LOG(press(i,k+1,j)/press(i,k,j))
1400 ELSE IF ( k .EQ. kx ) THEN
1401 tptc(i,k,j)=(-1./rconst)*(phiptc(i,k,j )-phiptc(i,k-1,j))/LOG(press(i,k,j)/press(i,k-1,j))
1403 tptc(i,k,j)=(-1./rconst)*(phiptc(i,k+1,j)-phiptc(i,k-1,j))/LOG(press(i,k+1,j)/press(i,k-1,j))
1405 t2(i,k,j) = t0(i,k,j) + tptc(i,k,j)
1406 if(t2(i,k,j) .gt. 400) then
1407 print *,"interesting temperature "
1408 print *,t2(i,k,j),i,k,j,tptc(i,k,j)
1416 ! Sea level pressure change.
1419 dph = phi2(i,k00,j)-phi1(i,k00,j)
1420 delpx(i,j) = rho*dph*0.01
1426 ! print *,"new slp",nstrm
1429 pslx(i,j) = pslx(i,j)+delpx(i,j)
1430 grid%pslv_gc(i,j) = pslx(i,j) * 100.
1435 ! Set new geopotential at surface to terrain elevation.
1438 z2(i,1,j) = terrain(i,j)
1442 ! Geopotential back to height.
1447 z2(i,k,j) = phi2(i,k,j)/9.81
1453 ! New surface temperature, assuming same theta as from 1000 mb.
1454 ! print *,"new surface temperature"
1458 t2(i,1,j) = t2(i,k00,j)*((ps/1000.)**rovcp)
1459 if(t2(i,1,j) .gt. 400) then
1460 print *,"Interesting surface temperature"
1461 print *,t2(i,1,j),t2(i,k00,j),ps,i,j
1468 ! Set surface RH to the value from 1000 mb.
1471 rh2(i,1,j) = rh2(i,k00,j)
1475 ! Modification of tropical storm complete.
1476 PRINT '(A,I3,A)' ,' Bogus storm number ',nstrm,' completed.'
1481 u1(i,k,j) = u2(i,k,j)
1482 grid%u_gc(i,k,j) = u2(i,k,j)
1490 v1(i,k,j) = v2(i,k,j)
1491 grid%v_gc(i,k,j) = v2(i,k,j)
1499 t1(i,k,j) = t2(i,k,j)
1500 grid%t_gc(i,k,j) = t2(i,k,j)
1501 rh1(i,k,j) = rh2(i,k,j)
1502 grid%rh_gc(i,k,j) = rh2(i,k,j)
1503 phi1(i,k,j) = phi2(i,k,j)
1504 grid%ght_gc(i,k,j) = z2(i,k,j)
1524 if(grid%ht_gc(i,j) .gt. 1) then
1525 grid%p_gc(i,1,j) = grid%p_gc(i,1,j) + (pslx(i,j) * 100. - old_slp(i,j))
1526 grid%psfc(i,j) = grid%psfc(i,j) + (pslx(i,j) * 100. - old_slp(i,j))
1528 grid%p_gc(i,1,j) = pslx(i,j) * 100.
1529 grid%psfc(i,j) = pslx(i,j) * 100.
1534 END SUBROUTINE tc_bogus
1536 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1537 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1539 SUBROUTINE rankine(dx,dy,ds,nlvl,vwgt,rmax,vmax,uu,vv,psi,vor)
1541 ! Define analytical bogus vortex
1546 REAL , DIMENSION(nlvl) :: uu, vv, psi, vor
1547 REAL , DIMENSION(nlvl) :: vwgt
1548 REAL :: dx,dy,ds,rmax,vmax
1550 REAL , PARAMETER :: alpha1= 1.
1551 REAL , PARAMETER :: alpha2= -0.75
1556 REAL :: vr , ang , rr , term1 , bb , term2 , alpha
1559 pi = 3.141592653589793
1563 rr = SQRT(dx**2+dy**2)*ds
1564 IF ( rr .LT. rmax ) THEN
1566 ELSE IF ( rr .GE. rmax ) THEN
1569 vr = vmax * (rr/rmax)**(alpha)
1570 IF ( dx.GE.0. ) THEN
1571 ang = (pi/2.) - ATAN2(dy,MAX(dx,1.e-6))
1572 uu(k) = vwgt(k)*(-vr*COS(ang))
1573 vv(k) = vwgt(k)*( vr*SIN(ang))
1574 ELSE IF ( dx.LT.0. ) THEN
1575 ang = ((3.*pi)/2.) + ATAN2(dy,dx)
1576 uu(k) = vwgt(k)*(-vr*COS(ang))
1577 vv(k) = vwgt(k)*(-vr*SIN(ang))
1584 rr = SQRT(dx**2+dy**2)*ds
1585 IF ( rr .LT. rmax ) THEN
1586 psi(k) = vwgt(k) * (vmax*rr*rr)/(2.*rmax)
1587 ELSE IF ( rr .GE. rmax ) THEN
1588 IF (alpha1.EQ.1.0 .AND. alpha2.eq.-1.0) THEN
1589 psi(k) = vwgt(k) * vmax*rmax*(0.5+LOG(rr/rmax))
1590 ELSE IF (alpha1.EQ.1.0 .AND. alpha2.NE.-1.0) THEN
1591 term1 = vmax/(rmax**alpha1)*(rmax**(alpha1+1)/(alpha1+1))
1592 bb = (rr**(alpha2+1)/(alpha2+1))-(rmax**(alpha2+1))/(alpha2+1)
1593 term2 = vmax/(rmax**alpha2)*bb
1594 psi(k) = vwgt(k) * (term1 + term2)
1602 rr = SQRT(dx**2+dy**2)*ds
1603 IF ( rr .LT. rmax ) THEN
1604 vor(k) = vwgt(k) * (2.*vmax)/rmax
1605 ELSE IF ( rr .GE. rmax ) THEN
1606 vor(k) = vwgt(k) * ( (vmax/rmax**alpha2)*(rr**(alpha2-1.))*(1.+alpha2) )
1610 END SUBROUTINE rankine
1612 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1613 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1615 SUBROUTINE vor(uin,vin,msfu,msfv,msfm,ew,ns,nz,ds,vort)
1617 !Here we assume that the U and V's are still on the WRF staggered grid.
1618 !The vorticity is then calculated at the mass points on the WRF grid.
1623 INTEGER :: jp1,jm1,ip1,im1,i,j,k
1624 INTEGER :: ns, ew, nz, k1
1626 REAL , DIMENSION(ew,nz,ns-1) :: uin !u values on unstaggered U grid
1627 REAL , DIMENSION(ew-1,nz,ns) :: vin !v values on unstaggered V grid
1628 REAL , DIMENSION(ew-1,nz,ns-1) :: vort !vort is defined on the mass points
1630 REAL , DIMENSION(ew,ns-1) :: msfu !map scale factors on U staggered grid
1631 REAL , DIMENSION(ew-1,ns) :: msfv !map scale factors on V staggered grid
1632 REAL , DIMENSION(ew-1,ns-1) :: msfm !map scale factors on unstaggered grid
1634 real :: u(ew,ns-1),v(ew-1,ns)
1639 REAL :: dsx,dsy , u1 , u2 , u3 , u4 , v1 , v2 , v3 , v4
1640 real :: dudy,dvdx,mm
1659 !Our indicies are from 2 to ns-2 and ew-2. This is because out
1660 !map scale factors are not defined for the entire grid.
1663 mm = msfm(i,j) * msfm(i,j)
1664 u1 = u(i ,j-1)/msfu(i ,j-1)
1665 u2 = u(i+1,j-1)/msfu(i+1,j-1)
1666 u3 = u(i+1,j+1)/msfu(i+1,j+1)
1667 u4 = u(i ,j+1)/msfu(i ,j+1)
1668 dudy = mm * (u4 + u3 -(u1 + u2)) /(4*ds)
1670 v1 = v(i-1,j )/msfv(i-1,j)
1671 v2 = v(i+1,j )/msfv(i+1,j)
1672 v3 = v(i-1 ,j+1)/msfv(i-1,j+1)
1673 v4 = v(i+1,j+1)/msfv(i+1,j+1)
1674 dvdx = mm * (v4 + v2 - (v1 + v3))/(4*ds)
1676 vort(i,k,j) = dvdx - dudy
1679 !Our vorticity array goes out to ew-1 and ns-1 which is the
1680 !mass point grid dimensions.
1682 vort(i,k,1) = vort(i,k,2) !bottom not corners
1683 vort(i,k,ns-1) = vort(i,k,ns-2) !top not corners
1687 vort(ew-1,k,j) = vort(ew-2,k,j) !right side including corners
1688 vort(1,k,j) = vort(2,k,j) !left side including corners
1691 end do ! this is the k loop end
1695 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1696 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1698 SUBROUTINE diverg(uin,vin,msfu,msfv,msfm,ew,ns,nz,ds,div)
1700 ! Computes divergence on unstaggered grid. The divergence is calculated
1701 ! at the mass points on the WRF grid.
1702 ! div = m*m (du/dx + dv/dy)
1706 INTEGER :: jp1,jm1,ip1,im1,i,j,k
1707 INTEGER :: ns, ew, nz, k1
1709 REAL , DIMENSION(ew,nz,ns-1) :: uin !u values on unstaggered U grid
1710 REAL , DIMENSION(ew-1,nz,ns) :: vin !v values on unstaggered V grid
1711 REAL , DIMENSION(ew-1,nz,ns-1) :: div !divergence is calculate on the mass points
1712 REAL , DIMENSION(ew,ns-1) :: msfu !map scale factors on U staggered grid
1713 REAL , DIMENSION(ew-1,ns) :: msfv !map scale factors on V staggered grid
1714 REAL , DIMENSION(ew-1,ns-1) :: msfm !map scale factors on unstaggered grid
1716 real :: u(ew,ns-1),v(ew-1,ns)
1721 REAL :: dsr,u1,u2,v1,v2
1722 real :: dudx,dvdy,mm,arg1,arg2
1739 !Our indicies are from 2 to ns-2 and ew-2. This is because out
1740 !map scale factors are not defined for the entire grid.
1743 mm = msfm(i,j) * msfm(i,j)
1744 u1 = u(i+1,j)/msfu(i+1,j)
1745 u2 = u(i ,j)/msfu(i ,j)
1747 v1 = v(i,j+1)/msfv(i,j+1)
1748 v2 = v(i,j) /msfv(i,j)
1750 div(i,k,j) = mm * (u1 - u2 + v1 - v2) * dsr
1754 !Our divergence array is defined on the mass points.
1756 div(i,k,1) = div(i,k,2) !bottom not corners
1757 div(i,k,ns-1) = div(i,k,ns-2) !top not corners
1761 div(ew-1,k,j) = div(ew-2,k,j) !right side including corners
1762 div(1,k,j) = div(2,k,j) !left side including corners
1765 end do !end for the k loop
1767 END SUBROUTINE diverg
1769 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1770 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1772 SUBROUTINE mxratprs (rh, t, ppa, ew, ns, nz, q, min_RH_value)
1777 INTEGER :: i , ew , j , ns , k , nz
1780 REAL :: min_RH_value
1781 REAL :: ppa(ew-1,nz,ns-1)
1782 REAL :: p( ew-1,nz,ns-1 )
1783 REAL :: q (ew-1,nz,ns-1),rh(ew-1,nz,ns-1),t(ew-1,nz,ns-1)
1788 REAL :: svp1,svp2,svp3
1793 ! This function is designed to compute (q) from basic variables
1794 ! p (mb), t(K) and rh(0-100%) to give (q) in (kg/kg).
1802 rh(i,k,j) = MIN ( MAX ( rh(i,k,j) ,min_RH_value ) , 100. )
1816 es = svp1 * 10. * EXP(svp2 * (t(i,k,j) - celkel ) / (t(i,k,j) - svp3 ))
1817 qs = eps * es / (p(i,k,j) - es)
1818 q(i,k,j) = MAX(0.01 * rh(i,k,j) * qs,0.0)
1823 END SUBROUTINE mxratprs
1825 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1826 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1827 SUBROUTINE mass2_Ustag(field,dim1,dim2,dim3)
1831 INTEGER :: dim1 , dim2 , dim3
1832 REAL , DIMENSION(dim1,dim2,dim3) :: field,dummy
1835 dummy(:,2:dim2-1,:) = ( field(:,1:dim2-2,:) + &
1836 field(:,2:dim2-1,:) ) * 0.5
1837 dummy(:,1,:) = field(:,1,:)
1838 dummy(:,dim2,:) = field(:,dim2-1,:)
1842 END SUBROUTINE mass2_Ustag
1844 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1845 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1846 SUBROUTINE mass2_Vstag(field,dim1,dim2,dim3)
1850 INTEGER :: dim1 , dim2 , dim3
1851 REAL , DIMENSION(dim1,dim2,dim3) :: field,dummy
1854 dummy(2:dim1-1,:,:) = ( field(1:dim1-2,:,:) + &
1855 field(2:dim1-1,:,:) ) * 0.5
1856 dummy(1,:,:) = field(1,:,:)
1857 dummy(dim1,:,:) = field(dim1-1,:,:)
1861 END SUBROUTINE mass2_Vstag
1864 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1865 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1867 SUBROUTINE relax (chi, ff, rd, ew, ns, ds, smallres, alpha)
1871 INTEGER, PARAMETER :: mm = 20000
1875 INTEGER :: ew !ew direction
1880 INTEGER :: ns !ns direction
1885 REAL :: chi(ew-1,ns-1)
1890 REAL :: ff(ew-1,ns-1)
1891 REAL :: rd(ew-1,ns-1)
1895 LOGICAL :: converged = .FALSE.
1898 alphaov4 = alpha * 0.25
1905 ff(i,j) = fac * ff(i,j)
1910 iter_loop : DO iter = 1, mm
1917 chimx(j) = MAX(ABS(chi(i,j)),chimx(j))
1921 epx = MAXVAL(chimx) * SMALLRES * 4.0 / alpha
1925 rd(i,j) = chi(i,j+1) + chi(i,j-1) + chi(i+1,j) + chi(i-1,j) - 4.0 * chi(i,j) - ff(i,j)
1926 chi(i,j) = chi(i,j) + rd(i,j) * alphaov4
1934 rdmax(j) = MAX(ABS(rd(i,j)),rdmax(j))
1939 IF (MAXVAL(rdmax) .lt. epx) THEN
1946 IF (converged ) THEN
1947 ! PRINT '(A,I5,A)','Relaxation converged in ',mi,' iterations.'
1949 PRINT '(A,I5,A)','Relaxation did not converge in',mm,' iterations.'
1955 chi(i,ns-1) = chi(i,ns-2) !top not including corners
1956 chi(i,1) = chi(i,2) !bottom not including corners
1960 chi(ew-1,j) = chi(ew-2,j) !right side not including corners
1961 chi(1,j) = chi(2,j) !left side not including corners
1964 !Fill in the corners
1966 chi(ew-1,1) = chi(ew-2,1)
1967 chi(1,ns-1) = chi(2,ns-1)
1968 chi(ew-1,ns-1) = chi(ew-2,ns-1)
1972 END SUBROUTINE relax
1973 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1974 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1975 SUBROUTINE geowind(height,ew,ns,nz,ds,ug,vg)
1979 ! input height geopotential on wrf mass grid points
1980 ! ns wrf staggered V dimension n-s
1981 ! ew wrf staggered U dimension e-w
1982 ! nz number of vertical levels
1984 ! output ug u component of geo wind on wrf staggered V points
1985 ! vg v component of geo wind on wrf staggered U points
1987 INTEGER :: ew , ns , nz
1989 REAL , DIMENSION(ew-1,nz,ns-1) :: height
1990 REAL , DIMENSION(ew,nz,ns-1) :: ug
1991 REAL , DIMENSION(ew-1,nz,ns) :: vg
1993 REAL :: ds2r , h1 , h2 , h3 , h4, ds4r
1994 INTEGER :: i , j , k
1998 ! The height field comes in on the WRF mass points.
2002 ! ug is the derivative of height in the ns direction ug = -dheight/dy
2007 h1 = height(i,k,j+1)
2008 h2 = height(i-1,k,j+1)
2009 h3 = height(i ,k,j-1)
2010 h4 = height(i-1,k,j-1)
2011 ug(i,k,j) = -( (h1 + h2) - ( h3 + h4) ) * ds4r
2017 ug(i,:,1) = ug(i,:,2) !bottom not including corner points
2018 ug(i,:,ns-1) = ug(i,:,ns-2) !top not including corner points
2022 ug(1,:,j) = ug(2,:,j) !left side
2023 ug(ew,:,j) = ug(ew-1,:,j) !right side
2026 ug(1,:,1) = ug(2,:,1) !Lower left hand corner
2027 ug(1,:,ns-1) = ug(2,:,ns-1) !upper left hand corner
2028 ug(ew,:,1) = ug(ew-1,:,1) !Lower right hand corner
2029 ug(ew,:,ns-1) = ug(ew-1,:,ns-1) !upper right hand corner
2032 ! ug is the derivative of height in the ns direction vg = dheight/dx
2037 h1 = height(i+1,k,j)
2038 h2 = height(i-1,k,j)
2039 h3 = height(i+1,k,j-1)
2040 h4 = height(i-1,k,j-1)
2041 vg(i,k,j) = ( (h1 + h3) - ( h2 + h4) ) * ds4r
2047 vg(i,:,1) = vg(i,:,2) !bottom not including corner points
2048 vg(i,:,ns) = vg(i,:,ns-1) !top not including corner points
2052 vg(1,:,j) = vg(2,:,j) !left side not including corner points
2053 vg(ew-1,:,j) = vg(ew-2,:,j) !right side not including corner points
2056 vg(1,:,1) = vg(2,:,1) !Lower left hand corner
2057 vg(1,:,ns) = vg(2,:,ns) !upper left hand corner
2058 vg(ew-1,:,1) = vg(ew-2,:,1) !Lower right hand corner
2059 vg(ew-1,:,ns) = vg(ew-2,:,ns) !upper right hand corner
2062 END SUBROUTINE geowind
2063 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2064 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2066 SUBROUTINE balance (f,psi,ew,ns,ds,out)
2068 ! Calculates the forcing terms in balance equation
2073 ! psi stream function
2074 ! ew, ns grid points in east west, north south direction, respectively
2078 INTEGER :: ew , ns,nslast,ewlast,ifill
2079 REAL , DIMENSION(ew-1,ns-1) :: f,psi,out
2082 REAL :: psixx , psiyy , psiy , psix, psixy
2083 REAL :: dssq , ds2 , dssq4,arg1,arg2,arg3,arg4
2089 dssq4 = ds * ds * 4.
2091 !The forcing terms are calculated on the WRF mass points.
2095 psiyy = ( psi(i,j+1) + psi(i,j-1) - 2.*psi(i,j) ) / dssq
2096 psixx = ( psi(i+1,j) + psi(i-1,j) - 2.*psi(i,j) ) / dssq
2097 psiy = ( psi(i,j+1) - psi(i,j-1) ) / ds2
2098 psix = ( psi(i+1,j) - psi(i-1,j) ) / ds2
2099 psixy = ( psi(i+1,j+1)+psi(i-1,j-1)-psi(i-1,j+1)-psi(i+1,j-1)) / dssq4
2101 arg1 = f(i,j)* (psixx+psiyy)
2102 arg2 = ( ( f(i,j+1) - f(i,j-1)) / ds2 ) * psiy
2103 arg3 = ( ( f(i+1,j) - f(i-1,j)) / ds2 ) * psix
2104 arg4 = 2 *(psixy*psixy-psixx*psiyy)
2105 out(i,j)= arg1 + arg2 + arg3 - arg4
2110 out(i,ns-1) = out(i,ns-2) !top not including corners
2111 out(i,1) = out(i,2) !bottom not including corners
2115 out(ew-1,j) = out(ew-2,j) !right side not including corners
2116 out(1,j) = out(2,j) !left side not including corners
2119 !Fill in the corners
2121 out(ew-1,1) = out(ew-2,1)
2122 out(1,ns-1) = out(2,ns-1)
2123 out(ew-1,ns-1) = out(ew-2,ns-1)
2125 END SUBROUTINE balance
2127 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2128 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2130 SUBROUTINE qvtorh ( q , t , p , k00, ew , ns , nz , rh, min_RH_value )
2134 INTEGER , INTENT(IN) :: ew , ns , nz , k00
2135 REAL , INTENT(IN) , DIMENSION(ew-1,nz,ns-1) :: q ,t, p
2136 REAL , INTENT(OUT) , DIMENSION(ew-1,nz,ns-1) :: rh
2142 INTEGER :: i , j , k,fill
2146 REAL :: svp1,svp2,svp3
2158 es = svp1 * 10. * EXP(svp2 * (t(i,k,j) - celkel ) / (t(i,k,j) - svp3 ))
2159 qs = eps*es/(0.01*p(i,k,j) - es)
2160 rh(i,k,j) = MIN ( 100. , MAX ( 100.*q(i,k,j)/qs , min_RH_value ) )
2165 END SUBROUTINE qvtorh
2167 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2168 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2170 SUBROUTINE stagger_rankine_winds(utcp,vtcp,ew,ns,nz)
2173 !utcp and vtcp are the output winds of the rankine subroutine
2174 !The winds are calculated on the mass points of the WRF grid
2175 !so they need to be staggered out to the WRF staggering.
2176 !The utcp is placed on the staggered ew wind grid.
2177 !The vtcp is placed on the staggered ns wind grid.
2179 !ew is the full grid dimension in the ew direction.
2180 !ns is the full grid dimension in the ns direction.
2182 !nz is the number of vertical levels.
2184 INTEGER :: ew, ns, nz, i,k,j
2185 REAL utcp(ew,nz,ns-1), vtcp(ew-1,nz,ns)
2187 !----------------------------------------------------
2192 utcp(i,k,j) = ( utcp(i-1,k,j) + utcp(i,k,j) ) /2
2197 !Fill in U's along the left and right side.
2199 utcp(1,:,j) = utcp(2,:,j)
2200 utcp(ew,:,j) = utcp(ew-1,:,j)
2208 vtcp(i,k,j) = ( vtcp(i,k,j+1) + vtcp(i,k,j-1) ) /2
2213 !Fill in V's along the bottom and bottom.
2215 vtcp(i,:,1) = vtcp(i,:,2)
2216 vtcp(i,:,ns) = vtcp(i,:,ns-1)
2220 END SUBROUTINE stagger_rankine_winds
2222 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2223 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2225 subroutine final_ew_velocity(u2,u1,chi,psi,utcr,dx,ew,ns,nz)
2228 integer :: ew,ns,nz,i,j,k
2229 real :: u1(ew,nz,ns-1),utcr(ew,nz,ns-1)
2230 real :: psi(ew-1,nz,ns-1),chi(ew-1,nz,ns-1)
2232 ! u1 is the original wind coming in from the metgrid file.
2233 ! utcr is the rankine winds rotated to the map projection put on u WRF staggered grid points.
2235 ! psi comes in on the WRF mass points. psi is the perturbation field
2236 ! calculated from the relaxation of the vorticity.
2238 ! chi is the relaxation of the divergent winds on WRF mass points.
2241 ! ew is the grid dimension of the WRF ew staggered wind
2242 ! ns is the grid dimension of the WRF ns staggered wind
2243 ! nz is the number of vertical levels
2244 ! dx is the grid spacing
2245 !-------------------------------------------------------------------------------------------
2247 real :: u2(ew,nz,ns-1)
2248 ! output array u2 is the new wind in the ew direction. Is is on WRF staggering.
2249 !-------------------------------------------------------------------------------------------
2251 real upos(ew,nz,ns-1),u0(ew,nz,ns-1),uchi(ew,nz,ns-1)
2252 ! upos is the derivative of psi in the ns direction u = -dpsi/dy
2253 ! u0 is the background ew velocity
2254 ! uchi is the array chi on the u staggered grid.
2256 real :: dx,arg1,arg2
2258 !-------------------------------------------------------------
2259 !Take the derivative of chi in the ew direction.
2261 DO k=1,nz !start of k loop
2264 uchi(i,k,j) = ( chi(i,k,j) - chi(i-1,k,j) )/dx
2269 uchi(1,k,j) = uchi(2,k,j) !fill in the left side
2270 uchi(ew,k,j) = uchi(ew-1,k,j) !fill in the right side
2274 !-----------------------------------------------------------------------------------------
2275 ! Take the derivative of psi in the ns direction.
2281 arg1 = psi(i,k,j+1) + psi(i-1,k,j+1)
2282 arg2 = psi(i,k,j-1) + psi(i-1,k,j-1)
2283 upos(i,k,j) = -( arg1 - arg2 )/(4.*dx)
2288 upos(i,k,1) = upos(i,k,2) !bottom not including corner points
2289 upos(i,k,ns-1) = upos(i,k,ns-2) !top not including corner points
2293 upos(1,k,j) = upos(2,k,j) !left side not including corners
2294 upos(ew,k,j) = upos(ew-1,k,j) !right side not including corners
2298 upos(1,k,1) = upos(2,k,1) !Lower left hand corner
2299 upos(1,k,ns-1) = upos(2,k,ns-1) !upper left hand corner
2300 upos(ew,k,1) = upos(ew-1,k,1) !Lower right hand corner
2301 upos(ew,k,ns-1) = upos(ew-1,k,ns-1) !upper right hand corner
2303 end do !k loop for dspi/dy
2307 !-----------------------------------------------------------------------------------------
2309 ! Background u field.
2310 ! Subtract the first quess wind field from the original winds.
2314 u0(i,k,j) = u1(i,k,j)-(upos(i,k,j)+uchi(i,k,j))
2320 ! Calculate the final velocity
2324 u2(i,k,j) = u0(i,k,j)+utcr(i,k,j)
2329 end subroutine final_ew_velocity
2331 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2332 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2334 subroutine final_ns_velocity(v2,v1,chi,psi,vtcr,dx,ew,ns,nz)
2337 integer :: ew,ns,nz,i,j,k
2338 real :: v1(ew-1,nz,ns),vtcr(ew-1,nz,ns)
2339 real :: psi(ew-1,nz,ns-1),chi(ew-1,nz,ns-1)
2341 ! v1 is the original wind coming in from the metgrid file.
2342 ! vtcr is the is the rankine winds rotated to the map projection put on v WRF staggered grid points.
2344 ! psi comes on the WRF mass points. psi is the perturbation field
2345 ! calculated from the relaxation of the vorticity.
2347 ! chi is the relaxation of the divergent winds on WRF mass points.
2349 ! ew is the grid dimension of the WRF ew staggered wind
2350 ! ns is the grid dimension of the WRF ns staggered wind
2351 ! nz is the number of vertical levels
2354 real :: v2(ew-1,nz,ns)
2355 ! output array v2 is the new wind in the ns direction. Is is on WRF staggering.
2358 real vpos(ew-1,nz,ns),v0(ew-1,nz,ns),vchi(ew-1,nz,ns)
2359 ! vpos is the derivative of psi in the ew direction v = dpsi/dx
2360 ! v0 is the background ns velocity
2361 ! vchi is the relaxation of the divergent wind put on v WRF staggered grid points.
2363 real :: dx,arg1,arg2
2366 !-----------------------------------------------------------------------------------------
2367 vchi(:,:,:) = -999.0
2368 !The derivative dchi in the ns direction.
2372 vchi(i,k,j) = ( chi(i,k,j) - chi(i,k,j-1))/dx
2377 vchi(i,k,1) = vchi(i,k,2)
2378 vchi(i,k,ns) = vchi(i,k,ns-1)
2381 end do !end of k loop
2383 !-----------------------------------------------------------------------------------------
2384 !Take the derivative of psi in the ew direction.
2390 arg1 = psi(i+1,k,j) + psi(i+1,k,j-1)
2391 arg2 = psi(i-1,k,j) + psi(i-1,k,j-1)
2392 vpos(i,k,j) = ( arg1 - arg2 )/(4.*dx)
2397 vpos(i,k,1) = vpos(i,k,2) !bottom not including corner points
2398 vpos(i,k,ns) = vpos(i,k,ns-1) !top not including corner points
2402 vpos(1,k,j) = vpos(2,k,j) !left side not including corner points
2403 vpos(ew-1,k,j) = vpos(ew-2,k,j) !right side not including corner points
2407 vpos(1,k,1) = vpos(2,k,1) !Lower left hand corner
2408 vpos(1,k,ns) = vpos(2,k,ns) !upper left hand corner
2409 vpos(ew-1,k,1) = vpos(ew-2,k,1) !Lower right hand corner
2410 vpos(ew-1,k,ns) = vpos(ew-2,k,ns) !upper right hand corner
2412 END DO!k loop for dspi/dx
2418 v0(i,k,j) = v1(i,k,j)-(vpos(i,k,j)+vchi(i,k,j))
2419 if( v0(i,k,j) .gt. 100.) then
2420 print *,vchi(i,k,j),i,k,j
2428 ! Calculate the final velocity
2432 v2(i,k,j) = v0(i,k,j)+vtcr(i,k,j)
2437 end subroutine final_ns_velocity
2438 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2439 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2440 subroutine final_RH(rh2,rh0,rhmx,strmci,strmcj,rmax_nstrm,ew,ns,nz,k00, &
2441 dx,ew_gcntr,ns_gcntr,r_vor2)
2446 real :: rh2(ew-1,nz,ns-1) !The final output relative humidity.
2447 real :: rh0(ew-1,nz,ns-1) !First quess rh read from the metgrid input file.
2449 real :: ew_gcntr !ew grid center as returned from the map projection routines.
2450 real :: ns_gcntr !ns grid center as returned from the map projection routines.
2451 real :: dx !grid spacing
2455 !Local real variables
2456 real :: sum_rh,avg_rh,rh_min,rhbkg,rhbog,r_ratio
2458 real :: rhtc(ew-1,nz,ns-1)
2460 integer :: nct,k00,i,j,k,ew_mvc,ns_mvc
2461 integer :: strmci(nz), strmcj(nz)
2464 !-----------------------------------------------------------------------
2475 rad = SQRT(REAL(i-ew_mvc)**2.+REAL(j-ns_mvc)**2.)*dx
2476 IF ( (rad .LT. r_vor2).AND.(rad .GE. 0.8*r_vor2) ) THEN
2477 sum_rh = sum_rh + rh0(i,k,j)
2482 avg_rh = sum_rh/MAX(REAL(nct),1.)
2487 rad = SQRT((REAL(i)-ew_gcntr)**2.+(REAL(j)-ns_gcntr)**2.)*dx
2488 IF ( rad .LE. rmax_nstrm ) THEN
2489 rhtc(i,k,j) = rh_max
2491 rhtc(i,k,j) = (rmax_nstrm/rad)*rh_max+(1.-(rmax_nstrm/rad))*rh_min
2504 rad = SQRT((REAL(i)-ew_mvc)**2.+(REAL(j)-ns_mvc)**2.)*dx
2505 IF ( (rad.GT.rmax_nstrm) .AND. (rad.LE.r_vor2) ) THEN
2506 r_ratio = (rad-rmax_nstrm)/(r_vor2-rmax_nstrm)
2507 rh2(i,k,j) = ((1.-r_ratio)*rhbog) + (r_ratio*rhbkg)
2508 ELSE IF (rad .LE. rmax_nstrm ) THEN
2520 end subroutine final_RH
2522 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2523 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!