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 : realonly
15 #ifdef NO_LEAP_CALENDAR
16 USE module_symbols_util, ONLY: wrfu_cal_noleap
18 USE module_symbols_util, ONLY: wrfu_cal_gregorian
20 USE module_utility, ONLY : WRFU_finalize
27 INTEGER :: loop , levels_to_process , debug_level
30 TYPE(domain) , POINTER :: null_domain
31 TYPE(domain) , POINTER :: grid , another_grid
32 TYPE(domain) , POINTER :: grid_ptr , grid_ptr2
33 TYPE (grid_config_rec_type) :: config_flags
34 INTEGER :: number_at_same_level
36 INTEGER :: max_dom, domain_id , grid_id , parent_id , parent_id1 , id
37 INTEGER :: e_we , e_sn , i_parent_start , j_parent_start
38 INTEGER :: idum1, idum2
41 INTEGER, PARAMETER :: configbuflen = 4* CONFIG_BUF_LEN
42 INTEGER :: configbuf( configbuflen )
43 LOGICAL , EXTERNAL :: wrf_dm_on_monitor
47 INTEGER :: ids , ide , jds , jde , kds , kde
48 INTEGER :: ims , ime , jms , jme , kms , kme
49 INTEGER :: ips , ipe , jps , jpe , kps , kpe
50 INTEGER :: ijds , ijde , spec_bdy_width
51 INTEGER :: i , j , k , idts, rc
52 INTEGER :: sibling_count , parent_id_hold , dom_loop
54 CHARACTER (LEN=80) :: message
56 INTEGER :: start_year , start_month , start_day , start_hour , start_minute , start_second
57 INTEGER :: end_year , end_month , end_day , end_hour , end_minute , end_second
58 INTEGER :: interval_seconds , real_data_init_type
59 INTEGER :: time_loop_max , time_loop, bogus_id, storm
61 real :: latc_loc(max_bogus),lonc_loc(max_bogus),vmax(max_bogus),rmax(max_bogus)
64 SUBROUTINE Setup_Timekeeping( grid )
65 USE module_domain, ONLY : domain
66 TYPE(domain), POINTER :: grid
67 END SUBROUTINE Setup_Timekeeping
70 #include "version_decl"
72 ! Define the name of this program (program_name defined in module_domain)
74 program_name = "TC_EM " // TRIM(release_version) // " PREPROCESSOR"
76 ! The TC bogus algorithm assumes that the user defines a central point, and then
77 ! allows the program to remove a typhoon based on a distance in km. This is
78 ! implemented on a single processor only.
81 IF ( .NOT. wrf_dm_on_monitor() ) THEN
82 CALL wrf_error_fatal( 'TC bogus must run with a single processor only, re-run with num procs set to 1' )
90 ! Initialize the modules used by the WRF system. Many of the CALLs made from the
91 ! init_modules routine are NO-OPs. Typical initializations are: the size of a
92 ! REAL, setting the file handles to a pre-use value, defining moisture and
93 ! chemistry indices, etc.
95 CALL wrf_debug ( 100 , 'real_em: calling init_modules ' )
96 CALL init_modules(1) ! Phase 1 returns after MPI_INIT() (if it is called)
97 #ifdef NO_LEAP_CALENDAR
98 CALL WRFU_Initialize( defaultCalKind=WRFU_CAL_NOLEAP, rc=rc )
100 CALL WRFU_Initialize( defaultCalKind=WRFU_CAL_GREGORIAN, rc=rc )
102 CALL init_modules(2) ! Phase 2 resumes after MPI_INIT() (if it is called)
104 ! The configuration switches mostly come from the NAMELIST input.
107 IF ( wrf_dm_on_monitor() ) THEN
110 CALL get_config_as_buffer( configbuf, configbuflen, nbytes )
111 CALL wrf_dm_bcast_bytes( configbuf, nbytes )
112 CALL set_config_as_buffer( configbuf, configbuflen )
113 ! CALL wrf_dm_initialize
119 CALL nl_get_debug_level ( 1, debug_level )
120 CALL set_wrf_debug_level ( debug_level )
122 CALL wrf_message ( program_name )
124 ! There are variables in the Registry that are only required for the real
125 ! program, fields that come from the WPS package. We define the run-time
126 ! flag that says to allocate space for these input-from-WPS-only arrays.
128 CALL nl_set_use_wps_input ( 1 , REALONLY )
130 ! Allocate the space for the mother of all domains.
132 NULLIFY( null_domain )
133 CALL wrf_debug ( 100 , 'real_em: calling alloc_and_configure_domain ' )
134 CALL alloc_and_configure_domain ( domain_id = 1 , &
136 parent = null_domain , &
140 CALL nl_get_max_dom ( 1 , max_dom )
142 IF ( model_config_rec%interval_seconds .LE. 0 ) THEN
143 CALL wrf_error_fatal( 'namelist value for interval_seconds must be > 0')
146 all_domains : DO domain_id = 1 , max_dom
148 IF ( ( model_config_rec%input_from_file(domain_id) ) .OR. &
149 ( domain_id .EQ. 1 ) ) THEN
151 CALL Setup_Timekeeping ( grid )
152 CALL set_current_grid_ptr( grid )
153 CALL domain_clockprint ( 150, grid, &
154 'DEBUG real: clock after Setup_Timekeeping,' )
155 CALL domain_clock_set( grid, &
156 time_step_seconds=model_config_rec%interval_seconds )
157 CALL domain_clockprint ( 150, grid, &
158 'DEBUG real: clock after timeStep set,' )
161 CALL wrf_debug ( 100 , 'tc_em: calling set_scalar_indices_from_config ' )
162 CALL set_scalar_indices_from_config ( grid%id , idum1, idum2 )
164 !This is goofy but we need to loop through the number of storms to get
165 !the namelist variables for the tc_bogus. But then we need to
166 !call model_to_grid_config_rec with the grid%id = to 1 in order to
167 !reset to the correct information.
168 CALL wrf_debug ( 100 , 'tc_em: calling model_to_grid_config_rec ' )
173 CALL model_to_grid_config_rec ( grid%id , model_config_rec , config_flags )
174 lonc_loc(1) = config_flags%lonc_loc
175 latc_loc(1) = config_flags%latc_loc
176 vmax(1) = config_flags%vmax_meters_per_second
177 rmax(1) = config_flags%rmax
178 rankine_lid = config_flags%rankine_lid
179 do storm = 2,config_flags%num_storm
181 CALL model_to_grid_config_rec ( bogus_id , model_config_rec , config_flags )
182 lonc_loc(storm) = config_flags%lonc_loc
183 latc_loc(storm) = config_flags%latc_loc
184 vmax(storm) = config_flags%vmax_meters_per_second
185 rmax(storm) = config_flags%rmax
186 ! print *,"in loop ",storm,lonc_loc(storm),latc_loc(storm),vmax(storm),rmax(storm)
188 CALL model_to_grid_config_rec ( grid%id , model_config_rec , config_flags )
190 ! Initialize the WRF IO: open files, init file handles, etc.
192 CALL wrf_debug ( 100 , 'tc_em: calling init_wrfio' )
195 ! Some of the configuration values may have been modified from the initial READ
196 ! of the NAMELIST, so we re-broadcast the configuration records.
199 CALL wrf_debug ( 100 , 'tc_em: re-broadcast the configuration records' )
200 CALL get_config_as_buffer( configbuf, configbuflen, nbytes )
201 CALL wrf_dm_bcast_bytes( configbuf, nbytes )
202 CALL set_config_as_buffer( configbuf, configbuflen )
205 ! No looping in this layer.
207 CALL wrf_debug ( 100 , 'calling tc_med_sidata_input' )
208 CALL tc_med_sidata_input ( grid , config_flags, latc_loc, lonc_loc, &
209 vmax,rmax,rankine_lid)
210 CALL wrf_debug ( 100 , 'backfrom tc_med_sidata_input' )
218 CALL set_current_grid_ptr( head_grid )
222 CALL wrf_debug ( 0 , 'tc_em: SUCCESS COMPLETE TC BOGUS' )
226 CALL WRFU_Finalize( rc=rc )
232 !-----------------------------------------------------------------
233 SUBROUTINE tc_med_sidata_input ( grid , config_flags, latc_loc, lonc_loc, &
234 vmax, rmax,rankine_lid)
240 USE module_bc_time_utilities
241 USE module_optional_input
251 SUBROUTINE start_domain ( grid , allowed_to_read ) ! comes from module_start in appropriate dyn_ directory
254 LOGICAL, INTENT(IN) :: allowed_to_read
255 END SUBROUTINE start_domain
260 TYPE (grid_config_rec_type) :: config_flags
262 INTEGER :: time_step_begin_restart
263 INTEGER :: idsi , ierr , myproc, internal_time_loop,iflag
264 ! Declarations for the netcdf routines.
267 CHARACTER (LEN=80) :: si_inpname
268 CHARACTER (LEN=80) :: message
270 CHARACTER(LEN=19) :: start_date_char , end_date_char , current_date_char , next_date_char
271 CHARACTER(LEN=8) :: flag_name
273 INTEGER :: time_loop_max , loop, rc,icnt,itmp
274 INTEGER :: julyr , julday ,metndims, metnvars, metngatts, nunlimdimid,rcode
277 real :: latc_loc(max_bogus), lonc_loc(max_bogus)
278 real :: vmax(max_bogus),rmax(max_bogus),rankine_lid
280 grid%input_from_file = .true.
281 grid%input_from_file = .false.
283 CALL tc_compute_si_start ( model_config_rec%start_year (grid%id) , &
284 model_config_rec%start_month (grid%id) , &
285 model_config_rec%start_day (grid%id) , &
286 model_config_rec%start_hour (grid%id) , &
287 model_config_rec%start_minute(grid%id) , &
288 model_config_rec%start_second(grid%id) , &
289 model_config_rec%interval_seconds , &
290 model_config_rec%real_data_init_type , &
293 end_date_char = start_date_char
294 IF ( end_date_char .LT. start_date_char ) THEN
295 CALL wrf_error_fatal( 'Ending date in namelist ' // end_date_char // ' prior to beginning date ' // start_date_char )
297 print *,"the start date char ",start_date_char
298 print *,"the end date char ",end_date_char
301 ! Override stop time with value computed above.
302 CALL domain_clock_set( grid, stop_timestr=end_date_char )
304 ! TBH: for now, turn off stop time and let it run data-driven
305 CALL WRFU_ClockStopTimeDisable( grid%domain_clock, rc=rc )
306 CALL wrf_check_error( WRFU_SUCCESS, rc, &
307 'WRFU_ClockStopTimeDisable(grid%domain_clock) FAILED', &
310 CALL domain_clockprint ( 150, grid, &
311 'DEBUG med_sidata_input: clock after stopTime set,' )
313 ! Here we define the initial time to process, for later use by the code.
315 current_date_char = start_date_char
316 start_date = start_date_char // '.0000'
317 current_date = start_date
319 CALL nl_set_bdyfrq ( grid%id , REAL(model_config_rec%interval_seconds) )
323 DO loop = 1 , time_loop_max
325 internal_time_loop = loop
326 IF ( ( grid%id .GT. 1 ) .AND. ( loop .GT. 1 ) .AND. &
327 ( model_config_rec%grid_fdda(grid%id) .EQ. 0 ) .AND. &
328 ( model_config_rec%sst_update .EQ. 0 ) ) EXIT
331 print *,'-----------------------------------------------------------------------------'
333 print '(A,I2,A,A,A,I4,A,I4)' , &
334 ' Domain ',grid%id,': Current date being processed: ',current_date, ', which is loop #',loop,' out of ',time_loop_max
336 ! After current_date has been set, fill in the julgmt stuff.
338 CALL geth_julgmt ( config_flags%julyr , config_flags%julday , config_flags%gmt )
340 print *,'configflags%julyr, %julday, %gmt:',config_flags%julyr, config_flags%julday, config_flags%gmt
341 ! Now that the specific Julian info is available, save these in the model config record.
343 CALL nl_set_gmt (grid%id, config_flags%gmt)
344 CALL nl_set_julyr (grid%id, config_flags%julyr)
345 CALL nl_set_julday (grid%id, config_flags%julday)
347 ! Open the input file for tc stuff. Either the "new" one or the "old" one. The "new" one could have
348 ! a suffix for the type of the data format. Check to see if either is around.
351 WRITE ( wrf_err_message , FMT='(A,A)' )'med_sidata_input: calling open_r_dataset for ', &
352 TRIM(config_flags%auxinput1_inname)
353 CALL wrf_debug ( 100 , wrf_err_message )
354 IF ( config_flags%auxinput1_inname(1:8) .NE. 'wrf_real' ) THEN
355 CALL construct_filename4a( si_inpname , config_flags%auxinput1_inname , grid%id , 2 , &
356 current_date_char , config_flags%io_form_auxinput1 )
358 CALL construct_filename2a( si_inpname , config_flags%auxinput1_inname , grid%id , 2 , &
361 CALL open_r_dataset ( idsi, TRIM(si_inpname) , grid , config_flags , "DATASET=AUXINPUT1", ierr )
362 IF ( ierr .NE. 0 ) THEN
363 CALL wrf_error_fatal( 'error opening ' // TRIM(si_inpname) // &
364 ' for input; bad date in namelist or file not in directory' )
369 CALL wrf_debug ( 100 , 'med_sidata_input: calling input_auxinput1' )
370 CALL input_auxinput1 ( idsi , grid , config_flags , ierr )
371 WRITE ( wrf_err_message , FMT='(A,I10,A)' ) 'Timing for input ',NINT(t4-t3) ,' s.'
372 CALL wrf_debug( 0, wrf_err_message )
374 ! Possible optional SI input. This sets flags used by init_domain.
377 CALL wrf_debug ( 100 , 'med_sidata_input: calling init_module_optional_input' )
378 CALL init_module_optional_input ( grid , config_flags )
379 CALL wrf_debug ( 100 , 'med_sidata_input: calling optional_input' )
380 CALL optional_input ( grid , idsi , config_flags )
382 !Here we check the flags yet again. The flags are checked in optional_input but
383 !the grid% flags are not set.
384 flag_name(1:8) = 'SM000010'
385 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
386 IF ( ierr .EQ. 0 ) THEN
387 grid%flag_sm000010 = 1
390 flag_name(1:8) = 'SM010040'
391 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
392 IF ( ierr .EQ. 0 ) THEN
393 grid%flag_sm010040 = 1
396 flag_name(1:8) = 'SM040100'
397 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
398 IF ( ierr .EQ. 0 ) THEN
399 grid%flag_sm040100 = itmp
403 flag_name(1:8) = 'SM100200'
404 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
405 IF ( ierr .EQ. 0 ) THEN
406 grid%flag_sm100200 = itmp
409 ! flag_name(1:8) = 'SM010200'
410 ! CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
411 ! IF ( ierr .EQ. 0 ) THEN
412 ! config_flags%flag_sm010200 = itmp
413 ! print *,"found the flag_sm010200 "
416 !Now the soil temperature flags
417 flag_name(1:8) = 'ST000010'
418 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
419 IF ( ierr .EQ. 0 ) THEN
420 grid%flag_st000010 = 1
424 flag_name(1:8) = 'ST010040'
425 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
426 IF ( ierr .EQ. 0 ) THEN
427 grid%flag_st010040 = 1
430 flag_name(1:8) = 'ST040100'
431 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
432 IF ( ierr .EQ. 0 ) THEN
433 grid%flag_st040100 = 1
437 flag_name(1:8) = 'ST100200'
438 CALL wrf_get_dom_ti_integer ( idsi, 'FLAG_' // flag_name, itmp, 1, icnt, ierr )
439 IF ( ierr .EQ. 0 ) THEN
440 grid%flag_st100200 = 1
445 CALL close_dataset ( idsi , config_flags , "DATASET=AUXINPUT1" )
448 ! Possible optional SI input. This sets flags used by init_domain.
449 ! We need to call the optional input routines to get the flags that
450 ! are in the metgrid output file so they can be put in the tc bogus
451 ! output file for real to read.
453 already_been_here = .FALSE.
454 CALL model_to_grid_config_rec ( grid%id , model_config_rec , config_flags )
459 CALL assemble_output ( grid , config_flags , loop , time_loop_max, current_date_char, &
460 latc_loc, lonc_loc, vmax, rmax, rankine_lid,si_inpname)
462 WRITE ( wrf_err_message , FMT='(A,I10,A)' ) 'Timing for output ',NINT(t4-t3) ,' s.'
463 CALL wrf_debug( 0, wrf_err_message )
465 WRITE ( wrf_err_message , FMT='(A,I4,A,I10,A)' ) 'Timing for loop # ',loop,' = ',NINT(t2-t1) ,' s.'
466 CALL wrf_debug( 0, wrf_err_message )
471 END SUBROUTINE tc_med_sidata_input
474 !-------------------------------------------------------------------------------------
475 SUBROUTINE tc_compute_si_start( &
476 start_year , start_month , start_day , start_hour , start_minute , start_second , &
477 interval_seconds , real_data_init_type , &
484 INTEGER :: start_year , start_month , start_day , start_hour , start_minute , start_second
485 INTEGER :: end_year , end_month , end_day , end_hour , end_minute , end_second
486 INTEGER :: interval_seconds , real_data_init_type
487 INTEGER :: time_loop_max , time_loop
489 CHARACTER(LEN=19) :: current_date_char , start_date_char , end_date_char , next_date_char
492 WRITE ( start_date_char , FMT = '(I4.4,"-",I5.5,"_",I2.2,":",I2.2,":",I2.2)' ) &
493 start_year,start_day,start_hour,start_minute,start_second
495 WRITE ( start_date_char , FMT = '(I4.4,"-",I2.2,"-",I2.2,"_",I2.2,":",I2.2,":",I2.2)' ) &
496 start_year,start_month,start_day,start_hour,start_minute,start_second
500 END SUBROUTINE tc_compute_si_start
502 !-----------------------------------------------------------------------
503 SUBROUTINE assemble_output ( grid , config_flags , loop , time_loop_max,current_date_char, &
504 latc_loc, lonc_loc,vmax,rmax,rankine_lid,si_inpname)
506 USE module_big_step_utilities_em
515 TYPE (grid_config_rec_type) :: config_flags
517 INTEGER , INTENT(IN) :: loop , time_loop_max
519 !These values are in the name list and are avaiable from
520 !from the config_flags.
521 real :: vmax(max_bogus),vmax_ratio,rankine_lid
522 real :: rmax(max_bogus),stand_lon,cen_lat,ptop_in_pa
523 real :: latc_loc(max_bogus),lonc_loc(max_bogus)
525 INTEGER :: ijds , ijde , spec_bdy_width
526 INTEGER :: i , j , k , idts,map_proj,remove_only,storms
528 INTEGER :: id1 , interval_seconds , ierr, rc, sst_update, grid_fdda
529 INTEGER , SAVE :: id, id2, id4
530 CHARACTER (LEN=80) :: tcoutname , bdyname,si_inpname
531 CHARACTER(LEN= 4) :: loop_char
532 CHARACTER(LEN=19) :: current_date_char
534 character *19 :: temp19
535 character *24 :: temp24 , temp24b
537 real::t1,t2,truelat1,truelat2
540 ! Boundary width, scalar value.
542 spec_bdy_width = model_config_rec%spec_bdy_width
543 interval_seconds = model_config_rec%interval_seconds
544 sst_update = model_config_rec%sst_update
545 grid_fdda = model_config_rec%grid_fdda(grid%id)
546 truelat1 = config_flags%truelat1
547 truelat2 = config_flags%truelat2
549 stand_lon = config_flags%stand_lon
550 cen_lat = config_flags%cen_lat
551 map_proj = config_flags%map_proj
553 vmax_ratio = config_flags%vmax_ratio
554 ptop_in_pa = config_flags%p_top_requested
556 if(config_flags%remove_storm) then
560 storms = config_flags%num_storm
561 print *,"number of storms ",config_flags%num_storm
562 call tc_bogus(cen_lat,stand_lon,map_proj,truelat1,truelat2, &
563 grid%dx,grid%e_we,grid%e_sn,grid%num_metgrid_levels,ptop_in_pa, &
564 rankine_lid,latc_loc,lonc_loc,vmax,vmax_ratio,rmax,remove_only, &
569 ! Open the tc bogused output file. cd
570 CALL construct_filename4a( tcoutname , config_flags%auxinput1_outname , grid%id , 2 , &
571 current_date_char , config_flags%io_form_auxinput1 )
573 print *,"outfile name from construct filename ",tcoutname
574 CALL open_w_dataset ( id1, TRIM(tcoutname) , grid , config_flags ,output_auxinput1,"DATASET=AUXINPUT1",ierr )
575 IF ( ierr .NE. 0 ) THEN
576 CALL wrf_error_fatal( 'tc_em: error opening tc bogus file for writing' )
578 CALL output_auxinput1( id1, grid , config_flags , ierr )
579 CALL close_dataset ( id1 , config_flags , "DATASET=AUXINPUT1" )
582 END SUBROUTINE assemble_output
584 !----------------------------------------------------------------------------------------------
586 SUBROUTINE tc_bogus(centerlat,stdlon,nproj,truelat1,truelat2,dsm,ew,ns,nz,ptop_in_pa, &
587 rankine_lid,latc_loc,lonc_loc,vmax,vmax_ratio,rmax,remove_only, &
590 !!Original Author Dave Gill. Modified by Sherrie Fredrick
591 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
592 !These are read in from the netcdf file.
593 !centerlat The center latitude from the global attributes in the netcdf file.
594 !stdlon The center longitude from the global attributes in the netcdf file.
595 !nproj The map projection from the global attributes in the netcdf file.
596 !dsm The spacing in meters from the global attributes in the netcdf file.
597 !ew The west_east_stag from the dimensions in the netcdf file..
598 !ns The south_north_stag from the dimensions in the netcdf file. .
599 !nz The number of metgrid levels from the dimensions in the netcdf file.
601 !ptop_in_pa This is part of the namelist.input file under the &domains section.
603 !These values are part of the namelist.input file under the &tc section specifically
604 !for the tc bogus code.
605 !NOTES: There can be up to five bogus storms. The variable max_bogus is set in
606 !the WRF subroutine called module_driver_constants.F in the ./WRFV3/frame directory.
608 !latc_loc The center latitude of the bogus strorm. This is an array dimensioned max_bogus.
610 !lonc_loc The center longitude of the bogus strorm. This is an array dimensioned max_bogus.
612 !vmax The max vortex in meters/second it comes from the namelist entry.
613 ! This is an array dimensioned max_bogus.
615 !vmax_ratio This comes from the namelist entry.
617 !rmax The maximum radius this comes from the namelist entry.
618 ! This is an array dimensioned max_bogus
620 !remove_only If this is set to true in the namelist.input file a value of 0.1
621 ! is automatically assigned to vmax.
623 !rankine_lid This comes from the namelist entry. It can be used to determine
624 ! what model levels the bogus storm affects.
626 !storms The number of bogus storms.
628 !grid This is a Fortran structure which holds all of the field data values
629 ! for the netcdf that was read in.
630 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
633 !module_llxy resides in the share directory.
635 !This is for the large structure (grid)
645 real :: centerlat,stdlon,conef,truelat1,truelat2,dsm,dx,rankine_lid
646 real :: latc_loc(max_bogus),lonc_loc(max_bogus),vmax(max_bogus),vmax_ratio,rmax(max_bogus)
648 real :: press(ew-1,nz,ns-1),rhmx(nz), vwgt(nz),old_slp(ew-1,ns-1)
649 real, dimension(:,:,:) , allocatable :: u11,v11,t11,rh11,phi11
650 real, dimension(:,:,:) , allocatable :: u1 , v1 , t1 , rh1 , phi1
651 real, dimension(ew-1,ns-1) :: lond,terrain,cor,pslx
654 !The map scale factors.
655 real, dimension(ew,ns-1) :: msfu !The mapscale factor for the ew wind staggered grid
656 real, dimension(ew-1,ns) :: msfv !The mapscale factor for the ns wind staggered grid
657 real, dimension(ew-1,ns-1) :: msfm !The mapscale factor for the unstaggered grid.
663 real :: r_search,r_vor,beta,devps,humidity_max
664 real :: devpc,const,r_vor2,cnst,alphar,epsilon,vormx , rad , sum_q
665 real :: avg_q ,q_old,ror,q_new,dph,dphx0
666 real :: rh_max,min_RH_value,ps
667 integer :: vert_variation
668 integer :: i,k,j,kx,remove_only
669 integer :: k00,kfrm ,kto ,k85,n_iter,ew_mvc,ns_mvc,nct,itr
670 integer :: strmci(nz), strmcj(nz)
671 real :: disx,disy,alpha,degran,pie,rovcp,cp
672 REAL :: rho,pprm,phip0,x0,y0,vmx,xico,xjco,xicn,xjcn,p85,xlo,rconst,ew_gcntr,ns_gcntr
673 real :: ptop_in_pa,themax,themin
674 real :: latinc,loninc
675 real :: rtemp,colat0,colat
676 REAL :: q1(ew-1,nz,ns-1), psi1(ew-1,nz,ns-1)
678 ! This is the entire map projection enchilada.
679 TYPE(proj_info) :: proj
684 ! These values are read in from the data set.
685 real :: knowni,knownj
688 REAL utcr(ew,nz,ns-1), vtcr(ew-1,nz,ns)
689 REAL utcp(ew,nz,ns-1), vtcp(ew-1,nz,ns)
690 REAL psitc(ew-1,nz,ns-1), psiv(nz)
691 REAL vortc(ew-1,nz,ns-1), vorv(nz)
692 REAL tptc(ew-1,nz,ns-1)
693 REAL phiptc(ew-1,nz,ns-1)
696 REAL uuwork(nz), vvwork(nz), temp2(ew,ns)
697 REAL vort(ew-1,nz,ns-1), div(ew-1,nz,ns-1)
698 REAL vortsv(ew-1,nz,ns-1)
699 REAL theta(ew-1,nz,ns-1), t_reduce(ew-1,nz,ns-1)
700 REAL ug(ew,nz,ns-1), vg(ew-1,nz,ns), vorg(ew-1,nz,ns-1)
701 REAL delpx(ew-1,ns-1)
703 !subroutines for relaxation
704 REAL outold(ew-1,ns-1)
705 REAL rd(ew-1,ns-1), ff(ew-1,ns-1)
706 REAL tmp1(ew-1,ns-1), tmp2(ew-1,ns-1)
709 REAL , DIMENSION (ew-1,nz,ns-1) :: t0, t00, rh0, q0, phi0, psi0, chi
712 REAL , DIMENSION (ew-1,nz,ns-1) :: psipos, tpos, psi ,phipos, phip
715 REAL u2(ew,nz,ns-1), v2(ew-1,nz,ns)
716 REAL t2(ew-1,nz,ns-1),z2(ew-1,nz,ns-1)
717 REAL phi2(ew-1,nz,ns-1),rh2(ew-1,nz,ns-1)
719 print *,"the dimensions: north-south = ",ns," east-west =",ew
720 IF (nproj .EQ. 1) THEN
722 print *,"Lambert Conformal projection"
723 ELSE IF (nproj .EQ. 2) THEN
725 ELSE IF (nproj .EQ. 3) THEN
727 print *,"A mercator projection"
733 pie = 3.141592653589793
751 if(remove_only .eq. 1) then
757 ! Set up initializations for map projection so that the lat/lon
758 ! of the tropical storm can be put into model (i,j) space. This needs to be done once per
759 ! map projection definition. Since this is the domain that we are "GOING TO", it is a once
760 ! per regridder requirement. If the user somehow ends up calling this routine for several
761 ! time periods, there is no problemos, just a bit of overhead with redundant calls.
764 lat1 = grid%xlat_gc(1,1)
765 lon1 = grid%xlong_gc(1,1)
766 IF( jproj .EQ. 'ME' )THEN
767 IF ( lon1 .LT. -180. ) lon1 = lon1 + 360.
768 IF ( lon1 .GT. 180. ) lon1 = lon1 - 360.
769 IF ( stdlon .LT. -180. ) stdlon = stdlon + 360.
770 IF ( stdlon .GT. 180. ) stdlon = stdlon - 360.
771 CALL map_set ( proj_merc, proj, lat1, lon1, lat1, lon1, knowni, knownj, dx, &
772 latinc,loninc,stdlon , truelat1 , truelat2)
774 ELSE IF ( jproj .EQ. 'LC' ) THEN
775 if((truelat1 .eq. 0.0) .and. (truelat2 .eq. 0.0)) then
776 print *,"Truelat1 and Truelat2 are both 0"
779 CALL map_set (proj_lc,proj, lat1, lon1, lat1, lon1, knowni, knownj, dx, &
780 latinc,loninc,stdlon , truelat1 , truelat2)
782 ELSE IF ( jproj .EQ. 'ST' ) THEN
784 CALL map_set ( proj_ps,proj,lat1, lon1, lat1, lon1, knowni, knownj, dx, &
785 latinc,loninc,stdlon , truelat1 , truelat2)
788 ! Load the pressure array.
793 press(i,k,j) = grid%p_gc(i,k,j)*0.01
799 ! Initialize the vertical profiles for humidity and weighting.
800 !The ptop variable will be read in from the namelist
801 IF ( ( ptop_in_pa .EQ. 40000. ) .OR. ( ptop_in_pa .EQ. 60000. ) ) THEN
802 PRINT '(A)','Hold on pardner, your value for PTOP is gonna cause problems for the TC bogus option.'
803 PRINT '(A)','Make it higher up than 400 mb.'
804 STOP 'ptop_woes_for_tc_bogus'
807 IF ( vert_variation .EQ. 1 ) THEN
809 IF ( press(1,k,1) .GT. 400. ) THEN
810 rhmx(k) = humidity_max
812 rhmx(k) = humidity_max * MAX( 0.1 , (press(1,k,1) - ptop_in_pa/100.)/(400.-ptop_in_pa/100.) )
815 IF ( press(1,k,1) .GT. 600. ) THEN
817 ELSE IF ( press(1,k,1) .LE. 100. ) THEN
820 vwgt(k) = MAX ( 0.0001 , (press(1,k,1)-ptop_in_pa/100.)/(600.-ptop_in_pa/100.) )
824 ELSE IF ( vert_variation .EQ. 2 ) THEN
825 IF ( kx .eq. 24 ) THEN
826 rhmx = (/ 95., 95., 95., 95., 95., 95., 95., 95., &
827 95., 95., 95., 95., 95., 90., 85., 80., 75., &
828 70., 66., 60., 39., 10., 10., 10./)
829 vwgt = (/ 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 0.9850, &
830 0.9680, 0.9500, 0.9290, 0.9060, 0.8810, 0.8500, 0.7580, 0.6500, 0.5100, &
831 0.3500, 0.2120, 0.0500, 0.0270, 0.0001, 0.0001, 0.0001/)
833 PRINT '(A)','Number of vertical levels assumed to be 24 for AFWA TC bogus option'
834 STOP 'AFWA_TC_BOGUS_LEVEL_ERROR'
838 !Remember that ns = the north south staggered. This is one more than the ns mass point grid.
839 ! ew = the east west staggered. This is one more than the ew mass point grid.
842 !Put the U and V into the new arrays.
843 !Remember that the WRF ordering is ew,vert level,ns
844 !Vorticity and Divergence calculatins are done on
845 !the staggered grids so the winds are not destaggered
846 allocate(u11 (1:ew, 1:nz, 1:ns-1))
847 allocate(u1 (1:ew, 1:nz, 1:ns-1))
848 allocate(v11 (1:ew-1, 1:nz, 1:ns))
849 allocate(v1 (1:ew-1, 1:nz, 1:ns))
853 u11(i,k,j) = grid%u_gc(i,k,j)
854 u1(i,k,j) = grid%u_gc(i,k,j)
855 msfu(i,j) = grid%msfu(i,j) !map scale factor on the U staggered grid
864 v11(i,k,j) = grid%v_gc(i,k,j)
865 v1(i,k,j) = grid%v_gc(i,k,j)
866 msfv(i,j) = grid%msfv(i,j) !map scale factor on the V staggered grid
872 !Put the temperature, relative humidity and height fields
873 !into arrays. Save the initial fields also.
874 !These arrays are on the WRF mass points
875 allocate(t11 (1:ew-1, 1:nz, 1:ns-1))
876 allocate(t1 (1:ew-1, 1:nz, 1:ns-1))
877 allocate(rh11 (1:ew-1, 1:nz, 1:ns-1))
878 allocate(rh1 (1:ew-1, 1:nz, 1:ns-1))
879 allocate(phi11(1:ew-1, 1:nz, 1:ns-1))
880 allocate(phi1 (1:ew-1, 1:nz, 1:ns-1))
884 t11(i,k,j) = grid%t_gc(i,k,j)
885 t1(i,k,j) = grid%t_gc(i,k,j)
886 rh11(i,k,j) = grid%rh_gc(i,k,j)
887 rh1(i,k,j) = grid%rh_gc(i,k,j)
888 msfm(i,j) = grid%msft(i,j)
890 phi11(i,k,j) = grid%ht_gc(i,j)
891 phi1(i,k,j) = grid%ht_gc(i,j) * 9.81
893 phi11(i,k,j) = grid%ght_gc(i,k,j)
894 phi1(i,k,j) = grid%ght_gc(i,k,j) * 9.81
901 !The terrain soil height is from ght at level 1
904 pslx(i,j) = grid%pslv_gc(i,j) * 0.01
905 cor(i,j) = grid%f(i,j) !coreolous
906 lond(i,j) = grid%xlong_gc(i,j)
907 terrain(i,j) = grid%ht_gc(i,j)
908 old_slp(i,j) = grid%pslv_gc(i,j)
914 ! Loop over the number of storms to process.
917 all_storms : DO nstrm=1,storms
920 !Make sure the user has defined the rmax variable
921 if(rmax(nstrm) .eq. -999.) then
922 print *,"Please enter a value for rmax in the namelist"
933 IF ( press(1,k,1) .GE. p85 ) THEN
940 ! Parameters for max wind
946 !latc_loc and lonc_loc come in from the namelist.
947 !These x0 and y0 points are relative to the mass points.
948 CALL latlon_to_ij ( proj , latc_loc(nstrm) , lonc_loc(nstrm) , x0 , y0 )
949 IF ( ( x0 .LT. 1. ) .OR. ( x0 .GT. REAL(ew-1) ) .OR. &
950 ( y0 .LT. 1. ) .OR. ( y0 .GT. REAL(ns-1) ) ) THEN
951 PRINT '(A,I3,A,A,A)',' Storm position is outside the computational domain.'
952 PRINT '(A,2F6.2,A)' ,' Storm postion: (x,y) = ',x0,y0,'.'
957 ! Bogus vortex specifications, vmax (m/s); rmax (m);
958 vmx = vmax(nstrm) * vmax_ratio
960 IF ( latc_loc(nstrm) .LT. 0. ) THEN
964 IF ( vmax(nstrm) .LE. 0. ) THEN
965 vmx = SQRT( 2.*(1-beta)*ABS(phip0) )
968 ew_gcntr = x0 !ew center grid location
969 ns_gcntr = y0 !ns center grid location
970 !For right now we are adding 0.5 to the grid location this
971 !makes the output of the wrf tc_bogus scheme analogous to the
972 !ouput of the MM5 tc_bogus scheme.
980 PRINT '(/,A,I3,A,A,A)' ,'---> TC: Processing storm number= ',nstrm
981 PRINT '(A,F6.2,A,F7.2,A)' ,' Storm center lat= ',latc_loc(nstrm),' lon= ',lonc_loc(nstrm),'.'
982 PRINT '(A,2F6.2,A)' ,' Storm center grid position (x,y)= ',ew_gcntr,ns_gcntr,'.'
983 PRINT '(A,F5.2,F9.2,A)' ,' Storm max wind (m/s) and max radius (m)= ',vmx,rmax(nstrm),'.'
984 PRINT '(A,F5.2,A)' ,' Estimated central press dev (mb)= ',devpc,'.'
987 ! Initialize storm center to (1,1)
994 ! Define complete field of bogus storm
995 !Note dx is spacing in meters.
996 !The output arrays from the rankine subroutine vvwork,uuwork,psiv and vorv
997 !are defined on the WRF mass points.
1000 print *,"nstrm ",rmax(nstrm),ew_gcntr,ns_gcntr
1003 disx = REAL(i) - ew_gcntr
1004 disy = REAL(j) - ns_gcntr
1005 CALL rankine(disx,disy,dx,kx,vwgt,rmax(nstrm),vmx,uuwork,vvwork,psiv,vorv)
1007 utcp(i,k,j) = uuwork(k)
1008 vtcp(i,k,j) = vvwork(k)
1009 psitc(i,k,j) = psiv(k)
1010 vortc(i,k,j) = vorv(k)
1014 call stagger_rankine_winds(utcp,vtcp,ew,ns,nz)
1019 ! dave Rotate wind to map proj, on the correct staggering
1022 xlo = stdlon-grid%xlong_u(i,j)
1023 IF ( xlo .GT. 180.)xlo = xlo-360.
1024 IF ( xlo .LT.-180.)xlo = xlo+360.
1026 alpha = xlo*conef*degran*SIGN(1.,centerlat)
1028 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)
1029 if(utcr(i,k,j) .gt. 300.) then
1030 print *,i,k,j,"a very bad value of utcr"
1040 xlo = stdlon-grid%xlong_v(i,j)
1041 IF ( xlo .GT. 180.)xlo = xlo-360.
1042 IF ( xlo .LT.-180.)xlo = xlo+360.
1044 alpha = xlo*conef*degran*SIGN(1.,centerlat)
1046 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)
1047 if(vtcr(i,k,j) .gt. 300.) then
1048 print *,i,k,j,"a very bad value of vtcr"
1056 !Fill in UTCR's along the left and right side.
1058 utcr(1,:,j) = utcr(2,:,j)
1059 utcr(ew,:,j) = utcr(ew-1,:,j)
1062 !Fill in V's along the bottom and top.
1064 vtcr(i,:,1) = vtcr(i,:,2)
1065 vtcr(i,:,ns) = vtcr(i,:,ns-1)
1069 ! Compute vorticity of FG. This is the vorticity of the original winds
1070 ! on the staggered grid. The vorticity and divergence are defined at
1071 ! the mass points when done.
1072 CALL vor(u1,v1,msfu,msfv,msfm,ew,ns,kx,dx,vort)
1075 ! Compute divergence of FG
1076 CALL diverg(u1,v1,msfu,msfv,msfm,ew,ns,kx,dx,div)
1079 ! Compute mixing ratio of FG
1080 CALL mxratprs(rh1,t1,press*100.,ew,ns,kx,q1,min_RH_value)
1081 q1(:,1,:) = q1(:,2,:)
1084 ! Compute initial streamfunction - PSI1
1089 ! Solve for streamfunction.
1093 ff(i,j) = vort(i,k,j)
1098 CALL relax(tmp1,ff,rd,ew,ns,dx,epsilon,alphar)
1101 psi1(i,k,j) = tmp1(i,j)
1107 DO k=1,kx !start of the k loop
1108 IF ( latc_loc(nstrm) .GE. 0. ) THEN
1119 rad = SQRT((REAL(i)-ew_gcntr)**2.+(REAL(j)-ns_gcntr)**2.)*dx
1120 IF ( rad .LE. r_search ) THEN
1121 IF ( latc_loc(nstrm) .GE. 0. ) THEN
1122 IF ( vortsv(i,k,j) .GT. vormx ) THEN
1123 vormx = vortsv(i,k,j)
1127 ELSE IF (latc_loc(nstrm) .LT. 0. ) THEN
1128 IF ( vortsv(i,k,j) .LT. vormx ) THEN
1129 vormx = vortsv(i,k,j)
1143 rad = SQRT(REAL((i-ew_mvc)**2.+(j-ns_mvc)**2.))*dx
1144 IF ( rad .GT. r_vor ) THEN
1156 rad = SQRT(REAL(i-ew_mvc)**2.+REAL(j-ns_mvc)**2.)*dx
1157 IF ( (rad .LT. r_vor2).AND.(rad .GE. 0.8*r_vor2) ) THEN
1158 sum_q = sum_q + q0(i,k,j)
1163 avg_q = sum_q/MAX(REAL(nct),1.)
1168 rad = SQRT(REAL(i-ew_mvc)**2.+REAL(j-ns_mvc)**2.)*dx
1169 IF ( rad .LT. r_vor2 ) THEN
1171 q_new = ((1.-ror)*avg_q) + (ror*q_old)
1176 END DO !end of itr loop
1177 END DO !of the k loop
1180 ! Compute divergent wind (chi) at the mass points
1184 ff(i,j) = div(i,k,j)
1190 CALL relax(tmp1,ff,rd,ew,ns,dx,epsilon,alphar)
1193 chi(i,k,j) = tmp1(i,j)
1196 END DO !of the k loop for divergent winds
1200 ! Compute background streamfunction (PSI0) and perturbation field (PSI)
1201 ! print *,"perturbation field (PSI) relax three"
1210 CALL relax(tmp1,ff,rd,ew,ns,dx,epsilon,alphar)
1213 psi(i,k,j)=tmp1(i,j)
1219 !We can now calculate the final wind fields.
1220 call final_ew_velocity(u2,u1,chi,psi,utcr,dx,ew,ns,nz)
1221 call final_ns_velocity(v2,v1,chi,psi,vtcr,dx,ew,ns,nz)
1226 psi0(i,k,j) = psi1(i,k,j)-psi(i,k,j)
1234 psipos(i,k,j)=psi(i,k,j)
1240 ! Geostrophic vorticity.
1241 !We calculate the ug and vg on the wrf U and V staggered grids
1242 !since this is where the vorticity subroutine expects them.
1244 CALL geowind(phi1,ew,ns,kx,dx,ug,vg)
1245 CALL vor(ug,vg,msfu,msfv,msfm,ew,ns,kx,dx,vorg)
1253 rad = SQRT(REAL(i-ew_mvc)**2.+REAL(j-ns_mvc)**2.)*dx
1254 IF ( rad .GT. r_vor ) THEN
1264 ff(i,j) = vorg(i,k,j)
1269 CALL relax(tmp1,ff,rd,ew,ns,dx,epsilon,alphar)
1272 phip(i,k,j) = tmp1(i,j)
1278 ! Background geopotential.
1282 phi0(i,k,j) = phi1(i,k,j) - phip(i,k,j)
1288 ! Background temperature
1293 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))
1294 ELSE IF ( k .EQ. kx ) THEN
1295 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))
1297 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))
1299 t0(i,k,j) = t1(i,k,j)-tpos(i,k,j)
1300 t00(i,k,j) = t0(i,k,j)
1301 if(t0(i,k,j) .gt. 400) then
1302 print *,"interesting temperature ",t0(i,k,j)," at ",i,j,k
1310 CALL qvtorh (q0,t0,press*100.,k00,ew,ns,kx,rh0,min_RH_value)
1311 call final_RH(rh2,rh0,rhmx,strmci,strmcj,rmax(nstrm),ew,ns,nz,k00,dx,ew_gcntr,ns_gcntr,r_vor2)
1319 theta(i,k,j) = t1(i,k,j)*(1000./press(i,k,j))**rovcp
1325 ew_mvc = strmci(k00)
1326 ns_mvc = strmcj(k00)
1330 rad = SQRT(REAL(i-ew_mvc)**2.+REAL(j-ns_mvc)**2.)*dx
1331 IF ( rad .LT. r_vor2 ) THEN
1332 t_reduce(i,k,j) = theta(i,k85,j)-0.03*(press(i,k,j)-press(i,k85,j))
1333 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))
1339 ! Geopotential perturbation
1343 tmp1(i,j)=psitc(i,k,j)
1346 CALL balance(cor,tmp1,ew,ns,dx,outold)
1354 CALL relax (tmp1,ff,rd,ew,ns,dx,epsilon,alphar)
1357 phiptc(i,k,j) = tmp1(i,j)
1363 ! New geopotential field.
1367 phi2(i,k,j) = phi0(i,k,j) + phiptc(i,k,j)
1373 ! New temperature field.
1378 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))
1379 ELSE IF ( k .EQ. kx ) THEN
1380 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))
1382 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))
1384 t2(i,k,j) = t0(i,k,j) + tptc(i,k,j)
1385 if(t2(i,k,j) .gt. 400) then
1386 print *,"interesting temperature "
1387 print *,t2(i,k,j),i,k,j,tptc(i,k,j)
1395 ! Sea level pressure change.
1398 dph = phi2(i,k00,j)-phi1(i,k00,j)
1399 delpx(i,j) = rho*dph*0.01
1405 ! print *,"new slp",nstrm
1408 pslx(i,j) = pslx(i,j)+delpx(i,j)
1409 grid%pslv_gc(i,j) = pslx(i,j) * 100.
1414 ! Set new geopotential at surface to terrain elevation.
1417 z2(i,1,j) = terrain(i,j)
1421 ! Geopotential back to height.
1426 z2(i,k,j) = phi2(i,k,j)/9.81
1432 ! New surface temperature, assuming same theta as from 1000 mb.
1433 ! print *,"new surface temperature"
1437 t2(i,1,j) = t2(i,k00,j)*((ps/1000.)**rovcp)
1438 if(t2(i,1,j) .gt. 400) then
1439 print *,"Interesting surface temperature"
1440 print *,t2(i,1,j),t2(i,k00,j),ps,i,j
1447 ! Set surface RH to the value from 1000 mb.
1450 rh2(i,1,j) = rh2(i,k00,j)
1454 ! Modification of tropical storm complete.
1455 PRINT '(A,I3,A)' ,' Bogus storm number ',nstrm,' completed.'
1460 u1(i,k,j) = u2(i,k,j)
1461 grid%u_gc(i,k,j) = u2(i,k,j)
1469 v1(i,k,j) = v2(i,k,j)
1470 grid%v_gc(i,k,j) = v2(i,k,j)
1478 t1(i,k,j) = t2(i,k,j)
1479 grid%t_gc(i,k,j) = t2(i,k,j)
1480 rh1(i,k,j) = rh2(i,k,j)
1481 grid%rh_gc(i,k,j) = rh2(i,k,j)
1482 phi1(i,k,j) = phi2(i,k,j)
1483 grid%ght_gc(i,k,j) = z2(i,k,j)
1503 if(grid%ht_gc(i,j) .gt. 1) then
1504 grid%p_gc(i,1,j) = grid%p_gc(i,1,j) + (pslx(i,j) * 100. - old_slp(i,j))
1505 grid%psfc(i,j) = grid%psfc(i,j) + (pslx(i,j) * 100. - old_slp(i,j))
1507 grid%p_gc(i,1,j) = pslx(i,j) * 100.
1508 grid%psfc(i,j) = pslx(i,j) * 100.
1513 END SUBROUTINE tc_bogus
1515 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1516 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1518 SUBROUTINE rankine(dx,dy,ds,nlvl,vwgt,rmax,vmax,uu,vv,psi,vor)
1520 ! Define analytical bogus vortex
1525 REAL , DIMENSION(nlvl) :: uu, vv, psi, vor
1526 REAL , DIMENSION(nlvl) :: vwgt
1527 REAL :: dx,dy,ds,rmax,vmax
1529 REAL , PARAMETER :: alpha1= 1.
1530 REAL , PARAMETER :: alpha2= -0.75
1535 REAL :: vr , ang , rr , term1 , bb , term2 , alpha
1538 pi = 3.141592653589793
1542 rr = SQRT(dx**2+dy**2)*ds
1543 IF ( rr .LT. rmax ) THEN
1545 ELSE IF ( rr .GE. rmax ) THEN
1548 vr = vmax * (rr/rmax)**(alpha)
1549 IF ( dx.GE.0. ) THEN
1550 ang = (pi/2.) - ATAN2(dy,MAX(dx,1.e-6))
1551 uu(k) = vwgt(k)*(-vr*COS(ang))
1552 vv(k) = vwgt(k)*( vr*SIN(ang))
1553 ELSE IF ( dx.LT.0. ) THEN
1554 ang = ((3.*pi)/2.) + ATAN2(dy,dx)
1555 uu(k) = vwgt(k)*(-vr*COS(ang))
1556 vv(k) = vwgt(k)*(-vr*SIN(ang))
1563 rr = SQRT(dx**2+dy**2)*ds
1564 IF ( rr .LT. rmax ) THEN
1565 psi(k) = vwgt(k) * (vmax*rr*rr)/(2.*rmax)
1566 ELSE IF ( rr .GE. rmax ) THEN
1567 IF (alpha1.EQ.1.0 .AND. alpha2.eq.-1.0) THEN
1568 psi(k) = vwgt(k) * vmax*rmax*(0.5+LOG(rr/rmax))
1569 ELSE IF (alpha1.EQ.1.0 .AND. alpha2.NE.-1.0) THEN
1570 term1 = vmax/(rmax**alpha1)*(rmax**(alpha1+1)/(alpha1+1))
1571 bb = (rr**(alpha2+1)/(alpha2+1))-(rmax**(alpha2+1))/(alpha2+1)
1572 term2 = vmax/(rmax**alpha2)*bb
1573 psi(k) = vwgt(k) * (term1 + term2)
1581 rr = SQRT(dx**2+dy**2)*ds
1582 IF ( rr .LT. rmax ) THEN
1583 vor(k) = vwgt(k) * (2.*vmax)/rmax
1584 ELSE IF ( rr .GE. rmax ) THEN
1585 vor(k) = vwgt(k) * ( (vmax/rmax**alpha2)*(rr**(alpha2-1.))*(1.+alpha2) )
1589 END SUBROUTINE rankine
1591 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1592 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1594 SUBROUTINE vor(uin,vin,msfu,msfv,msfm,ew,ns,nz,ds,vort)
1596 !Here we assume that the U and V's are still on the WRF staggered grid.
1597 !The vorticity is then calculated at the mass points on the WRF grid.
1602 INTEGER :: jp1,jm1,ip1,im1,i,j,k
1603 INTEGER :: ns, ew, nz, k1
1605 REAL , DIMENSION(ew,nz,ns-1) :: uin !u values on unstaggered U grid
1606 REAL , DIMENSION(ew-1,nz,ns) :: vin !v values on unstaggered V grid
1607 REAL , DIMENSION(ew-1,nz,ns-1) :: vort !vort is defined on the mass points
1609 REAL , DIMENSION(ew,ns-1) :: msfu !map scale factors on U staggered grid
1610 REAL , DIMENSION(ew-1,ns) :: msfv !map scale factors on V staggered grid
1611 REAL , DIMENSION(ew-1,ns-1) :: msfm !map scale factors on unstaggered grid
1613 real :: u(ew,ns-1),v(ew-1,ns)
1618 REAL :: dsx,dsy , u1 , u2 , u3 , u4 , v1 , v2 , v3 , v4
1619 real :: dudy,dvdx,mm
1638 !Our indicies are from 2 to ns-2 and ew-2. This is because out
1639 !map scale factors are not defined for the entire grid.
1642 mm = msfm(i,j) * msfm(i,j)
1643 u1 = u(i ,j-1)/msfu(i ,j-1)
1644 u2 = u(i+1,j-1)/msfu(i+1,j-1)
1645 u3 = u(i+1,j+1)/msfu(i+1,j+1)
1646 u4 = u(i ,j+1)/msfu(i ,j+1)
1647 dudy = mm * (u4 + u3 -(u1 + u2)) /(4*ds)
1649 v1 = v(i-1,j )/msfv(i-1,j)
1650 v2 = v(i+1,j )/msfv(i+1,j)
1651 v3 = v(i-1 ,j+1)/msfv(i-1,j+1)
1652 v4 = v(i+1,j+1)/msfv(i+1,j+1)
1653 dvdx = mm * (v4 + v2 - (v1 + v3))/(4*ds)
1655 vort(i,k,j) = dvdx - dudy
1658 !Our vorticity array goes out to ew-1 and ns-1 which is the
1659 !mass point grid dimensions.
1661 vort(i,k,1) = vort(i,k,2) !bottom not corners
1662 vort(i,k,ns-1) = vort(i,k,ns-2) !top not corners
1666 vort(ew-1,k,j) = vort(ew-2,k,j) !right side including corners
1667 vort(1,k,j) = vort(2,k,j) !left side including corners
1670 end do ! this is the k loop end
1674 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1675 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1677 SUBROUTINE diverg(uin,vin,msfu,msfv,msfm,ew,ns,nz,ds,div)
1679 ! Computes divergence on unstaggered grid. The divergence is calculated
1680 ! at the mass points on the WRF grid.
1681 ! div = m*m (du/dx + dv/dy)
1685 INTEGER :: jp1,jm1,ip1,im1,i,j,k
1686 INTEGER :: ns, ew, nz, k1
1688 REAL , DIMENSION(ew,nz,ns-1) :: uin !u values on unstaggered U grid
1689 REAL , DIMENSION(ew-1,nz,ns) :: vin !v values on unstaggered V grid
1690 REAL , DIMENSION(ew-1,nz,ns-1) :: div !divergence is calculate on the mass points
1691 REAL , DIMENSION(ew,ns-1) :: msfu !map scale factors on U staggered grid
1692 REAL , DIMENSION(ew-1,ns) :: msfv !map scale factors on V staggered grid
1693 REAL , DIMENSION(ew-1,ns-1) :: msfm !map scale factors on unstaggered grid
1695 real :: u(ew,ns-1),v(ew-1,ns)
1700 REAL :: dsr,u1,u2,v1,v2
1701 real :: dudx,dvdy,mm,arg1,arg2
1718 !Our indicies are from 2 to ns-2 and ew-2. This is because out
1719 !map scale factors are not defined for the entire grid.
1722 mm = msfm(i,j) * msfm(i,j)
1723 u1 = u(i+1,j)/msfu(i+1,j)
1724 u2 = u(i ,j)/msfu(i ,j)
1726 v1 = v(i,j+1)/msfv(i,j+1)
1727 v2 = v(i,j) /msfv(i,j)
1729 div(i,k,j) = mm * (u1 - u2 + v1 - v2) * dsr
1733 !Our divergence array is defined on the mass points.
1735 div(i,k,1) = div(i,k,2) !bottom not corners
1736 div(i,k,ns-1) = div(i,k,ns-2) !top not corners
1740 div(ew-1,k,j) = div(ew-2,k,j) !right side including corners
1741 div(1,k,j) = div(2,k,j) !left side including corners
1744 end do !end for the k loop
1746 END SUBROUTINE diverg
1748 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1749 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1751 SUBROUTINE mxratprs (rh, t, ppa, ew, ns, nz, q, min_RH_value)
1756 INTEGER :: i , ew , j , ns , k , nz
1759 REAL :: min_RH_value
1760 REAL :: ppa(ew-1,nz,ns-1)
1761 REAL :: p( ew-1,nz,ns-1 )
1762 REAL :: q (ew-1,nz,ns-1),rh(ew-1,nz,ns-1),t(ew-1,nz,ns-1)
1767 REAL :: svp1,svp2,svp3
1772 ! This function is designed to compute (q) from basic variables
1773 ! p (mb), t(K) and rh(0-100%) to give (q) in (kg/kg).
1781 rh(i,k,j) = MIN ( MAX ( rh(i,k,j) ,min_RH_value ) , 100. )
1795 es = svp1 * 10. * EXP(svp2 * (t(i,k,j) - celkel ) / (t(i,k,j) - svp3 ))
1796 qs = eps * es / (p(i,k,j) - es)
1797 q(i,k,j) = MAX(0.01 * rh(i,k,j) * qs,0.0)
1802 END SUBROUTINE mxratprs
1804 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1805 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1806 SUBROUTINE mass2_Ustag(field,dim1,dim2,dim3)
1810 INTEGER :: dim1 , dim2 , dim3
1811 REAL , DIMENSION(dim1,dim2,dim3) :: field,dummy
1814 dummy(:,2:dim2-1,:) = ( field(:,1:dim2-2,:) + &
1815 field(:,2:dim2-1,:) ) * 0.5
1816 dummy(:,1,:) = field(:,1,:)
1817 dummy(:,dim2,:) = field(:,dim2-1,:)
1821 END SUBROUTINE mass2_Ustag
1823 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1824 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1825 SUBROUTINE mass2_Vstag(field,dim1,dim2,dim3)
1829 INTEGER :: dim1 , dim2 , dim3
1830 REAL , DIMENSION(dim1,dim2,dim3) :: field,dummy
1833 dummy(2:dim1-1,:,:) = ( field(1:dim1-2,:,:) + &
1834 field(2:dim1-1,:,:) ) * 0.5
1835 dummy(1,:,:) = field(1,:,:)
1836 dummy(dim1,:,:) = field(dim1-1,:,:)
1840 END SUBROUTINE mass2_Vstag
1843 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1844 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1846 SUBROUTINE relax (chi, ff, rd, ew, ns, ds, smallres, alpha)
1850 INTEGER, PARAMETER :: mm = 20000
1854 INTEGER :: ew !ew direction
1859 INTEGER :: ns !ns direction
1864 REAL :: chi(ew-1,ns-1)
1869 REAL :: ff(ew-1,ns-1)
1870 REAL :: rd(ew-1,ns-1)
1874 LOGICAL :: converged = .FALSE.
1877 alphaov4 = alpha * 0.25
1884 ff(i,j) = fac * ff(i,j)
1889 iter_loop : DO iter = 1, mm
1896 chimx(j) = MAX(ABS(chi(i,j)),chimx(j))
1900 epx = MAXVAL(chimx) * SMALLRES * 4.0 / alpha
1904 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)
1905 chi(i,j) = chi(i,j) + rd(i,j) * alphaov4
1913 rdmax(j) = MAX(ABS(rd(i,j)),rdmax(j))
1918 IF (MAXVAL(rdmax) .lt. epx) THEN
1925 IF (converged ) THEN
1926 ! PRINT '(A,I5,A)','Relaxation converged in ',mi,' iterations.'
1928 PRINT '(A,I5,A)','Relaxation did not converge in',mm,' iterations.'
1934 chi(i,ns-1) = chi(i,ns-2) !top not including corners
1935 chi(i,1) = chi(i,2) !bottom not including corners
1939 chi(ew-1,j) = chi(ew-2,j) !right side not including corners
1940 chi(1,j) = chi(2,j) !left side not including corners
1943 !Fill in the corners
1945 chi(ew-1,1) = chi(ew-2,1)
1946 chi(1,ns-1) = chi(2,ns-1)
1947 chi(ew-1,ns-1) = chi(ew-2,ns-1)
1951 END SUBROUTINE relax
1952 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1953 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1954 SUBROUTINE geowind(height,ew,ns,nz,ds,ug,vg)
1958 ! input height geopotential on wrf mass grid points
1959 ! ns wrf staggered V dimension n-s
1960 ! ew wrf staggered U dimension e-w
1961 ! nz number of vertical levels
1963 ! output ug u component of geo wind on wrf staggered V points
1964 ! vg v component of geo wind on wrf staggered U points
1966 INTEGER :: ew , ns , nz
1968 REAL , DIMENSION(ew-1,nz,ns-1) :: height
1969 REAL , DIMENSION(ew,nz,ns-1) :: ug
1970 REAL , DIMENSION(ew-1,nz,ns) :: vg
1972 REAL :: ds2r , h1 , h2 , h3 , h4, ds4r
1973 INTEGER :: i , j , k
1977 ! The height field comes in on the WRF mass points.
1981 ! ug is the derivative of height in the ns direction ug = -dheight/dy
1986 h1 = height(i,k,j+1)
1987 h2 = height(i-1,k,j+1)
1988 h3 = height(i ,k,j-1)
1989 h4 = height(i-1,k,j-1)
1990 ug(i,k,j) = -( (h1 + h2) - ( h3 + h4) ) * ds4r
1996 ug(i,:,1) = ug(i,:,2) !bottom not including corner points
1997 ug(i,:,ns-1) = ug(i,:,ns-2) !top not including corner points
2001 ug(1,:,j) = ug(2,:,j) !left side
2002 ug(ew,:,j) = ug(ew-1,:,j) !right side
2005 ug(1,:,1) = ug(2,:,1) !Lower left hand corner
2006 ug(1,:,ns-1) = ug(2,:,ns-1) !upper left hand corner
2007 ug(ew,:,1) = ug(ew-1,:,1) !Lower right hand corner
2008 ug(ew,:,ns-1) = ug(ew-1,:,ns-1) !upper right hand corner
2011 ! ug is the derivative of height in the ns direction vg = dheight/dx
2016 h1 = height(i+1,k,j)
2017 h2 = height(i-1,k,j)
2018 h3 = height(i+1,k,j-1)
2019 h4 = height(i-1,k,j-1)
2020 vg(i,k,j) = ( (h1 + h3) - ( h2 + h4) ) * ds4r
2026 vg(i,:,1) = vg(i,:,2) !bottom not including corner points
2027 vg(i,:,ns) = vg(i,:,ns-1) !top not including corner points
2031 vg(1,:,j) = vg(2,:,j) !left side not including corner points
2032 vg(ew-1,:,j) = vg(ew-2,:,j) !right side not including corner points
2035 vg(1,:,1) = vg(2,:,1) !Lower left hand corner
2036 vg(1,:,ns) = vg(2,:,ns) !upper left hand corner
2037 vg(ew-1,:,1) = vg(ew-2,:,1) !Lower right hand corner
2038 vg(ew-1,:,ns) = vg(ew-2,:,ns) !upper right hand corner
2041 END SUBROUTINE geowind
2042 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2043 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2045 SUBROUTINE balance (f,psi,ew,ns,ds,out)
2047 ! Calculates the forcing terms in balance equation
2052 ! psi stream function
2053 ! ew, ns grid points in east west, north south direction, respectively
2057 INTEGER :: ew , ns,nslast,ewlast,ifill
2058 REAL , DIMENSION(ew-1,ns-1) :: f,psi,out
2061 REAL :: psixx , psiyy , psiy , psix, psixy
2062 REAL :: dssq , ds2 , dssq4,arg1,arg2,arg3,arg4
2068 dssq4 = ds * ds * 4.
2070 !The forcing terms are calculated on the WRF mass points.
2074 psiyy = ( psi(i,j+1) + psi(i,j-1) - 2.*psi(i,j) ) / dssq
2075 psixx = ( psi(i+1,j) + psi(i-1,j) - 2.*psi(i,j) ) / dssq
2076 psiy = ( psi(i,j+1) - psi(i,j-1) ) / ds2
2077 psix = ( psi(i+1,j) - psi(i-1,j) ) / ds2
2078 psixy = ( psi(i+1,j+1)+psi(i-1,j-1)-psi(i-1,j+1)-psi(i+1,j-1)) / dssq4
2080 arg1 = f(i,j)* (psixx+psiyy)
2081 arg2 = ( ( f(i,j+1) - f(i,j-1)) / ds2 ) * psiy
2082 arg3 = ( ( f(i+1,j) - f(i-1,j)) / ds2 ) * psix
2083 arg4 = 2 *(psixy*psixy-psixx*psiyy)
2084 out(i,j)= arg1 + arg2 + arg3 - arg4
2089 out(i,ns-1) = out(i,ns-2) !top not including corners
2090 out(i,1) = out(i,2) !bottom not including corners
2094 out(ew-1,j) = out(ew-2,j) !right side not including corners
2095 out(1,j) = out(2,j) !left side not including corners
2098 !Fill in the corners
2100 out(ew-1,1) = out(ew-2,1)
2101 out(1,ns-1) = out(2,ns-1)
2102 out(ew-1,ns-1) = out(ew-2,ns-1)
2104 END SUBROUTINE balance
2106 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2107 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2109 SUBROUTINE qvtorh ( q , t , p , k00, ew , ns , nz , rh, min_RH_value )
2113 INTEGER , INTENT(IN) :: ew , ns , nz , k00
2114 REAL , INTENT(IN) , DIMENSION(ew-1,nz,ns-1) :: q ,t, p
2115 REAL , INTENT(OUT) , DIMENSION(ew-1,nz,ns-1) :: rh
2121 INTEGER :: i , j , k,fill
2125 REAL :: svp1,svp2,svp3
2137 es = svp1 * 10. * EXP(svp2 * (t(i,k,j) - celkel ) / (t(i,k,j) - svp3 ))
2138 qs = eps*es/(0.01*p(i,k,j) - es)
2139 rh(i,k,j) = MIN ( 100. , MAX ( 100.*q(i,k,j)/qs , min_RH_value ) )
2144 END SUBROUTINE qvtorh
2146 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2147 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2149 SUBROUTINE stagger_rankine_winds(utcp,vtcp,ew,ns,nz)
2152 !utcp and vtcp are the output winds of the rankine subroutine
2153 !The winds are calculated on the mass points of the WRF grid
2154 !so they need to be staggered out to the WRF staggering.
2155 !The utcp is placed on the staggered ew wind grid.
2156 !The vtcp is placed on the staggered ns wind grid.
2158 !ew is the full grid dimension in the ew direction.
2159 !ns is the full grid dimension in the ns direction.
2161 !nz is the number of vertical levels.
2163 INTEGER :: ew, ns, nz, i,k,j
2164 REAL utcp(ew,nz,ns-1), vtcp(ew-1,nz,ns)
2166 !----------------------------------------------------
2171 utcp(i,k,j) = ( utcp(i-1,k,j) + utcp(i,k,j) ) /2
2176 !Fill in U's along the left and right side.
2178 utcp(1,:,j) = utcp(2,:,j)
2179 utcp(ew,:,j) = utcp(ew-1,:,j)
2187 vtcp(i,k,j) = ( vtcp(i,k,j+1) + vtcp(i,k,j-1) ) /2
2192 !Fill in V's along the bottom and bottom.
2194 vtcp(i,:,1) = vtcp(i,:,2)
2195 vtcp(i,:,ns) = vtcp(i,:,ns-1)
2199 END SUBROUTINE stagger_rankine_winds
2201 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2202 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2204 subroutine final_ew_velocity(u2,u1,chi,psi,utcr,dx,ew,ns,nz)
2207 integer :: ew,ns,nz,i,j,k
2208 real :: u1(ew,nz,ns-1),utcr(ew,nz,ns-1)
2209 real :: psi(ew-1,nz,ns-1),chi(ew-1,nz,ns-1)
2211 ! u1 is the original wind coming in from the metgrid file.
2212 ! utcr is the rankine winds rotated to the map projection put on u WRF staggered grid points.
2214 ! psi comes in on the WRF mass points. psi is the perturbation field
2215 ! calculated from the relaxation of the vorticity.
2217 ! chi is the relaxation of the divergent winds on WRF mass points.
2220 ! ew is the grid dimension of the WRF ew staggered wind
2221 ! ns is the grid dimension of the WRF ns staggered wind
2222 ! nz is the number of vertical levels
2223 ! dx is the grid spacing
2224 !-------------------------------------------------------------------------------------------
2226 real :: u2(ew,nz,ns-1)
2227 ! output array u2 is the new wind in the ew direction. Is is on WRF staggering.
2228 !-------------------------------------------------------------------------------------------
2230 real upos(ew,nz,ns-1),u0(ew,nz,ns-1),uchi(ew,nz,ns-1)
2231 ! upos is the derivative of psi in the ns direction u = -dpsi/dy
2232 ! u0 is the background ew velocity
2233 ! uchi is the array chi on the u staggered grid.
2235 real :: dx,arg1,arg2
2237 !-------------------------------------------------------------
2238 !Take the derivative of chi in the ew direction.
2240 DO k=1,nz !start of k loop
2243 uchi(i,k,j) = ( chi(i,k,j) - chi(i-1,k,j) )/dx
2248 uchi(1,k,j) = uchi(2,k,j) !fill in the left side
2249 uchi(ew,k,j) = uchi(ew-1,k,j) !fill in the right side
2253 !-----------------------------------------------------------------------------------------
2254 ! Take the derivative of psi in the ns direction.
2260 arg1 = psi(i,k,j+1) + psi(i-1,k,j+1)
2261 arg2 = psi(i,k,j-1) + psi(i-1,k,j-1)
2262 upos(i,k,j) = -( arg1 - arg2 )/(4.*dx)
2267 upos(i,k,1) = upos(i,k,2) !bottom not including corner points
2268 upos(i,k,ns-1) = upos(i,k,ns-2) !top not including corner points
2272 upos(1,k,j) = upos(2,k,j) !left side not including corners
2273 upos(ew,k,j) = upos(ew-1,k,j) !right side not including corners
2277 upos(1,k,1) = upos(2,k,1) !Lower left hand corner
2278 upos(1,k,ns-1) = upos(2,k,ns-1) !upper left hand corner
2279 upos(ew,k,1) = upos(ew-1,k,1) !Lower right hand corner
2280 upos(ew,k,ns-1) = upos(ew-1,k,ns-1) !upper right hand corner
2282 end do !k loop for dspi/dy
2286 !-----------------------------------------------------------------------------------------
2288 ! Background u field.
2289 ! Subtract the first quess wind field from the original winds.
2293 u0(i,k,j) = u1(i,k,j)-(upos(i,k,j)+uchi(i,k,j))
2299 ! Calculate the final velocity
2303 u2(i,k,j) = u0(i,k,j)+utcr(i,k,j)
2308 end subroutine final_ew_velocity
2310 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2311 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2313 subroutine final_ns_velocity(v2,v1,chi,psi,vtcr,dx,ew,ns,nz)
2316 integer :: ew,ns,nz,i,j,k
2317 real :: v1(ew-1,nz,ns),vtcr(ew-1,nz,ns)
2318 real :: psi(ew-1,nz,ns-1),chi(ew-1,nz,ns-1)
2320 ! v1 is the original wind coming in from the metgrid file.
2321 ! vtcr is the is the rankine winds rotated to the map projection put on v WRF staggered grid points.
2323 ! psi comes on the WRF mass points. psi is the perturbation field
2324 ! calculated from the relaxation of the vorticity.
2326 ! chi is the relaxation of the divergent winds on WRF mass points.
2328 ! ew is the grid dimension of the WRF ew staggered wind
2329 ! ns is the grid dimension of the WRF ns staggered wind
2330 ! nz is the number of vertical levels
2333 real :: v2(ew-1,nz,ns)
2334 ! output array v2 is the new wind in the ns direction. Is is on WRF staggering.
2337 real vpos(ew-1,nz,ns),v0(ew-1,nz,ns),vchi(ew-1,nz,ns)
2338 ! vpos is the derivative of psi in the ew direction v = dpsi/dx
2339 ! v0 is the background ns velocity
2340 ! vchi is the relaxation of the divergent wind put on v WRF staggered grid points.
2342 real :: dx,arg1,arg2
2345 !-----------------------------------------------------------------------------------------
2346 vchi(:,:,:) = -999.0
2347 !The derivative dchi in the ns direction.
2351 vchi(i,k,j) = ( chi(i,k,j) - chi(i,k,j-1))/dx
2356 vchi(i,k,1) = vchi(i,k,2)
2357 vchi(i,k,ns) = vchi(i,k,ns-1)
2360 end do !end of k loop
2362 !-----------------------------------------------------------------------------------------
2363 !Take the derivative of psi in the ew direction.
2369 arg1 = psi(i+1,k,j) + psi(i+1,k,j-1)
2370 arg2 = psi(i-1,k,j) + psi(i-1,k,j-1)
2371 vpos(i,k,j) = ( arg1 - arg2 )/(4.*dx)
2376 vpos(i,k,1) = vpos(i,k,2) !bottom not including corner points
2377 vpos(i,k,ns) = vpos(i,k,ns-1) !top not including corner points
2381 vpos(1,k,j) = vpos(2,k,j) !left side not including corner points
2382 vpos(ew-1,k,j) = vpos(ew-2,k,j) !right side not including corner points
2386 vpos(1,k,1) = vpos(2,k,1) !Lower left hand corner
2387 vpos(1,k,ns) = vpos(2,k,ns) !upper left hand corner
2388 vpos(ew-1,k,1) = vpos(ew-2,k,1) !Lower right hand corner
2389 vpos(ew-1,k,ns) = vpos(ew-2,k,ns) !upper right hand corner
2391 END DO!k loop for dspi/dx
2397 v0(i,k,j) = v1(i,k,j)-(vpos(i,k,j)+vchi(i,k,j))
2398 if( v0(i,k,j) .gt. 100.) then
2399 print *,vchi(i,k,j),i,k,j
2407 ! Calculate the final velocity
2411 v2(i,k,j) = v0(i,k,j)+vtcr(i,k,j)
2416 end subroutine final_ns_velocity
2417 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2418 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2419 subroutine final_RH(rh2,rh0,rhmx,strmci,strmcj,rmax_nstrm,ew,ns,nz,k00, &
2420 dx,ew_gcntr,ns_gcntr,r_vor2)
2425 real :: rh2(ew-1,nz,ns-1) !The final output relative humidity.
2426 real :: rh0(ew-1,nz,ns-1) !First quess rh read from the metgrid input file.
2428 real :: ew_gcntr !ew grid center as returned from the map projection routines.
2429 real :: ns_gcntr !ns grid center as returned from the map projection routines.
2430 real :: dx !grid spacing
2434 !Local real variables
2435 real :: sum_rh,avg_rh,rh_min,rhbkg,rhbog,r_ratio
2437 real :: rhtc(ew-1,nz,ns-1)
2439 integer :: nct,k00,i,j,k,ew_mvc,ns_mvc
2440 integer :: strmci(nz), strmcj(nz)
2443 !-----------------------------------------------------------------------
2454 rad = SQRT(REAL(i-ew_mvc)**2.+REAL(j-ns_mvc)**2.)*dx
2455 IF ( (rad .LT. r_vor2).AND.(rad .GE. 0.8*r_vor2) ) THEN
2456 sum_rh = sum_rh + rh0(i,k,j)
2461 avg_rh = sum_rh/MAX(REAL(nct),1.)
2466 rad = SQRT((REAL(i)-ew_gcntr)**2.+(REAL(j)-ns_gcntr)**2.)*dx
2467 IF ( rad .LE. rmax_nstrm ) THEN
2468 rhtc(i,k,j) = rh_max
2470 rhtc(i,k,j) = (rmax_nstrm/rad)*rh_max+(1.-(rmax_nstrm/rad))*rh_min
2483 rad = SQRT((REAL(i)-ew_mvc)**2.+(REAL(j)-ns_mvc)**2.)*dx
2484 IF ( (rad.GT.rmax_nstrm) .AND. (rad.LE.r_vor2) ) THEN
2485 r_ratio = (rad-rmax_nstrm)/(r_vor2-rmax_nstrm)
2486 rh2(i,k,j) = ((1.-r_ratio)*rhbog) + (r_ratio*rhbkg)
2487 ELSE IF (rad .LE. rmax_nstrm ) THEN
2499 end subroutine final_RH
2501 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2502 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!