1 !REAL:MODEL_LAYER:INITIALIZATION
4 ! This MODULE holds the routines which are used to perform various initializations
5 ! for the individual domains, specifically for the Eulerian, mass-based coordinate.
7 !-----------------------------------------------------------------------
9 MODULE module_initialize_real
15 USE module_model_constants
16 USE module_state_description
23 USE module_comm_dm, ONLY : &
29 ,HALO_EM_VINTERP_UV_1_sub
32 REAL , SAVE :: p_top_save
33 INTEGER :: internal_time_loop
37 !-------------------------------------------------------------------
39 SUBROUTINE init_domain ( grid )
43 ! Input space and data. No gridded meteorological data has been stored, though.
45 ! TYPE (domain), POINTER :: grid
50 INTEGER :: idum1, idum2
52 CALL set_scalar_indices_from_config ( head_grid%id , idum1, idum2 )
54 CALL init_domain_rk( grid &
56 #include "actual_new_args.inc"
59 END SUBROUTINE init_domain
61 !-------------------------------------------------------------------
63 SUBROUTINE init_domain_rk ( grid &
65 #include "dummy_new_args.inc"
69 USE module_optional_input
72 ! Input space and data. No gridded meteorological data has been stored, though.
74 ! TYPE (domain), POINTER :: grid
77 #include "dummy_new_decl.inc"
79 TYPE (grid_config_rec_type) :: config_flags
81 ! Local domain indices and counters.
83 INTEGER :: num_veg_cat , num_soil_top_cat , num_soil_bot_cat
84 INTEGER :: loop , num_seaice_changes
86 INTEGER :: ids, ide, jds, jde, kds, kde, &
87 ims, ime, jms, jme, kms, kme, &
88 its, ite, jts, jte, kts, kte, &
89 ips, ipe, jps, jpe, kps, kpe, &
92 INTEGER :: imsx, imex, jmsx, jmex, kmsx, kmex, &
93 ipsx, ipex, jpsx, jpex, kpsx, kpex, &
94 imsy, imey, jmsy, jmey, kmsy, kmey, &
95 ipsy, ipey, jpsy, jpey, kpsy, kpey
102 INTEGER :: im, num_3d_m, num_3d_s
103 REAL :: p_surf, p_level
105 REAL :: qvf , qvf1 , qvf2 , pd_surf
106 REAL :: p00 , t00 , a , tiso
107 REAL :: hold_znw , ptemp
108 REAL :: vap_pres_mb , sat_vap_pres_mb
111 LOGICAL :: stretch_grid, dry_sounding, debug
114 REAL :: p_top_requested , temp
115 INTEGER :: num_metgrid_levels
116 REAL , DIMENSION(max_eta) :: eta_levels
119 ! INTEGER , PARAMETER :: nl_max = 1000
120 ! REAL , DIMENSION(nl_max) :: grid%dn
124 REAL :: zap_close_levels
125 INTEGER :: force_sfc_in_vinterp
126 INTEGER :: interp_type , lagrange_order , extrap_type , t_extrap_type
127 LOGICAL :: lowest_lev_from_sfc , use_levels_below_ground , use_surface
128 LOGICAL :: we_have_tavgsfc , we_have_tsk
130 INTEGER :: lev500 , loop_count
131 REAL :: zl , zu , pl , pu , z500 , dz500 , tvsfc , dpmu
132 REAL :: pfu, pfd, phm
134 LOGICAL , PARAMETER :: want_full_levels = .TRUE.
135 LOGICAL , PARAMETER :: want_half_levels = .FALSE.
137 CHARACTER (LEN=80) :: a_message
142 LOGICAL :: any_valid_points
143 INTEGER :: i_valid , j_valid
145 !-- Carsel and Parrish [1988]
146 REAL , DIMENSION(100) :: lqmi
148 REAL :: t_start , t_end
150 ! Dimension information stored in grid data structure.
152 CALL cpu_time(t_start)
153 CALL get_ijk_from_grid ( grid , &
154 ids, ide, jds, jde, kds, kde, &
155 ims, ime, jms, jme, kms, kme, &
156 ips, ipe, jps, jpe, kps, kpe, &
157 imsx, imex, jmsx, jmex, kmsx, kmex, &
158 ipsx, ipex, jpsx, jpex, kpsx, kpex, &
159 imsy, imey, jmsy, jmey, kmsy, kmey, &
160 ipsy, ipey, jpsy, jpey, kpsy, kpey )
161 its = ips ; ite = ipe ; jts = jps ; jte = jpe ; kts = kps ; kte = kpe
164 CALL model_to_grid_config_rec ( grid%id , model_config_rec , config_flags )
166 ! Send out a quick message about the time steps based on the map scale factors.
168 IF ( ( internal_time_loop .EQ. 1 ) .AND. ( grid%id .EQ. 1 ) .AND. &
169 ( .NOT. config_flags%map_proj .EQ. PROJ_CASSINI ) ) THEN
170 max_mf = grid%msft(its,jts)
171 DO j=jts,MIN(jde-1,jte)
172 DO i=its,MIN(ide-1,ite)
173 max_mf = MAX ( max_mf , grid%msft(i,j) )
176 #if ( defined(DM_PARALLEL) && ! defined(STUBMPI) )
177 max_mf = wrf_dm_max_real ( max_mf )
179 WRITE ( a_message , FMT='(A,F5.2,A)' ) 'Max map factor in domain 1 = ',max_mf, &
180 '. Scale the dt in the model accordingly.'
181 CALL wrf_message ( a_message )
184 ! Check to see if the boundary conditions are set properly in the namelist file.
185 ! This checks for sufficiency and redundancy.
187 CALL boundary_condition_check( config_flags, bdyzone, error, grid%id )
189 ! Some sort of "this is the first time" initialization. Who knows.
194 ! Pull in the info in the namelist to compare it to the input data.
196 grid%real_data_init_type = model_config_rec%real_data_init_type
198 ! To define the base state, we call a USER MODIFIED routine to set the three
199 ! necessary constants: p00 (sea level pressure, Pa), t00 (sea level temperature, K),
200 ! and A (temperature difference, from 1000 mb to 300 mb, K).
202 CALL const_module_initialize ( p00 , t00 , a , tiso )
204 ! Save these constants to write out in model output file
211 ! Are there any hold-ups to us bypassing the middle of the domain? These
212 ! holdups would be situations where we need data in the middle of the domain.
213 ! FOr example, if this si the first time period, we need the full domain
214 ! processed for ICs. Also, if there is some sort of gridded FDDA turned on, or
215 ! if the SST update is activated, then we can't just blow off the middle of the
216 ! domain all willy-nilly. Other cases of these hold-ups? Sure - what if the
217 ! user wants to smooth the CG topo, we need several rows and columns available.
218 ! What if the lat/lon proj is used, then we need to run a spectral filter on
219 ! the topo. Both are killers when trying to ignore data in the middle of the
222 ! If hold_ups = .F., then there are no hold-ups to excluding the middle
223 ! domain processing. If hold_ups = .T., then there are hold-ups, and we
224 ! must process the middle of the domain.
226 hold_ups = ( internal_time_loop .EQ. 1 ) .OR. &
227 ( config_flags%grid_fdda .NE. 0 ) .OR. &
228 ( config_flags%sst_update .EQ. 1 ) .OR. &
229 ( config_flags%all_ic_times ) .OR. &
230 ( config_flags%smooth_cg_topo ) .OR. &
231 ( config_flags%map_proj .EQ. PROJ_CASSINI )
233 ! There are a few checks that we need to do when the input data comes in with the middle
236 IF ( flag_excluded_middle .NE. 0 ) THEN
238 ! If this time period of data from WPS has the middle excluded, it had better be OK for
242 WRITE ( a_message,* ) 'None of the following are allowed to be TRUE : '
243 CALL wrf_message ( a_message )
244 WRITE ( a_message,* ) ' ( internal_time_loop .EQ. 1 ) ', ( internal_time_loop .EQ. 1 )
245 CALL wrf_message ( a_message )
246 WRITE ( a_message,* ) ' ( config_flags%grid_fdda .NE. 0 ) ', ( config_flags%grid_fdda .NE. 0 )
247 CALL wrf_message ( a_message )
248 WRITE ( a_message,* ) ' ( config_flags%sst_update .EQ. 1 ) ', ( config_flags%sst_update .EQ. 1 )
249 CALL wrf_message ( a_message )
250 WRITE ( a_message,* ) ' ( config_flags%all_ic_times ) ', ( config_flags%all_ic_times )
251 CALL wrf_message ( a_message )
252 WRITE ( a_message,* ) ' ( config_flags%smooth_cg_topo ) ', ( config_flags%smooth_cg_topo )
253 CALL wrf_message ( a_message )
254 WRITE ( a_message,* ) ' ( config_flags%map_proj .EQ. PROJ_CASSINI ) ', ( config_flags%map_proj .EQ. PROJ_CASSINI )
255 CALL wrf_message ( a_message )
257 WRITE ( a_message,* ) 'Problems, we cannot have excluded middle data from WPS'
258 CALL wrf_error_fatal ( a_message )
261 ! Make sure that the excluded middle data from metgrid is "wide enough". We only have to check
262 ! when the excluded middle was actually used in WPS.
264 IF ( config_flags%spec_bdy_width .GT. flag_excluded_middle ) THEN
265 WRITE ( a_message,* ) 'The WRF &bdy_control namelist.input spec_bdy_width = ', config_flags%spec_bdy_width
266 CALL wrf_message ( a_message )
267 WRITE ( a_message,* ) 'The WPS &metgrid namelist.wps process_only_bdy width = ',flag_excluded_middle
268 CALL wrf_message ( a_message )
269 WRITE ( a_message,* ) 'WPS process_only_bdy must be >= WRF spec_bdy_width'
270 CALL wrf_error_fatal ( a_message )
273 em_width = config_flags%spec_bdy_width
275 ! We need to find if there are any valid non-excluded-middle points in this
276 ! tile. If so, then we need to hang on to a valid i,j location.
278 any_valid_points = .false.
279 find_valid : DO j = jts,jte
281 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
282 any_valid_points = .true.
289 ! Replace traditional seaice field with optional seaice (AFWA source)
291 IF ( flag_icefrac .EQ. 1 ) THEN
292 DO j=jts,MIN(jde-1,jte)
293 DO i=its,MIN(ide-1,ite)
294 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
295 grid%xice(i,j) = grid%icefrac_gc(i,j)
300 ! Fix the snow (water equivalent depth, kg/m^2) and the snowh (physical snow
303 IF ( ( flag_snow .EQ. 0 ) .AND. ( flag_snowh .EQ. 0 ) ) THEN
304 DO j=jts,MIN(jde-1,jte)
305 DO i=its,MIN(ide-1,ite)
306 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
312 ELSE IF ( ( flag_snow .EQ. 0 ) .AND. ( flag_snowh .EQ. 1 ) ) THEN
313 DO j=jts,MIN(jde-1,jte)
314 DO i=its,MIN(ide-1,ite)
315 ! ( m -> kg/m^2 ) & ( reduce to liquid, 5:1 ratio )
316 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
317 grid%snow(i,j) = grid%snowh(i,j) * 1000. / 5.
321 ELSE IF ( ( flag_snow .EQ. 1 ) .AND. ( flag_snowh .EQ. 0 ) ) THEN
322 DO j=jts,MIN(jde-1,jte)
323 DO i=its,MIN(ide-1,ite)
324 ! ( kg/m^2 -> m) & ( liquid to snow depth, 5:1 ratio )
325 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
326 grid%snowh(i,j) = grid%snow(i,j) / 1000. * 5.
332 ! For backward compatibility, we might need to assign the map factors from
333 ! what they were, to what they are.
335 IF ( ( config_flags%polar ) .AND. ( flag_mf_xy .EQ. 1 ) ) THEN
336 DO j=max(jds+1,jts),min(jde-1,jte)
337 DO i=its,min(ide-1,ite)
338 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
339 grid%msfvx_inv(i,j) = 1./grid%msfvx(i,j)
344 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
345 grid%msfvx(i,jts) = 0.
346 grid%msfvx_inv(i,jts) = 0.
351 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
352 grid%msfvx(i,jte) = 0.
353 grid%msfvx_inv(i,jte) = 0.
356 ELSE IF ( ( config_flags%map_proj .EQ. PROJ_CASSINI ) .AND. ( flag_mf_xy .EQ. 1 ) ) THEN
358 DO i=its,min(ide-1,ite)
359 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
360 grid%msfvx_inv(i,j) = 1./grid%msfvx(i,j)
363 ELSE IF ( ( .NOT. config_flags%map_proj .EQ. PROJ_CASSINI ) .AND. ( flag_mf_xy .NE. 1 ) ) THEN
366 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
367 grid%msfvx(i,j) = grid%msfv(i,j)
368 grid%msfvy(i,j) = grid%msfv(i,j)
369 grid%msfux(i,j) = grid%msfu(i,j)
370 grid%msfuy(i,j) = grid%msfu(i,j)
371 grid%msftx(i,j) = grid%msft(i,j)
372 grid%msfty(i,j) = grid%msft(i,j)
375 DO j=jts,min(jde,jte)
376 DO i=its,min(ide-1,ite)
377 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
378 grid%msfvx_inv(i,j) = 1./grid%msfvx(i,j)
381 ELSE IF ( ( .NOT. config_flags%map_proj .EQ. PROJ_CASSINI ) .AND. ( flag_mf_xy .EQ. 1 ) ) THEN
382 IF ( grid%msfvx(its,jts) .EQ. 0 ) THEN
383 CALL wrf_error_fatal ( 'Maybe you do not have the new map factors, try re-running geogrid' )
385 DO j=jts,min(jde,jte)
386 DO i=its,min(ide-1,ite)
387 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
388 grid%msfvx_inv(i,j) = 1./grid%msfvx(i,j)
391 ELSE IF ( ( config_flags%map_proj .EQ. PROJ_CASSINI ) .AND. ( flag_mf_xy .NE. 1 ) ) THEN
392 CALL wrf_error_fatal ( 'Neither SI data nor older metgrid data can initialize a global domain' )
395 ! Check to see what available surface temperatures we have.
397 IF ( flag_tavgsfc .EQ. 1 ) THEN
398 we_have_tavgsfc = .TRUE.
400 we_have_tavgsfc = .FALSE.
403 IF ( flag_tsk .EQ. 1 ) THEN
406 we_have_tsk = .FALSE.
409 IF ( config_flags%use_tavg_for_tsk ) THEN
410 IF ( we_have_tsk .OR. we_have_tavgsfc ) THEN
413 CALL wrf_error_fatal ( 'We either need TSK or TAVGSFC, verify these fields are coming from WPS' )
416 ! Since we require a skin temperature in the model, we can use the average 2-m temperature if provided.
418 IF ( we_have_tavgsfc ) THEN
419 DO j=jts,min(jde,jte)
420 DO i=its,min(ide-1,ite)
421 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
422 grid%tsk(i,j) = grid%tavgsfc(i,j)
428 ! Is there any vertical interpolation to do? The "old" data comes in on the correct
429 ! vertical locations already.
431 IF ( flag_metgrid .EQ. 1 ) THEN ! <----- START OF VERTICAL INTERPOLATION PART ---->
433 ! If this is data from the PINTERP program, it is emulating METGRID output.
434 ! One of the caveats of this data is the way that the vertical structure is
435 ! handled. We take the k=1 level and toss it (it is disposable), and we
436 ! swap in the surface data. This is done for all of the 3d fields about
437 ! which we show some interest: u, v, t, rh, ght, and p. For u, v, and rh,
438 ! we assume no interesting vertical structure, and just assign the 1000 mb
439 ! data. We directly use the 2-m temp for surface temp. We use the surface
440 ! pressure field and the topography elevation for the lowest level of
441 ! pressure and height, respectively.
443 IF ( flag_pinterp .EQ. 1 ) THEN
445 WRITE ( a_message , * ) 'Data from P_INTERP program, filling k=1 level with artificial surface fields.'
446 CALL wrf_message ( a_message )
449 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
450 grid%u_gc(i,1,j) = grid%u_gc(i,2,j)
451 grid%v_gc(i,1,j) = grid%v_gc(i,2,j)
452 grid%rh_gc(i,1,j) = grid%rh_gc(i,2,j)
453 grid%t_gc(i,1,j) = grid%t2(i,j)
454 grid%ght_gc(i,1,j) = grid%ht(i,j)
455 grid%p_gc(i,1,j) = grid%psfc(i,j)
462 ! Variables that are named differently between SI and WPS.
464 DO j = jts, MIN(jte,jde-1)
465 DO i = its, MIN(ite,ide-1)
466 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
467 grid%tsk(i,j) = grid%tsk_gc(i,j)
468 grid%tmn(i,j) = grid%tmn_gc(i,j)
469 grid%xlat(i,j) = grid%xlat_gc(i,j)
470 grid%xlong(i,j) = grid%xlong_gc(i,j)
471 grid%ht(i,j) = grid%ht_gc(i,j)
475 ! A user could request that the most coarse grid has the
476 ! topography along the outer boundary smoothed. This smoothing
477 ! is similar to the coarse/nest interface. The outer rows and
478 ! cols come from the existing large scale topo, and then the
479 ! next several rows/cols are a linear ramp of the large scale
480 ! model and the hi-res topo from WPS. We only do this for the
481 ! coarse grid since we are going to make the interface consistent
482 ! in the model betwixt the CG and FG domains.
484 IF ( ( config_flags%smooth_cg_topo ) .AND. &
485 ( grid%id .EQ. 1 ) .AND. &
486 ( flag_soilhgt .EQ. 1) ) THEN
487 CALL blend_terrain ( grid%toposoil , grid%ht , &
488 ids , ide , jds , jde , 1 , 1 , &
489 ims , ime , jms , jme , 1 , 1 , &
490 ips , ipe , jps , jpe , 1 , 1 )
494 ! Filter the input topography if this is a polar projection.
496 IF ( ( config_flags%polar ) .AND. ( grid%fft_filter_lat .GT. 90 ) ) THEN
497 CALL wrf_error_fatal ( 'If the polar boundary condition is used, then fft_filter_lat must be set in namelist.input' )
500 IF ( config_flags%map_proj .EQ. PROJ_CASSINI ) THEN
501 #if ( defined( DM_PARALLEL ) && ( ! defined( STUBMPI ) ) )
503 ! We stick the topo and map fac in an unused 3d array. The map scale
504 ! factor and computational latitude are passed along for the ride
505 ! (part of the transpose process - we only do 3d arrays) to determine
506 ! "how many" values are used to compute the mean. We want a number
507 ! that is consistent with the original grid resolution.
510 DO j = jts, MIN(jte,jde-1)
512 DO i = its, MIN(ite,ide-1)
513 grid%t_init(i,k,j) = 1.
516 DO i = its, MIN(ite,ide-1)
517 grid%t_init(i,1,j) = grid%ht(i,j)
518 grid%t_init(i,2,j) = grid%msftx(i,j)
519 grid%t_init(i,3,j) = grid%clat(i,j)
523 # include "XPOSE_POLAR_FILTER_TOPO_z2x.inc"
525 ! Retrieve the 2d arrays for topo, map factors, and the
526 ! computational latitude.
528 DO j = jpsx, MIN(jpex,jde-1)
529 DO i = ipsx, MIN(ipex,ide-1)
530 grid%ht_xxx(i,j) = grid%t_xxx(i,1,j)
531 grid%mf_xxx(i,j) = grid%t_xxx(i,2,j)
532 grid%clat_xxx(i,j) = grid%t_xxx(i,3,j)
536 ! Get a mean topo field that is consistent with the grid
537 ! distance on each computational latitude loop.
539 CALL filter_topo ( grid%ht_xxx , grid%clat_xxx , grid%mf_xxx , &
540 grid%fft_filter_lat , &
541 ids, ide, jds, jde, 1 , 1 , &
542 imsx, imex, jmsx, jmex, 1, 1, &
543 ipsx, ipex, jpsx, jpex, 1, 1 )
545 ! Stick the filtered topo back into the dummy 3d array to
546 ! transpose it back to "all z on a patch".
548 DO j = jpsx, MIN(jpex,jde-1)
549 DO i = ipsx, MIN(ipex,ide-1)
550 grid%t_xxx(i,1,j) = grid%ht_xxx(i,j)
554 # include "XPOSE_POLAR_FILTER_TOPO_x2z.inc"
556 ! Get the un-transposed topo data.
558 DO j = jts, MIN(jte,jde-1)
559 DO i = its, MIN(ite,ide-1)
560 grid%ht(i,j) = grid%t_init(i,1,j)
564 CALL filter_topo ( grid%ht , grid%clat , grid%msftx , &
565 grid%fft_filter_lat , &
566 ids, ide, jds, jde, 1,1, &
567 ims, ime, jms, jme, 1,1, &
568 its, ite, jts, jte, 1,1 )
572 ! If we have any input low-res surface pressure, we store it.
574 IF ( flag_psfc .EQ. 1 ) THEN
575 DO j = jts, MIN(jte,jde-1)
576 DO i = its, MIN(ite,ide-1)
577 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
578 grid%psfc_gc(i,j) = grid%psfc(i,j)
579 grid%p_gc(i,1,j) = grid%psfc(i,j)
584 ! If we have the low-resolution surface elevation, stick that in the
585 ! "input" locations of the 3d height. We still have the "hi-res" topo
586 ! stuck in the grid%ht array. The grid%landmask if test is required as some sources
587 ! have ZERO elevation over water (thank you very much).
589 IF ( flag_soilhgt .EQ. 1) THEN
590 DO j = jts, MIN(jte,jde-1)
591 DO i = its, MIN(ite,ide-1)
592 ! IF ( grid%landmask(i,j) .GT. 0.5 ) THEN
593 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
594 grid%ght_gc(i,1,j) = grid%toposoil(i,j)
595 grid%ht_gc(i,j)= grid%toposoil(i,j)
601 ! The number of vertical levels in the input data. There is no staggering for
602 ! different variables.
604 num_metgrid_levels = grid%num_metgrid_levels
606 ! For UM data, swap incoming extra (theta-based) pressure with the standardly
607 ! named (rho-based) pressure.
609 IF ( flag_ptheta .EQ. 1 ) THEN
610 DO j = jts, MIN(jte,jde-1)
611 DO k = 1 , num_metgrid_levels
612 DO i = its, MIN(ite,ide-1)
613 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
614 ptemp = grid%p_gc(i,k,j)
615 grid%p_gc(i,k,j) = grid%prho_gc(i,k,j)
616 grid%prho_gc(i,k,j) = ptemp
621 ! For UM data, the "surface" and the "first hybrid" level for the theta-level data fields are the same.
622 ! Average the surface (k=1) and the second hybrid level (k=num_metgrid_levels-1) to get the first hybrid
623 ! layer. We only do this for the theta-level data: pressure, temperature, specific humidity, and
624 ! geopotential height (i.e. we do not modify u, v, or the rho-based pressure).
626 DO j = jts, MIN(jte,jde-1)
627 DO i = its, MIN(ite,ide-1)
628 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
629 grid% p_gc(i,num_metgrid_levels,j) = ( grid% p_gc(i,1,j) + grid% p_gc(i,num_metgrid_levels-1,j) ) * 0.5
630 grid% t_gc(i,num_metgrid_levels,j) = ( grid% t_gc(i,1,j) + grid% t_gc(i,num_metgrid_levels-1,j) ) * 0.5
631 grid% sh_gc(i,num_metgrid_levels,j) = ( grid% sh_gc(i,1,j) + grid% sh_gc(i,num_metgrid_levels-1,j) ) * 0.5
632 grid%ght_gc(i,num_metgrid_levels,j) = ( grid%ght_gc(i,1,j) + grid%ght_gc(i,num_metgrid_levels-1,j) ) * 0.5
637 IF ( any_valid_points ) THEN
638 ! Check for and semi-fix missing surface fields.
640 IF ( grid%p_gc(i_valid,num_metgrid_levels,j_valid) .LT. grid%p_gc(i_valid,2,j_valid) ) THEN
643 k = num_metgrid_levels
646 IF ( grid%t_gc(i_valid,1,j_valid) .EQ. -1.E30 ) THEN
647 DO j = jts, MIN(jte,jde-1)
648 DO i = its, MIN(ite,ide-1)
649 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
650 grid%t_gc(i,1,j) = grid%t_gc(i,k,j)
653 config_flags%use_surface = .FALSE.
654 grid%use_surface = .FALSE.
655 WRITE ( a_message , * ) 'Missing surface temp, replaced with closest level, use_surface set to false.'
656 CALL wrf_message ( a_message )
659 IF ( grid%rh_gc(i_valid,1,j_valid) .EQ. -1.E30 ) THEN
660 DO j = jts, MIN(jte,jde-1)
661 DO i = its, MIN(ite,ide-1)
662 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
663 grid%rh_gc(i,1,j) = grid%rh_gc(i,k,j)
666 config_flags%use_surface = .FALSE.
667 grid%use_surface = .FALSE.
668 WRITE ( a_message , * ) 'Missing surface RH, replaced with closest level, use_surface set to false.'
669 CALL wrf_message ( a_message )
672 IF ( grid%u_gc(i_valid,1,j_valid) .EQ. -1.E30 ) THEN
673 DO j = jts, MIN(jte,jde-1)
675 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
676 grid%u_gc(i,1,j) = grid%u_gc(i,k,j)
679 config_flags%use_surface = .FALSE.
680 grid%use_surface = .FALSE.
681 WRITE ( a_message , * ) 'Missing surface u wind, replaced with closest level, use_surface set to false.'
682 CALL wrf_message ( a_message )
685 IF ( grid%v_gc(i_valid,1,j_valid) .EQ. -1.E30 ) THEN
687 DO i = its, MIN(ite,ide-1)
688 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
689 grid%v_gc(i,1,j) = grid%v_gc(i,k,j)
692 config_flags%use_surface = .FALSE.
693 grid%use_surface = .FALSE.
694 WRITE ( a_message , * ) 'Missing surface v wind, replaced with closest level, use_surface set to false.'
695 CALL wrf_message ( a_message )
698 ! Compute the mixing ratio from the input relative humidity.
700 IF ( ( flag_qv .NE. 1 ) .AND. ( flag_sh .NE. 1 ) ) THEN
701 IF ( grid%p_gc(i_valid,num_metgrid_levels,j_valid) .LT. grid%p_gc(i_valid,2,j_valid) ) THEN
704 k = num_metgrid_levels
707 IF ( config_flags%rh2qv_method .eq. 1 ) THEN
708 CALL rh_to_mxrat1(grid%rh_gc, grid%t_gc, grid%p_gc, grid%qv_gc , &
709 config_flags%rh2qv_wrt_liquid , &
710 config_flags%qv_max_p_safe , &
711 config_flags%qv_max_flag , config_flags%qv_max_value , &
712 config_flags%qv_min_p_safe , &
713 config_flags%qv_min_flag , config_flags%qv_min_value , &
714 ids , ide , jds , jde , 1 , num_metgrid_levels , &
715 ims , ime , jms , jme , 1 , num_metgrid_levels , &
716 its , ite , jts , jte , 1 , num_metgrid_levels )
717 ELSE IF ( config_flags%rh2qv_method .eq. 2 ) THEN
718 CALL rh_to_mxrat2(grid%rh_gc, grid%t_gc, grid%p_gc, grid%qv_gc , &
719 config_flags%rh2qv_wrt_liquid , &
720 config_flags%qv_max_p_safe , &
721 config_flags%qv_max_flag , config_flags%qv_max_value , &
722 config_flags%qv_min_p_safe , &
723 config_flags%qv_min_flag , config_flags%qv_min_value , &
724 ids , ide , jds , jde , 1 , num_metgrid_levels , &
725 ims , ime , jms , jme , 1 , num_metgrid_levels , &
726 its , ite , jts , jte , 1 , num_metgrid_levels )
730 ELSE IF ( flag_sh .EQ. 1 ) THEN
731 IF ( grid%p_gc(i_valid,num_metgrid_levels,j_valid) .LT. grid%p_gc(i_valid,2,j_valid) ) THEN
734 k = num_metgrid_levels
736 IF ( grid%sh_gc(i_valid,kts,j_valid) .LT. 1.e-6 ) THEN
737 DO j = jts, MIN(jte,jde-1)
738 DO i = its, MIN(ite,ide-1)
739 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
740 grid%sh_gc(i,1,j) = grid%sh_gc(i,k,j)
745 DO j = jts, MIN(jte,jde-1)
746 DO k = 1 , num_metgrid_levels
747 DO i = its, MIN(ite,ide-1)
748 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
749 grid%qv_gc(i,k,j) = grid%sh_gc(i,k,j) /( 1. - grid%sh_gc(i,k,j) )
750 sat_vap_pres_mb = 0.6112*10.*EXP(17.67*(grid%t_gc(i,k,j)-273.15)/(grid%t_gc(i,k,j)-29.65))
751 vap_pres_mb = grid%qv_gc(i,k,j) * grid%p_gc(i,k,j)/100. / (grid%qv_gc(i,k,j) + 0.622 )
752 IF ( sat_vap_pres_mb .GT. 0 ) THEN
753 grid%rh_gc(i,k,j) = ( vap_pres_mb / sat_vap_pres_mb ) * 100.
755 grid%rh_gc(i,k,j) = 0.
763 ! Some data sets do not provide a 3d geopotential height field.
765 IF ( grid%ght_gc(i_valid,grid%num_metgrid_levels/2,j_valid) .LT. 1 ) THEN
766 DO j = jts, MIN(jte,jde-1)
767 DO k = kts+1 , grid%num_metgrid_levels
768 DO i = its, MIN(ite,ide-1)
769 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
770 grid%ght_gc(i,k,j) = grid%ght_gc(i,k-1,j) - &
771 R_d / g * 0.5 * ( grid%t_gc(i,k ,j) * ( 1 + 0.608 * grid%qv_gc(i,k ,j) ) + &
772 grid%t_gc(i,k-1,j) * ( 1 + 0.608 * grid%qv_gc(i,k-1,j) ) ) * &
773 LOG ( grid%p_gc(i,k,j) / grid%p_gc(i,k-1,j) )
779 ! If the pressure levels in the middle of the atmosphere are upside down, then
780 ! this is hybrid data. Computing the new surface pressure should use sfcprs2.
782 IF ( grid%p_gc(i_valid,num_metgrid_levels/2,j_valid) .LT. grid%p_gc(i_valid,num_metgrid_levels/2+1,j_valid) ) THEN
783 config_flags%sfcp_to_sfcp = .TRUE.
787 ! Assign surface fields with original input values. If this is hybrid data,
788 ! the values are not exactly representative. However - this is only for
789 ! plotting purposes and such at the 0h of the forecast, so we are not all that
792 DO j = jts, min(jde-1,jte)
793 DO i = its, min(ide,ite)
794 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
795 grid%u10(i,j)=grid%u_gc(i,1,j)
799 DO j = jts, min(jde,jte)
800 DO i = its, min(ide-1,ite)
801 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
802 grid%v10(i,j)=grid%v_gc(i,1,j)
806 DO j = jts, min(jde-1,jte)
807 DO i = its, min(ide-1,ite)
808 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
809 grid%t2(i,j)=grid%t_gc(i,1,j)
813 IF ( flag_qv .EQ. 1 ) THEN
814 DO j = jts, min(jde-1,jte)
815 DO i = its, min(ide-1,ite)
816 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
817 grid%q2(i,j)=grid%qv_gc(i,1,j)
822 ! The requested ptop for real data cases.
824 p_top_requested = grid%p_top_requested
826 ! Compute the top pressure, grid%p_top. For isobaric data, this is just the
827 ! top level. For the generalized vertical coordinate data, we find the
828 ! max pressure on the top level. We have to be careful of two things:
829 ! 1) the value has to be communicated, 2) the value can not increase
830 ! at subsequent times from the initial value.
832 IF ( internal_time_loop .EQ. 1 ) THEN
833 CALL find_p_top ( grid%p_gc , grid%p_top , &
834 ids , ide , jds , jde , 1 , num_metgrid_levels , &
835 ims , ime , jms , jme , 1 , num_metgrid_levels , &
836 its , ite , jts , jte , 1 , num_metgrid_levels )
838 #if ( defined( DM_PARALLEL ) && ( ! defined( STUBMPI ) ) )
839 grid%p_top = wrf_dm_max_real ( grid%p_top )
842 ! Compare the requested grid%p_top with the value available from the input data.
844 IF ( p_top_requested .LT. grid%p_top ) THEN
845 print *,'p_top_requested = ',p_top_requested
846 print *,'allowable grid%p_top in data = ',grid%p_top
847 CALL wrf_error_fatal ( 'p_top_requested < grid%p_top possible from data' )
850 ! The grid%p_top valus is the max of what is available from the data and the
851 ! requested value. We have already compared <, so grid%p_top is directly set to
852 ! the value in the namelist.
854 grid%p_top = p_top_requested
856 ! For subsequent times, we have to remember what the grid%p_top for the first
857 ! time was. Why? If we have a generalized vert coordinate, the grid%p_top value
860 p_top_save = grid%p_top
863 CALL find_p_top ( grid%p_gc , grid%p_top , &
864 ids , ide , jds , jde , 1 , num_metgrid_levels , &
865 ims , ime , jms , jme , 1 , num_metgrid_levels , &
866 its , ite , jts , jte , 1 , num_metgrid_levels )
868 #if ( defined( DM_PARALLEL ) && ( ! defined( STUBMPI ) ) )
869 grid%p_top = wrf_dm_max_real ( grid%p_top )
871 IF ( grid%p_top .GT. p_top_save ) THEN
872 print *,'grid%p_top from last time period = ',p_top_save
873 print *,'grid%p_top from this time period = ',grid%p_top
874 CALL wrf_error_fatal ( 'grid%p_top > previous value' )
876 grid%p_top = p_top_save
879 ! Get the monthly values interpolated to the current date for the traditional monthly
880 ! fields of green-ness fraction and background albedo.
882 CALL monthly_interp_to_date ( grid%greenfrac , current_date , grid%vegfra , &
883 ids , ide , jds , jde , kds , kde , &
884 ims , ime , jms , jme , kms , kme , &
885 its , ite , jts , jte , kts , kte )
887 CALL monthly_interp_to_date ( grid%albedo12m , current_date , grid%albbck , &
888 ids , ide , jds , jde , kds , kde , &
889 ims , ime , jms , jme , kms , kme , &
890 its , ite , jts , jte , kts , kte )
892 ! Get the min/max of each i,j for the monthly green-ness fraction.
894 CALL monthly_min_max ( grid%greenfrac , grid%shdmin , grid%shdmax , &
895 ids , ide , jds , jde , kds , kde , &
896 ims , ime , jms , jme , kms , kme , &
897 its , ite , jts , jte , kts , kte )
899 ! The model expects the green-ness values in percent, not fraction.
901 DO j = jts, MIN(jte,jde-1)
902 DO i = its, MIN(ite,ide-1)
903 grid%vegfra(i,j) = grid%vegfra(i,j) * 100.
904 grid%shdmax(i,j) = grid%shdmax(i,j) * 100.
905 grid%shdmin(i,j) = grid%shdmin(i,j) * 100.
909 ! The model expects the albedo fields as a fraction, not a percent. Set the
910 ! water values to 8%.
912 DO j = jts, MIN(jte,jde-1)
913 DO i = its, MIN(ite,ide-1)
914 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
915 grid%albbck(i,j) = grid%albbck(i,j) / 100.
916 grid%snoalb(i,j) = grid%snoalb(i,j) / 100.
917 IF ( grid%landmask(i,j) .LT. 0.5 ) THEN
918 grid%albbck(i,j) = 0.08
919 grid%snoalb(i,j) = 0.08
924 ! Two ways to get the surface pressure. 1) If we have the low-res input surface
925 ! pressure and the low-res topography, then we can do a simple hydrostatic
926 ! relation. 2) Otherwise we compute the surface pressure from the sea-level
928 ! Note that on output, grid%psfc is now hi-res. The low-res surface pressure and
929 ! elevation are grid%psfc_gc and grid%ht_gc (same as grid%ght_gc(k=1)).
931 IF ( ( flag_psfc .EQ. 1 ) .AND. &
932 ( flag_soilhgt .EQ. 1 ) .AND. &
933 ( flag_slp .EQ. 1 ) .AND. &
934 ( .NOT. config_flags%sfcp_to_sfcp ) ) THEN
935 WRITE(a_message,FMT='(A)') 'Using sfcprs3 to compute psfc'
936 CALL wrf_message ( a_message )
937 CALL sfcprs3(grid%ght_gc, grid%p_gc, grid%ht, &
938 grid%pslv_gc, grid%psfc, &
939 ids , ide , jds , jde , 1 , num_metgrid_levels , &
940 ims , ime , jms , jme , 1 , num_metgrid_levels , &
941 its , ite , jts , jte , 1 , num_metgrid_levels )
942 ELSE IF ( ( flag_psfc .EQ. 1 ) .AND. &
943 ( flag_soilhgt .EQ. 1 ) .AND. &
944 ( config_flags%sfcp_to_sfcp ) ) THEN
945 WRITE(a_message,FMT='(A)') 'Using sfcprs2 to compute psfc'
946 CALL wrf_message ( a_message )
947 CALL sfcprs2(grid%t_gc, grid%qv_gc, grid%ght_gc, grid%psfc_gc, grid%ht, &
948 grid%tavgsfc, grid%p_gc, grid%psfc, we_have_tavgsfc, &
949 ids , ide , jds , jde , 1 , num_metgrid_levels , &
950 ims , ime , jms , jme , 1 , num_metgrid_levels , &
951 its , ite , jts , jte , 1 , num_metgrid_levels )
952 ELSE IF ( flag_slp .EQ. 1 ) THEN
953 WRITE(a_message,FMT='(A)') 'Using sfcprs to compute psfc'
954 CALL wrf_message ( a_message )
955 CALL sfcprs (grid%t_gc, grid%qv_gc, grid%ght_gc, grid%pslv_gc, grid%ht, &
956 grid%tavgsfc, grid%p_gc, grid%psfc, we_have_tavgsfc, &
957 ids , ide , jds , jde , 1 , num_metgrid_levels , &
958 ims , ime , jms , jme , 1 , num_metgrid_levels , &
959 its , ite , jts , jte , 1 , num_metgrid_levels )
961 WRITE(a_message,FMT='(3(A,I2),A,L1)') 'ERROR in psfc: flag_psfc = ',flag_psfc, &
962 ', flag_soilhgt = ',flag_soilhgt , &
963 ', flag_slp = ',flag_slp , &
964 ', sfcp_to_sfcp = ',config_flags%sfcp_to_sfcp
965 CALL wrf_message ( a_message )
966 CALL wrf_error_fatal ( 'not enough info for a p sfc computation' )
969 ! If we have no input surface pressure, we'd better stick something in there.
971 IF ( flag_psfc .NE. 1 ) THEN
972 DO j = jts, MIN(jte,jde-1)
973 DO i = its, MIN(ite,ide-1)
974 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
975 grid%psfc_gc(i,j) = grid%psfc(i,j)
976 grid%p_gc(i,1,j) = grid%psfc(i,j)
981 ! Integrate the mixing ratio to get the vapor pressure.
983 CALL integ_moist ( grid%qv_gc , grid%p_gc , grid%pd_gc , grid%t_gc , grid%ght_gc , grid%intq_gc , &
984 ids , ide , jds , jde , 1 , num_metgrid_levels , &
985 ims , ime , jms , jme , 1 , num_metgrid_levels , &
986 its , ite , jts , jte , 1 , num_metgrid_levels )
988 ! If this is UM data, the same moisture removed from the "theta" level pressure data can
989 ! be removed from the "rho" level pressures. This is an approximation. We'll revisit to
990 ! see if this is a bad idea.
992 IF ( flag_ptheta .EQ. 1 ) THEN
993 DO j = jts, MIN(jte,jde-1)
994 DO k = num_metgrid_levels-1 , 1 , -1
995 DO i = its, MIN(ite,ide-1)
996 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
997 ptemp = ((grid%p_gc(i,k,j) - grid%pd_gc(i,k,j)) + (grid%p_gc(i,k+1,j) - grid%pd_gc(i,k+1,j)))/2
998 grid%pdrho_gc(i,k,j) = grid%prho_gc(i,k,j) - ptemp
1005 ! Compute the difference between the dry, total surface pressure (input) and the
1006 ! dry top pressure (constant).
1008 CALL p_dts ( grid%mu0 , grid%intq_gc , grid%psfc , grid%p_top , &
1009 ids , ide , jds , jde , 1 , num_metgrid_levels , &
1010 ims , ime , jms , jme , 1 , num_metgrid_levels , &
1011 its , ite , jts , jte , 1 , num_metgrid_levels )
1013 ! Compute the dry, hydrostatic surface pressure.
1015 CALL p_dhs ( grid%pdhs , grid%ht , p00 , t00 , a , &
1016 ids , ide , jds , jde , kds , kde , &
1017 ims , ime , jms , jme , kms , kme , &
1018 its , ite , jts , jte , kts , kte )
1020 ! Compute the eta levels if not defined already.
1022 IF ( grid%znw(1) .NE. 1.0 ) THEN
1024 eta_levels(1:kde) = model_config_rec%eta_levels(1:kde)
1025 max_dz = model_config_rec%max_dz
1027 CALL compute_eta ( grid%znw , &
1028 eta_levels , max_eta , max_dz , &
1029 grid%p_top , g , p00 , cvpm , a , r_d , cp , t00 , p1000mb , t0 , tiso , &
1030 ids , ide , jds , jde , kds , kde , &
1031 ims , ime , jms , jme , kms , kme , &
1032 its , ite , jts , jte , kts , kte )
1035 IF ( config_flags%interp_theta ) THEN
1037 ! The input field is temperature, we want potential temp.
1039 CALL t_to_theta ( grid%t_gc , grid%p_gc , p00 , &
1040 ids , ide , jds , jde , 1 , num_metgrid_levels , &
1041 ims , ime , jms , jme , 1 , num_metgrid_levels , &
1042 its , ite , jts , jte , 1 , num_metgrid_levels )
1045 IF ( flag_slp .EQ. 1 ) THEN
1047 ! On the eta surfaces, compute the dry pressure = mu eta, stored in
1048 ! grid%pb, since it is a pressure, and we don't need another kms:kme 3d
1049 ! array floating around. The grid%pb array is re-computed as the base pressure
1050 ! later after the vertical interpolations are complete.
1052 CALL p_dry ( grid%mu0 , grid%znw , grid%p_top , grid%pb , want_full_levels , &
1053 ids , ide , jds , jde , kds , kde , &
1054 ims , ime , jms , jme , kms , kme , &
1055 its , ite , jts , jte , kts , kte )
1057 ! All of the vertical interpolations are done in dry-pressure space. The
1058 ! input data has had the moisture removed (grid%pd_gc). The target levels (grid%pb)
1059 ! had the vapor pressure removed from the surface pressure, then they were
1060 ! scaled by the eta levels.
1063 lagrange_order = grid%lagrange_order
1064 lowest_lev_from_sfc = .FALSE.
1065 use_levels_below_ground = .TRUE.
1066 use_surface = .TRUE.
1067 zap_close_levels = grid%zap_close_levels
1068 force_sfc_in_vinterp = 0
1069 t_extrap_type = grid%t_extrap_type
1072 ! For the height field, the lowest level pressure is the slp (approximately "dry"). The
1073 ! lowest level of the input height field (to be associated with slp) then is an array
1076 DO j = jts, MIN(jte,jde-1)
1077 DO i = its, MIN(ite,ide-1)
1078 grid%psfc_gc(i,j) = grid%pd_gc(i,1,j)
1079 grid%pd_gc(i,1,j) = grid%pslv_gc(i,j) - ( grid%p_gc(i,1,j) - grid%pd_gc(i,1,j) )
1080 grid%ht_gc(i,j) = grid%ght_gc(i,1,j)
1081 grid%ght_gc(i,1,j) = 0.
1085 CALL vert_interp ( grid%ght_gc , grid%pd_gc , grid%ph0 , grid%pb , &
1086 num_metgrid_levels , 'Z' , &
1087 interp_type , lagrange_order , extrap_type , &
1088 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
1089 zap_close_levels , force_sfc_in_vinterp , &
1090 ids , ide , jds , jde , kds , kde , &
1091 ims , ime , jms , jme , kms , kme , &
1092 its , ite , jts , jte , kts , kte )
1094 ! Put things back to normal.
1096 DO j = jts, MIN(jte,jde-1)
1097 DO i = its, MIN(ite,ide-1)
1098 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1099 grid%pd_gc(i,1,j) = grid%psfc_gc(i,j)
1100 grid%ght_gc(i,1,j) = grid%ht_gc(i,j)
1106 ! Now the rest of the variables on half-levels to inteprolate.
1108 CALL p_dry ( grid%mu0 , grid%znw , grid%p_top , grid%pb , want_half_levels , &
1109 ids , ide , jds , jde , kds , kde , &
1110 ims , ime , jms , jme , kms , kme , &
1111 its , ite , jts , jte , kts , kte )
1113 interp_type = grid%interp_type
1114 lagrange_order = grid%lagrange_order
1115 lowest_lev_from_sfc = grid%lowest_lev_from_sfc
1116 use_levels_below_ground = grid%use_levels_below_ground
1117 use_surface = grid%use_surface
1118 zap_close_levels = grid%zap_close_levels
1119 force_sfc_in_vinterp = grid%force_sfc_in_vinterp
1120 t_extrap_type = grid%t_extrap_type
1121 extrap_type = grid%extrap_type
1123 ! Interpolate RH, diagnose Qv later when have temp and pressure. Temporarily
1124 ! store this in the u_1 space, for later diagnosis into Qv and stored into moist.
1126 CALL vert_interp ( grid%rh_gc , grid%pd_gc , grid%u_1 , grid%pb , &
1127 num_metgrid_levels , 'Q' , &
1128 interp_type , lagrange_order , extrap_type , &
1129 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
1130 zap_close_levels , force_sfc_in_vinterp , &
1131 ids , ide , jds , jde , kds , kde , &
1132 ims , ime , jms , jme , kms , kme , &
1133 its , ite , jts , jte , kts , kte )
1135 ! Depending on the setting of interp_theta = T/F, t_gc is is either theta Xor
1136 ! temperature, and that means that the t_2 field is also the associated field.
1137 ! It is better to interpolate temperature and potential temperature in LOG(p),
1138 ! regardless of requested default.
1141 CALL vert_interp ( grid%t_gc , grid%pd_gc , grid%t_2 , grid%pb , &
1142 num_metgrid_levels , 'T' , &
1143 interp_type , lagrange_order , t_extrap_type , &
1144 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
1145 zap_close_levels , force_sfc_in_vinterp , &
1146 ids , ide , jds , jde , kds , kde , &
1147 ims , ime , jms , jme , kms , kme , &
1148 its , ite , jts , jte , kts , kte )
1149 interp_type = grid%interp_type
1151 ! It is better to interpolate pressure in p regardless default options
1154 CALL vert_interp ( grid%p_gc , grid%pd_gc , grid%p , grid%pb , &
1155 num_metgrid_levels , 'T' , &
1156 interp_type , lagrange_order , t_extrap_type , &
1157 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
1158 zap_close_levels , force_sfc_in_vinterp , &
1159 ids , ide , jds , jde , kds , kde , &
1160 ims , ime , jms , jme , kms , kme , &
1161 its , ite , jts , jte , kts , kte )
1162 interp_type = grid%interp_type
1164 ! Do not have full pressure on eta levels, get a first guess at Qv by using
1165 ! dry pressure. The use of u_1 (rh) and v_1 (temperature) is temporary.
1166 ! We fix the approximation to Qv after the total pressure is available on
1171 IF ( config_flags%interp_theta ) THEN
1172 CALL theta_to_t ( grid%v_1 , grid%p , p00 , &
1173 ids , ide , jds , jde , kds , kde , &
1174 ims , ime , jms , jme , kms , kme , &
1175 its , ite , jts , jte , kts , kte )
1178 IF ( config_flags%rh2qv_method .eq. 1 ) THEN
1179 CALL rh_to_mxrat1(grid%u_1, grid%v_1, grid%p , moist(:,:,:,P_QV) , &
1180 config_flags%rh2qv_wrt_liquid , &
1181 config_flags%qv_max_p_safe , &
1182 config_flags%qv_max_flag , config_flags%qv_max_value , &
1183 config_flags%qv_min_p_safe , &
1184 config_flags%qv_min_flag , config_flags%qv_min_value , &
1185 ids , ide , jds , jde , kds , kde , &
1186 ims , ime , jms , jme , kms , kme , &
1187 its , ite , jts , jte , kts , kte-1 )
1188 ELSE IF ( config_flags%rh2qv_method .eq. 2 ) THEN
1189 CALL rh_to_mxrat2(grid%u_1, grid%v_1, grid%p , moist(:,:,:,P_QV) , &
1190 config_flags%rh2qv_wrt_liquid , &
1191 config_flags%qv_max_p_safe , &
1192 config_flags%qv_max_flag , config_flags%qv_max_value , &
1193 config_flags%qv_min_p_safe , &
1194 config_flags%qv_min_flag , config_flags%qv_min_value , &
1195 ids , ide , jds , jde , kds , kde , &
1196 ims , ime , jms , jme , kms , kme , &
1197 its , ite , jts , jte , kts , kte-1 )
1200 IF ( .NOT. config_flags%interp_theta ) THEN
1201 CALL t_to_theta ( grid%t_2 , grid%p , p00 , &
1202 ids , ide , jds , jde , kds , kde , &
1203 ims , ime , jms , jme , kms , kme , &
1204 its , ite , jts , jte , kts , kte )
1207 num_3d_m = num_moist
1208 num_3d_s = num_scalar
1210 IF ( flag_qr .EQ. 1 ) THEN
1211 DO im = PARAM_FIRST_SCALAR, num_3d_m
1212 IF ( im .EQ. P_QR ) THEN
1213 CALL vert_interp ( grid%qr_gc , grid%pd_gc , moist(:,:,:,P_QR) , grid%pb , &
1214 num_metgrid_levels , 'Q' , &
1215 interp_type , lagrange_order , extrap_type , &
1216 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
1217 zap_close_levels , force_sfc_in_vinterp , &
1218 ids , ide , jds , jde , kds , kde , &
1219 ims , ime , jms , jme , kms , kme , &
1220 its , ite , jts , jte , kts , kte )
1225 IF ( flag_qc .EQ. 1 ) THEN
1226 DO im = PARAM_FIRST_SCALAR, num_3d_m
1227 IF ( im .EQ. P_QC ) THEN
1228 CALL vert_interp ( grid%qc_gc , grid%pd_gc , moist(:,:,:,P_QC) , grid%pb , &
1229 num_metgrid_levels , 'Q' , &
1230 interp_type , lagrange_order , extrap_type , &
1231 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
1232 zap_close_levels , force_sfc_in_vinterp , &
1233 ids , ide , jds , jde , kds , kde , &
1234 ims , ime , jms , jme , kms , kme , &
1235 its , ite , jts , jte , kts , kte )
1240 IF ( flag_qi .EQ. 1 ) THEN
1241 DO im = PARAM_FIRST_SCALAR, num_3d_m
1242 IF ( im .EQ. P_QI ) THEN
1243 CALL vert_interp ( grid%qi_gc , grid%pd_gc , moist(:,:,:,P_QI) , grid%pb , &
1244 num_metgrid_levels , 'Q' , &
1245 interp_type , lagrange_order , extrap_type , &
1246 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
1247 zap_close_levels , force_sfc_in_vinterp , &
1248 ids , ide , jds , jde , kds , kde , &
1249 ims , ime , jms , jme , kms , kme , &
1250 its , ite , jts , jte , kts , kte )
1255 IF ( flag_qs .EQ. 1 ) THEN
1256 DO im = PARAM_FIRST_SCALAR, num_3d_m
1257 IF ( im .EQ. P_QS ) THEN
1258 CALL vert_interp ( grid%qs_gc , grid%pd_gc , moist(:,:,:,P_QS) , grid%pb , &
1259 num_metgrid_levels , 'Q' , &
1260 interp_type , lagrange_order , extrap_type , &
1261 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
1262 zap_close_levels , force_sfc_in_vinterp , &
1263 ids , ide , jds , jde , kds , kde , &
1264 ims , ime , jms , jme , kms , kme , &
1265 its , ite , jts , jte , kts , kte )
1270 IF ( flag_qg .EQ. 1 ) THEN
1271 DO im = PARAM_FIRST_SCALAR, num_3d_m
1272 IF ( im .EQ. P_QG ) THEN
1273 CALL vert_interp ( grid%qg_gc , grid%pd_gc , moist(:,:,:,P_QG) , grid%pb , &
1274 num_metgrid_levels , 'Q' , &
1275 interp_type , lagrange_order , extrap_type , &
1276 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
1277 zap_close_levels , force_sfc_in_vinterp , &
1278 ids , ide , jds , jde , kds , kde , &
1279 ims , ime , jms , jme , kms , kme , &
1280 its , ite , jts , jte , kts , kte )
1285 IF ( flag_qh .EQ. 1 ) THEN
1286 DO im = PARAM_FIRST_SCALAR, num_3d_m
1287 IF ( im .EQ. P_QH ) THEN
1288 CALL vert_interp ( grid%qh_gc , grid%pd_gc , moist(:,:,:,P_QH) , grid%pb , &
1289 num_metgrid_levels , 'Q' , &
1290 interp_type , lagrange_order , extrap_type , &
1291 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
1292 zap_close_levels , force_sfc_in_vinterp , &
1293 ids , ide , jds , jde , kds , kde , &
1294 ims , ime , jms , jme , kms , kme , &
1295 its , ite , jts , jte , kts , kte )
1300 IF ( flag_qni .EQ. 1 ) THEN
1301 DO im = PARAM_FIRST_SCALAR, num_3d_s
1302 IF ( im .EQ. P_QNI ) THEN
1303 CALL vert_interp ( grid%qni_gc , grid%pd_gc , scalar(:,:,:,P_QNI) , grid%pb , &
1304 num_metgrid_levels , 'Q' , &
1305 interp_type , lagrange_order , extrap_type , &
1306 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
1307 zap_close_levels , force_sfc_in_vinterp , &
1308 ids , ide , jds , jde , kds , kde , &
1309 ims , ime , jms , jme , kms , kme , &
1310 its , ite , jts , jte , kts , kte )
1315 ! If this is UM data, put the dry rho-based pressure back into the dry pressure array.
1316 ! Since the dry pressure is no longer needed, no biggy.
1318 IF ( flag_ptheta .EQ. 1 ) THEN
1319 DO j = jts, MIN(jte,jde-1)
1320 DO k = 1 , num_metgrid_levels
1321 DO i = its, MIN(ite,ide-1)
1322 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1323 grid%pd_gc(i,k,j) = grid%prho_gc(i,k,j)
1330 ips = its ; ipe = ite ; jps = jts ; jpe = jte ; kps = kts ; kpe = kte
1332 ! For the U and V vertical interpolation, we need the pressure defined
1333 ! at both the locations for the horizontal momentum, which we get by
1334 ! averaging two pressure values (i and i-1 for U, j and j-1 for V). The
1335 ! pressure field on input (grid%pd_gc) and the pressure of the new coordinate
1336 ! (grid%pb) are both communicated with an 8 stencil.
1338 # include "HALO_EM_VINTERP_UV_1.inc"
1341 CALL vert_interp ( grid%u_gc , grid%pd_gc , grid%u_2 , grid%pb , &
1342 num_metgrid_levels , 'U' , &
1343 interp_type , lagrange_order , extrap_type , &
1344 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
1345 zap_close_levels , force_sfc_in_vinterp , &
1346 ids , ide , jds , jde , kds , kde , &
1347 ims , ime , jms , jme , kms , kme , &
1348 its , ite , jts , jte , kts , kte )
1350 CALL vert_interp ( grid%v_gc , grid%pd_gc , grid%v_2 , grid%pb , &
1351 num_metgrid_levels , 'V' , &
1352 interp_type , lagrange_order , extrap_type , &
1353 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
1354 zap_close_levels , force_sfc_in_vinterp , &
1355 ids , ide , jds , jde , kds , kde , &
1356 ims , ime , jms , jme , kms , kme , &
1357 its , ite , jts , jte , kts , kte )
1359 END IF ! <----- END OF VERTICAL INTERPOLATION PART ---->
1361 ! Set the temperature of the inland lakes to tavgsfc if the temperature is available
1362 ! and islake is > num_veg_cat
1364 num_veg_cat = SIZE ( grid%landusef , DIM=2 )
1365 CALL nl_get_iswater ( grid%id , grid%iswater )
1366 CALL nl_get_islake ( grid%id , grid%islake )
1368 IF ( grid%islake < 0 ) THEN
1369 CALL wrf_debug ( 0 , 'Old data, no inland lake information')
1371 DO j=jts,MIN(jde-1,jte)
1372 DO i=its,MIN(ide-1,ite)
1373 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1374 IF ( ( ( grid%landusef(i,grid%iswater,j) >= 0.5 ) .OR. ( grid%lu_index(i,j) == grid%iswater ) ) .AND. &
1375 ( ( grid%sst(i,j) .LT. 150 ) .OR. ( grid%sst(i,j) .GT. 400 ) ) ) THEN
1376 IF ( we_have_tavgsfc ) THEN
1377 grid%sst(i,j) = grid%tavgsfc(i,j)
1379 IF ( ( grid%sst(i,j) .LT. 150 ) .OR. ( grid%sst(i,j) .GT. 400 ) ) THEN
1380 grid%sst(i,j) = grid%tsk(i,j)
1382 IF ( ( grid%sst(i,j) .LT. 150 ) .OR. ( grid%sst(i,j) .GT. 400 ) ) THEN
1383 grid%sst(i,j) = grid%t2(i,j)
1389 IF ( we_have_tavgsfc ) THEN
1391 CALL wrf_debug ( 0 , 'Using inland lakes with average surface temperature')
1392 DO j=jts,MIN(jde-1,jte)
1393 DO i=its,MIN(ide-1,ite)
1394 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1395 IF ( ( grid%landusef(i,grid%islake,j) >= 0.5 ) .OR. ( grid%lu_index(i,j) == grid%islake ) ) THEN
1396 grid%sst(i,j) = grid%tavgsfc(i,j)
1397 grid%tsk(i,j) = grid%tavgsfc(i,j)
1399 IF ( ( grid%sst(i,j) .LT. 150 ) .OR. ( grid%sst(i,j) .GT. 400 ) ) THEN
1400 grid%sst(i,j) = grid%t2(i,j)
1405 ELSE ! We don't have tavgsfc
1407 CALL wrf_debug ( 0 , 'No average surface temperature for use with inland lakes')
1410 DO j=jts,MIN(jde-1,jte)
1411 DO i=its,MIN(ide-1,ite)
1412 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1413 grid%landusef(i,grid%iswater,j) = grid%landusef(i,grid%iswater,j) + &
1414 grid%landusef(i,grid%islake,j)
1415 grid%landusef(i,grid%islake,j) = 0.
1421 ! Save the grid%tsk field for later use in the sea ice surface temperature
1422 ! for the Noah LSM scheme.
1424 DO j = jts, MIN(jte,jde-1)
1425 DO i = its, MIN(ite,ide-1)
1426 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1427 grid%tsk_save(i,j) = grid%tsk(i,j)
1431 ! Protect against bad grid%tsk values over water by supplying grid%sst (if it is
1432 ! available, and if the grid%sst is reasonable).
1434 DO j = jts, MIN(jde-1,jte)
1435 DO i = its, MIN(ide-1,ite)
1436 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1437 IF ( ( grid%landmask(i,j) .LT. 0.5 ) .AND. ( flag_sst .EQ. 1 ) .AND. &
1438 ( grid%sst(i,j) .GT. 170. ) .AND. ( grid%sst(i,j) .LT. 400. ) ) THEN
1439 grid%tsk(i,j) = grid%sst(i,j)
1444 ! Take the data from the input file and store it in the variables that
1445 ! use the WRF naming and ordering conventions.
1447 DO j = jts, MIN(jte,jde-1)
1448 DO i = its, MIN(ite,ide-1)
1449 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1450 IF ( grid%snow(i,j) .GE. 10. ) then
1451 grid%snowc(i,j) = 1.
1453 grid%snowc(i,j) = 0.0
1458 ! Set flag integers for presence of snowh and soilw fields
1460 grid%ifndsnowh = flag_snowh
1461 IF (num_sw_levels_input .GE. 1) THEN
1467 ! We require input data for the various LSM schemes.
1469 enough_data : SELECT CASE ( model_config_rec%sf_surface_physics(grid%id) )
1471 CASE ( LSMSCHEME, NOAHMPSCHEME )
1472 IF ( num_st_levels_input .LT. 2 ) THEN
1473 CALL wrf_error_fatal ( 'Not enough soil temperature data for Noah LSM scheme.')
1477 IF ( num_st_levels_input .LT. 2 ) THEN
1478 CALL wrf_error_fatal ( 'Not enough soil temperature data for RUC LSM scheme.')
1482 IF ( num_st_levels_input .LT. 2 ) THEN
1483 CALL wrf_error_fatal ( 'Not enough soil temperature data for P-X LSM scheme.')
1485 !---------- fds (06/2010) ---------------------------------
1487 IF ( num_st_levels_input .LT. 2 ) THEN
1488 CALL wrf_error_fatal ( 'Not enough soil temperature data for SSIB LSM scheme.')
1490 !--------------------------------------------------------
1492 END SELECT enough_data
1494 interpolate_soil_tmw : SELECT CASE ( model_config_rec%sf_surface_physics(grid%id) )
1496 CASE ( SLABSCHEME , LSMSCHEME, NOAHMPSCHEME , RUCLSMSCHEME, PXLSMSCHEME, SSIBSCHEME )
1497 CALL process_soil_real ( grid%tsk , grid%tmn , grid%tavgsfc, &
1498 grid%landmask , grid%sst , grid%ht, grid%toposoil, &
1499 st_input , sm_input , sw_input , &
1500 st_levels_input , sm_levels_input , sw_levels_input , &
1501 grid%zs , grid%dzs , grid%tslb , grid%smois , grid%sh2o , &
1502 flag_sst , flag_tavgsfc, flag_soilhgt,&
1503 flag_soil_layers, flag_soil_levels, &
1504 ids , ide , jds , jde , kds , kde , &
1505 ims , ime , jms , jme , kms , kme , &
1506 its , ite , jts , jte , kts , kte , &
1507 model_config_rec%sf_surface_physics(grid%id) , &
1508 model_config_rec%num_soil_layers , &
1509 model_config_rec%real_data_init_type , &
1510 num_st_levels_input , num_sm_levels_input , num_sw_levels_input , &
1511 num_st_levels_alloc , num_sm_levels_alloc , num_sw_levels_alloc )
1513 END SELECT interpolate_soil_tmw
1515 ! surface_input_source=1 => use data from static file (fractional category as input)
1516 ! surface_input_source=2 => use data from grib file (dominant category as input)
1517 ! surface_input_source=3 => use dominant data from static file (dominant category as input)
1519 IF ( any_valid_points ) THEN
1520 IF ( config_flags%surface_input_source .EQ. 1 ) THEN
1522 ! Generate the vegetation and soil category information from the fractional input
1523 ! data, or use the existing dominant category fields if they exist.
1525 grid%vegcat (its,jts) = 0
1526 grid%soilcat(its,jts) = 0
1528 num_veg_cat = SIZE ( grid%landusef , DIM=2 )
1529 num_soil_top_cat = SIZE ( grid%soilctop , DIM=2 )
1530 num_soil_bot_cat = SIZE ( grid%soilcbot , DIM=2 )
1532 CALL process_percent_cat_new ( grid%landmask , &
1533 grid%landusef , grid%soilctop , grid%soilcbot , &
1534 grid%isltyp , grid%ivgtyp , &
1535 num_veg_cat , num_soil_top_cat , num_soil_bot_cat , &
1536 ids , ide , jds , jde , kds , kde , &
1537 ims , ime , jms , jme , kms , kme , &
1538 its , ite , jts , jte , kts , kte , &
1539 model_config_rec%iswater(grid%id) )
1541 ! Make all the veg/soil parms the same so as not to confuse the developer.
1543 DO j = jts , MIN(jde-1,jte)
1544 DO i = its , MIN(ide-1,ite)
1545 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1546 grid%vegcat(i,j) = grid%ivgtyp(i,j)
1547 grid%soilcat(i,j) = grid%isltyp(i,j)
1551 ELSE IF ( config_flags%surface_input_source .EQ. 2 ) THEN
1553 ! Do we have dominant soil and veg data from the input already?
1555 IF ( grid%soilcat(i_valid,j_valid) .GT. 0.5 ) THEN
1556 DO j = jts, MIN(jde-1,jte)
1557 DO i = its, MIN(ide-1,ite)
1558 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1559 grid%isltyp(i,j) = NINT( grid%soilcat(i,j) )
1563 IF ( grid%vegcat(i_valid,j_valid) .GT. 0.5 ) THEN
1564 DO j = jts, MIN(jde-1,jte)
1565 DO i = its, MIN(ide-1,ite)
1566 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1567 grid%ivgtyp(i,j) = NINT( grid%vegcat(i,j) )
1572 ELSE IF ( config_flags%surface_input_source .EQ. 3 ) THEN
1574 ! Do we have dominant soil and veg data from the static input already?
1576 IF ( grid%sct_dom_gc(i_valid,j_valid) .GT. 0.5 ) THEN
1577 DO j = jts, MIN(jde-1,jte)
1578 DO i = its, MIN(ide-1,ite)
1579 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1580 grid%isltyp(i,j) = NINT( grid%sct_dom_gc(i,j) )
1581 grid%soilcat(i,j) = grid%isltyp(i,j)
1585 WRITE ( a_message , * ) 'You have set surface_input_source = 3,'// &
1586 ' but your geogrid data does not have valid dominant soil data.'
1587 CALL wrf_error_fatal ( a_message )
1589 IF ( grid%lu_index(i_valid,j_valid) .GT. 0.5 ) THEN
1590 DO j = jts, MIN(jde-1,jte)
1591 DO i = its, MIN(ide-1,ite)
1592 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1593 grid%ivgtyp(i,j) = NINT( grid%lu_index(i,j) )
1594 grid%vegcat(i,j) = grid%ivgtyp(i,j)
1598 WRITE ( a_message , * ) 'You have set surface_input_source = 3,'//&
1599 ' but your geogrid data does not have valid dominant land use data.'
1600 CALL wrf_error_fatal ( a_message )
1606 ! Adjustments for the seaice field PRIOR to the grid%tslb computations. This is
1607 ! is for the 5-layer scheme.
1609 num_veg_cat = SIZE ( grid%landusef , DIM=2 )
1610 num_soil_top_cat = SIZE ( grid%soilctop , DIM=2 )
1611 num_soil_bot_cat = SIZE ( grid%soilcbot , DIM=2 )
1612 CALL nl_get_seaice_threshold ( grid%id , grid%seaice_threshold )
1613 CALL nl_get_isice ( grid%id , grid%isice )
1614 CALL nl_get_iswater ( grid%id , grid%iswater )
1615 CALL adjust_for_seaice_pre ( grid%xice , grid%landmask , grid%tsk , grid%ivgtyp , grid%vegcat , grid%lu_index , &
1616 grid%xland , grid%landusef , grid%isltyp , grid%soilcat , grid%soilctop , &
1617 grid%soilcbot , grid%tmn , &
1618 grid%seaice_threshold , &
1619 config_flags%fractional_seaice, &
1620 num_veg_cat , num_soil_top_cat , num_soil_bot_cat , &
1621 grid%iswater , grid%isice , &
1622 model_config_rec%sf_surface_physics(grid%id) , &
1623 ids , ide , jds , jde , kds , kde , &
1624 ims , ime , jms , jme , kms , kme , &
1625 its , ite , jts , jte , kts , kte )
1627 ! Land use assignment.
1629 DO j = jts, MIN(jde-1,jte)
1630 DO i = its, MIN(ide-1,ite)
1631 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1632 grid%lu_index(i,j) = grid%ivgtyp(i,j)
1633 IF ( grid%lu_index(i,j) .NE. model_config_rec%iswater(grid%id) ) THEN
1634 grid%landmask(i,j) = 1
1637 grid%landmask(i,j) = 0
1644 ! Fix grid%tmn and grid%tsk.
1646 fix_tsk_tmn : SELECT CASE ( model_config_rec%sf_surface_physics(grid%id) )
1648 CASE ( SLABSCHEME , LSMSCHEME , NOAHMPSCHEME , RUCLSMSCHEME, PXLSMSCHEME, SSIBSCHEME )
1649 DO j = jts, MIN(jde-1,jte)
1650 DO i = its, MIN(ide-1,ite)
1651 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1652 IF ( ( grid%landmask(i,j) .LT. 0.5 ) .AND. ( flag_sst .EQ. 1 ) .AND. &
1653 ( grid%sst(i,j) .GT. 170. ) .AND. ( grid%sst(i,j) .LT. 400. ) ) THEN
1654 grid%tmn(i,j) = grid%sst(i,j)
1655 grid%tsk(i,j) = grid%sst(i,j)
1656 ELSE IF ( grid%landmask(i,j) .LT. 0.5 ) THEN
1657 grid%tmn(i,j) = grid%tsk(i,j)
1661 END SELECT fix_tsk_tmn
1663 ! Is the grid%tsk reasonable?
1665 IF ( internal_time_loop .NE. 1 ) THEN
1666 DO j = jts, MIN(jde-1,jte)
1667 DO i = its, MIN(ide-1,ite)
1668 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1669 IF ( grid%tsk(i,j) .LT. 170 .or. grid%tsk(i,j) .GT. 400. ) THEN
1670 grid%tsk(i,j) = grid%t_2(i,1,j)
1675 DO j = jts, MIN(jde-1,jte)
1676 DO i = its, MIN(ide-1,ite)
1677 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1678 IF ( grid%tsk(i,j) .LT. 170 .or. grid%tsk(i,j) .GT. 400. ) THEN
1679 print *,'error in the grid%tsk'
1681 print *,'grid%landmask=',grid%landmask(i,j)
1682 print *,'grid%tsk, grid%sst, grid%tmn=',grid%tsk(i,j),grid%sst(i,j),grid%tmn(i,j)
1683 if(grid%tmn(i,j).gt.170. .and. grid%tmn(i,j).lt.400.)then
1684 grid%tsk(i,j)=grid%tmn(i,j)
1685 else if(grid%sst(i,j).gt.170. .and. grid%sst(i,j).lt.400.)then
1686 grid%tsk(i,j)=grid%sst(i,j)
1688 CALL wrf_error_fatal ( 'grid%tsk unreasonable' )
1695 ! Is the grid%tmn reasonable?
1697 DO j = jts, MIN(jde-1,jte)
1698 DO i = its, MIN(ide-1,ite)
1699 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1700 IF ( ( ( grid%tmn(i,j) .LT. 170. ) .OR. ( grid%tmn(i,j) .GT. 400. ) ) &
1701 .AND. ( grid%landmask(i,j) .GT. 0.5 ) ) THEN
1702 IF ( ( model_config_rec%sf_surface_physics(grid%id) .NE. LSMSCHEME ) .and. &
1703 ( model_config_rec%sf_surface_physics(grid%id) .NE. NOAHMPSCHEME ) ) THEN
1704 print *,'error in the grid%tmn'
1706 print *,'grid%landmask=',grid%landmask(i,j)
1707 print *,'grid%tsk, grid%sst, grid%tmn=',grid%tsk(i,j),grid%sst(i,j),grid%tmn(i,j)
1710 if(grid%tsk(i,j).gt.170. .and. grid%tsk(i,j).lt.400.)then
1711 grid%tmn(i,j)=grid%tsk(i,j)
1712 else if(grid%sst(i,j).gt.170. .and. grid%sst(i,j).lt.400.)then
1713 grid%tmn(i,j)=grid%sst(i,j)
1715 CALL wrf_error_fatal ( 'grid%tmn unreasonable' )
1722 ! Minimum soil values, residual, from RUC LSM scheme. For input from Noah or EC, and using
1723 ! RUC LSM scheme, this must be subtracted from the input total soil moisture. For
1724 ! input RUC data and using the Noah LSM scheme, this value must be added to the soil
1727 lqmi(1:num_soil_top_cat) = &
1728 (/0.045, 0.057, 0.065, 0.067, 0.034, 0.078, 0.10, &
1729 0.089, 0.095, 0.10, 0.070, 0.068, 0.078, 0.0, &
1731 ! 0.004, 0.065, 0.020, 0.004, 0.008 /) ! has extra levels for playa, lava, and white sand
1733 ! At the initial time we care about values of soil moisture and temperature, other times are
1734 ! ignored by the model, so we ignore them, too.
1736 IF ( domain_ClockIsStartTime(grid) ) THEN
1737 account_for_zero_soil_moisture : SELECT CASE ( model_config_rec%sf_surface_physics(grid%id) )
1739 CASE ( LSMSCHEME , NOAHMPSCHEME )
1741 IF ( flag_soil_layers == 1 ) THEN
1742 DO j = jts, MIN(jde-1,jte)
1743 DO i = its, MIN(ide-1,ite)
1744 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1745 IF ( (grid%landmask(i,j).gt.0.5) .and. ( grid%tslb(i,1,j) .gt. 170 ) .and. &
1746 ( grid%tslb(i,1,j) .lt. 400 ) .and. ( grid%smois(i,1,j) .lt. 0.005 ) ) then
1747 print *,'Noah -> Noah: bad soil moisture at i,j = ',i,j,grid%smois(i,:,j)
1748 iicount = iicount + 1
1749 grid%smois(i,:,j) = 0.005
1753 IF ( iicount .GT. 0 ) THEN
1754 print *,'Noah -> Noah: total number of small soil moisture locations = ',iicount
1756 ELSE IF ( flag_soil_levels == 1 ) THEN
1757 DO j = jts, MIN(jde-1,jte)
1758 DO i = its, MIN(ide-1,ite)
1759 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1760 grid%smois(i,:,j) = MAX ( grid%smois(i,:,j) , 0.005 )
1761 ! grid%smois(i,:,j) = MAX ( grid%smois(i,:,j) + lqmi(grid%isltyp(i,j)) , 0.005 )
1764 DO j = jts, MIN(jde-1,jte)
1765 DO i = its, MIN(ide-1,ite)
1766 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1767 IF ( (grid%landmask(i,j).gt.0.5) .and. ( grid%tslb(i,1,j) .gt. 170 ) .and. &
1768 ( grid%tslb(i,1,j) .lt. 400 ) .and. ( grid%smois(i,1,j) .lt. 0.005 ) ) then
1769 print *,'RUC -> Noah: bad soil moisture at i,j = ',i,j,grid%smois(i,:,j)
1770 iicount = iicount + 1
1771 grid%smois(i,:,j) = 0.005
1775 IF ( iicount .GT. 0 ) THEN
1776 print *,'RUC -> Noah: total number of small soil moisture locations = ',iicount
1780 CASE ( RUCLSMSCHEME )
1782 IF ( flag_soil_layers == 1 ) THEN
1783 DO j = jts, MIN(jde-1,jte)
1784 DO i = its, MIN(ide-1,ite)
1785 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1786 grid%smois(i,:,j) = MAX ( grid%smois(i,:,j) , 0.005 )
1787 ! grid%smois(i,:,j) = MAX ( grid%smois(i,:,j) - lqmi(grid%isltyp(i,j)) , 0.005 )
1790 ELSE IF ( flag_soil_levels == 1 ) THEN
1794 CASE ( PXLSMSCHEME )
1796 IF ( flag_soil_layers == 1 ) THEN
1798 ELSE IF ( flag_soil_levels == 1 ) THEN
1799 DO j = jts, MIN(jde-1,jte)
1800 DO i = its, MIN(ide-1,ite)
1801 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1802 grid%smois(i,:,j) = MAX ( grid%smois(i,:,j) , 0.005 )
1803 ! grid%smois(i,:,j) = MAX ( grid%smois(i,:,j) + lqmi(grid%isltyp(i,j)) , 0.005 )
1808 END SELECT account_for_zero_soil_moisture
1811 ! Is the grid%tslb reasonable?
1813 IF ( internal_time_loop .NE. 1 ) THEN
1814 DO j = jts, MIN(jde-1,jte)
1815 DO ns = 1 , model_config_rec%num_soil_layers
1816 DO i = its, MIN(ide-1,ite)
1817 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1818 IF ( grid%tslb(i,ns,j) .LT. 170 .or. grid%tslb(i,ns,j) .GT. 400. ) THEN
1819 grid%tslb(i,ns,j) = grid%t_2(i,1,j)
1820 grid%smois(i,ns,j) = 0.3
1826 DO j = jts, MIN(jde-1,jte)
1827 DO i = its, MIN(ide-1,ite)
1828 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1829 IF ( ( ( grid%tslb(i,1,j) .LT. 170. ) .OR. ( grid%tslb(i,1,j) .GT. 400. ) ) .AND. &
1830 ( grid%landmask(i,j) .GT. 0.5 ) ) THEN
1831 IF ( ( model_config_rec%sf_surface_physics(grid%id) .NE. LSMSCHEME ) .AND. &
1832 ( model_config_rec%sf_surface_physics(grid%id) .NE. NOAHMPSCHEME ) .AND. &
1833 ( model_config_rec%sf_surface_physics(grid%id) .NE. RUCLSMSCHEME ).AND. &
1834 ( model_config_rec%sf_surface_physics(grid%id) .NE. SSIBSCHEME ).AND. & !fds
1835 ( model_config_rec%sf_surface_physics(grid%id) .NE. PXLSMSCHEME ) ) THEN
1836 print *,'error in the grid%tslb'
1838 print *,'grid%landmask=',grid%landmask(i,j)
1839 print *,'grid%tsk, grid%sst, grid%tmn=',grid%tsk(i,j),grid%sst(i,j),grid%tmn(i,j)
1840 print *,'grid%tslb = ',grid%tslb(i,:,j)
1841 print *,'old grid%smois = ',grid%smois(i,:,j)
1842 grid%smois(i,1,j) = 0.3
1843 grid%smois(i,2,j) = 0.3
1844 grid%smois(i,3,j) = 0.3
1845 grid%smois(i,4,j) = 0.3
1848 IF ( (grid%tsk(i,j).GT.170. .AND. grid%tsk(i,j).LT.400.) .AND. &
1849 (grid%tmn(i,j).GT.170. .AND. grid%tmn(i,j).LT.400.) ) THEN
1850 fake_soil_temp : SELECT CASE ( model_config_rec%sf_surface_physics(grid%id) )
1852 DO ns = 1 , model_config_rec%num_soil_layers
1853 grid%tslb(i,ns,j) = ( grid%tsk(i,j)*(3.0 - grid%zs(ns)) + &
1854 grid%tmn(i,j)*(0.0 - grid%zs(ns)) ) /(3.0 - 0.0)
1856 CASE ( LSMSCHEME , NOAHMPSCHEME , RUCLSMSCHEME, PXLSMSCHEME, SSIBSCHEME )
1857 ! CALL wrf_error_fatal ( 'Assigned constant soil moisture to 0.3, stopping')
1858 DO ns = 1 , model_config_rec%num_soil_layers
1859 grid%tslb(i,ns,j) = ( grid%tsk(i,j)*(3.0 - grid%zs(ns)) + &
1860 grid%tmn(i,j)*(0.0 - grid%zs(ns)) ) /(3.0 - 0.0)
1862 END SELECT fake_soil_temp
1863 else if(grid%tsk(i,j).gt.170. .and. grid%tsk(i,j).lt.400.)then
1864 CALL wrf_error_fatal ( 'grid%tslb unreasonable 1' )
1865 DO ns = 1 , model_config_rec%num_soil_layers
1866 grid%tslb(i,ns,j)=grid%tsk(i,j)
1868 else if(grid%sst(i,j).gt.170. .and. grid%sst(i,j).lt.400.)then
1869 CALL wrf_error_fatal ( 'grid%tslb unreasonable 2' )
1870 DO ns = 1 , model_config_rec%num_soil_layers
1871 grid%tslb(i,ns,j)=grid%sst(i,j)
1873 else if(grid%tmn(i,j).gt.170. .and. grid%tmn(i,j).lt.400.)then
1874 CALL wrf_error_fatal ( 'grid%tslb unreasonable 3' )
1875 DO ns = 1 , model_config_rec%num_soil_layers
1876 grid%tslb(i,ns,j)=grid%tmn(i,j)
1879 CALL wrf_error_fatal ( 'grid%tslb unreasonable 4' )
1886 ! Adjustments for the seaice field AFTER the grid%tslb computations. This is
1887 ! is for the Noah LSM scheme.
1889 num_veg_cat = SIZE ( grid%landusef , DIM=2 )
1890 num_soil_top_cat = SIZE ( grid%soilctop , DIM=2 )
1891 num_soil_bot_cat = SIZE ( grid%soilcbot , DIM=2 )
1892 CALL nl_get_seaice_threshold ( grid%id , grid%seaice_threshold )
1893 CALL nl_get_isice ( grid%id , grid%isice )
1894 CALL nl_get_iswater ( grid%id , grid%iswater )
1895 CALL adjust_for_seaice_post ( grid%xice , grid%landmask , grid%tsk , grid%tsk_save , &
1896 grid%ivgtyp , grid%vegcat , grid%lu_index , &
1897 grid%xland , grid%landusef , grid%isltyp , grid%soilcat , &
1899 grid%soilcbot , grid%tmn , grid%vegfra , &
1900 grid%tslb , grid%smois , grid%sh2o , &
1901 grid%seaice_threshold , &
1902 grid%sst,flag_sst, &
1903 config_flags%fractional_seaice, &
1904 num_veg_cat , num_soil_top_cat , num_soil_bot_cat , &
1905 model_config_rec%num_soil_layers , &
1906 grid%iswater , grid%isice , &
1907 model_config_rec%sf_surface_physics(grid%id) , &
1908 ids , ide , jds , jde , kds , kde , &
1909 ims , ime , jms , jme , kms , kme , &
1910 its , ite , jts , jte , kts , kte )
1912 ! Let us make sure (again) that the grid%landmask and the veg/soil categories match.
1916 DO j = jts, MIN(jde-1,jte)
1917 DO i = its, MIN(ide-1,ite)
1918 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1919 IF ( ( ( grid%landmask(i,j) .LT. 0.5 ) .AND. &
1920 ( grid%ivgtyp(i,j) .NE. config_flags%iswater .OR. grid%isltyp(i,j) .NE. 14 ) ) .OR. &
1921 ( ( grid%landmask(i,j) .GT. 0.5 ) .AND. &
1922 ( grid%ivgtyp(i,j) .EQ. config_flags%iswater .OR. grid%isltyp(i,j) .EQ. 14 ) ) ) THEN
1923 IF ( grid%tslb(i,1,j) .GT. 1. ) THEN
1925 grid%ivgtyp(i,j) = 5
1926 grid%isltyp(i,j) = 8
1927 grid%landmask(i,j) = 1
1929 ELSE IF ( grid%sst(i,j) .GT. 1. ) THEN
1931 grid%ivgtyp(i,j) = config_flags%iswater
1932 grid%isltyp(i,j) = 14
1933 grid%landmask(i,j) = 0
1936 print *,'the grid%landmask and soil/veg cats do not match'
1938 print *,'grid%landmask=',grid%landmask(i,j)
1939 print *,'grid%ivgtyp=',grid%ivgtyp(i,j)
1940 print *,'grid%isltyp=',grid%isltyp(i,j)
1941 print *,'iswater=', config_flags%iswater
1942 print *,'grid%tslb=',grid%tslb(i,:,j)
1943 print *,'grid%sst=',grid%sst(i,j)
1944 CALL wrf_error_fatal ( 'mismatch_landmask_ivgtyp' )
1949 if (oops1.gt.0) then
1950 print *,'points artificially set to land : ',oops1
1953 print *,'points artificially set to water: ',oops2
1955 ! fill grid%sst array with grid%tsk if missing in real input (needed for time-varying grid%sst in wrf)
1956 DO j = jts, MIN(jde-1,jte)
1957 DO i = its, MIN(ide-1,ite)
1958 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1959 IF ( flag_sst .NE. 1 ) THEN
1960 grid%sst(i,j) = grid%tsk(i,j)
1964 !tgs set snoalb to land value if the water point is covered with ice
1965 DO j = jts, MIN(jde-1,jte)
1966 DO i = its, MIN(ide-1,ite)
1967 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
1968 IF ( grid%ivgtyp(i,j) .EQ. config_flags%isice) THEN
1969 grid%snoalb(i,j) = 0.75
1974 ! From the full level data, we can get the half levels, reciprocals, and layer
1975 ! thicknesses. These are all defined at half level locations, so one less level.
1976 ! We allow the vertical coordinate to *accidently* come in upside down. We want
1977 ! the first full level to be the ground surface.
1979 ! Check whether grid%znw (full level) data are truly full levels. If not, we need to adjust them
1980 ! to be full levels.
1981 ! in this test, we check if grid%znw(1) is neither 0 nor 1 (within a tolerance of 10**-5)
1984 IF ( ( (grid%znw(1).LT.(1-1.E-5) ) .OR. ( grid%znw(1).GT.(1+1.E-5) ) ).AND. &
1985 ( (grid%znw(1).LT.(0-1.E-5) ) .OR. ( grid%znw(1).GT.(0+1.E-5) ) ) ) THEN
1987 print *,'Your grid%znw input values are probably half-levels. '
1989 print *,'WRF expects grid%znw values to be full levels. '
1990 print *,'Adjusting now to full levels...'
1991 ! We want to ignore the first value if it's negative
1992 IF (grid%znw(1).LT.0) THEN
1996 grid%znw(k)=2*grid%znw(k)-grid%znw(k-1)
2000 ! Let's check our changes
2002 IF ( ( ( grid%znw(1) .LT. (1-1.E-5) ) .OR. ( grid%znw(1) .GT. (1+1.E-5) ) ).AND. &
2003 ( ( grid%znw(1) .LT. (0-1.E-5) ) .OR. ( grid%znw(1) .GT. (0+1.E-5) ) ) ) THEN
2004 print *,'The input grid%znw height values were half-levels or erroneous. '
2005 print *,'Attempts to treat the values as half-levels and change them '
2006 print *,'to valid full levels failed.'
2007 CALL wrf_error_fatal("bad grid%znw values from input files")
2008 ELSE IF ( were_bad ) THEN
2009 print *,'...adjusted. grid%znw array now contains full eta level values. '
2012 IF ( grid%znw(1) .LT. grid%znw(kde) ) THEN
2014 hold_znw = grid%znw(k)
2015 grid%znw(k)=grid%znw(kde+1-k)
2016 grid%znw(kde+1-k)=hold_znw
2021 grid%dnw(k) = grid%znw(k+1) - grid%znw(k)
2022 grid%rdnw(k) = 1./grid%dnw(k)
2023 grid%znu(k) = 0.5*(grid%znw(k+1)+grid%znw(k))
2026 ! Now the same sort of computations with the half eta levels, even ANOTHER
2027 ! level less than the one above.
2030 grid%dn(k) = 0.5*(grid%dnw(k)+grid%dnw(k-1))
2031 grid%rdn(k) = 1./grid%dn(k)
2032 grid%fnp(k) = .5* grid%dnw(k )/grid%dn(k)
2033 grid%fnm(k) = .5* grid%dnw(k-1)/grid%dn(k)
2036 ! Scads of vertical coefficients.
2038 cof1 = (2.*grid%dn(2)+grid%dn(3))/(grid%dn(2)+grid%dn(3))*grid%dnw(1)/grid%dn(2)
2039 cof2 = grid%dn(2) /(grid%dn(2)+grid%dn(3))*grid%dnw(1)/grid%dn(3)
2041 grid%cf1 = grid%fnp(2) + cof1
2042 grid%cf2 = grid%fnm(2) - cof1 - cof2
2045 grid%cfn = (.5*grid%dnw(kde-1)+grid%dn(kde-1))/grid%dn(kde-1)
2046 grid%cfn1 = -.5*grid%dnw(kde-1)/grid%dn(kde-1)
2048 ! Inverse grid distances.
2050 grid%rdx = 1./config_flags%dx
2051 grid%rdy = 1./config_flags%dy
2053 ! Some of the many weird geopotential initializations that we'll see today: grid%ph0 is total,
2054 ! and grid%ph_2 is a perturbation from the base state geopotential. We set the base geopotential
2055 ! at the lowest level to terrain elevation * gravity.
2059 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
2060 grid%ph0(i,1,j) = grid%ht(i,j) * g
2061 grid%ph_2(i,1,j) = 0.
2065 ! Base state potential temperature and inverse density (alpha = 1/rho) from
2066 ! the half eta levels and the base-profile surface pressure. Compute 1/rho
2067 ! from equation of state. The potential temperature is a perturbation from t0.
2069 DO j = jts, MIN(jte,jde-1)
2070 DO i = its, MIN(ite,ide-1)
2072 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
2074 ! Base state pressure is a function of eta level and terrain, only, plus
2075 ! the hand full of constants: p00 (sea level pressure, Pa), t00 (sea level
2076 ! temperature, K), and A (temperature difference, from 1000 mb to 300 mb, K).
2078 p_surf = p00 * EXP ( -t00/a + ( (t00/a)**2 - 2.*g*grid%ht(i,j)/a/r_d ) **0.5 )
2082 grid%php(i,k,j) = grid%znw(k)*(p_surf - grid%p_top) + grid%p_top ! temporary, full lev base pressure
2083 grid%pb(i,k,j) = grid%znu(k)*(p_surf - grid%p_top) + grid%p_top
2084 temp = MAX ( tiso, t00 + A*LOG(grid%pb(i,k,j)/p00) )
2085 ! temp = t00 + A*LOG(grid%pb(i,k,j)/p00)
2086 grid%t_init(i,k,j) = temp*(p00/grid%pb(i,k,j))**(r_d/cp) - t0
2087 grid%alb(i,k,j) = (r_d/p1000mb)*(grid%t_init(i,k,j)+t0)*(grid%pb(i,k,j)/p1000mb)**cvpm
2090 ! Base state mu is defined as base state surface pressure minus grid%p_top
2092 grid%mub(i,j) = p_surf - grid%p_top
2094 ! Dry surface pressure is defined as the following (this mu is from the input file
2095 ! computed from the dry pressure). Here the dry pressure is just reconstituted.
2097 pd_surf = grid%mu0(i,j) + grid%p_top
2099 ! Integrate base geopotential, starting at terrain elevation. This assures that
2100 ! the base state is in exact hydrostatic balance with respect to the model equations.
2101 ! This field is on full levels.
2103 grid%phb(i,1,j) = grid%ht(i,j) * g
2104 IF (grid%hypsometric_opt == 1) THEN
2106 grid%phb(i,k,j) = grid%phb(i,k-1,j) - grid%dnw(k-1)*grid%mub(i,j)*grid%alb(i,k-1,j)
2108 ELSE IF (grid%hypsometric_opt == 2) THEN
2110 pfu = grid%mub(i,j)*grid%znw(k) + grid%p_top
2111 pfd = grid%mub(i,j)*grid%znw(k-1) + grid%p_top
2112 phm = grid%mub(i,j)*grid%znu(k-1) + grid%p_top
2113 grid%phb(i,k,j) = grid%phb(i,k-1,j) + grid%alb(i,k-1,j)*phm*LOG(pfd/pfu)
2116 CALL wrf_error_fatal( 'initialize_real: hypsometric_opt should be 1 or 2' )
2122 ! Fill in the outer rows and columns to allow us to be sloppy.
2124 IF ( ite .EQ. ide ) THEN
2126 DO j = jts, MIN(jde-1,jte)
2127 grid%mub(i,j) = grid%mub(i-1,j)
2128 grid%mu_2(i,j) = grid%mu_2(i-1,j)
2130 grid%pb(i,k,j) = grid%pb(i-1,k,j)
2131 grid%t_init(i,k,j) = grid%t_init(i-1,k,j)
2132 grid%alb(i,k,j) = grid%alb(i-1,k,j)
2135 grid%phb(i,k,j) = grid%phb(i-1,k,j)
2140 IF ( jte .EQ. jde ) THEN
2143 grid%mub(i,j) = grid%mub(i,j-1)
2144 grid%mu_2(i,j) = grid%mu_2(i,j-1)
2146 grid%pb(i,k,j) = grid%pb(i,k,j-1)
2147 grid%t_init(i,k,j) = grid%t_init(i,k,j-1)
2148 grid%alb(i,k,j) = grid%alb(i,k,j-1)
2151 grid%phb(i,k,j) = grid%phb(i,k,j-1)
2156 ! Compute the perturbation dry pressure (grid%mub + grid%mu_2 + ptop = dry grid%psfc).
2158 DO j = jts, min(jde-1,jte)
2159 DO i = its, min(ide-1,ite)
2160 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
2161 grid%mu_2(i,j) = grid%mu0(i,j) - grid%mub(i,j)
2165 ! Fill in the outer rows and columns to allow us to be sloppy.
2167 IF ( ite .EQ. ide ) THEN
2169 DO j = jts, MIN(jde-1,jte)
2170 grid%mu_2(i,j) = grid%mu_2(i-1,j)
2174 IF ( jte .EQ. jde ) THEN
2177 grid%mu_2(i,j) = grid%mu_2(i,j-1)
2182 DO j = jts, min(jde-1,jte)
2183 DO i = its, min(ide-1,ite)
2184 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
2186 ! Assign the potential temperature (perturbation from t0) and qv on all the mass
2190 grid%t_2(i,k,j) = grid%t_2(i,k,j) - t0
2196 DO WHILE ( ( ABS(dpmu) .GT. 10. ) .AND. &
2197 ( loop_count .LT. 5 ) )
2199 loop_count = loop_count + 1
2201 ! Integrate the hydrostatic equation (from the RHS of the bigstep vertical momentum
2202 ! equation) down from the top to get the pressure perturbation. First get the pressure
2203 ! perturbation, moisture, and inverse density (total and perturbation) at the top-most level.
2207 qvf1 = 0.5*(moist(i,k,j,P_QV)+moist(i,k,j,P_QV))
2211 grid%p(i,k,j) = - 0.5*(grid%mu_2(i,j)+qvf1*grid%mub(i,j))/grid%rdnw(k)/qvf2
2212 qvf = 1. + rvovrd*moist(i,k,j,P_QV)
2213 grid%alt(i,k,j) = (r_d/p1000mb)*(grid%t_2(i,k,j)+t0)*qvf&
2214 *(((grid%p(i,k,j)+grid%pb(i,k,j))/p1000mb)**cvpm)
2215 grid%al(i,k,j) = grid%alt(i,k,j) - grid%alb(i,k,j)
2216 grid%p_hyd(i,k,j) = grid%p(i,k,j) + grid%pb(i,k,j)
2218 ! Now, integrate down the column to compute the pressure perturbation, and diagnose the two
2219 ! inverse density fields (total and perturbation).
2222 qvf1 = 0.5*(moist(i,k,j,P_QV)+moist(i,k+1,j,P_QV))
2225 grid%p(i,k,j) = grid%p(i,k+1,j) - (grid%mu_2(i,j) + qvf1*grid%mub(i,j))/qvf2/grid%rdn(k+1)
2226 qvf = 1. + rvovrd*moist(i,k,j,P_QV)
2227 grid%alt(i,k,j) = (r_d/p1000mb)*(grid%t_2(i,k,j)+t0)*qvf* &
2228 (((grid%p(i,k,j)+grid%pb(i,k,j))/p1000mb)**cvpm)
2229 grid%al(i,k,j) = grid%alt(i,k,j) - grid%alb(i,k,j)
2230 grid%p_hyd(i,k,j) = grid%p(i,k,j) + grid%pb(i,k,j)
2234 ! This is the hydrostatic equation used in the model after the small timesteps. In
2235 ! the model, grid%al (inverse density) is computed from the geopotential.
2237 IF (grid%hypsometric_opt == 1) THEN
2239 grid%ph_2(i,k,j) = grid%ph_2(i,k-1,j) - &
2240 grid%dnw(k-1) * ( (grid%mub(i,j)+grid%mu_2(i,j))*grid%al(i,k-1,j) &
2241 + grid%mu_2(i,j)*grid%alb(i,k-1,j) )
2242 grid%ph0(i,k,j) = grid%ph_2(i,k,j) + grid%phb(i,k,j)
2244 ELSE IF (grid%hypsometric_opt == 2) THEN
2245 ! Alternative hydrostatic eq.: dZ = -al*p*dLOG(p), where p is dry pressure.
2246 ! Note that al*p approximates Rd*T and dLOG(p) does z.
2247 ! Here T varies mostly linear with z, the first-order integration produces better result.
2249 grid%ph_2(i,1,j) = grid%phb(i,1,j)
2251 pfu = grid%mu0(i,j)*grid%znw(k) + grid%p_top
2252 pfd = grid%mu0(i,j)*grid%znw(k-1) + grid%p_top
2253 phm = grid%mu0(i,j)*grid%znu(k-1) + grid%p_top
2254 grid%ph_2(i,k,j) = grid%ph_2(i,k-1,j) + grid%alt(i,k-1,j)*phm*LOG(pfd/pfu)
2258 grid%ph_2(i,k,j) = grid%ph_2(i,k,j) - grid%phb(i,k,j)
2262 ! Get the perturbation geopotential from the 3d height array from WPS.
2265 grid%ph_2(i,k,j) = grid%ph0(i,k,j)*g - grid%phb(i,k,j)
2269 ! Adjust the column pressure so that the computed 500 mb height is close to the
2270 ! input value (of course, not when we are doing hybrid input).
2272 IF ( ( flag_metgrid .EQ. 1 ) .AND. ( i .EQ. i_valid ) .AND. ( j .EQ. j_valid ) ) THEN
2273 DO k = 1 , num_metgrid_levels
2274 IF ( ABS ( grid%p_gc(i,k,j) - 50000. ) .LT. 1. ) THEN
2281 ! We only do the adjustment of height if we have the input data on pressure
2282 ! surfaces, and folks have asked to do this option.
2284 IF ( ( flag_metgrid .EQ. 1 ) .AND. &
2285 ( flag_ptheta .EQ. 0 ) .AND. &
2286 ( config_flags%adjust_heights ) .AND. &
2287 ( lev500 .NE. 0 ) ) THEN
2291 ! Get the pressures on the full eta levels (grid%php is defined above as
2292 ! the full-lev base pressure, an easy array to use for 3d space).
2294 pl = grid%php(i,k ,j) + &
2295 ( grid%p(i,k-1 ,j) * ( grid%znw(k ) - grid%znu(k ) ) + &
2296 grid%p(i,k ,j) * ( grid%znu(k-1 ) - grid%znw(k ) ) ) / &
2297 ( grid%znu(k-1 ) - grid%znu(k ) )
2298 pu = grid%php(i,k+1,j) + &
2299 ( grid%p(i,k-1+1,j) * ( grid%znw(k +1) - grid%znu(k+1) ) + &
2300 grid%p(i,k +1,j) * ( grid%znu(k-1+1) - grid%znw(k+1) ) ) / &
2301 ( grid%znu(k-1+1) - grid%znu(k+1) )
2303 ! If these pressure levels trap 500 mb, use them to interpolate
2304 ! to the 500 mb level of the computed height.
2306 IF ( ( pl .GE. 50000. ) .AND. ( pu .LT. 50000. ) ) THEN
2307 zl = ( grid%ph_2(i,k ,j) + grid%phb(i,k ,j) ) / g
2308 zu = ( grid%ph_2(i,k+1,j) + grid%phb(i,k+1,j) ) / g
2310 z500 = ( zl * ( LOG(50000.) - LOG(pu ) ) + &
2311 zu * ( LOG(pl ) - LOG(50000.) ) ) / &
2312 ( LOG(pl) - LOG(pu) )
2313 ! z500 = ( zl * ( (50000.) - (pu ) ) + &
2314 ! zu * ( (pl ) - (50000.) ) ) / &
2317 ! Compute the difference of the 500 mb heights (computed minus input), and
2318 ! then the change in grid%mu_2. The grid%php is still full-levels, base pressure.
2320 dz500 = z500 - grid%ght_gc(i,lev500,j)
2321 tvsfc = ((grid%t_2(i,1,j)+t0)*((grid%p(i,1,j)+grid%php(i,1,j))/p1000mb)**(r_d/cp)) * &
2322 (1.+0.6*moist(i,1,j,P_QV))
2323 dpmu = ( grid%php(i,1,j) + grid%p(i,1,j) ) * EXP ( g * dz500 / ( r_d * tvsfc ) )
2324 dpmu = dpmu - ( grid%php(i,1,j) + grid%p(i,1,j) )
2325 grid%mu_2(i,j) = grid%mu_2(i,j) - dpmu
2339 ! If this is data from the SI, then we probably do not have the original
2340 ! surface data laying around. Note that these are all the lowest levels
2341 ! of the respective 3d arrays. For surface pressure, we assume that the
2342 ! vertical gradient of grid%p prime is zilch. This is not all that important.
2343 ! These are filled in so that the various plotting routines have something
2344 ! to play with at the initial time for the model.
2346 IF ( flag_metgrid .NE. 1 ) THEN
2347 DO j = jts, min(jde-1,jte)
2348 DO i = its, min(ide,ite)
2349 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
2350 grid%u10(i,j)=grid%u_2(i,1,j)
2354 DO j = jts, min(jde,jte)
2355 DO i = its, min(ide-1,ite)
2356 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
2357 grid%v10(i,j)=grid%v_2(i,1,j)
2361 DO j = jts, min(jde-1,jte)
2362 DO i = its, min(ide-1,ite)
2363 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
2364 p_surf = p00 * EXP ( -t00/a + ( (t00/a)**2 - 2.*g*grid%ht(i,j)/a/r_d ) **0.5 )
2365 grid%psfc(i,j)=p_surf + grid%p(i,1,j)
2366 grid%q2(i,j)=moist(i,1,j,P_QV)
2367 grid%th2(i,j)=grid%t_2(i,1,j)+300.
2368 grid%t2(i,j)=grid%th2(i,j)*(((grid%p(i,1,j)+grid%pb(i,1,j))/p00)**(r_d/cp))
2372 ! If this data is from WPS, then we have previously assigned the surface
2373 ! data for u, v, and t. If we have an input qv, welp, we assigned that one,
2374 ! too. Now we pick up the left overs, and if RH came in - we assign the
2377 ELSE IF ( flag_metgrid .EQ. 1 ) THEN
2379 DO j = jts, min(jde-1,jte)
2380 DO i = its, min(ide-1,ite)
2381 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
2382 ! p_surf = p00 * EXP ( -t00/a + ( (t00/a)**2 - 2.*g*grid%ht(i,j)/a/r_d ) **0.5 )
2383 ! grid%psfc(i,j)=p_surf + grid%p(i,1,j)
2384 grid%th2(i,j)=grid%t2(i,j)*(p00/(grid%p(i,1,j)+grid%pb(i,1,j)))**(r_d/cp)
2387 IF ( flag_qv .NE. 1 ) THEN
2388 DO j = jts, min(jde-1,jte)
2389 DO i = its, min(ide-1,ite)
2390 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
2391 ! grid%q2(i,j)=moist(i,1,j,P_QV)
2392 grid%q2(i,j)=grid%qv_gc(i,1,j)
2398 CALL cpu_time(t_end)
2400 ! Set flag to denote that we are saving original values of HT, MUB, and
2401 ! PHB for 2-way nesting and cycling.
2403 grid%save_topo_from_real=1
2405 ips = its ; ipe = ite ; jps = jts ; jpe = jte ; kps = kts ; kpe = kte
2407 # include "HALO_EM_INIT_1.inc"
2408 # include "HALO_EM_INIT_2.inc"
2409 # include "HALO_EM_INIT_3.inc"
2410 # include "HALO_EM_INIT_4.inc"
2411 # include "HALO_EM_INIT_5.inc"
2416 END SUBROUTINE init_domain_rk
2418 !---------------------------------------------------------------------
2420 SUBROUTINE const_module_initialize ( p00 , t00 , a , tiso )
2421 USE module_configure
2423 ! For the real-data-cases only.
2424 REAL , INTENT(OUT) :: p00 , t00 , a , tiso
2425 CALL nl_get_base_pres ( 1 , p00 )
2426 CALL nl_get_base_temp ( 1 , t00 )
2427 CALL nl_get_base_lapse ( 1 , a )
2428 CALL nl_get_iso_temp ( 1 , tiso )
2429 END SUBROUTINE const_module_initialize
2431 !-------------------------------------------------------------------
2433 SUBROUTINE rebalance_driver ( grid )
2437 TYPE (domain) :: grid
2439 CALL rebalance( grid &
2441 #include "actual_new_args.inc"
2445 END SUBROUTINE rebalance_driver
2447 !---------------------------------------------------------------------
2449 SUBROUTINE rebalance ( grid &
2451 #include "dummy_new_args.inc"
2456 TYPE (domain) :: grid
2458 #include "dummy_new_decl.inc"
2460 TYPE (grid_config_rec_type) :: config_flags
2462 REAL :: p_surf , pd_surf, p_surf_int , pb_int , ht_hold
2463 REAL :: qvf , qvf1 , qvf2
2464 REAL :: p00 , t00 , a , tiso
2465 REAL , DIMENSION(:,:,:) , ALLOCATABLE :: t_init_int
2467 ! Local domain indices and counters.
2469 INTEGER :: num_veg_cat , num_soil_top_cat , num_soil_bot_cat
2472 ids, ide, jds, jde, kds, kde, &
2473 ims, ime, jms, jme, kms, kme, &
2474 its, ite, jts, jte, kts, kte, &
2475 ips, ipe, jps, jpe, kps, kpe, &
2478 REAL :: temp, temp_int
2479 REAL :: pfu, pfd, phm
2480 REAL :: w1, w2, z0, z1, z2
2482 SELECT CASE ( model_data_order )
2483 CASE ( DATA_ORDER_ZXY )
2484 kds = grid%sd31 ; kde = grid%ed31 ;
2485 ids = grid%sd32 ; ide = grid%ed32 ;
2486 jds = grid%sd33 ; jde = grid%ed33 ;
2488 kms = grid%sm31 ; kme = grid%em31 ;
2489 ims = grid%sm32 ; ime = grid%em32 ;
2490 jms = grid%sm33 ; jme = grid%em33 ;
2492 kts = grid%sp31 ; kte = grid%ep31 ; ! note that tile is entire patch
2493 its = grid%sp32 ; ite = grid%ep32 ; ! note that tile is entire patch
2494 jts = grid%sp33 ; jte = grid%ep33 ; ! note that tile is entire patch
2496 CASE ( DATA_ORDER_XYZ )
2497 ids = grid%sd31 ; ide = grid%ed31 ;
2498 jds = grid%sd32 ; jde = grid%ed32 ;
2499 kds = grid%sd33 ; kde = grid%ed33 ;
2501 ims = grid%sm31 ; ime = grid%em31 ;
2502 jms = grid%sm32 ; jme = grid%em32 ;
2503 kms = grid%sm33 ; kme = grid%em33 ;
2505 its = grid%sp31 ; ite = grid%ep31 ; ! note that tile is entire patch
2506 jts = grid%sp32 ; jte = grid%ep32 ; ! note that tile is entire patch
2507 kts = grid%sp33 ; kte = grid%ep33 ; ! note that tile is entire patch
2509 CASE ( DATA_ORDER_XZY )
2510 ids = grid%sd31 ; ide = grid%ed31 ;
2511 kds = grid%sd32 ; kde = grid%ed32 ;
2512 jds = grid%sd33 ; jde = grid%ed33 ;
2514 ims = grid%sm31 ; ime = grid%em31 ;
2515 kms = grid%sm32 ; kme = grid%em32 ;
2516 jms = grid%sm33 ; jme = grid%em33 ;
2518 its = grid%sp31 ; ite = grid%ep31 ; ! note that tile is entire patch
2519 kts = grid%sp32 ; kte = grid%ep32 ; ! note that tile is entire patch
2520 jts = grid%sp33 ; jte = grid%ep33 ; ! note that tile is entire patch
2524 ALLOCATE ( t_init_int(ims:ime,kms:kme,jms:jme) )
2526 ! Fill config_flags the options for a particular domain
2528 CALL model_to_grid_config_rec ( grid%id , model_config_rec , config_flags )
2530 ! Some of the many weird geopotential initializations that we'll see today: grid%ph0 is total,
2531 ! and grid%ph_2 is a perturbation from the base state geopotential. We set the base geopotential
2532 ! at the lowest level to terrain elevation * gravity.
2536 grid%ph0(i,1,j) = grid%ht_fine(i,j) * g
2537 grid%ph_2(i,1,j) = 0.
2541 ! To define the base state, we call a USER MODIFIED routine to set the three
2542 ! necessary constants: p00 (sea level pressure, Pa), t00 (sea level temperature, K),
2543 ! and A (temperature difference, from 1000 mb to 300 mb, K), and constant stratosphere
2544 ! temp (tiso, K) either from input file or from namelist (for backward compatibiliy).
2546 IF ( config_flags%use_baseparam_fr_nml ) then
2547 ! get these from namelist
2548 CALL wrf_message('ndown: using namelist constants')
2549 CALL const_module_initialize ( p00 , t00 , a , tiso )
2551 ! get these constants from model data
2552 CALL wrf_message('ndown: using constants from file')
2558 IF (t00 .LT. 100. .or. p00 .LT. 10000.) THEN
2559 WRITE(wrf_err_message,*)&
2560 'ndown_em: did not find base state parameters in wrfout. Add use_baseparam_fr_nml = .t. in &dynamics and rerun'
2561 CALL wrf_error_fatal(TRIM(wrf_err_message))
2565 ! Base state potential temperature and inverse density (alpha = 1/rho) from
2566 ! the half eta levels and the base-profile surface pressure. Compute 1/rho
2567 ! from equation of state. The potential temperature is a perturbation from t0.
2569 DO j = jts, MIN(jte,jde-1)
2570 DO i = its, MIN(ite,ide-1)
2572 ! Base state pressure is a function of eta level and terrain, only, plus
2573 ! the hand full of constants: p00 (sea level pressure, Pa), t00 (sea level
2574 ! temperature, K), and A (temperature difference, from 1000 mb to 300 mb, K).
2575 ! The fine grid terrain is ht_fine, the interpolated is grid%ht.
2577 p_surf = p00 * EXP ( -t00/a + ( (t00/a)**2 - 2.*g*grid%ht_fine(i,j)/a/r_d ) **0.5 )
2578 p_surf_int = p00 * EXP ( -t00/a + ( (t00/a)**2 - 2.*g*grid%ht(i,j) /a/r_d ) **0.5 )
2581 grid%pb(i,k,j) = grid%znu(k)*(p_surf - grid%p_top) + grid%p_top
2582 pb_int = grid%znu(k)*(p_surf_int - grid%p_top) + grid%p_top
2583 temp = MAX ( tiso, t00 + A*LOG(grid%pb(i,k,j)/p00) )
2584 ! temp = t00 + A*LOG(pb/p00)
2585 grid%t_init(i,k,j) = temp*(p00/grid%pb(i,k,j))**(r_d/cp) - t0
2586 ! grid%t_init(i,k,j) = (t00 + A*LOG(grid%pb(i,k,j)/p00))*(p00/grid%pb(i,k,j))**(r_d/cp) - t0
2587 temp_int = MAX ( tiso, t00 + A*LOG(pb_int /p00) )
2588 t_init_int(i,k,j)= temp_int*(p00/pb_int )**(r_d/cp) - t0
2589 ! t_init_int(i,k,j)= (t00 + A*LOG(pb_int /p00))*(p00/pb_int )**(r_d/cp) - t0
2590 grid%alb(i,k,j) = (r_d/p1000mb)*(grid%t_init(i,k,j)+t0)*(grid%pb(i,k,j)/p1000mb)**cvpm
2593 ! Base state mu is defined as base state surface pressure minus grid%p_top
2595 grid%mub(i,j) = p_surf - grid%p_top
2597 ! Dry surface pressure is defined as the following (this mu is from the input file
2598 ! computed from the dry pressure). Here the dry pressure is just reconstituted.
2600 pd_surf = ( grid%mub(i,j) + grid%mu_2(i,j) ) + grid%p_top
2602 ! Integrate base geopotential, starting at terrain elevation. This assures that
2603 ! the base state is in exact hydrostatic balance with respect to the model equations.
2604 ! This field is on full levels.
2606 grid%phb(i,1,j) = grid%ht_fine(i,j) * g
2607 IF (grid%hypsometric_opt == 1) THEN
2609 grid%phb(i,k,j) = grid%phb(i,k-1,j) - grid%dnw(k-1)*grid%mub(i,j)*grid%alb(i,k-1,j)
2611 ELSE IF (grid%hypsometric_opt == 2) THEN
2613 pfu = grid%mub(i,j)*grid%znw(k) + grid%p_top
2614 pfd = grid%mub(i,j)*grid%znw(k-1) + grid%p_top
2615 phm = grid%mub(i,j)*grid%znu(k-1) + grid%p_top
2616 grid%phb(i,k,j) = grid%phb(i,k-1,j) + grid%alb(i,k-1,j)*phm*LOG(pfd/pfu)
2619 CALL wrf_error_fatal( 'initialize_real: hypsometric_opt should be 1 or 2' )
2624 ! Replace interpolated terrain with fine grid values.
2626 DO j = jts, MIN(jte,jde-1)
2627 DO i = its, MIN(ite,ide-1)
2628 grid%ht(i,j) = grid%ht_fine(i,j)
2632 ! Perturbation fields.
2634 DO j = jts, min(jde-1,jte)
2635 DO i = its, min(ide-1,ite)
2637 ! The potential temperature is THETAnest = THETAinterp + ( TBARnest - TBARinterp)
2640 grid%t_2(i,k,j) = grid%t_2(i,k,j) + ( grid%t_init(i,k,j) - t_init_int(i,k,j) )
2643 ! Integrate the hydrostatic equation (from the RHS of the bigstep vertical momentum
2644 ! equation) down from the top to get the pressure perturbation. First get the pressure
2645 ! perturbation, moisture, and inverse density (total and perturbation) at the top-most level.
2649 qvf1 = 0.5*(moist(i,k,j,P_QV)+moist(i,k,j,P_QV))
2653 grid%p(i,k,j) = - 0.5*(grid%mu_2(i,j)+qvf1*grid%mub(i,j))/grid%rdnw(k)/qvf2
2654 qvf = 1. + rvovrd*moist(i,k,j,P_QV)
2655 grid%alt(i,k,j) = (r_d/p1000mb)*(grid%t_2(i,k,j)+t0)*qvf* &
2656 (((grid%p(i,k,j)+grid%pb(i,k,j))/p1000mb)**cvpm)
2657 grid%al(i,k,j) = grid%alt(i,k,j) - grid%alb(i,k,j)
2659 ! Now, integrate down the column to compute the pressure perturbation, and diagnose the two
2660 ! inverse density fields (total and perturbation).
2663 qvf1 = 0.5*(moist(i,k,j,P_QV)+moist(i,k+1,j,P_QV))
2666 grid%p(i,k,j) = grid%p(i,k+1,j) - (grid%mu_2(i,j) + qvf1*grid%mub(i,j))/qvf2/grid%rdn(k+1)
2667 qvf = 1. + rvovrd*moist(i,k,j,P_QV)
2668 grid%alt(i,k,j) = (r_d/p1000mb)*(grid%t_2(i,k,j)+t0)*qvf* &
2669 (((grid%p(i,k,j)+grid%pb(i,k,j))/p1000mb)**cvpm)
2670 grid%al(i,k,j) = grid%alt(i,k,j) - grid%alb(i,k,j)
2673 ! This is the hydrostatic equation used in the model after the small timesteps. In
2674 ! the model, grid%al (inverse density) is computed from the geopotential.
2676 IF (grid%hypsometric_opt == 1) THEN
2678 grid%ph_2(i,k,j) = grid%ph_2(i,k-1,j) - &
2679 grid%dnw(k-1) * ( (grid%mub(i,j)+grid%mu_2(i,j))*grid%al(i,k-1,j) &
2680 + grid%mu_2(i,j)*grid%alb(i,k-1,j) )
2681 grid%ph0(i,k,j) = grid%ph_2(i,k,j) + grid%phb(i,k,j)
2683 ELSE IF (grid%hypsometric_opt == 2) THEN
2685 ! Alternative hydrostatic eq.: dZ = -al*p*dLOG(p), where p is dry pressure.
2686 ! Note that al*p approximates Rd*T and dLOG(p) does z.
2687 ! Here T varies mostly linear with z, the first-order integration produces better result.
2689 grid%ph_2(i,1,j) = grid%phb(i,1,j)
2691 pfu = grid%mu0(i,j)*grid%znw(k) + grid%p_top
2692 pfd = grid%mu0(i,j)*grid%znw(k-1) + grid%p_top
2693 phm = grid%mu0(i,j)*grid%znu(k-1) + grid%p_top
2694 grid%ph_2(i,k,j) = grid%ph_2(i,k-1,j) + grid%alt(i,k-1,j)*phm*LOG(pfd/pfu)
2698 grid%ph_2(i,k,j) = grid%ph_2(i,k,j) - grid%phb(i,k,j)
2703 ! update psfc in fine grid
2705 z0 = grid%ph0(i,1,j)/g
2706 z1 = 0.5*(grid%ph0(i,1,j)+grid%ph0(i,2,j))/g
2707 z2 = 0.5*(grid%ph0(i,2,j)+grid%ph0(i,3,j))/g
2708 w1 = (z0 - z2)/(z1 - z2)
2710 grid%psfc(i,j) = w1*(grid%p(i,1,j)+grid%pb(i,1,j))+w2*(grid%p(i,2,j)+grid%pb(i,2,j))
2715 DEALLOCATE ( t_init_int )
2717 ips = its ; ipe = ite ; jps = jts ; jpe = jte ; kps = kts ; kpe = kte
2719 # include "HALO_EM_INIT_1.inc"
2720 # include "HALO_EM_INIT_2.inc"
2721 # include "HALO_EM_INIT_3.inc"
2722 # include "HALO_EM_INIT_4.inc"
2723 # include "HALO_EM_INIT_5.inc"
2725 END SUBROUTINE rebalance
2727 !---------------------------------------------------------------------
2729 RECURSIVE SUBROUTINE find_my_parent ( grid_ptr_in , grid_ptr_out , id_i_am , id_wanted , found_the_id )
2731 ! RAR - Modified to correct problem in which the parent of a child domain could
2732 ! not be found in the namelist. This condition typically occurs while using the
2733 ! "allow_grid" namelist option when an inactive domain comes before an active
2734 ! domain in the list, i.e., the domain number of the active domain is greater than
2735 ! that of an inactive domain at the same level.
2739 TYPE(domain) , POINTER :: grid_ptr_in , grid_ptr_out
2740 TYPE(domain) , POINTER :: grid_ptr_sibling
2741 INTEGER :: id_wanted , id_i_am
2742 INTEGER :: nest ! RAR
2743 LOGICAL :: found_the_id
2745 found_the_id = .FALSE.
2746 grid_ptr_sibling => grid_ptr_in
2749 DO WHILE ( ASSOCIATED ( grid_ptr_sibling ) )
2751 IF ( grid_ptr_sibling%grid_id .EQ. id_wanted ) THEN
2752 found_the_id = .TRUE.
2753 grid_ptr_out => grid_ptr_sibling
2755 ! RAR ELSE IF ( grid_ptr_sibling%num_nests .GT. 0 ) THEN
2756 ELSE IF ( grid_ptr_sibling%num_nests .GT. 0 .AND. nest .LT. grid_ptr_sibling%num_nests ) THEN
2757 nest = nest + 1 ! RAR
2758 grid_ptr_sibling => grid_ptr_sibling%nests(nest)%ptr ! RAR
2759 CALL find_my_parent ( grid_ptr_sibling , grid_ptr_out , id_i_am , id_wanted , found_the_id )
2760 IF (.NOT. found_the_id) grid_ptr_sibling => grid_ptr_sibling%parents(1)%ptr ! RAR
2762 grid_ptr_sibling => grid_ptr_sibling%sibling
2767 END SUBROUTINE find_my_parent
2769 !---------------------------------------------------------------------
2771 RECURSIVE SUBROUTINE find_my_parent2 ( grid_ptr_in , grid_ptr_out , id_wanted , found_the_id )
2775 TYPE(domain) , POINTER :: grid_ptr_in
2776 TYPE(domain) , POINTER :: grid_ptr_out
2777 INTEGER , INTENT(IN ) :: id_wanted
2778 LOGICAL , INTENT(OUT) :: found_the_id
2782 TYPE(domain) , POINTER :: grid_ptr_holder
2787 found_the_id = .FALSE.
2788 grid_ptr_holder => grid_ptr_in
2791 ! Have we found the correct location? If so, we can just pop back up with
2792 ! the pointer to the right location (i.e. the parent), thank you very much.
2794 IF ( id_wanted .EQ. grid_ptr_in%grid_id ) THEN
2796 found_the_id = .TRUE.
2797 grid_ptr_out => grid_ptr_in
2800 ! We gotta keep looking.
2804 ! We drill down and process each nest from this domain. We don't have to
2805 ! worry about siblings, as we are running over all of the kids for this parent,
2806 ! so it amounts to the same set of domains being tested.
2808 loop_over_all_kids : DO kid = 1 , grid_ptr_in%num_nests
2810 IF ( ASSOCIATED ( grid_ptr_in%nests(kid)%ptr ) ) THEN
2812 CALL find_my_parent2 ( grid_ptr_in%nests(kid)%ptr , grid_ptr_out , id_wanted , found_the_id )
2813 IF ( found_the_id ) THEN
2814 EXIT loop_over_all_kids
2818 END DO loop_over_all_kids
2822 END SUBROUTINE find_my_parent2
2826 !---------------------------------------------------------------------
2830 !This is a main program for a small unit test for the vertical interpolation.
2836 integer , parameter :: ij = 3
2837 integer , parameter :: keta = 30
2838 integer , parameter :: kgen =20
2840 integer :: ids , ide , jds , jde , kds , kde , &
2841 ims , ime , jms , jme , kms , kme , &
2842 its , ite , jts , jte , kts , kte
2846 real , dimension(1:ij,kgen,1:ij) :: fo , po
2847 real , dimension(1:ij,1:keta,1:ij) :: fn_calc , fn_interp , pn
2849 integer, parameter :: interp_type = 1 ! 2
2850 ! integer, parameter :: lagrange_order = 2 ! 1
2851 integer :: lagrange_order
2852 logical, parameter :: lowest_lev_from_sfc = .FALSE. ! .TRUE.
2853 logical, parameter :: use_levels_below_ground = .FALSE. ! .TRUE.
2854 logical, parameter :: use_surface = .FALSE. ! .TRUE.
2855 real , parameter :: zap_close_levels = 500. ! 100.
2856 integer, parameter :: force_sfc_in_vinterp = 0 ! 6
2860 ids = 1 ; ide = ij ; jds = 1 ; jde = ij ; kds = 1 ; kde = keta
2861 ims = 1 ; ime = ij ; jms = 1 ; jme = ij ; kms = 1 ; kme = keta
2862 its = 1 ; ite = ij ; jts = 1 ; jte = ij ; kts = 1 ; kte = keta
2867 print *,'------------------------------------'
2868 print *,'UNIT TEST FOR VERTICAL INTERPOLATION'
2869 print *,'------------------------------------'
2871 do lagrange_order = 1 , 2
2873 print *,'------------------------------------'
2874 print *,'Lagrange Order = ',lagrange_order
2875 print *,'------------------------------------'
2877 call fillitup ( fo , po , fn_calc , pn , &
2878 ids , ide , jds , jde , kds , kde , &
2879 ims , ime , jms , jme , kms , kme , &
2880 its , ite , jts , jte , kts , kte , &
2881 generic , lagrange_order )
2884 print *,'Level Pressure Field'
2885 print *,' (Pa) (generic)'
2886 print *,'------------------------------------'
2889 write (*,fmt='(i2,2x,f12.3,1x,g15.8)' ) &
2890 k,po(2,k,2),fo(2,k,2)
2894 call vert_interp ( fo , po , fn_interp , pn , &
2896 interp_type , lagrange_order , &
2897 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
2898 zap_close_levels , force_sfc_in_vinterp , &
2899 ids , ide , jds , jde , kds , kde , &
2900 ims , ime , jms , jme , kms , kme , &
2901 its , ite , jts , jte , kts , kte )
2903 print *,'Multi-Order Interpolator'
2904 print *,'------------------------------------'
2906 print *,'Level Pressure Field Field Field'
2907 print *,' (Pa) Calc Interp Diff'
2908 print *,'------------------------------------'
2911 write (*,fmt='(i2,2x,f12.3,1x,3(g15.7))' ) &
2912 k,pn(2,k,2),fn_calc(2,k,2),fn_interp(2,k,2),fn_calc(2,k,2)-fn_interp(2,k,2)
2915 call vert_interp_old ( fo , po , fn_interp , pn , &
2917 interp_type , lagrange_order , &
2918 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
2919 zap_close_levels , force_sfc_in_vinterp , &
2920 ids , ide , jds , jde , kds , kde , &
2921 ims , ime , jms , jme , kms , kme , &
2922 its , ite , jts , jte , kts , kte )
2924 print *,'Linear Interpolator'
2925 print *,'------------------------------------'
2927 print *,'Level Pressure Field Field Field'
2928 print *,' (Pa) Calc Interp Diff'
2929 print *,'------------------------------------'
2932 write (*,fmt='(i2,2x,f12.3,1x,3(g15.7))' ) &
2933 k,pn(2,k,2),fn_calc(2,k,2),fn_interp(2,k,2),fn_calc(2,k,2)-fn_interp(2,k,2)
2939 subroutine wrf_error_fatal (string)
2940 character (len=*) :: string
2943 end subroutine wrf_error_fatal
2945 subroutine fillitup ( fo , po , fn , pn , &
2946 ids , ide , jds , jde , kds , kde , &
2947 ims , ime , jms , jme , kms , kme , &
2948 its , ite , jts , jte , kts , kte , &
2949 generic , lagrange_order )
2953 integer , intent(in) :: ids , ide , jds , jde , kds , kde , &
2954 ims , ime , jms , jme , kms , kme , &
2955 its , ite , jts , jte , kts , kte
2957 integer , intent(in) :: generic , lagrange_order
2959 real , dimension(ims:ime,generic,jms:jme) , intent(out) :: fo , po
2960 real , dimension(ims:ime,kms:kme,jms:jme) , intent(out) :: fn , pn
2962 integer :: i , j , k
2964 real , parameter :: piov2 = 3.14159265358 / 2.
2976 po(i,k,j) = ( 5000. * ( 1 - (k-1) ) + 100000. * ( (k-1) - (generic-1) ) ) / (1. - real(generic-1) )
2981 if ( lagrange_order .eq. 1 ) then
2985 fo(i,k,j) = po(i,k,j)
2986 ! fo(i,k,j) = sin(po(i,k,j) * piov2 / 102000. )
2990 else if ( lagrange_order .eq. 2 ) then
2994 fo(i,k,j) = (((po(i,k,j)-5000.)/102000.)*((102000.-po(i,k,j))/102000.))*102000.
2995 ! fo(i,k,j) = sin(po(i,k,j) * piov2 / 102000. )
3006 pn(i,k,j) = ( 5000. * ( 0 - (k-1) ) + 102000. * ( (k-1) - (kte-1) ) ) / (-1. * real(kte-1) )
3014 pn(i,k,j) = ( pn(i,k,j) + pn(i,k+1,j) ) /2.
3020 if ( lagrange_order .eq. 1 ) then
3024 fn(i,k,j) = pn(i,k,j)
3025 ! fn(i,k,j) = sin(pn(i,k,j) * piov2 / 102000. )
3029 else if ( lagrange_order .eq. 2 ) then
3033 fn(i,k,j) = (((pn(i,k,j)-5000.)/102000.)*((102000.-pn(i,k,j))/102000.))*102000.
3034 ! fn(i,k,j) = sin(pn(i,k,j) * piov2 / 102000. )
3040 end subroutine fillitup
3044 !---------------------------------------------------------------------
3046 SUBROUTINE vert_interp ( fo , po , fnew , pnu , &
3047 generic , var_type , &
3048 interp_type , lagrange_order , extrap_type , &
3049 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
3050 zap_close_levels , force_sfc_in_vinterp , &
3051 ids , ide , jds , jde , kds , kde , &
3052 ims , ime , jms , jme , kms , kme , &
3053 its , ite , jts , jte , kts , kte )
3055 ! Vertically interpolate the new field. The original field on the original
3056 ! pressure levels is provided, and the new pressure surfaces to interpolate to.
3060 INTEGER , INTENT(IN) :: interp_type , lagrange_order , extrap_type
3061 LOGICAL , INTENT(IN) :: lowest_lev_from_sfc , use_levels_below_ground , use_surface
3062 REAL , INTENT(IN) :: zap_close_levels
3063 INTEGER , INTENT(IN) :: force_sfc_in_vinterp
3064 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
3065 ims , ime , jms , jme , kms , kme , &
3066 its , ite , jts , jte , kts , kte
3067 INTEGER , INTENT(IN) :: generic
3069 CHARACTER (LEN=1) :: var_type
3071 REAL , DIMENSION(ims:ime,generic,jms:jme) , INTENT(IN) :: fo , po
3072 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: pnu
3073 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(OUT) :: fnew
3075 REAL , DIMENSION(ims:ime,generic,jms:jme) :: forig , porig
3076 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) :: pnew
3080 INTEGER :: i , j , k , ko , kn , k1 , k2 , ko_1 , ko_2 , knext
3081 INTEGER :: istart , iend , jstart , jend , kstart , kend
3082 INTEGER , DIMENSION(ims:ime,kms:kme ) :: k_above , k_below
3083 INTEGER , DIMENSION(ims:ime ) :: ks
3084 INTEGER , DIMENSION(ims:ime ) :: ko_above_sfc
3085 INTEGER :: count , zap , zap_below , zap_above , kst , kcount
3086 INTEGER :: kinterp_start , kinterp_end , sfc_level
3088 LOGICAL :: any_below_ground
3090 REAL :: p1 , p2 , pn, hold
3091 REAL , DIMENSION(1:generic) :: ordered_porig , ordered_forig
3092 REAL , DIMENSION(kts:kte) :: ordered_pnew , ordered_fnew
3096 LOGICAL :: any_valid_points
3097 INTEGER :: i_valid , j_valid
3098 LOGICAL :: flip_data_required
3100 ! Horiontal loop bounds for different variable types.
3102 IF ( var_type .EQ. 'U' ) THEN
3106 jend = MIN(jde-1,jte)
3111 DO i = MAX(ids+1,its) , MIN(ide-1,ite)
3112 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
3113 porig(i,k,j) = ( po(i,k,j) + po(i-1,k,j) ) * 0.5
3116 IF ( ids .EQ. its ) THEN
3118 porig(its,k,j) = po(its,k,j)
3121 IF ( ide .EQ. ite ) THEN
3123 porig(ite,k,j) = po(ite-1,k,j)
3128 DO i = MAX(ids+1,its) , MIN(ide-1,ite)
3129 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
3130 pnew(i,k,j) = ( pnu(i,k,j) + pnu(i-1,k,j) ) * 0.5
3133 IF ( ids .EQ. its ) THEN
3135 pnew(its,k,j) = pnu(its,k,j)
3138 IF ( ide .EQ. ite ) THEN
3140 pnew(ite,k,j) = pnu(ite-1,k,j)
3144 ELSE IF ( var_type .EQ. 'V' ) THEN
3146 iend = MIN(ide-1,ite)
3153 DO j = MAX(jds+1,jts) , MIN(jde-1,jte)
3154 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
3155 porig(i,k,j) = ( po(i,k,j) + po(i,k,j-1) ) * 0.5
3158 IF ( jds .EQ. jts ) THEN
3160 porig(i,k,jts) = po(i,k,jts)
3163 IF ( jde .EQ. jte ) THEN
3165 porig(i,k,jte) = po(i,k,jte-1)
3170 DO j = MAX(jds+1,jts) , MIN(jde-1,jte)
3171 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
3172 pnew(i,k,j) = ( pnu(i,k,j) + pnu(i,k,j-1) ) * 0.5
3175 IF ( jds .EQ. jts ) THEN
3177 pnew(i,k,jts) = pnu(i,k,jts)
3180 IF ( jde .EQ. jte ) THEN
3182 pnew(i,k,jte) = pnu(i,k,jte-1)
3186 ELSE IF ( ( var_type .EQ. 'W' ) .OR. ( var_type .EQ. 'Z' ) ) THEN
3188 iend = MIN(ide-1,ite)
3190 jend = MIN(jde-1,jte)
3196 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
3197 porig(i,k,j) = po(i,k,j)
3203 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
3204 pnew(i,k,j) = pnu(i,k,j)
3208 ELSE IF ( ( var_type .EQ. 'T' ) .OR. ( var_type .EQ. 'Q' ) ) THEN
3210 iend = MIN(ide-1,ite)
3212 jend = MIN(jde-1,jte)
3218 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
3219 porig(i,k,j) = po(i,k,j)
3225 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
3226 pnew(i,k,j) = pnu(i,k,j)
3232 iend = MIN(ide-1,ite)
3234 jend = MIN(jde-1,jte)
3240 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
3241 porig(i,k,j) = po(i,k,j)
3247 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
3248 pnew(i,k,j) = pnu(i,k,j)
3254 ! We need to find if there are any valid non-excluded-middle points in this
3255 ! tile. If so, then we need to hang on to a valid i,j location.
3257 any_valid_points = .false.
3258 find_valid : DO j = jstart , jend
3259 DO i = istart , iend
3260 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
3261 any_valid_points = .true.
3267 IF ( .NOT. any_valid_points ) THEN
3271 IF ( porig(i_valid,2,j_valid) .LT. porig(i_valid,generic,j_valid) ) THEN
3272 flip_data_required = .true.
3274 flip_data_required = .false.
3277 DO j = jstart , jend
3279 ! The lowest level is the surface. Levels 2 through "generic" are supposed to
3280 ! be "bottom-up". Flip if they are not. This is based on the input pressure
3283 IF ( flip_data_required ) THEN
3284 DO kn = 2 , ( generic + 1 ) / 2
3285 DO i = istart , iend
3286 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
3287 hold = porig(i,kn,j)
3288 porig(i,kn,j) = porig(i,generic+2-kn,j)
3289 porig(i,generic+2-kn,j) = hold
3290 forig(i,kn,j) = fo (i,generic+2-kn,j)
3291 forig(i,generic+2-kn,j) = fo (i,kn,j)
3294 DO i = istart , iend
3295 forig(i,1,j) = fo (i,1,j)
3297 IF ( MOD(generic,2) .EQ. 0 ) THEN
3299 DO i = istart , iend
3300 forig(i,k,j) = fo (i,k,j)
3305 DO i = istart , iend
3306 forig(i,kn,j) = fo (i,kn,j)
3311 ! Skip all of the levels below ground in the original data based upon the surface pressure.
3312 ! The ko_above_sfc is the index in the pressure array that is above the surface. If there
3313 ! are no levels underground, this is index = 2. The remaining levels are eligible for use
3314 ! in the vertical interpolation.
3316 DO i = istart , iend
3317 ko_above_sfc(i) = -1
3319 DO ko = kstart+1 , generic
3320 DO i = istart , iend
3321 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
3322 IF ( ko_above_sfc(i) .EQ. -1 ) THEN
3323 IF ( porig(i,1,j) .GT. porig(i,ko,j) ) THEN
3324 ko_above_sfc(i) = ko
3330 ! Piece together columns of the original input data. Pass the vertical columns to
3333 DO i = istart , iend
3334 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
3336 ! If the surface value is in the middle of the array, three steps: 1) do the
3337 ! values below the ground (this is just to catch the occasional value that is
3338 ! inconsistently below the surface based on input data), 2) do the surface level, then
3339 ! 3) add in the levels that are above the surface. For the levels next to the surface,
3340 ! we check to remove any levels that are "too close". When building the column of input
3341 ! pressures, we also attend to the request for forcing the surface analysis to be used
3342 ! in a few lower eta-levels.
3344 ! Fill in the column from up to the level just below the surface with the input
3345 ! presssure and the input field (orig or old, which ever). For an isobaric input
3346 ! file, this data is isobaric.
3348 ! How many levels have we skipped in the input column.
3354 IF ( ko_above_sfc(i) .GT. 2 ) THEN
3356 DO ko = 2 , ko_above_sfc(i)-1
3357 ordered_porig(count) = porig(i,ko,j)
3358 ordered_forig(count) = forig(i,ko,j)
3362 ! Make sure the pressure just below the surface is not "too close", this
3363 ! will cause havoc with the higher order interpolators. In case of a "too close"
3364 ! instance, we toss out the offending level (NOT the surface one) by simply
3365 ! decrementing the accumulating loop counter.
3367 IF ( ordered_porig(count-1) - porig(i,1,j) .LT. zap_close_levels ) THEN
3373 ! Add in the surface values.
3375 ordered_porig(count) = porig(i,1,j)
3376 ordered_forig(count) = forig(i,1,j)
3379 ! A usual way to do the vertical interpolation is to pay more attention to the
3380 ! surface data. Why? Well it has about 20x the density as the upper air, so we
3381 ! hope the analysis is better there. We more strongly use this data by artificially
3382 ! tossing out levels above the surface that are beneath a certain number of prescribed
3383 ! eta levels at this (i,j). The "zap" value is how many levels of input we are
3384 ! removing, which is used to tell the interpolator how many valid values are in
3385 ! the column. The "count" value is the increment to the index of levels, and is
3386 ! only used for assignments.
3388 IF ( force_sfc_in_vinterp .GT. 0 ) THEN
3390 ! Get the pressure at the eta level. We want to remove all input pressure levels
3391 ! between the level above the surface to the pressure at this eta surface. That
3392 ! forces the surface value to be used through the selected eta level. Keep track
3393 ! of two things: the level to use above the eta levels, and how many levels we are
3396 knext = ko_above_sfc(i)
3397 find_level : DO ko = ko_above_sfc(i) , generic
3398 IF ( porig(i,ko,j) .LE. pnew(i,force_sfc_in_vinterp,j) ) THEN
3403 zap_above = zap_above + 1
3407 ! No request for special interpolation, so we just assign the next level to use
3408 ! above the surface as, ta da, the first level above the surface. I know, wow.
3411 knext = ko_above_sfc(i)
3414 ! One more time, make sure the pressure just above the surface is not "too close", this
3415 ! will cause havoc with the higher order interpolators. In case of a "too close"
3416 ! instance, we toss out the offending level above the surface (NOT the surface one) by simply
3417 ! incrementing the loop counter. Here, count-1 is the surface level and knext is either
3418 ! the next level up OR it is the level above the prescribed number of eta surfaces.
3420 IF ( ordered_porig(count-1) - porig(i,knext,j) .LT. zap_close_levels ) THEN
3423 zap_above = zap_above + 1
3428 DO ko = kst , generic
3429 ordered_porig(count) = porig(i,ko,j)
3430 ordered_forig(count) = forig(i,ko,j)
3434 ! This is easy, the surface is the lowest level, just stick them in, in this order. OK,
3435 ! there are a couple of subtleties. We have to check for that special interpolation that
3436 ! skips some input levels so that the surface is used for the lowest few eta levels. Also,
3437 ! we must make sure that we still do not have levels that are "too close" together.
3441 ! Initialize no input levels have yet been removed from consideration.
3445 ! The surface is the lowest level, so it gets set right away to location 1.
3447 ordered_porig(1) = porig(i,1,j)
3448 ordered_forig(1) = forig(i,1,j)
3450 ! We start filling in the array at loc 2, as in just above the level we just stored.
3454 ! Are we forcing the interpolator to skip valid input levels so that the
3455 ! surface data is used through more levels? Essentially as above.
3457 IF ( force_sfc_in_vinterp .GT. 0 ) THEN
3459 find_level2: DO ko = 2 , generic
3460 IF ( porig(i,ko,j) .LE. pnew(i,force_sfc_in_vinterp,j) ) THEN
3465 zap_above = zap_above + 1
3472 ! Fill in the data above the surface. The "knext" index is either the one
3473 ! just above the surface OR it is the index associated with the level that
3474 ! is just above the pressure at this (i,j) of the top eta level that is to
3475 ! be directly impacted with the surface level in interpolation.
3477 DO ko = knext , generic
3478 IF ( ( ordered_porig(count-1) - porig(i,ko,j) .LT. zap_close_levels ) .AND. &
3479 ( ko .LT. generic ) ) THEN
3481 zap_above = zap_above + 1
3484 ordered_porig(count) = porig(i,ko,j)
3485 ordered_forig(count) = forig(i,ko,j)
3491 ! Now get the column of the "new" pressure data. So, this one is easy.
3493 DO kn = kstart , kend
3494 ordered_pnew(kn) = pnew(i,kn,j)
3497 ! How many levels (count) are we shipping to the Lagrange interpolator.
3499 IF ( ( use_levels_below_ground ) .AND. ( use_surface ) ) THEN
3501 ! Use all levels, including the input surface, and including the pressure
3502 ! levels below ground. We know to stop when we have reached the top of
3503 ! the input pressure data.
3506 find_how_many_1 : DO ko = 1 , generic
3507 IF ( porig(i,generic,j) .EQ. ordered_porig(ko) ) THEN
3509 EXIT find_how_many_1
3513 END DO find_how_many_1
3515 kinterp_end = kinterp_start + count - 1
3517 ELSE IF ( ( use_levels_below_ground ) .AND. ( .NOT. use_surface ) ) THEN
3519 ! Use all levels (excluding the input surface) and including the pressure
3520 ! levels below ground. We know to stop when we have reached the top of
3521 ! the input pressure data.
3524 find_sfc_2 : DO ko = 1 , generic
3525 IF ( porig(i,1,j) .EQ. ordered_porig(ko) ) THEN
3531 DO ko = sfc_level , generic-1
3532 ordered_porig(ko) = ordered_porig(ko+1)
3533 ordered_forig(ko) = ordered_forig(ko+1)
3535 ordered_porig(generic) = 1.E-5
3536 ordered_forig(generic) = 1.E10
3539 find_how_many_2 : DO ko = 1 , generic
3540 IF ( porig(i,generic,j) .EQ. ordered_porig(ko) ) THEN
3542 EXIT find_how_many_2
3546 END DO find_how_many_2
3548 kinterp_end = kinterp_start + count - 1
3550 ELSE IF ( ( .NOT. use_levels_below_ground ) .AND. ( use_surface ) ) THEN
3552 ! Use all levels above the input surface pressure.
3554 kcount = ko_above_sfc(i)-1-zap_below
3557 IF ( porig(i,ko,j) .EQ. ordered_porig(kcount) ) THEN
3558 ! write (6,fmt='(f11.3,f11.3,g11.5)') porig(i,ko,j),ordered_porig(kcount),ordered_forig(kcount)
3562 ! write (6,fmt='(f11.3 )') porig(i,ko,j)
3565 kinterp_start = ko_above_sfc(i)-1-zap_below
3566 kinterp_end = kinterp_start + count - 1
3570 ! The polynomials are either in pressure or LOG(pressure).
3572 IF ( interp_type .EQ. 1 ) THEN
3573 CALL lagrange_setup ( var_type , interp_type , &
3574 ordered_porig(kinterp_start:kinterp_end) , &
3575 ordered_forig(kinterp_start:kinterp_end) , &
3576 count , lagrange_order , extrap_type , &
3577 ordered_pnew(kstart:kend) , ordered_fnew , kend-kstart+1 ,i,j)
3579 CALL lagrange_setup ( var_type , interp_type , &
3580 LOG(ordered_porig(kinterp_start:kinterp_end)) , &
3581 ordered_forig(kinterp_start:kinterp_end) , &
3582 count , lagrange_order , extrap_type , &
3583 LOG(ordered_pnew(kstart:kend)) , ordered_fnew , kend-kstart+1 ,i,j)
3586 ! Save the computed data.
3588 DO kn = kstart , kend
3589 fnew(i,kn,j) = ordered_fnew(kn)
3592 ! There may have been a request to have the surface data from the input field
3593 ! to be assigned as to the lowest eta level. This assumes thin layers (usually
3594 ! the isobaric original field has the surface from 2-m T and RH, and 10-m U and V).
3596 IF ( lowest_lev_from_sfc ) THEN
3597 fnew(i,1,j) = forig(i,ko_above_sfc(i)-1,j)
3604 END SUBROUTINE vert_interp
3606 !---------------------------------------------------------------------
3608 SUBROUTINE vert_interp_old ( forig , po , fnew , pnu , &
3609 generic , var_type , &
3610 interp_type , lagrange_order , extrap_type , &
3611 lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
3612 zap_close_levels , force_sfc_in_vinterp , &
3613 ids , ide , jds , jde , kds , kde , &
3614 ims , ime , jms , jme , kms , kme , &
3615 its , ite , jts , jte , kts , kte )
3617 ! Vertically interpolate the new field. The original field on the original
3618 ! pressure levels is provided, and the new pressure surfaces to interpolate to.
3622 INTEGER , INTENT(IN) :: interp_type , lagrange_order , extrap_type
3623 LOGICAL , INTENT(IN) :: lowest_lev_from_sfc , use_levels_below_ground , use_surface
3624 REAL , INTENT(IN) :: zap_close_levels
3625 INTEGER , INTENT(IN) :: force_sfc_in_vinterp
3626 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
3627 ims , ime , jms , jme , kms , kme , &
3628 its , ite , jts , jte , kts , kte
3629 INTEGER , INTENT(IN) :: generic
3631 CHARACTER (LEN=1) :: var_type
3633 REAL , DIMENSION(ims:ime,generic,jms:jme) , INTENT(IN) :: forig , po
3634 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: pnu
3635 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(OUT) :: fnew
3637 REAL , DIMENSION(ims:ime,generic,jms:jme) :: porig
3638 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) :: pnew
3642 INTEGER :: i , j , k , ko , kn , k1 , k2 , ko_1 , ko_2
3643 INTEGER :: istart , iend , jstart , jend , kstart , kend
3644 INTEGER , DIMENSION(ims:ime,kms:kme ) :: k_above , k_below
3645 INTEGER , DIMENSION(ims:ime ) :: ks
3646 INTEGER , DIMENSION(ims:ime ) :: ko_above_sfc
3648 LOGICAL :: any_below_ground
3650 REAL :: p1 , p2 , pn
3654 ! Horiontal loop bounds for different variable types.
3656 IF ( var_type .EQ. 'U' ) THEN
3660 jend = MIN(jde-1,jte)
3665 DO i = MAX(ids+1,its) , MIN(ide-1,ite)
3666 porig(i,k,j) = ( po(i,k,j) + po(i-1,k,j) ) * 0.5
3669 IF ( ids .EQ. its ) THEN
3671 porig(its,k,j) = po(its,k,j)
3674 IF ( ide .EQ. ite ) THEN
3676 porig(ite,k,j) = po(ite-1,k,j)
3681 DO i = MAX(ids+1,its) , MIN(ide-1,ite)
3682 pnew(i,k,j) = ( pnu(i,k,j) + pnu(i-1,k,j) ) * 0.5
3685 IF ( ids .EQ. its ) THEN
3687 pnew(its,k,j) = pnu(its,k,j)
3690 IF ( ide .EQ. ite ) THEN
3692 pnew(ite,k,j) = pnu(ite-1,k,j)
3696 ELSE IF ( var_type .EQ. 'V' ) THEN
3698 iend = MIN(ide-1,ite)
3705 DO j = MAX(jds+1,jts) , MIN(jde-1,jte)
3706 porig(i,k,j) = ( po(i,k,j) + po(i,k,j-1) ) * 0.5
3709 IF ( jds .EQ. jts ) THEN
3711 porig(i,k,jts) = po(i,k,jts)
3714 IF ( jde .EQ. jte ) THEN
3716 porig(i,k,jte) = po(i,k,jte-1)
3721 DO j = MAX(jds+1,jts) , MIN(jde-1,jte)
3722 pnew(i,k,j) = ( pnu(i,k,j) + pnu(i,k,j-1) ) * 0.5
3725 IF ( jds .EQ. jts ) THEN
3727 pnew(i,k,jts) = pnu(i,k,jts)
3730 IF ( jde .EQ. jte ) THEN
3732 pnew(i,k,jte) = pnu(i,k,jte-1)
3736 ELSE IF ( ( var_type .EQ. 'W' ) .OR. ( var_type .EQ. 'Z' ) ) THEN
3738 iend = MIN(ide-1,ite)
3740 jend = MIN(jde-1,jte)
3746 porig(i,k,j) = po(i,k,j)
3752 pnew(i,k,j) = pnu(i,k,j)
3756 ELSE IF ( ( var_type .EQ. 'T' ) .OR. ( var_type .EQ. 'Q' ) ) THEN
3758 iend = MIN(ide-1,ite)
3760 jend = MIN(jde-1,jte)
3766 porig(i,k,j) = po(i,k,j)
3772 pnew(i,k,j) = pnu(i,k,j)
3778 iend = MIN(ide-1,ite)
3780 jend = MIN(jde-1,jte)
3786 porig(i,k,j) = po(i,k,j)
3792 pnew(i,k,j) = pnu(i,k,j)
3798 DO j = jstart , jend
3800 ! Skip all of the levels below ground in the original data based upon the surface pressure.
3801 ! The ko_above_sfc is the index in the pressure array that is above the surface. If there
3802 ! are no levels underground, this is index = 2. The remaining levels are eligible for use
3803 ! in the vertical interpolation.
3805 DO i = istart , iend
3806 ko_above_sfc(i) = -1
3808 DO ko = kstart+1 , kend
3809 DO i = istart , iend
3810 IF ( ko_above_sfc(i) .EQ. -1 ) THEN
3811 IF ( porig(i,1,j) .GT. porig(i,ko,j) ) THEN
3812 ko_above_sfc(i) = ko
3818 ! Initialize interpolation location. These are the levels in the original pressure
3819 ! data that are physically below and above the targeted new pressure level.
3828 ! Starting location is no lower than previous found location. This is for O(n logn)
3829 ! and not O(n^2), where n is the number of vertical levels to search.
3835 ! Find trapping layer for interpolation. The kn index runs through all of the "new"
3838 DO kn = kstart , kend
3840 DO i = istart , iend
3842 ! For each "new" level (kn), we search to find the trapping levels in the "orig"
3843 ! data. Most of the time, the "new" levels are the eta surfaces, and the "orig"
3844 ! levels are the input pressure levels.
3846 found_trap_above : DO ko = ks(i) , generic-1
3848 ! Because we can have levels in the interpolation that are not valid,
3849 ! let's toss out any candidate orig pressure values that are below ground
3850 ! based on the surface pressure. If the level =1, then this IS the surface
3851 ! level, so we HAVE to keep that one, but maybe not the ones above. If the
3852 ! level (ks) is NOT=1, then we have to just CYCLE our loop to find a legit
3853 ! below-pressure value. If we are not below ground, then we choose two
3854 ! neighboring levels to test whether they surround the new pressure level.
3856 ! The input trapping levels that we are trying is the surface and the first valid
3857 ! level above the surface.
3859 IF ( ( ko .LT. ko_above_sfc(i) ) .AND. ( ko .EQ. 1 ) ) THEN
3861 ko_2 = ko_above_sfc(i)
3863 ! The "below" level is underground, cycle until we get to a valid pressure
3866 ELSE IF ( ( ko .LT. ko_above_sfc(i) ) .AND. ( ko .NE. 1 ) ) THEN
3867 CYCLE found_trap_above
3869 ! The "below" level is above the surface, so we are in the clear to test these
3878 ! The test of the candidate levels: "below" has to have a larger pressure, and
3879 ! "above" has to have a smaller pressure.
3881 ! OK, we found the correct two surrounding levels. The locations are saved for use in the
3884 IF ( ( porig(i,ko_1,j) .GE. pnew(i,kn,j) ) .AND. &
3885 ( porig(i,ko_2,j) .LT. pnew(i,kn,j) ) ) THEN
3886 k_above(i,kn) = ko_2
3887 k_below(i,kn) = ko_1
3889 EXIT found_trap_above
3891 ! What do we do is we need to extrapolate the data underground? This happens when the
3892 ! lowest pressure that we have is physically "above" the new target pressure. Our
3893 ! actions depend on the type of variable we are interpolating.
3895 ELSE IF ( porig(i,1,j) .LT. pnew(i,kn,j) ) THEN
3897 ! For horizontal winds and moisture, we keep a constant value under ground.
3899 IF ( ( var_type .EQ. 'U' ) .OR. &
3900 ( var_type .EQ. 'V' ) .OR. &
3901 ( var_type .EQ. 'Q' ) ) THEN
3905 ! For temperature and height, we extrapolate the data. Hopefully, we are not
3906 ! extrapolating too far. For pressure level input, the eta levels are always
3907 ! contained within the surface to p_top levels, so no extrapolation is ever
3910 ELSE IF ( ( var_type .EQ. 'Z' ) .OR. &
3911 ( var_type .EQ. 'T' ) ) THEN
3912 k_above(i,kn) = ko_above_sfc(i)
3916 ! Just a catch all right now.
3923 EXIT found_trap_above
3925 ! The other extrapolation that might be required is when we are going above the
3926 ! top level of the input data. Usually this means we chose a P_PTOP value that
3927 ! was inappropriate, and we should stop and let someone fix this mess.
3929 ELSE IF ( porig(i,generic,j) .GT. pnew(i,kn,j) ) THEN
3930 print *,'data is too high, try a lower p_top'
3931 print *,'pnew=',pnew(i,kn,j)
3932 print *,'porig=',porig(i,:,j)
3933 CALL wrf_error_fatal ('requested p_top is higher than input data, lower p_top')
3936 END DO found_trap_above
3940 ! Linear vertical interpolation.
3942 DO kn = kstart , kend
3943 DO i = istart , iend
3944 IF ( k_above(i,kn) .EQ. 1 ) THEN
3945 fnew(i,kn,j) = forig(i,1,j)
3947 k2 = MAX ( k_above(i,kn) , 2)
3948 k1 = MAX ( k_below(i,kn) , 1)
3949 IF ( k1 .EQ. k2 ) THEN
3950 CALL wrf_error_fatal ( 'identical values in the interp, bad for divisions' )
3952 IF ( interp_type .EQ. 1 ) THEN
3956 ELSE IF ( interp_type .EQ. 2 ) THEN
3957 p1 = ALOG(porig(i,k1,j))
3958 p2 = ALOG(porig(i,k2,j))
3959 pn = ALOG(pnew(i,kn,j))
3961 IF ( ( p1-pn) * (p2-pn) > 0. ) THEN
3962 ! CALL wrf_error_fatal ( 'both trapping pressures are on the same side of the new pressure' )
3963 ! CALL wrf_debug ( 0 , 'both trapping pressures are on the same side of the new pressure' )
3964 vert_extrap = vert_extrap + 1
3966 fnew(i,kn,j) = ( forig(i,k1,j) * ( p2 - pn ) + &
3967 forig(i,k2,j) * ( pn - p1 ) ) / &
3973 search_below_ground : DO kn = kstart , kend
3974 any_below_ground = .FALSE.
3975 DO i = istart , iend
3976 IF ( k_above(i,kn) .EQ. 1 ) THEN
3977 fnew(i,kn,j) = forig(i,1,j)
3978 any_below_ground = .TRUE.
3981 IF ( .NOT. any_below_ground ) THEN
3982 EXIT search_below_ground
3984 END DO search_below_ground
3986 ! There may have been a request to have the surface data from the input field
3987 ! to be assigned as to the lowest eta level. This assumes thin layers (usually
3988 ! the isobaric original field has the surface from 2-m T and RH, and 10-m U and V).
3990 DO i = istart , iend
3991 IF ( lowest_lev_from_sfc ) THEN
3992 fnew(i,1,j) = forig(i,ko_above_sfc(i),j)
3997 print *,'VERT EXTRAP = ', vert_extrap
3999 END SUBROUTINE vert_interp_old
4001 !---------------------------------------------------------------------
4003 SUBROUTINE lagrange_setup ( var_type , interp_type , all_x , all_y , all_dim , n , extrap_type , &
4004 target_x , target_y , target_dim ,i,j)
4006 ! We call a Lagrange polynomial interpolator. The parallel concerns are put off as this
4007 ! is initially set up for vertical use. The purpose is an input column of pressure (all_x),
4008 ! and the associated pressure level data (all_y). These are assumed to be sorted (ascending
4009 ! or descending, no matter). The locations to be interpolated to are the pressures in
4010 ! target_x, probably the new vertical coordinate values. The field that is output is the
4011 ! target_y, which is defined at the target_x location. Mostly we expect to be 2nd order
4012 ! overlapping polynomials, with only a single 2nd order method near the top and bottom.
4013 ! When n=1, this is linear; when n=2, this is a second order interpolator.
4017 CHARACTER (LEN=1) :: var_type
4018 INTEGER , INTENT(IN) :: interp_type , all_dim , n , extrap_type , target_dim
4019 REAL, DIMENSION(all_dim) , INTENT(IN) :: all_x , all_y
4020 REAL , DIMENSION(target_dim) , INTENT(IN) :: target_x
4021 REAL , DIMENSION(target_dim) , INTENT(OUT) :: target_y
4023 ! Brought in for debug purposes, all of the computations are in a single column.
4025 INTEGER , INTENT(IN) :: i,j
4029 REAL , DIMENSION(n+1) :: x , y
4031 REAL :: target_y_1 , target_y_2
4032 LOGICAL :: found_loc
4033 INTEGER :: loop , loc_center_left , loc_center_right , ist , iend , target_loop
4034 INTEGER :: vboundb , vboundt
4036 ! Local vars for the problem of extrapolating theta below ground.
4038 REAL :: temp_1 , temp_2 , temp_3 , temp_y
4039 REAL :: depth_of_extrap_in_p , avg_of_extrap_p , temp_extrap_starting_point , dhdp , dh , dt
4040 REAL , PARAMETER :: RovCp = rcp
4041 REAL , PARAMETER :: CRC_const1 = 11880.516 ! m
4042 REAL , PARAMETER :: CRC_const2 = 0.1902632 !
4043 REAL , PARAMETER :: CRC_const3 = 0.0065 ! K/km
4044 REAL, DIMENSION(all_dim) :: all_x_full
4045 REAL , DIMENSION(target_dim) :: target_x_full
4047 IF ( all_dim .LT. n+1 ) THEN
4048 print *,'all_dim = ',all_dim
4049 print *,'order = ',n
4050 print *,'i,j = ',i,j
4051 print *,'p array = ',all_x
4052 print *,'f array = ',all_y
4053 print *,'p target= ',target_x
4054 CALL wrf_error_fatal ( 'troubles, the interpolating order is too large for this few input values' )
4057 IF ( n .LT. 1 ) THEN
4058 CALL wrf_error_fatal ( 'pal, linear is about as low as we go' )
4061 ! We can pinch in the area of the higher order interpolation with vbound. If
4062 ! vbound = 0, no pinching. If vbound = m, then we make the lower "m" and upper
4063 ! "m" eta levels use a linear interpolation.
4068 ! Loop over the list of target x and y values.
4070 DO target_loop = 1 , target_dim
4072 ! Find the two trapping x values, and keep the indices.
4075 find_trap : DO loop = 1 , all_dim -1
4076 a = target_x(target_loop) - all_x(loop)
4077 b = target_x(target_loop) - all_x(loop+1)
4078 IF ( a*b .LE. 0.0 ) THEN
4079 loc_center_left = loop
4080 loc_center_right = loop+1
4086 IF ( ( .NOT. found_loc ) .AND. ( target_x(target_loop) .GT. all_x(1) ) ) THEN
4088 ! Get full pressure back so that our extrpolations make sense.
4090 IF ( interp_type .EQ. 1 ) THEN
4092 target_x_full = target_x
4094 all_x_full = EXP ( all_x )
4095 target_x_full = EXP ( target_x )
4097 ! Isothermal extrapolation.
4099 IF ( ( extrap_type .EQ. 1 ) .AND. ( var_type .EQ. 'T' ) ) THEN
4101 temp_1 = all_y(1) * ( all_x_full(1) / 100000. ) ** RovCp
4102 target_y(target_loop) = temp_1 * ( 100000. / target_x_full(target_loop) ) ** RovCp
4104 ! Standard atmosphere -6.5 K/km lapse rate for the extrapolation.
4106 ELSE IF ( ( extrap_type .EQ. 2 ) .AND. ( var_type .EQ. 'T' ) ) THEN
4108 depth_of_extrap_in_p = target_x_full(target_loop) - all_x_full(1)
4109 avg_of_extrap_p = ( target_x_full(target_loop) + all_x_full(1) ) * 0.5
4110 temp_extrap_starting_point = all_y(1) * ( all_x_full(1) / 100000. ) ** RovCp
4111 dhdp = CRC_const1 * CRC_const2 * ( avg_of_extrap_p / 100. ) ** ( CRC_const2 - 1. )
4112 dh = dhdp * ( depth_of_extrap_in_p / 100. )
4113 dt = dh * CRC_const3
4114 target_y(target_loop) = ( temp_extrap_starting_point + dt ) * ( 100000. / target_x_full(target_loop) ) ** RovCp
4116 ! Adiabatic extrapolation for theta.
4118 ELSE IF ( ( extrap_type .EQ. 3 ) .AND. ( var_type .EQ. 'T' ) ) THEN
4120 target_y(target_loop) = all_y(1)
4123 ! Wild extrapolation for non-temperature vars.
4125 ELSE IF ( extrap_type .EQ. 1 ) THEN
4127 target_y(target_loop) = ( all_y(2) * ( target_x(target_loop) - all_x(3) ) + &
4128 all_y(3) * ( all_x(2) - target_x(target_loop) ) ) / &
4129 ( all_x(2) - all_x(3) )
4131 ! Use a constant value below ground.
4133 ELSE IF ( extrap_type .EQ. 2 ) THEN
4135 target_y(target_loop) = all_y(1)
4137 ELSE IF ( extrap_type .EQ. 3 ) THEN
4138 CALL wrf_error_fatal ( 'You are not allowed to use extrap_option #3 for any var except for theta.' )
4142 ELSE IF ( .NOT. found_loc ) THEN
4143 print *,'i,j = ',i,j
4144 print *,'target pressure and value = ',target_x(target_loop),target_y(target_loop)
4145 DO loop = 1 , all_dim
4146 print *,'column of pressure and value = ',all_x(loop),all_y(loop)
4148 CALL wrf_error_fatal ( 'troubles, could not find trapping x locations' )
4151 ! Even or odd order? We can put the value in the middle if this is
4152 ! an odd order interpolator. For the even guys, we'll do it twice
4153 ! and shift the range one index, then get an average.
4155 IF ( MOD(n,2) .NE. 0 ) THEN
4156 IF ( ( loc_center_left -(((n+1)/2)-1) .GE. 1 ) .AND. &
4157 ( loc_center_right+(((n+1)/2)-1) .LE. all_dim ) ) THEN
4158 ist = loc_center_left -(((n+1)/2)-1)
4160 CALL lagrange_interp ( all_x(ist:iend) , all_y(ist:iend) , n , target_x(target_loop) , target_y(target_loop) )
4162 IF ( .NOT. found_loc ) THEN
4163 CALL wrf_error_fatal ( 'I doubt this will happen, I will only do 2nd order for now' )
4167 ELSE IF ( ( MOD(n,2) .EQ. 0 ) .AND. &
4168 ( ( target_loop .GE. 1 + vboundb ) .AND. ( target_loop .LE. target_dim - vboundt ) ) ) THEN
4169 IF ( ( loc_center_left -(((n )/2)-1) .GE. 1 ) .AND. &
4170 ( loc_center_right+(((n )/2) ) .LE. all_dim ) .AND. &
4171 ( loc_center_left -(((n )/2) ) .GE. 1 ) .AND. &
4172 ( loc_center_right+(((n )/2)-1) .LE. all_dim ) ) THEN
4173 ist = loc_center_left -(((n )/2)-1)
4175 CALL lagrange_interp ( all_x(ist:iend) , all_y(ist:iend) , n , target_x(target_loop) , target_y_1 )
4176 ist = loc_center_left -(((n )/2) )
4178 CALL lagrange_interp ( all_x(ist:iend) , all_y(ist:iend) , n , target_x(target_loop) , target_y_2 )
4179 target_y(target_loop) = ( target_y_1 + target_y_2 ) * 0.5
4181 ELSE IF ( ( loc_center_left -(((n )/2)-1) .GE. 1 ) .AND. &
4182 ( loc_center_right+(((n )/2) ) .LE. all_dim ) ) THEN
4183 ist = loc_center_left -(((n )/2)-1)
4185 CALL lagrange_interp ( all_x(ist:iend) , all_y(ist:iend) , n , target_x(target_loop) , target_y(target_loop) )
4186 ELSE IF ( ( loc_center_left -(((n )/2) ) .GE. 1 ) .AND. &
4187 ( loc_center_right+(((n )/2)-1) .LE. all_dim ) ) THEN
4188 ist = loc_center_left -(((n )/2) )
4190 CALL lagrange_interp ( all_x(ist:iend) , all_y(ist:iend) , n , target_x(target_loop) , target_y(target_loop) )
4192 CALL wrf_error_fatal ( 'unauthorized area, you should not be here' )
4195 ELSE IF ( MOD(n,2) .EQ. 0 ) THEN
4196 ist = loc_center_left
4197 iend = loc_center_right
4198 CALL lagrange_interp ( all_x(ist:iend) , all_y(ist:iend) , 1 , target_x(target_loop) , target_y(target_loop) )
4204 END SUBROUTINE lagrange_setup
4206 !---------------------------------------------------------------------
4208 SUBROUTINE lagrange_interp ( x , y , n , target_x , target_y )
4210 ! Interpolation using Lagrange polynomials.
4211 ! P(x) = f(x0)Ln0(x) + ... + f(xn)Lnn(x)
4212 ! where Lnk(x) = (x -x0)(x -x1)...(x -xk-1)(x -xk+1)...(x -xn)
4213 ! ---------------------------------------------
4214 ! (xk-x0)(xk-x1)...(xk-xk-1)(xk-xk+1)...(xk-xn)
4218 INTEGER , INTENT(IN) :: n
4219 REAL , DIMENSION(0:n) , INTENT(IN) :: x , y
4220 REAL , INTENT(IN) :: target_x
4222 REAL , INTENT(OUT) :: target_y
4227 REAL :: numer , denom , Px
4228 REAL , DIMENSION(0:n) :: Ln
4235 IF ( k .EQ. i ) CYCLE
4236 numer = numer * ( target_x - x(k) )
4237 denom = denom * ( x(i) - x(k) )
4239 IF ( denom .NE. 0. ) THEN
4240 Ln(i) = y(i) * numer / denom
4246 END SUBROUTINE lagrange_interp
4249 !---------------------------------------------------------------------
4251 SUBROUTINE p_dry ( mu0 , eta , pdht , pdry , full_levs , &
4252 ids , ide , jds , jde , kds , kde , &
4253 ims , ime , jms , jme , kms , kme , &
4254 its , ite , jts , jte , kts , kte )
4256 ! Compute reference pressure and the reference mu.
4260 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
4261 ims , ime , jms , jme , kms , kme , &
4262 its , ite , jts , jte , kts , kte
4264 LOGICAL :: full_levs
4266 REAL , DIMENSION(ims:ime, jms:jme) , INTENT(IN) :: mu0
4267 REAL , DIMENSION( kms:kme ) , INTENT(IN) :: eta
4269 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(OUT) :: pdry
4273 INTEGER :: i , j , k
4274 REAL , DIMENSION( kms:kme ) :: eta_h
4276 IF ( full_levs ) THEN
4277 DO j = jts , MIN ( jde-1 , jte )
4279 DO i = its , MIN (ide-1 , ite )
4280 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4281 pdry(i,k,j) = eta(k) * mu0(i,j) + pdht
4288 eta_h(k) = ( eta(k) + eta(k+1) ) * 0.5
4291 DO j = jts , MIN ( jde-1 , jte )
4293 DO i = its , MIN (ide-1 , ite )
4294 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4295 pdry(i,k,j) = eta_h(k) * mu0(i,j) + pdht
4301 END SUBROUTINE p_dry
4303 !---------------------------------------------------------------------
4305 SUBROUTINE p_dts ( pdts , intq , psfc , p_top , &
4306 ids , ide , jds , jde , kds , kde , &
4307 ims , ime , jms , jme , kms , kme , &
4308 its , ite , jts , jte , kts , kte )
4310 ! Compute difference between the dry, total surface pressure and the top pressure.
4314 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
4315 ims , ime , jms , jme , kms , kme , &
4316 its , ite , jts , jte , kts , kte
4318 REAL , INTENT(IN) :: p_top
4319 REAL , DIMENSION(ims:ime,jms:jme) , INTENT(IN) :: psfc
4320 REAL , DIMENSION(ims:ime,jms:jme) , INTENT(IN) :: intq
4321 REAL , DIMENSION(ims:ime,jms:jme) , INTENT(OUT) :: pdts
4325 INTEGER :: i , j , k
4327 DO j = jts , MIN ( jde-1 , jte )
4328 DO i = its , MIN (ide-1 , ite )
4329 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4330 pdts(i,j) = psfc(i,j) - intq(i,j) - p_top
4334 END SUBROUTINE p_dts
4336 !---------------------------------------------------------------------
4338 SUBROUTINE p_dhs ( pdhs , ht , p0 , t0 , a , &
4339 ids , ide , jds , jde , kds , kde , &
4340 ims , ime , jms , jme , kms , kme , &
4341 its , ite , jts , jte , kts , kte )
4343 ! Compute dry, hydrostatic surface pressure.
4347 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
4348 ims , ime , jms , jme , kms , kme , &
4349 its , ite , jts , jte , kts , kte
4351 REAL , DIMENSION(ims:ime, jms:jme) , INTENT(IN) :: ht
4352 REAL , DIMENSION(ims:ime, jms:jme) , INTENT(OUT) :: pdhs
4354 REAL , INTENT(IN) :: p0 , t0 , a
4358 INTEGER :: i , j , k
4360 REAL , PARAMETER :: Rd = r_d
4362 DO j = jts , MIN ( jde-1 , jte )
4363 DO i = its , MIN (ide-1 , ite )
4364 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4365 pdhs(i,j) = p0 * EXP ( -t0/a + SQRT ( (t0/a)**2 - 2. * g * ht(i,j)/(a * Rd) ) )
4369 END SUBROUTINE p_dhs
4371 !---------------------------------------------------------------------
4373 SUBROUTINE find_p_top ( p , p_top , &
4374 ids , ide , jds , jde , kds , kde , &
4375 ims , ime , jms , jme , kms , kme , &
4376 its , ite , jts , jte , kts , kte )
4378 ! Find the largest pressure in the top level. This is our p_top. We are
4379 ! assuming that the top level is the location where the pressure is a minimum
4380 ! for each column. In cases where the top surface is not isobaric, a
4381 ! communicated value must be shared in the calling routine. Also in cases
4382 ! where the top surface is not isobaric, care must be taken that the new
4383 ! maximum pressure is not greater than the previous value. This test is
4384 ! also handled in the calling routine.
4388 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
4389 ims , ime , jms , jme , kms , kme , &
4390 its , ite , jts , jte , kts , kte
4393 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: p
4397 INTEGER :: i , j , k, min_lev
4404 IF ( p_top .GT. p(i,k,j) ) THEN
4411 p_top = p(its,k,jts)
4412 DO j = jts , MIN ( jde-1 , jte )
4413 DO i = its , MIN (ide-1 , ite )
4414 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4415 p_top = MAX ( p_top , p(i,k,j) )
4419 END SUBROUTINE find_p_top
4421 !---------------------------------------------------------------------
4423 SUBROUTINE t_to_theta ( t , p , p00 , &
4424 ids , ide , jds , jde , kds , kde , &
4425 ims , ime , jms , jme , kms , kme , &
4426 its , ite , jts , jte , kts , kte )
4428 ! Compute potential temperature from temperature and pressure.
4432 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
4433 ims , ime , jms , jme , kms , kme , &
4434 its , ite , jts , jte , kts , kte
4436 REAL , INTENT(IN) :: p00
4437 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: p
4438 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(INOUT) :: t
4442 INTEGER :: i , j , k
4444 REAL , PARAMETER :: Rd = r_d
4446 DO j = jts , MIN ( jde-1 , jte )
4448 DO i = its , MIN (ide-1 , ite )
4449 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4450 t(i,k,j) = t(i,k,j) * ( p00 / p(i,k,j) ) ** (Rd / Cp)
4455 END SUBROUTINE t_to_theta
4458 !---------------------------------------------------------------------
4460 SUBROUTINE theta_to_t ( t , p , p00 , &
4461 ids , ide , jds , jde , kds , kde , &
4462 ims , ime , jms , jme , kms , kme , &
4463 its , ite , jts , jte , kts , kte )
4465 ! Compute temperature from potential temp and pressure.
4469 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
4470 ims , ime , jms , jme , kms , kme , &
4471 its , ite , jts , jte , kts , kte
4473 REAL , INTENT(IN) :: p00
4474 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: p
4475 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(INOUT) :: t
4479 INTEGER :: i , j , k
4481 REAL , PARAMETER :: Rd = r_d
4482 CHARACTER (LEN=80) :: mess
4484 DO j = jts , MIN ( jde-1 , jte )
4486 DO i = its , MIN (ide-1 , ite )
4487 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4488 if ( p(i,k,j) .NE. 0. ) then
4489 t(i,k,j) = t(i,k,j) / ( ( p00 / p(i,k,j) ) ** (Rd / Cp) )
4491 WRITE(mess,*) 'Troubles in theta_to_t'
4492 CALL wrf_debug(0,mess)
4493 WRITE(mess,*) "i,j,k = ", i,j,k
4494 CALL wrf_debug(0,mess)
4495 WRITE(mess,*) "p(i,k,j) = ", p(i,k,j)
4496 CALL wrf_debug(0,mess)
4497 WRITE(mess,*) "t(i,k,j) = ", t(i,k,j)
4498 CALL wrf_debug(0,mess)
4504 END SUBROUTINE theta_to_t
4506 !---------------------------------------------------------------------
4508 SUBROUTINE integ_moist ( q_in , p_in , pd_out , t_in , ght_in , intq , &
4509 ids , ide , jds , jde , kds , kde , &
4510 ims , ime , jms , jme , kms , kme , &
4511 its , ite , jts , jte , kts , kte )
4513 ! Integrate the moisture field vertically. Mostly used to get the total
4514 ! vapor pressure, which can be subtracted from the total pressure to get
4519 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
4520 ims , ime , jms , jme , kms , kme , &
4521 its , ite , jts , jte , kts , kte
4523 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: q_in , p_in , t_in , ght_in
4524 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(OUT) :: pd_out
4525 REAL , DIMENSION(ims:ime, jms:jme) , INTENT(OUT) :: intq
4529 INTEGER :: i , j , k
4530 INTEGER , DIMENSION(ims:ime) :: level_above_sfc
4531 REAL , DIMENSION(ims:ime,jms:jme) :: psfc , tsfc , qsfc, zsfc
4532 REAL , DIMENSION(ims:ime,kms:kme) :: q , p , t , ght, pd
4534 REAL :: rhobar , qbar , dz
4535 REAL :: p1 , p2 , t1 , t2 , q1 , q2 , z1, z2
4537 LOGICAL :: upside_down
4538 LOGICAL :: already_assigned_upside_down
4540 REAL , PARAMETER :: Rd = r_d
4542 ! Is the data upside down?
4545 already_assigned_upside_down = .FALSE.
4546 find_valid : DO j = jts , MIN ( jde-1 , jte )
4547 DO i = its , MIN (ide-1 , ite )
4548 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4549 IF ( p_in(i,kts+1,j) .LT. p_in(i,kte,j) ) THEN
4550 upside_down = .TRUE.
4551 already_assigned_upside_down = .TRUE.
4553 upside_down = .FALSE.
4554 already_assigned_upside_down = .TRUE.
4560 IF ( .NOT. already_assigned_upside_down ) THEN
4561 upside_down = .FALSE.
4564 ! Get a surface value, always the first level of a 3d field.
4566 DO j = jts , MIN ( jde-1 , jte )
4567 DO i = its , MIN (ide-1 , ite )
4568 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4569 psfc(i,j) = p_in(i,kts,j)
4570 tsfc(i,j) = t_in(i,kts,j)
4571 qsfc(i,j) = q_in(i,kts,j)
4572 zsfc(i,j) = ght_in(i,kts,j)
4576 DO j = jts , MIN ( jde-1 , jte )
4578 ! Initialize the integrated quantity of moisture to zero.
4580 DO i = its , MIN (ide-1 , ite )
4584 IF ( upside_down ) THEN
4585 DO i = its , MIN (ide-1 , ite )
4586 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4587 p(i,kts) = p_in(i,kts,j)
4588 t(i,kts) = t_in(i,kts,j)
4589 q(i,kts) = q_in(i,kts,j)
4590 ght(i,kts) = ght_in(i,kts,j)
4592 p(i,k) = p_in(i,kte+2-k,j)
4593 t(i,k) = t_in(i,kte+2-k,j)
4594 q(i,k) = q_in(i,kte+2-k,j)
4595 ght(i,k) = ght_in(i,kte+2-k,j)
4599 DO i = its , MIN (ide-1 , ite )
4600 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4602 p(i,k) = p_in(i,k ,j)
4603 t(i,k) = t_in(i,k ,j)
4604 q(i,k) = q_in(i,k ,j)
4605 ght(i,k) = ght_in(i,k ,j)
4610 ! Find the first level above the ground. If all of the levels are above ground, such as
4611 ! a terrain following lower coordinate, then the first level above ground is index #2.
4613 DO i = its , MIN (ide-1 , ite )
4614 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4615 level_above_sfc(i) = -1
4616 IF ( p(i,kts+1) .LT. psfc(i,j) ) THEN
4617 level_above_sfc(i) = kts+1
4619 find_k : DO k = kts+1,kte-1
4620 IF ( ( p(i,k )-psfc(i,j) .GE. 0. ) .AND. &
4621 ( p(i,k+1)-psfc(i,j) .LT. 0. ) ) THEN
4622 level_above_sfc(i) = k+1
4626 IF ( level_above_sfc(i) .EQ. -1 ) THEN
4627 print *,'i,j = ',i,j
4628 print *,'p = ',p(i,:)
4629 print *,'p sfc = ',psfc(i,j)
4630 CALL wrf_error_fatal ( 'Could not find level above ground')
4635 DO i = its , MIN (ide-1 , ite )
4636 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4638 ! Account for the moisture above the ground.
4640 pd(i,kte) = p(i,kte)
4641 DO k = kte-1,level_above_sfc(i),-1
4642 rhobar = ( p(i,k ) / ( Rd * t(i,k ) ) + &
4643 p(i,k+1) / ( Rd * t(i,k+1) ) ) * 0.5
4644 qbar = ( q(i,k ) + q(i,k+1) ) * 0.5
4645 dz = ght(i,k+1) - ght(i,k)
4646 intq(i,j) = intq(i,j) + g * qbar * rhobar / (1. + qbar) * dz
4647 pd(i,k) = p(i,k) - intq(i,j)
4650 ! Account for the moisture between the surface and the first level up.
4652 IF ( ( p(i,level_above_sfc(i)-1)-psfc(i,j) .GE. 0. ) .AND. &
4653 ( p(i,level_above_sfc(i) )-psfc(i,j) .LT. 0. ) .AND. &
4654 ( level_above_sfc(i) .GT. kts ) ) THEN
4656 p2 = p(i,level_above_sfc(i))
4658 t2 = t(i,level_above_sfc(i))
4660 q2 = q(i,level_above_sfc(i))
4662 z2 = ght(i,level_above_sfc(i))
4663 rhobar = ( p1 / ( Rd * t1 ) + &
4664 p2 / ( Rd * t2 ) ) * 0.5
4665 qbar = ( q1 + q2 ) * 0.5
4667 IF ( dz .GT. 0.1 ) THEN
4668 intq(i,j) = intq(i,j) + g * qbar * rhobar / (1. + qbar) * dz
4671 ! Fix the underground values.
4673 DO k = level_above_sfc(i)-1,kts+1,-1
4674 pd(i,k) = p(i,k) - intq(i,j)
4677 pd(i,kts) = psfc(i,j) - intq(i,j)
4681 IF ( upside_down ) THEN
4682 DO i = its , MIN (ide-1 , ite )
4683 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4684 pd_out(i,kts,j) = pd(i,kts)
4686 pd_out(i,kte+2-k,j) = pd(i,k)
4690 DO i = its , MIN (ide-1 , ite )
4691 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4693 pd_out(i,k,j) = pd(i,k)
4700 END SUBROUTINE integ_moist
4702 !---------------------------------------------------------------------
4704 SUBROUTINE rh_to_mxrat2(rh, t, p, q , wrt_liquid , &
4706 qv_max_flag , qv_max_value , &
4708 qv_min_flag , qv_min_value , &
4709 ids , ide , jds , jde , kds , kde , &
4710 ims , ime , jms , jme , kms , kme , &
4711 its , ite , jts , jte , kts , kte )
4713 ! This subroutine computes mixing ratio (q, kg/kg) from basic variables
4714 ! pressure (p, Pa), temperature (t, K) and relative humidity (rh, 0-100%).
4715 ! Phase transition, liquid water to ice, occurs over (0,-23) temperature range (Celcius).
4716 ! Formulation used here is based on:
4717 ! WMO, General meteorological standards and recommended practices,
4718 ! Appendix A, WMO Technical Regulations, WMO-No. 49, corrigendum,
4719 ! August 2000. --TKW 03/30/2011
4723 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
4724 ims , ime , jms , jme , kms , kme , &
4725 its , ite , jts , jte , kts , kte
4727 LOGICAL , INTENT(IN) :: wrt_liquid
4729 REAL , INTENT(IN) :: qv_max_p_safe , qv_max_flag , qv_max_value
4730 REAL , INTENT(IN) :: qv_min_p_safe , qv_min_flag , qv_min_value
4732 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: p , t
4733 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(INOUT) :: rh
4734 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(OUT) :: q
4738 REAL, PARAMETER :: T0K = 273.16
4739 REAL, PARAMETER :: Tice = T0K - 23.0
4741 REAL, PARAMETER :: cfe = 1.0/(23.0*23.0)
4742 REAL, PARAMETER :: eps = 0.622
4744 ! Coefficients for esat over liquid water
4745 REAL, PARAMETER :: cw1 = 10.79574
4746 REAL, PARAMETER :: cw2 = -5.02800
4747 REAL, PARAMETER :: cw3 = 1.50475E-4
4748 REAL, PARAMETER :: cw4 = 0.42873E-3
4749 REAL, PARAMETER :: cw5 = 0.78614
4751 ! Coefficients for esat over ice
4752 REAL, PARAMETER :: ci1 = -9.09685
4753 REAL, PARAMETER :: ci2 = -3.56654
4754 REAL, PARAMETER :: ci3 = 0.87682
4755 REAL, PARAMETER :: ci4 = 0.78614
4757 REAL, PARAMETER :: Tn = 273.16
4759 ! 1 ppm is a reasonable estimate for minimum QV even for stratospheric altitudes
4760 REAL, PARAMETER :: QV_MIN = 1.e-6
4762 ! Maximum allowed QV is computed under the extreme condition:
4763 ! Saturated at 40 degree in Celcius and 1000 hPa
4764 REAL, PARAMETER :: QV_MAX = 0.045
4766 ! Need to constrain WVP in the stratosphere where pressure
4767 ! is low but tempearure is hot (warm)
4768 ! Maximum ratio of e/p, = q/(0.622+q)
4769 REAL, PARAMETER :: EP_MAX = QV_MAX/(eps+QV_MAX)
4771 INTEGER :: i , j , k
4773 REAL :: ew , q1 , t1
4774 REAL :: ta, tb, pw3, pw4, pwr
4775 REAL :: es, esw, esi, wvp, pmb, wvpmax
4777 DO j = jts , MIN ( jde-1 , jte )
4779 DO i = its , MIN (ide-1 , ite )
4780 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4781 rh(i,k,j) = MIN ( MAX ( rh(i,k,j) , 0. ) , 100. )
4786 IF ( wrt_liquid ) THEN
4787 DO j = jts , MIN ( jde-1 , jte )
4789 DO i = its , MIN (ide-1 , ite )
4790 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4793 pw3 = -8.2969*(Tb-1.0)
4794 pw4 = 4.76955*(1.0-Ta)
4795 pwr = cw1*(1.0-Ta) + cw2*LOG10(Tb) + cw3*(1.0-10.0**pw3) + cw4*(10.0**pw4-1.0) + cw5
4796 es = 10.0**pwr ! Saturation WVP
4797 wvp = 0.01*rh(i,k,j)*es ! Actual WVP
4799 wvpmax = EP_MAX*pmb ! Prevents unrealistic QV in the stratosphere
4800 wvp = MIN(wvp,wvpmax)
4801 q(i,k,j) = eps*wvp/(pmb-wvp)
4807 DO j = jts , MIN ( jde-1 , jte )
4809 DO i = its , MIN (ide-1 , ite )
4810 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4813 IF (t(i,k,j) >= T0K) THEN ! Over liquid water
4814 pw3 = -8.2969*(Tb-1.0)
4815 pw4 = 4.76955*(1.0-Ta)
4816 pwr = cw1*(1.0-Ta) + cw2*LOG10(Tb) + cw3*(1.0-10.0**pw3) + cw4*(10.0**pw4-1.0) + cw5
4818 wvp = 0.01*rh(i,k,j)*es
4819 ELSE IF (t(i,k,j) <= Tice) THEN ! Over ice
4820 pwr = ci1*(Ta-1.0) + ci2*LOG10(Ta) + ci3*(1.0-Tb) + ci4
4822 wvp = 0.01*rh(i,k,j)*es
4824 pw3 = -8.2969*(Tb-1.0)
4825 pw4 = 4.76955*(1.0-Ta)
4826 pwr = cw1*(1.0-Ta) + cw2*LOG10(Tb) + cw3*(1.0-10.0**pw3) + cw4*(10.0**pw4-1.0) + cw5
4827 esw = 10.0**pwr ! Over liquid water
4829 pwr = ci1*(Ta-1.0) + ci2*LOG10(Ta) + ci3*(1.0-Tb) + ci4
4830 esi = 10.0**pwr ! Over ice
4832 es = esi + (esw-esi)*cfe*(T(i,k,j)-Tice)*(T(i,k,j)-Tice)
4833 wvp = 0.01*rh(i,k,j)*es
4836 wvpmax = EP_MAX*pmb ! Prevents unrealistic QV in the stratosphere
4837 wvp = MIN(wvp,wvpmax)
4838 q(i,k,j) = eps*wvp/(pmb-wvp)
4844 ! For pressures above a defined level, reasonable Qv values should be
4845 ! a certain value or smaller. If they are larger than this, the input data
4846 ! probably had "missing" RH, and we filled in some values. This is an
4847 ! attempt to catch those. Also, set the minimum value for the entire
4848 ! domain that is above the selected pressure level.
4850 DO j = jts , MIN ( jde-1 , jte )
4852 DO i = its , MIN (ide-1 , ite )
4853 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4854 IF ( p(i,k,j) .LT. qv_max_p_safe ) THEN
4855 IF ( q(i,k,j) .GT. qv_max_flag ) THEN
4856 q(i,k,j) = qv_max_value
4859 IF ( p(i,k,j) .LT. qv_min_p_safe ) THEN
4860 IF ( q(i,k,j) .LT. qv_min_flag ) THEN
4861 q(i,k,j) = qv_min_value
4868 END SUBROUTINE rh_to_mxrat2
4870 !---------------------------------------------------------------------
4872 SUBROUTINE rh_to_mxrat1(rh, t, p, q , wrt_liquid , &
4874 qv_max_flag , qv_max_value , &
4876 qv_min_flag , qv_min_value , &
4877 ids , ide , jds , jde , kds , kde , &
4878 ims , ime , jms , jme , kms , kme , &
4879 its , ite , jts , jte , kts , kte )
4883 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
4884 ims , ime , jms , jme , kms , kme , &
4885 its , ite , jts , jte , kts , kte
4887 LOGICAL , INTENT(IN) :: wrt_liquid
4889 REAL , INTENT(IN) :: qv_max_p_safe , qv_max_flag , qv_max_value
4890 REAL , INTENT(IN) :: qv_min_p_safe , qv_min_flag , qv_min_value
4892 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: p , t
4893 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(INOUT) :: rh
4894 REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(OUT) :: q
4898 INTEGER :: i , j , k
4900 REAL :: ew , q1 , t1
4902 REAL, PARAMETER :: T_REF = 0.0
4903 REAL, PARAMETER :: MW_AIR = 28.966
4904 REAL, PARAMETER :: MW_VAP = 18.0152
4906 REAL, PARAMETER :: A0 = 6.107799961
4907 REAL, PARAMETER :: A1 = 4.436518521e-01
4908 REAL, PARAMETER :: A2 = 1.428945805e-02
4909 REAL, PARAMETER :: A3 = 2.650648471e-04
4910 REAL, PARAMETER :: A4 = 3.031240396e-06
4911 REAL, PARAMETER :: A5 = 2.034080948e-08
4912 REAL, PARAMETER :: A6 = 6.136820929e-11
4914 REAL, PARAMETER :: ES0 = 6.1121
4916 REAL, PARAMETER :: C1 = 9.09718
4917 REAL, PARAMETER :: C2 = 3.56654
4918 REAL, PARAMETER :: C3 = 0.876793
4919 REAL, PARAMETER :: EIS = 6.1071
4921 REAL, PARAMETER :: TF = 273.16
4926 REAL, PARAMETER :: EPS = 0.622
4927 REAL, PARAMETER :: SVP1 = 0.6112
4928 REAL, PARAMETER :: SVP2 = 17.67
4929 REAL, PARAMETER :: SVP3 = 29.65
4930 REAL, PARAMETER :: SVPT0 = 273.15
4932 CHARACTER (LEN=80) :: mess
4934 ! This subroutine computes mixing ratio (q, kg/kg) from basic variables
4935 ! pressure (p, Pa), temperature (t, K) and relative humidity (rh, 1-100%).
4936 ! The reference temperature (t_ref, C) is used to describe the temperature
4937 ! at which the liquid and ice phase change occurs.
4939 DO j = jts , MIN ( jde-1 , jte )
4941 DO i = its , MIN (ide-1 , ite )
4942 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4943 rh(i,k,j) = MIN ( MAX ( rh(i,k,j) , 0. ) , 100. )
4948 IF ( wrt_liquid ) THEN
4949 DO j = jts , MIN ( jde-1 , jte )
4951 DO i = its , MIN (ide-1 , ite )
4952 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4954 ! es is reduced by RH here to avoid problems in low-pressure cases
4955 if (t(i,k,j) .ne. 0.) then
4956 es=.01*rh(i,k,j)*svp1*10.*EXP(svp2*(t(i,k,j)-svpt0)/(t(i,k,j)-svp3))
4957 IF (es .ge. p(i,k,j)/100.)THEN
4959 WRITE(mess,*) 'Warning: vapor pressure exceeds total pressure, setting Qv to 0'
4960 CALL wrf_debug(0,mess)
4962 q(i,k,j)=eps*es/(p(i,k,j)/100.-es)
4966 WRITE(mess,*) 't(i,j,k) was 0 at ', i,j,k,', setting Qv to 0'
4967 CALL wrf_debug(0,mess)
4974 DO j = jts , MIN ( jde-1 , jte )
4976 DO i = its , MIN (ide-1 , ite )
4977 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
4979 t1 = t(i,k,j) - 273.16
4983 IF ( t1 .lt. -200. ) THEN
4988 ! First compute the ambient vapor pressure of water
4990 ! Liquid phase t > 0 C
4992 IF ( t1 .GE. t_ref ) THEN
4993 ew = a0 + t1 * (a1 + t1 * (a2 + t1 * (a3 + t1 * (a4 + t1 * (a5 + t1 * a6)))))
4995 ! Mixed phase -47 C < t < 0 C
4997 ELSE IF ( ( t1 .LT. t_ref ) .AND. ( t1 .GE. -47. ) ) THEN
4998 ew = es0 * exp(17.67 * t1 / ( t1 + 243.5))
5000 ! Ice phase t < -47 C
5002 ELSE IF ( t1 .LT. -47. ) THEN
5004 rhs = -c1 * (tf / tk - 1.) - c2 * alog10(tf / tk) + &
5005 c3 * (1. - tk / tf) + alog10(eis)
5010 ! Now sat vap pres obtained compute local vapor pressure
5012 ew = MAX ( ew , 0. ) * rh(i,k,j) * 0.01
5014 ! Now compute the specific humidity using the partial vapor
5015 ! pressures of water vapor (ew) and dry air (p-ew). The
5016 ! constants assume that the pressure is in hPa, so we divide
5017 ! the pressures by 100.
5020 q1 = q1 / (q1 + mw_air * (p(i,k,j)/100. - ew))
5022 q(i,k,j) = q1 / (1. - q1 )
5031 ! For pressures above a defined level, reasonable Qv values should be
5032 ! a certain value or smaller. If they are larger than this, the input data
5033 ! probably had "missing" RH, and we filled in some values. This is an
5034 ! attempt to catch those. Also, set the minimum value for the entire
5035 ! domain that is above the selected pressure level.
5037 DO j = jts , MIN ( jde-1 , jte )
5039 DO i = its , MIN (ide-1 , ite )
5040 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5041 IF ( p(i,k,j) .LT. qv_max_p_safe ) THEN
5042 IF ( q(i,k,j) .GT. qv_max_flag ) THEN
5043 q(i,k,j) = qv_max_value
5046 IF ( p(i,k,j) .LT. qv_min_p_safe ) THEN
5047 IF ( q(i,k,j) .LT. qv_min_flag ) THEN
5048 q(i,k,j) = qv_min_value
5055 END SUBROUTINE rh_to_mxrat1
5057 !---------------------------------------------------------------------
5059 SUBROUTINE compute_eta ( znw , &
5060 eta_levels , max_eta , max_dz , &
5061 p_top , g , p00 , cvpm , a , r_d , cp , t00 , p1000mb , t0 , tiso , &
5062 ids , ide , jds , jde , kds , kde , &
5063 ims , ime , jms , jme , kms , kme , &
5064 its , ite , jts , jte , kts , kte )
5066 ! Compute eta levels, either using given values from the namelist (hardly
5067 ! a computation, yep, I know), or assuming a constant dz above the PBL,
5068 ! knowing p_top and the number of eta levels.
5072 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
5073 ims , ime , jms , jme , kms , kme , &
5074 its , ite , jts , jte , kts , kte
5075 REAL , INTENT(IN) :: max_dz
5076 REAL , INTENT(IN) :: p_top , g , p00 , cvpm , a , r_d , cp , t00 , p1000mb , t0 , tiso
5077 INTEGER , INTENT(IN) :: max_eta
5078 REAL , DIMENSION (max_eta) , INTENT(IN) :: eta_levels
5080 REAL , DIMENSION (kts:kte) , INTENT(OUT) :: znw
5085 REAL :: mub , t_init , p_surf , pb, ztop, ztop_pbl , dz , temp
5086 REAL , DIMENSION(kts:kte) :: dnw
5088 INTEGER , PARAMETER :: prac_levels = 17
5089 INTEGER :: loop , loop1
5090 REAL , DIMENSION(prac_levels) :: znw_prac , znu_prac , dnw_prac
5091 REAL , DIMENSION(kts:kte) :: alb , phb
5093 ! Gee, do the eta levels come in from the namelist?
5095 IF ( ABS(eta_levels(1)+1.) .GT. 0.0000001 ) THEN
5097 ! Check to see if the array is oriented OK, we can easily fix an upside down oops.
5099 IF ( ( ABS(eta_levels(1 )-1.) .LT. 0.0000001 ) .AND. &
5100 ( ABS(eta_levels(kde)-0.) .LT. 0.0000001 ) ) THEN
5101 DO k = kds+1 , kde-1
5102 znw(k) = eta_levels(k)
5106 ELSE IF ( ( ABS(eta_levels(kde)-1.) .LT. 0.0000001 ) .AND. &
5107 ( ABS(eta_levels(1 )-0.) .LT. 0.0000001 ) ) THEN
5108 DO k = kds+1 , kde-1
5109 znw(k) = eta_levels(kde+1-k)
5114 CALL wrf_error_fatal ( 'First eta level should be 1.0 and the last 0.0 in namelist' )
5117 ! Check to see if the input full-level eta array is monotonic.
5120 IF ( znw(k) .LE. znw(k+1) ) THEN
5121 PRINT *,'eta on full levels is not monotonic'
5122 PRINT *,'eta (',k,') = ',znw(k)
5123 PRINT *,'eta (',k+1,') = ',znw(k+1)
5124 CALL wrf_error_fatal ( 'Fix non-monotonic "eta_levels" in the namelist.input file' )
5128 ! Compute eta levels assuming a constant delta z above the PBL.
5132 ! Compute top of the atmosphere with some silly levels. We just want to
5133 ! integrate to get a reasonable value for ztop. We use the planned PBL-esque
5134 ! levels, and then just coarse resolution above that. We know p_top, and we
5135 ! have the base state vars.
5139 znw_prac = (/ 1.000 , 0.993 , 0.983 , 0.970 , 0.954 , 0.934 , 0.909 , &
5140 0.88 , 0.8 , 0.7 , 0.6 , 0.5 , 0.4 , 0.3 , 0.2 , 0.1 , 0.0 /)
5142 DO k = 1 , prac_levels - 1
5143 znu_prac(k) = ( znw_prac(k) + znw_prac(k+1) ) * 0.5
5144 dnw_prac(k) = znw_prac(k+1) - znw_prac(k)
5147 DO k = 1, prac_levels-1
5148 pb = znu_prac(k)*(p_surf - p_top) + p_top
5149 temp = MAX ( tiso, t00 + A*LOG(pb/p00) )
5150 ! temp = t00 + A*LOG(pb/p00)
5151 t_init = temp*(p00/pb)**(r_d/cp) - t0
5152 alb(k) = (r_d/p1000mb)*(t_init+t0)*(pb/p1000mb)**cvpm
5155 ! Base state mu is defined as base state surface pressure minus p_top
5157 mub = p_surf - p_top
5159 ! Integrate base geopotential, starting at terrain elevation.
5162 DO k = 2,prac_levels
5163 phb(k) = phb(k-1) - dnw_prac(k-1)*mub*alb(k-1)
5166 ! So, now we know the model top in meters. Get the average depth above the PBL
5167 ! of each of the remaining levels. We are going for a constant delta z thickness.
5169 ztop = phb(prac_levels) / g
5170 ztop_pbl = phb(8 ) / g
5171 dz = ( ztop - ztop_pbl ) / REAL ( kde - 8 )
5173 ! Standard levels near the surface so no one gets in trouble.
5176 znw(k) = znw_prac(k)
5179 ! Using d phb(k)/ d eta(k) = -mub * alb(k), eqn 2.9
5180 ! Skamarock et al, NCAR TN 468. Use full levels, so
5181 ! use twice the thickness.
5184 pb = znw(k) * (p_surf - p_top) + p_top
5185 temp = MAX ( tiso, t00 + A*LOG(pb/p00) )
5186 ! temp = t00 + A*LOG(pb/p00)
5187 t_init = temp*(p00/pb)**(r_d/cp) - t0
5188 alb(k) = (r_d/p1000mb)*(t_init+t0)*(pb/p1000mb)**cvpm
5189 znw(k+1) = znw(k) - dz*g / ( mub*alb(k) )
5193 ! There is some iteration. We want the top level, ztop, to be
5194 ! consistent with the delta z, and we want the half level values
5195 ! to be consistent with the eta levels. The inner loop to 10 gets
5196 ! the eta levels very accurately, but has a residual at the top, due
5197 ! to dz changing. We reset dz five times, and then things seem OK.
5202 pb = (znw(k)+znw(k+1))*0.5 * (p_surf - p_top) + p_top
5203 temp = MAX ( tiso, t00 + A*LOG(pb/p00) )
5204 ! temp = t00 + A*LOG(pb/p00)
5205 t_init = temp*(p00/pb)**(r_d/cp) - t0
5206 alb(k) = (r_d/p1000mb)*(t_init+t0)*(pb/p1000mb)**cvpm
5207 znw(k+1) = znw(k) - dz*g / ( mub*alb(k) )
5209 IF ( ( loop1 .EQ. 5 ) .AND. ( loop .EQ. 10 ) ) THEN
5210 print *,'Converged znw(kte) should be about 0.0 = ',znw(kte-2)
5215 ! Here is where we check the eta levels values we just computed.
5218 pb = (znw(k)+znw(k+1))*0.5 * (p_surf - p_top) + p_top
5219 temp = MAX ( tiso, t00 + A*LOG(pb/p00) )
5220 ! temp = t00 + A*LOG(pb/p00)
5221 t_init = temp*(p00/pb)**(r_d/cp) - t0
5222 alb(k) = (r_d/p1000mb)*(t_init+t0)*(pb/p1000mb)**cvpm
5227 phb(k) = phb(k-1) - (znw(k)-znw(k-1)) * mub*alb(k-1)
5230 ! Reset the model top and the dz, and iterate.
5234 dz = ( ztop - ztop_pbl ) / REAL ( (kde-2) - 8 )
5237 IF ( dz .GT. max_dz ) THEN
5238 print *,'z (m) = ',phb(1)/g
5240 print *,'z (m) and dz (m) = ',phb(k)/g,(phb(k)-phb(k-1))/g
5242 print *,'dz (m) above fixed eta levels = ',dz
5243 print *,'namelist max_dz (m) = ',max_dz
5244 print *,'namelist p_top (Pa) = ',p_top
5245 CALL wrf_debug ( 0, 'You need one of three things:' )
5246 CALL wrf_debug ( 0, '1) More eta levels to reduce the dz: e_vert' )
5247 CALL wrf_debug ( 0, '2) A lower p_top so your total height is reduced: p_top_requested')
5248 CALL wrf_debug ( 0, '3) Increase the maximum allowable eta thickness: max_dz')
5249 CALL wrf_debug ( 0, 'All are namelist options')
5250 CALL wrf_error_fatal ( 'dz above fixed eta levels is too large')
5253 ! Add those 2 levels back into the middle, just above the 8 levels
5254 ! that semi define a boundary layer. After we open up the levels,
5255 ! then we just linearly interpolate in znw. So now levels 1-8 are
5256 ! specified as the fixed boundary layer levels given in this routine.
5257 ! The top levels, 12 through kte are those computed. The middle
5258 ! levels 9, 10, and 11 are equi-spaced in znw, and are each 1/2 the
5259 ! the znw thickness of levels 11 through 12.
5261 DO k = kte-2 , 9 , -1
5265 znw( 9) = 0.75 * znw( 8) + 0.25 * znw(12)
5266 znw(10) = 0.50 * znw( 8) + 0.50 * znw(12)
5267 znw(11) = 0.25 * znw( 8) + 0.75 * znw(12)
5271 END SUBROUTINE compute_eta
5273 !---------------------------------------------------------------------
5275 SUBROUTINE monthly_min_max ( field_in , field_min , field_max , &
5276 ids , ide , jds , jde , kds , kde , &
5277 ims , ime , jms , jme , kms , kme , &
5278 its , ite , jts , jte , kts , kte )
5280 ! Plow through each month, find the max, min values for each i,j.
5284 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
5285 ims , ime , jms , jme , kms , kme , &
5286 its , ite , jts , jte , kts , kte
5288 REAL , DIMENSION(ims:ime,12,jms:jme) , INTENT(IN) :: field_in
5289 REAL , DIMENSION(ims:ime, jms:jme) , INTENT(OUT) :: field_min , field_max
5293 INTEGER :: i , j , l
5294 REAL :: minner , maxxer
5296 DO j = jts , MIN(jde-1,jte)
5297 DO i = its , MIN(ide-1,ite)
5298 minner = field_in(i,1,j)
5299 maxxer = field_in(i,1,j)
5301 IF ( field_in(i,l,j) .LT. minner ) THEN
5302 minner = field_in(i,l,j)
5304 IF ( field_in(i,l,j) .GT. maxxer ) THEN
5305 maxxer = field_in(i,l,j)
5308 field_min(i,j) = minner
5309 field_max(i,j) = maxxer
5313 END SUBROUTINE monthly_min_max
5315 !---------------------------------------------------------------------
5317 SUBROUTINE monthly_interp_to_date ( field_in , date_str , field_out , &
5318 ids , ide , jds , jde , kds , kde , &
5319 ims , ime , jms , jme , kms , kme , &
5320 its , ite , jts , jte , kts , kte )
5322 ! Linrarly in time interpolate data to a current valid time. The data is
5323 ! assumed to come in "monthly", valid at the 15th of every month.
5327 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
5328 ims , ime , jms , jme , kms , kme , &
5329 its , ite , jts , jte , kts , kte
5331 CHARACTER (LEN=24) , INTENT(IN) :: date_str
5332 REAL , DIMENSION(ims:ime,12,jms:jme) , INTENT(IN) :: field_in
5333 REAL , DIMENSION(ims:ime, jms:jme) , INTENT(OUT) :: field_out
5337 INTEGER :: i , j , l
5338 INTEGER , DIMENSION(0:13) :: middle
5339 INTEGER :: target_julyr , target_julday , target_date
5340 INTEGER :: julyr , julday , int_month , month1 , month2
5342 CHARACTER (LEN=4) :: yr
5343 CHARACTER (LEN=2) :: mon , day15
5346 WRITE(day15,FMT='(I2.2)') 15
5348 WRITE(mon,FMT='(I2.2)') l
5349 CALL get_julgmt ( date_str(1:4)//'-'//mon//'-'//day15//'_'//'00:00:00.0000' , julyr , julday , gmt )
5350 middle(l) = julyr*1000 + julday
5354 middle(l) = middle( 1) - 31
5357 middle(l) = middle(12) + 31
5359 CALL get_julgmt ( date_str , target_julyr , target_julday , gmt )
5360 target_date = target_julyr * 1000 + target_julday
5361 find_month : DO l = 0 , 12
5362 IF ( ( middle(l) .LT. target_date ) .AND. ( middle(l+1) .GE. target_date ) ) THEN
5363 DO j = jts , MIN ( jde-1 , jte )
5364 DO i = its , MIN (ide-1 , ite )
5365 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5367 IF ( ( int_month .EQ. 0 ) .OR. ( int_month .EQ. 12 ) ) THEN
5374 field_out(i,j) = ( field_in(i,month2,j) * ( target_date - middle(l) ) + &
5375 field_in(i,month1,j) * ( middle(l+1) - target_date ) ) / &
5376 ( middle(l+1) - middle(l) )
5383 END SUBROUTINE monthly_interp_to_date
5385 !---------------------------------------------------------------------
5387 SUBROUTINE sfcprs (t, q, height, pslv, ter, avgsfct, p, &
5389 ids , ide , jds , jde , kds , kde , &
5390 ims , ime , jms , jme , kms , kme , &
5391 its , ite , jts , jte , kts , kte )
5394 ! Computes the surface pressure using the input height,
5395 ! temperature and q (already computed from relative
5396 ! humidity) on p surfaces. Sea level pressure is used
5397 ! to extrapolate a first guess.
5401 REAL, PARAMETER :: gamma = 6.5E-3
5402 REAL, PARAMETER :: pconst = 10000.0
5403 REAL, PARAMETER :: Rd = r_d
5404 REAL, PARAMETER :: TC = svpt0 + 17.5
5406 REAL, PARAMETER :: gammarg = gamma * Rd / g
5407 REAL, PARAMETER :: rov2 = Rd / 2.
5409 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
5410 ims , ime , jms , jme , kms , kme , &
5411 its , ite , jts , jte , kts , kte
5412 LOGICAL , INTENT ( IN ) :: ez_method
5414 REAL , DIMENSION (ims:ime,kms:kme,jms:jme) , INTENT(IN ):: t, q, height, p
5415 REAL , DIMENSION (ims:ime, jms:jme) , INTENT(IN ):: pslv , ter, avgsfct
5416 REAL , DIMENSION (ims:ime, jms:jme) , INTENT(OUT):: psfc
5421 INTEGER , DIMENSION (its:ite,jts:jte) :: k500 , k700 , k850
5428 REAL :: gamma78 ( its:ite,jts:jte )
5429 REAL :: gamma57 ( its:ite,jts:jte )
5430 REAL :: ht ( its:ite,jts:jte )
5431 REAL :: p1 ( its:ite,jts:jte )
5432 REAL :: t1 ( its:ite,jts:jte )
5433 REAL :: t500 ( its:ite,jts:jte )
5434 REAL :: t700 ( its:ite,jts:jte )
5435 REAL :: t850 ( its:ite,jts:jte )
5436 REAL :: tfixed ( its:ite,jts:jte )
5437 REAL :: tsfc ( its:ite,jts:jte )
5438 REAL :: tslv ( its:ite,jts:jte )
5440 ! We either compute the surface pressure from a time averaged surface temperature
5441 ! (what we will call the "easy way"), or we try to remove the diurnal impact on the
5442 ! surface temperature (what we will call the "other way"). Both are essentially
5443 ! corrections to a sea level pressure with a high-resolution topography field.
5445 IF ( ez_method ) THEN
5447 DO j = jts , MIN(jde-1,jte)
5448 DO i = its , MIN(ide-1,ite)
5449 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5450 psfc(i,j) = pslv(i,j) * ( 1.0 + gamma * ter(i,j) / avgsfct(i,j) ) ** ( - g / ( Rd * gamma ) )
5456 ! Find the locations of the 850, 700 and 500 mb levels.
5458 k850 = 0 ! find k at: P=850
5465 IF (NINT(p(i,k,j)) .EQ. 85000) THEN
5467 ELSE IF (NINT(p(i,k,j)) .EQ. 70000) THEN
5469 ELSE IF (NINT(p(i,k,j)) .EQ. 50000) THEN
5474 IF ( ( k850(i,j) .EQ. 0 ) .OR. ( k700(i,j) .EQ. 0 ) .OR. ( k500(i,j) .EQ. 0 ) ) THEN
5476 DO j = jts , MIN(jde-1,jte)
5477 DO i = its , MIN(ide-1,ite)
5478 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5479 psfc(i,j) = pslv(i,j) * ( 1.0 + gamma * ter(i,j) / t(i,1,j) ) ** ( - g / ( Rd * gamma ) )
5486 ! Possibly it is just that we have a generalized vertical coord, so we do not
5487 ! have the values exactly. Do a simple assignment to a close vertical level.
5489 DO j = jts , MIN(jde-1,jte)
5490 DO i = its , MIN(ide-1,ite)
5491 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5492 DO k = kts+1 , kte-1
5493 IF ( ( p(i,k,j) - 85000. ) * ( p(i,k+1,j) - 85000. ) .LE. 0.0 ) THEN
5496 IF ( ( p(i,k,j) - 70000. ) * ( p(i,k+1,j) - 70000. ) .LE. 0.0 ) THEN
5499 IF ( ( p(i,k,j) - 50000. ) * ( p(i,k+1,j) - 50000. ) .LE. 0.0 ) THEN
5506 ! If we *still* do not have the k levels, punt. I mean, we did try.
5509 DO j = jts , MIN(jde-1,jte)
5510 DO i = its , MIN(ide-1,ite)
5511 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5512 IF ( ( k850(i,j) .EQ. 0 ) .OR. ( k700(i,j) .EQ. 0 ) .OR. ( k500(i,j) .EQ. 0 ) ) THEN
5514 PRINT '(A)','(i,j) = ',i,j,' Error in finding p level for 850, 700 or 500 hPa.'
5516 PRINT '(A,I3,A,F10.2,A)','K = ',k,' PRESSURE = ',p(i,k,j),' Pa'
5518 PRINT '(A)','Expected 850, 700, and 500 mb values, at least.'
5522 IF ( .NOT. OK ) THEN
5523 CALL wrf_error_fatal ( 'wrong pressure levels' )
5527 ! We are here if the data is isobaric and we found the levels for 850, 700,
5528 ! and 500 mb right off the bat.
5531 DO j = jts , MIN(jde-1,jte)
5532 DO i = its , MIN(ide-1,ite)
5533 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5534 k850(i,j) = k850(its,jts)
5535 k700(i,j) = k700(its,jts)
5536 k500(i,j) = k500(its,jts)
5541 ! The 850 hPa level of geopotential height is called something special.
5543 DO j = jts , MIN(jde-1,jte)
5544 DO i = its , MIN(ide-1,ite)
5545 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5546 ht(i,j) = height(i,k850(i,j),j)
5550 ! The variable ht is now -ter/ht(850 hPa). The plot thickens.
5552 DO j = jts , MIN(jde-1,jte)
5553 DO i = its , MIN(ide-1,ite)
5554 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5555 ht(i,j) = -ter(i,j) / ht(i,j)
5559 ! Make an isothermal assumption to get a first guess at the surface
5560 ! pressure. This is to tell us which levels to use for the lapse
5563 DO j = jts , MIN(jde-1,jte)
5564 DO i = its , MIN(ide-1,ite)
5565 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5566 psfc(i,j) = pslv(i,j) * (pslv(i,j) / p(i,k850(i,j),j)) ** ht(i,j)
5570 ! Get a pressure more than pconst Pa above the surface - p1. The
5571 ! p1 is the top of the level that we will use for our lapse rate
5574 DO j = jts , MIN(jde-1,jte)
5575 DO i = its , MIN(ide-1,ite)
5576 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5577 IF ( ( psfc(i,j) - 95000. ) .GE. 0. ) THEN
5579 ELSE IF ( ( psfc(i,j) - 70000. ) .GE. 0. ) THEN
5580 p1(i,j) = psfc(i,j) - pconst
5587 ! Compute virtual temperatures for k850, k700, and k500 layers. Now
5588 ! you see why we wanted Q on pressure levels, it all is beginning
5591 DO j = jts , MIN(jde-1,jte)
5592 DO i = its , MIN(ide-1,ite)
5593 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5594 t850(i,j) = t(i,k850(i,j),j) * (1. + 0.608 * q(i,k850(i,j),j))
5595 t700(i,j) = t(i,k700(i,j),j) * (1. + 0.608 * q(i,k700(i,j),j))
5596 t500(i,j) = t(i,k500(i,j),j) * (1. + 0.608 * q(i,k500(i,j),j))
5600 ! Compute lapse rates between these three levels. These are
5601 ! environmental values for each (i,j).
5603 DO j = jts , MIN(jde-1,jte)
5604 DO i = its , MIN(ide-1,ite)
5605 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5606 gamma78(i,j) = ALOG(t850(i,j) / t700(i,j)) / ALOG (p(i,k850(i,j),j) / p(i,k700(i,j),j) )
5607 gamma57(i,j) = ALOG(t700(i,j) / t500(i,j)) / ALOG (p(i,k700(i,j),j) / p(i,k500(i,j),j) )
5611 DO j = jts , MIN(jde-1,jte)
5612 DO i = its , MIN(ide-1,ite)
5613 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5614 IF ( ( psfc(i,j) - 95000. ) .GE. 0. ) THEN
5616 ELSE IF ( ( psfc(i,j) - 85000. ) .GE. 0. ) THEN
5617 t1(i,j) = t700(i,j) * (p1(i,j) / (p(i,k700(i,j),j))) ** gamma78(i,j)
5618 ELSE IF ( ( psfc(i,j) - 70000. ) .GE. 0.) THEN
5619 t1(i,j) = t500(i,j) * (p1(i,j) / (p(i,k500(i,j),j))) ** gamma57(i,j)
5626 ! From our temperature way up in the air, we extrapolate down to
5627 ! the sea level to get a guess at the sea level temperature.
5629 DO j = jts , MIN(jde-1,jte)
5630 DO i = its , MIN(ide-1,ite)
5631 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5632 tslv(i,j) = t1(i,j) * (pslv(i,j) / p1(i,j)) ** gammarg
5636 ! The new surface temperature is computed from the with new sea level
5637 ! temperature, just using the elevation and a lapse rate. This lapse
5638 ! rate is -6.5 K/km.
5640 DO j = jts , MIN(jde-1,jte)
5641 DO i = its , MIN(ide-1,ite)
5642 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5643 tsfc(i,j) = tslv(i,j) - gamma * ter(i,j)
5647 ! A small correction to the sea-level temperature, in case it is too warm.
5649 DO j = jts , MIN(jde-1,jte)
5650 DO i = its , MIN(ide-1,ite)
5651 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5652 tfixed(i,j) = tc - 0.005 * (tsfc(i,j) - tc) ** 2
5656 DO j = jts , MIN(jde-1,jte)
5657 DO i = its , MIN(ide-1,ite)
5658 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5659 l1 = tslv(i,j) .LT. tc
5660 l2 = tsfc(i,j) .LE. tc
5662 IF ( l2 .AND. l3 ) THEN
5664 ELSE IF ( ( .NOT. l2 ) .AND. l3 ) THEN
5665 tslv(i,j) = tfixed(i,j)
5670 ! Finally, we can get to the surface pressure.
5672 DO j = jts , MIN(jde-1,jte)
5673 DO i = its , MIN(ide-1,ite)
5674 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5675 p1(i,j) = - ter(i,j) * g / ( rov2 * ( tsfc(i,j) + tslv(i,j) ) )
5676 psfc(i,j) = pslv(i,j) * EXP ( p1(i,j) )
5682 ! Surface pressure and sea-level pressure are the same at sea level.
5684 ! DO j = jts , MIN(jde-1,jte)
5685 ! DO i = its , MIN(ide-1,ite)
5686 ! IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5687 ! IF ( ABS ( ter(i,j) ) .LT. 0.1 ) THEN
5688 ! psfc(i,j) = pslv(i,j)
5693 END SUBROUTINE sfcprs
5695 !---------------------------------------------------------------------
5697 SUBROUTINE sfcprs2(t, q, height, psfc_in, ter, avgsfct, p, &
5699 ids , ide , jds , jde , kds , kde , &
5700 ims , ime , jms , jme , kms , kme , &
5701 its , ite , jts , jte , kts , kte )
5704 ! Computes the surface pressure using the input height,
5705 ! temperature and q (already computed from relative
5706 ! humidity) on p surfaces. Sea level pressure is used
5707 ! to extrapolate a first guess.
5711 REAL, PARAMETER :: Rd = r_d
5713 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
5714 ims , ime , jms , jme , kms , kme , &
5715 its , ite , jts , jte , kts , kte
5716 LOGICAL , INTENT ( IN ) :: ez_method
5718 REAL , DIMENSION (ims:ime,kms:kme,jms:jme) , INTENT(IN ):: t, q, height, p
5719 REAL , DIMENSION (ims:ime, jms:jme) , INTENT(IN ):: psfc_in , ter, avgsfct
5720 REAL , DIMENSION (ims:ime, jms:jme) , INTENT(OUT):: psfc
5726 REAL :: tv_sfc_avg , tv_sfc , del_z
5728 ! Compute the new surface pressure from the old surface pressure, and a
5729 ! known change in elevation at the surface.
5731 ! del_z = diff in surface topo, lo-res vs hi-res
5732 ! psfc = psfc_in * exp ( g del_z / (Rd Tv_sfc ) )
5735 IF ( ez_method ) THEN
5736 DO j = jts , MIN(jde-1,jte)
5737 DO i = its , MIN(ide-1,ite)
5738 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5739 tv_sfc_avg = avgsfct(i,j) * (1. + 0.608 * q(i,1,j))
5740 del_z = height(i,1,j) - ter(i,j)
5741 psfc(i,j) = psfc_in(i,j) * EXP ( g * del_z / ( Rd * tv_sfc_avg ) )
5745 DO j = jts , MIN(jde-1,jte)
5746 DO i = its , MIN(ide-1,ite)
5747 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5748 tv_sfc = t(i,1,j) * (1. + 0.608 * q(i,1,j))
5749 del_z = height(i,1,j) - ter(i,j)
5750 psfc(i,j) = psfc_in(i,j) * EXP ( g * del_z / ( Rd * tv_sfc ) )
5755 END SUBROUTINE sfcprs2
5757 !---------------------------------------------------------------------
5759 SUBROUTINE sfcprs3( height , p , ter , slp , psfc , &
5760 ids , ide , jds , jde , kds , kde , &
5761 ims , ime , jms , jme , kms , kme , &
5762 its , ite , jts , jte , kts , kte )
5764 ! Computes the surface pressure by vertically interpolating
5765 ! linearly (or log) in z the pressure, to the targeted topography.
5769 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
5770 ims , ime , jms , jme , kms , kme , &
5771 its , ite , jts , jte , kts , kte
5773 REAL , DIMENSION (ims:ime,kms:kme,jms:jme) , INTENT(IN ):: height, p
5774 REAL , DIMENSION (ims:ime, jms:jme) , INTENT(IN ):: ter , slp
5775 REAL , DIMENSION (ims:ime, jms:jme) , INTENT(OUT):: psfc
5781 LOGICAL :: found_loc
5783 REAL :: zl , zu , pl , pu , zm
5785 ! Loop over each grid point
5787 DO j = jts , MIN(jde-1,jte)
5788 DO i = its , MIN(ide-1,ite)
5789 IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
5791 ! Special case where near the ocean level. Assume that the SLP is a good value.
5793 IF ( ter(i,j) .LT. 50 ) THEN
5794 psfc(i,j) = slp(i,j) + ( p(i,2,j)-p(i,3,j) ) / ( height(i,2,j)-height(i,3,j) ) * ter(i,j)
5798 ! Find the trapping levels
5802 ! Normal sort of scenario - the model topography is somewhere between
5803 ! the height values of 1000 mb and the top of the model.
5805 found_k_loc : DO k = kts+1 , kte-2
5806 IF ( ( height(i,k ,j) .LE. ter(i,j) ) .AND. &
5807 ( height(i,k+1,j) .GT. ter(i,j) ) ) THEN
5809 zu = height(i,k+1,j)
5813 psfc(i,j) = EXP ( ( LOG(pl) * ( zm - zu ) + LOG(pu) * ( zl - zm ) ) / ( zl - zu ) )
5819 ! Interpolate betwixt slp and the first isobaric level above - this is probably the
5820 ! usual thing over the ocean.
5822 IF ( .NOT. found_loc ) THEN
5823 IF ( slp(i,j) .GE. p(i,2,j) ) THEN
5829 psfc(i,j) = EXP ( ( LOG(pl) * ( zm - zu ) + LOG(pu) * ( zl - zm ) ) / ( zl - zu ) )
5832 found_slp_loc : DO k = kts+1 , kte-3
5833 IF ( ( slp(i,j) .GE. p(i,k+1,j) ) .AND. &
5834 ( slp(i,j) .LT. p(i,k ,j) ) ) THEN
5836 zu = height(i,k+1,j)
5840 psfc(i,j) = EXP ( ( LOG(pl) * ( zm - zu ) + LOG(pu) * ( zl - zm ) ) / ( zl - zu ) )
5844 END DO found_slp_loc
5848 ! Did we do what we wanted done.
5850 IF ( .NOT. found_loc ) THEN
5851 print *,'i,j = ',i,j
5852 print *,'p column = ',p(i,2:,j)
5853 print *,'z column = ',height(i,2:,j)
5854 print *,'model topo = ',ter(i,j)
5855 CALL wrf_error_fatal ( ' probs with sfc p computation ' )
5861 END SUBROUTINE sfcprs3
5862 !---------------------------------------------------------------------
5864 SUBROUTINE filter_topo ( ht_in , xlat , msftx , fft_filter_lat , &
5865 ids , ide , jds , jde , kds , kde , &
5866 ims , ime , jms , jme , kms , kme , &
5867 its , ite , jts , jte , kts , kte )
5871 INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
5872 ims , ime , jms , jme , kms , kme , &
5873 its , ite , jts , jte , kts , kte
5875 REAL , INTENT(IN) :: fft_filter_lat
5876 REAL , DIMENSION(ims:ime,jms:jme) , INTENT(INOUT) :: ht_in
5877 REAL , DIMENSION(ims:ime,jms:jme) , INTENT(IN) :: xlat , msftx
5882 INTEGER :: i , j , j_lat_pos , j_lat_neg
5883 INTEGER :: i_kicker , ik , i1, i2, i3, i4
5884 REAL :: length_scale , sum
5885 REAL , DIMENSION(its:ite,jts:jte) :: ht_out
5887 ! The filtering is a simple average on a latitude loop. Possibly a LONG list of
5888 ! numbers. We assume that ALL of the 2d arrays have been transposed so that
5889 ! each patch has the entire domain size of the i-dim local.
5891 IF ( ( its .NE. ids ) .OR. ( ite .NE. ide ) ) THEN
5892 CALL wrf_error_fatal ( 'filtering assumes all values on X' )
5895 ! Starting at the south pole, we find where the
5896 ! grid distance is big enough, then go back a point. Continuing to the
5897 ! north pole, we find the first small grid distance. These are the
5898 ! computational latitude loops and the associated computational poles.
5902 loop_neg : DO j = jts , MIN(jde-1,jte)
5903 IF ( xlat(its,j) .LT. 0.0 ) THEN
5904 IF ( ABS(xlat(its,j)) .LT. fft_filter_lat ) THEN
5911 loop_pos : DO j = jts , MIN(jde-1,jte)
5912 IF ( xlat(its,j) .GT. 0.0 ) THEN
5913 IF ( xlat(its,j) .GE. fft_filter_lat ) THEN
5920 ! Set output values to initial input topo values for whole patch.
5922 DO j = jts , MIN(jde-1,jte)
5923 DO i = its , MIN(ide-1,ite)
5924 ht_out(i,j) = ht_in(i,j)
5928 ! Filter the topo at the negative lats.
5930 DO j = j_lat_neg , jts , -1
5931 i_kicker = MIN( MAX ( NINT(msftx(its,j)) , 1 ) , (ide - ids) / 2 )
5932 print *,'j = ' , j, ', kicker = ',i_kicker
5933 DO i = its , MIN(ide-1,ite)
5934 IF ( ( i - i_kicker .GE. its ) .AND. ( i + i_kicker .LE. ide-1 ) ) THEN
5936 DO ik = 1 , i_kicker
5937 sum = sum + ht_in(i+ik,j) + ht_in(i-ik,j)
5939 ht_out(i,j) = ( ht_in(i,j) + sum ) / REAL ( 2 * i_kicker + 1 )
5940 ELSE IF ( ( i - i_kicker .LT. its ) .AND. ( i + i_kicker .LE. ide-1 ) ) THEN
5942 DO ik = 1 , i_kicker
5943 sum = sum + ht_in(i+ik,j)
5945 i1 = i - i_kicker + ide -1
5950 sum = sum + ht_in(ik,j)
5953 sum = sum + ht_in(ik,j)
5955 ht_out(i,j) = ( ht_in(i,j) + sum ) / REAL ( 2 * i_kicker + 1 )
5956 ELSE IF ( ( i - i_kicker .GE. its ) .AND. ( i + i_kicker .GT. ide-1 ) ) THEN
5958 DO ik = 1 , i_kicker
5959 sum = sum + ht_in(i-ik,j)
5964 i4 = ids + ( i_kicker+i ) - ide
5966 sum = sum + ht_in(ik,j)
5969 sum = sum + ht_in(ik,j)
5971 ht_out(i,j) = ( ht_in(i,j) + sum ) / REAL ( 2 * i_kicker + 1 )
5976 ! Filter the topo at the positive lats.
5978 DO j = j_lat_pos , MIN(jde-1,jte)
5979 i_kicker = MIN( MAX ( NINT(msftx(its,j)) , 1 ) , (ide - ids) / 2 )
5980 print *,'j = ' , j, ', kicker = ',i_kicker
5981 DO i = its , MIN(ide-1,ite)
5982 IF ( ( i - i_kicker .GE. its ) .AND. ( i + i_kicker .LE. ide-1 ) ) THEN
5984 DO ik = 1 , i_kicker
5985 sum = sum + ht_in(i+ik,j) + ht_in(i-ik,j)
5987 ht_out(i,j) = ( ht_in(i,j) + sum ) / REAL ( 2 * i_kicker + 1 )
5988 ELSE IF ( ( i - i_kicker .LT. its ) .AND. ( i + i_kicker .LE. ide-1 ) ) THEN
5990 DO ik = 1 , i_kicker
5991 sum = sum + ht_in(i+ik,j)
5993 i1 = i - i_kicker + ide -1
5998 sum = sum + ht_in(ik,j)
6001 sum = sum + ht_in(ik,j)
6003 ht_out(i,j) = ( ht_in(i,j) + sum ) / REAL ( 2 * i_kicker + 1 )
6004 ELSE IF ( ( i - i_kicker .GE. its ) .AND. ( i + i_kicker .GT. ide-1 ) ) THEN
6006 DO ik = 1 , i_kicker
6007 sum = sum + ht_in(i-ik,j)
6012 i4 = ids + ( i_kicker+i ) - ide
6014 sum = sum + ht_in(ik,j)
6017 sum = sum + ht_in(ik,j)
6019 ht_out(i,j) = ( ht_in(i,j) + sum ) / REAL ( 2 * i_kicker + 1 )
6024 ! Set output values to initial input topo values for whole patch.
6026 DO j = jts , MIN(jde-1,jte)
6027 DO i = its , MIN(ide-1,ite)
6028 ht_in(i,j) = ht_out(i,j)
6032 END SUBROUTINE filter_topo
6034 !---------------------------------------------------------------------
6036 SUBROUTINE init_module_initialize
6037 END SUBROUTINE init_module_initialize
6039 !---------------------------------------------------------------------
6041 END MODULE module_initialize_real