2 !WRF:MODEL_LAYER:DYNAMICS
4 #if ( defined(ADVECT_KERNEL) )
5 ! cpp -traditional-cpp -P -DADVECT_KERNEL module_advect_em.F > advection_kernel.f90
6 ! gfortran -ffree-form -ffree-line-length-none advection_kernel.f90
8 MODULE advection_kernel
9 TYPE grid_config_rec_type
10 INTEGER :: scalar_adv_opt = 0
11 INTEGER :: h_sca_adv_order = 5
12 INTEGER :: v_sca_adv_order = 3
13 LOGICAL :: periodic_x = .false.
14 LOGICAL :: periodic_y = .false.
15 LOGICAL :: symmetric_xs = .false.
16 LOGICAL :: symmetric_xe = .false.
17 LOGICAL :: symmetric_ys = .false.
18 LOGICAL :: symmetric_ye = .false.
19 LOGICAL :: open_xs = .false.
20 LOGICAL :: open_xe = .false.
21 LOGICAL :: open_ys = .false.
22 LOGICAL :: open_ye = .false.
23 LOGICAL :: specified = .true.
24 LOGICAL :: nested = .false.
25 LOGICAL :: polar = .false.
26 END TYPE grid_config_rec_type
27 CHARACTER (LEN=256) :: wrf_err_message
29 !----------------------------------------------------------------
30 SUBROUTINE wrf_error_fatal ( message )
32 CHARACTER(LEN=*) , INTENT(IN) :: message
33 PRINT *,'advect_scalar_pd: FATAL MESSAGE = ',TRIM(message)
35 END SUBROUTINE wrf_error_fatal
36 !----------------------------------------------------------------
37 SUBROUTINE init ( config_flags )
39 TYPE (grid_config_rec_type) :: config_flags
40 config_flags%h_sca_adv_order = 5
41 config_flags%v_sca_adv_order = 3
42 config_flags%periodic_x = .true.
43 config_flags%periodic_y = .true.
44 config_flags%symmetric_xs = .false.
45 config_flags%symmetric_xe = .false.
46 config_flags%symmetric_ys = .false.
47 config_flags%symmetric_ye = .false.
48 config_flags%open_xs = .false.
49 config_flags%open_xe = .false.
50 config_flags%open_ys = .false.
51 config_flags%open_ye = .false.
52 config_flags%specified = .false.
53 config_flags%nested = .false.
55 !----------------------------------------------------------------
56 SUBROUTINE tophat ( field, num_scalars , &
57 ids, ide, jds, jde, kds, kde, &
58 ims, ime, jms, jme, kms, kme, &
59 its, ite, jts, jte, kts, kte )
61 INTEGER , INTENT(IN ) :: num_scalars , ids, ide, jds, jde, kds, kde, &
62 ims, ime, jms, jme, kms, kme, &
63 its, ite, jts, jte, kts, kte
64 REAL , DIMENSION( ims:ime , kms:kme , jms:jme , num_scalars ) , INTENT(OUT) :: field
65 INTEGER :: i, j, k , n
69 DO n = 1 , num_scalars
73 IF ( i .gt. 35 .and. i.lt. 55 ) THEN
81 !----------------------------------------------------------------
82 SUBROUTINE column (loop , data_list, its,ite)
84 INTEGER , INTENT(IN) :: loop, its, ite
85 REAL , INTENT(IN) , DIMENSION(its:ite) :: data_list
86 INTEGER , DIMENSION(its:ite) :: data_int
88 CHARACTER (len = 10 ) :: filename
91 OPEN (unit=7,file = "x_locations.txt" , &
92 form = "formatted" , &
93 access = "sequential" )
101 WRITE(filename,fmt='(i6.6,".txt")') loop
102 OPEN (unit=7,file = filename , &
103 form = "formatted" , &
104 access = "sequential" )
106 data_int = NINT(data_list * 100 )
108 write (7,*) data_int(i)
112 END SUBROUTINE column
113 !----------------------------------------------------------------
114 #elif ( ! defined(ADVECT_KERNEL) )
116 MODULE module_advect_em
119 USE module_model_constants
124 !-------------------------------------------------------------------------------
126 SUBROUTINE advect_u ( u, u_old, tendency, &
129 mut, time_step, config_flags, &
130 msfux, msfuy, msfvx, msfvy, &
134 ids, ide, jds, jde, kds, kde, &
135 ims, ime, jms, jme, kms, kme, &
136 its, ite, jts, jte, kts, kte )
142 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
144 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
145 ims, ime, jms, jme, kms, kme, &
146 its, ite, jts, jte, kts, kte
148 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: u, &
154 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut
155 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
157 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
164 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
170 REAL , INTENT(IN ) :: rdx, &
172 INTEGER , INTENT(IN ) :: time_step
176 INTEGER :: i, j, k, itf, jtf, ktf
177 INTEGER :: i_start, i_end, j_start, j_end
178 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
179 INTEGER :: jmin, jmax, jp, jm, imin, imax, im, ip
180 INTEGER :: jp1, jp0, jtmp
182 INTEGER :: horz_order, vert_order
184 REAL :: mrdx, mrdy, ub, vb, uw, vw, dvm, dvp
185 REAL , DIMENSION(its:ite, kts:kte) :: vflux
188 REAL, DIMENSION( its-1:ite+1, kts:kte ) :: fqx
189 REAL, DIMENSION( its:ite, kts:kte, 2) :: fqy
191 LOGICAL :: degrade_xs, degrade_ys
192 LOGICAL :: degrade_xe, degrade_ye
194 ! definition of flux operators, 3rd, 4th, 5th or 6th order
196 REAL :: flux3, flux4, flux5, flux6
197 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel
199 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
200 ( 7.*(q_i + q_im1) - (q_ip1 + q_im2) )/12.0
202 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
203 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
204 sign(1,time_step)*sign(1.,ua)*((q_ip1 - q_im2)-3.*(q_i-q_im1))/12.0
206 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
207 ( 37.*(q_i+q_im1) - 8.*(q_ip1+q_im2) &
208 +(q_ip2+q_im3) )/60.0
210 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
211 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
212 -sign(1,time_step)*sign(1.,ua)*( &
213 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )/60.0
219 if(config_flags%specified .or. config_flags%nested) specified = .true.
221 ! set order for vertical and horzontal flux operators
223 horz_order = config_flags%h_mom_adv_order
224 vert_order = config_flags%v_mom_adv_order
228 ! begin with horizontal flux divergence
230 horizontal_order_test : IF( horz_order == 6 ) THEN
232 ! determine boundary mods for flux operators
233 ! We degrade the flux operators from 3rd/4th order
234 ! to second order one gridpoint in from the boundaries for
235 ! all boundary conditions except periodic and symmetry - these
236 ! conditions have boundary zone data fill for correct application
237 ! of the higher order flux stencils
244 IF( config_flags%periodic_x .or. &
245 config_flags%symmetric_xs .or. &
246 (its > ids+3) ) degrade_xs = .false.
247 IF( config_flags%periodic_x .or. &
248 config_flags%symmetric_xe .or. &
249 (ite < ide-2) ) degrade_xe = .false.
250 IF( config_flags%periodic_y .or. &
251 config_flags%symmetric_ys .or. &
252 (jts > jds+3) ) degrade_ys = .false.
253 IF( config_flags%periodic_y .or. &
254 config_flags%symmetric_ye .or. &
255 (jte < jde-4) ) degrade_ye = .false.
257 !--------------- y - advection first
261 IF ( config_flags%open_xs .or. specified ) i_start = MAX(ids+1,its)
262 IF ( config_flags%open_xe .or. specified ) i_end = MIN(ide-1,ite)
263 IF ( config_flags%periodic_x ) i_start = its
264 IF ( config_flags%periodic_x ) i_end = ite
267 j_end = MIN(jte,jde-1)
269 ! higher order flux has a 5 or 7 point stencil, so compute
270 ! bounds so we can switch to second order flux close to the boundary
276 j_start = MAX(jts,jds+1)
281 j_end = MIN(jte,jde-2)
285 IF(config_flags%polar) j_end = MIN(jte,jde-1)
287 ! compute fluxes, 5th or 6th order
292 j_loop_y_flux_6 : DO j = j_start, j_end+1
294 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN ! use full stencil
297 DO i = i_start, i_end
298 vel = 0.5*(rv(i,k,j)+rv(i-1,k,j))
299 fqy( i, k, jp1 ) = vel*flux6( &
300 u(i,k,j-3), u(i,k,j-2), u(i,k,j-1), &
301 u(i,k,j ), u(i,k,j+1), u(i,k,j+2), vel )
305 ! we must be close to some boundary where we need to reduce the order of the stencil
307 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
310 DO i = i_start, i_end
311 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i-1,k,j)) &
312 *(u(i,k,j)+u(i,k,j-1))
316 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
319 DO i = i_start, i_end
320 vel = 0.5*(rv(i,k,j)+rv(i-1,k,j))
321 fqy( i, k, jp1 ) = vel*flux4( &
322 u(i,k,j-2),u(i,k,j-1), u(i,k,j),u(i,k,j+1),vel )
326 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
329 DO i = i_start, i_end
330 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i-1,k,j)) &
331 *(u(i,k,j)+u(i,k,j-1))
335 ELSE IF ( j == jde-2 ) THEN ! 3rd order flux 2 in from north boundary
338 DO i = i_start, i_end
339 vel = 0.5*(rv(i,k,j)+rv(i-1,k,j))
340 fqy( i, k, jp1 ) = vel*flux4( &
341 u(i,k,j-2),u(i,k,j-1), &
342 u(i,k,j),u(i,k,j+1),vel )
348 ! y flux-divergence into tendency
350 ! (j > j_start) will miss the u(,,jds) tendency
351 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
353 DO i = i_start, i_end
354 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
355 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
358 ! This would be seen by (j > j_start) but we need to zero out the NP tendency
359 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
361 DO i = i_start, i_end
362 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
363 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
371 DO i = i_start, i_end
372 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
373 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
386 ENDDO j_loop_y_flux_6
388 ! next, x - flux divergence
394 j_end = MIN(jte,jde-1)
396 ! higher order flux has a 5 or 7 point stencil, so compute
397 ! bounds so we can switch to second order flux close to the boundary
403 i_start = MAX(ids+1,its)
408 i_end = MIN(ide-1,ite)
414 DO j = j_start, j_end
416 ! 5th or 6th order flux
419 DO i = i_start_f, i_end_f
420 vel = 0.5*(ru(i,k,j)+ru(i-1,k,j))
421 fqx( i,k ) = vel*flux6( u(i-3,k,j), u(i-2,k,j), &
422 u(i-1,k,j), u(i ,k,j), &
423 u(i+1,k,j), u(i+2,k,j), &
428 ! lower order fluxes close to boundaries (if not periodic or symmetric)
429 ! specified uses upstream normal wind at boundaries
431 IF( degrade_xs ) THEN
433 IF( i_start == ids+1 ) THEN ! second order flux next to the boundary
437 IF (specified .AND. u(i,k,j) .LT. 0.)ub = u(i,k,j)
438 fqx(i, k) = 0.25*(ru(i,k,j)+ru(i-1,k,j)) &
445 vel = 0.5*(ru(i,k,j)+ru(i-1,k,j))
446 fqx( i, k ) = vel*flux4( u(i-2,k,j), u(i-1,k,j), &
447 u(i ,k,j), u(i+1,k,j), &
453 IF( degrade_xe ) THEN
455 IF( i_end == ide-1 ) THEN ! second order flux next to the boundary
459 IF (specified .AND. u(i-1,k,j) .GT. 0.)ub = u(i-1,k,j)
460 fqx(i, k) = 0.25*(ru(i,k,j)+ru(i-1,k,j)) &
467 vel = 0.5*(ru(i,k,j)+ru(i-1,k,j))
468 fqx( i,k ) = vel*flux4( u(i-2,k,j), u(i-1,k,j), &
469 u(i ,k,j), u(i+1,k,j), &
475 ! x flux-divergence into tendency
478 DO i = i_start, i_end
479 mrdx=msfux(i,j)*rdx ! ADT eqn 44, 1st term on RHS
480 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
486 ELSE IF( horz_order == 5 ) THEN
488 ! 5th order horizontal flux calculation
489 ! This code is EXACTLY the same as the 6th order code
490 ! EXCEPT the 5th order and 3rd operators are used in
491 ! place of the 6th and 4th order operators
493 ! determine boundary mods for flux operators
494 ! We degrade the flux operators from 3rd/4th order
495 ! to second order one gridpoint in from the boundaries for
496 ! all boundary conditions except periodic and symmetry - these
497 ! conditions have boundary zone data fill for correct application
498 ! of the higher order flux stencils
505 IF( config_flags%periodic_x .or. &
506 config_flags%symmetric_xs .or. &
507 (its > ids+3) ) degrade_xs = .false.
508 IF( config_flags%periodic_x .or. &
509 config_flags%symmetric_xe .or. &
510 (ite < ide-2) ) degrade_xe = .false.
511 IF( config_flags%periodic_y .or. &
512 config_flags%symmetric_ys .or. &
513 (jts > jds+3) ) degrade_ys = .false.
514 IF( config_flags%periodic_y .or. &
515 config_flags%symmetric_ye .or. &
516 (jte < jde-4) ) degrade_ye = .false.
518 !--------------- y - advection first
522 IF ( config_flags%open_xs .or. specified ) i_start = MAX(ids+1,its)
523 IF ( config_flags%open_xe .or. specified ) i_end = MIN(ide-1,ite)
524 IF ( config_flags%periodic_x ) i_start = its
525 IF ( config_flags%periodic_x ) i_end = ite
528 j_end = MIN(jte,jde-1)
530 ! higher order flux has a 5 or 7 point stencil, so compute
531 ! bounds so we can switch to second order flux close to the boundary
537 j_start = MAX(jts,jds+1)
542 j_end = MIN(jte,jde-2)
546 IF(config_flags%polar) j_end = MIN(jte,jde-1)
548 ! compute fluxes, 5th or 6th order
553 j_loop_y_flux_5 : DO j = j_start, j_end+1
555 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN ! use full stencil
558 DO i = i_start, i_end
559 vel = 0.5*(rv(i,k,j)+rv(i-1,k,j))
560 fqy( i, k, jp1 ) = vel*flux5( &
561 u(i,k,j-3), u(i,k,j-2), u(i,k,j-1), &
562 u(i,k,j ), u(i,k,j+1), u(i,k,j+2), vel )
566 ! we must be close to some boundary where we need to reduce the order of the stencil
568 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
571 DO i = i_start, i_end
572 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i-1,k,j)) &
573 *(u(i,k,j)+u(i,k,j-1))
577 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
580 DO i = i_start, i_end
581 vel = 0.5*(rv(i,k,j)+rv(i-1,k,j))
582 fqy( i, k, jp1 ) = vel*flux3( &
583 u(i,k,j-2),u(i,k,j-1), u(i,k,j),u(i,k,j+1),vel )
587 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
590 DO i = i_start, i_end
591 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i-1,k,j)) &
592 *(u(i,k,j)+u(i,k,j-1))
596 ELSE IF ( j == jde-2 ) THEN ! 3rd order flux 2 in from north boundary
599 DO i = i_start, i_end
600 vel = 0.5*(rv(i,k,j)+rv(i-1,k,j))
601 fqy( i, k, jp1 ) = vel*flux3( &
602 u(i,k,j-2),u(i,k,j-1), &
603 u(i,k,j),u(i,k,j+1),vel )
609 ! y flux-divergence into tendency
611 ! (j > j_start) will miss the u(,,jds) tendency
612 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
614 DO i = i_start, i_end
615 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
616 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
619 ! This would be seen by (j > j_start) but we need to zero out the NP tendency
620 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
622 DO i = i_start, i_end
623 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
624 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
632 DO i = i_start, i_end
633 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
634 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
647 ENDDO j_loop_y_flux_5
649 ! next, x - flux divergence
655 j_end = MIN(jte,jde-1)
657 ! higher order flux has a 5 or 7 point stencil, so compute
658 ! bounds so we can switch to second order flux close to the boundary
664 i_start = MAX(ids+1,its)
669 i_end = MIN(ide-1,ite)
675 DO j = j_start, j_end
677 ! 5th or 6th order flux
680 DO i = i_start_f, i_end_f
681 vel = 0.5*(ru(i,k,j)+ru(i-1,k,j))
682 fqx( i,k ) = vel*flux5( u(i-3,k,j), u(i-2,k,j), &
683 u(i-1,k,j), u(i ,k,j), &
684 u(i+1,k,j), u(i+2,k,j), &
689 ! lower order fluxes close to boundaries (if not periodic or symmetric)
690 ! specified uses upstream normal wind at boundaries
692 IF( degrade_xs ) THEN
694 IF( i_start == ids+1 ) THEN ! second order flux next to the boundary
698 IF (specified .AND. u(i,k,j) .LT. 0.)ub = u(i,k,j)
699 fqx(i, k) = 0.25*(ru(i,k,j)+ru(i-1,k,j)) &
706 vel = 0.5*(ru(i,k,j)+ru(i-1,k,j))
707 fqx( i, k ) = vel*flux3( u(i-2,k,j), u(i-1,k,j), &
708 u(i ,k,j), u(i+1,k,j), &
714 IF( degrade_xe ) THEN
716 IF( i_end == ide-1 ) THEN ! second order flux next to the boundary
720 IF (specified .AND. u(i-1,k,j) .GT. 0.)ub = u(i-1,k,j)
721 fqx(i, k) = 0.25*(ru(i,k,j)+ru(i-1,k,j)) &
728 vel = 0.5*(ru(i,k,j)+ru(i-1,k,j))
729 fqx( i,k ) = vel*flux3( u(i-2,k,j), u(i-1,k,j), &
730 u(i ,k,j), u(i+1,k,j), &
736 ! x flux-divergence into tendency
739 DO i = i_start, i_end
740 mrdx=msfux(i,j)*rdx ! ADT eqn 44, 1st term on RHS
741 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
747 ELSE IF( horz_order == 4 ) THEN
749 ! determine boundary mods for flux operators
750 ! We degrade the flux operators from 3rd/4th order
751 ! to second order one gridpoint in from the boundaries for
752 ! all boundary conditions except periodic and symmetry - these
753 ! conditions have boundary zone data fill for correct application
754 ! of the higher order flux stencils
761 IF( config_flags%periodic_x .or. &
762 config_flags%symmetric_xs .or. &
763 (its > ids+2) ) degrade_xs = .false.
764 IF( config_flags%periodic_x .or. &
765 config_flags%symmetric_xe .or. &
766 (ite < ide-1) ) degrade_xe = .false.
767 IF( config_flags%periodic_y .or. &
768 config_flags%symmetric_ys .or. &
769 (jts > jds+2) ) degrade_ys = .false.
770 IF( config_flags%periodic_y .or. &
771 config_flags%symmetric_ye .or. &
772 (jte < jde-3) ) degrade_ye = .false.
774 !--------------- x - advection first
779 j_end = MIN(jte,jde-1)
781 ! 3rd or 4th order flux has a 5 point stencil, so compute
782 ! bounds so we can switch to second order flux close to the boundary
789 i_start_f = i_start+1
799 DO j = j_start, j_end
802 DO i = i_start_f, i_end_f
803 vel = 0.5*(ru(i,k,j)+ru(i-1,k,j))
804 fqx( i, k ) = vel*flux4( u(i-2,k,j), u(i-1,k,j), &
805 u(i ,k,j), u(i+1,k,j), vel )
809 ! second order flux close to boundaries (if not periodic or symmetric)
810 ! specified uses upstream normal wind at boundaries
812 IF( degrade_xs ) THEN
816 IF (specified .AND. u(i,k,j) .LT. 0.)ub = u(i,k,j)
817 fqx(i, k) = 0.25*(ru(i,k,j)+ru(i-1,k,j)) &
822 IF( degrade_xe ) THEN
826 IF (specified .AND. u(i-1,k,j) .GT. 0.)ub = u(i-1,k,j)
827 fqx(i, k) = 0.25*(ru(i,k,j)+ru(i-1,k,j)) &
832 ! x flux-divergence into tendency
835 DO i = i_start, i_end
836 mrdx=msfux(i,j)*rdx ! ADT eqn 44, 1st term on RHS
837 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
847 IF ( config_flags%open_xs .or. specified ) i_start = MAX(ids+1,its)
848 IF ( config_flags%open_xe .or. specified ) i_end = MIN(ide-1,ite)
849 IF ( config_flags%periodic_x ) i_start = its
850 IF ( config_flags%periodic_x ) i_end = ite
853 j_end = MIN(jte,jde-1)
855 ! 3rd or 4th order flux has a 5 point stencil, so compute
856 ! bounds so we can switch to second order flux close to the boundary
861 !CJM these may not work with tiling because they define j_start and end in terms of domain dim
864 j_start_f = j_start+1
872 IF(config_flags%polar) j_end = MIN(jte,jde-1)
874 ! j flux loop for v flux of u momentum
879 DO j = j_start, j_end+1
881 IF ( (j < j_start_f) .and. degrade_ys) THEN
883 DO i = i_start, i_end
884 fqy(i, k, jp1) = 0.25*(rv(i,k,j_start)+rv(i-1,k,j_start)) &
885 *(u(i,k,j_start)+u(i,k,j_start-1))
888 ELSE IF ((j > j_end_f) .and. degrade_ye) THEN
890 DO i = i_start, i_end
891 ! Assumes j>j_end_f is ONLY j_end+1 ...
892 ! fqy(i, k, jp1) = 0.25*(rv(i,k,j_end+1)+rv(i-1,k,j_end+1)) &
893 ! *(u(i,k,j_end+1)+u(i,k,j_end))
894 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i-1,k,j)) &
895 *(u(i,k,j)+u(i,k,j-1))
899 ! 3rd or 4th order flux
901 DO i = i_start, i_end
902 vel = 0.5*(rv(i,k,j)+rv(i-1,k,j))
903 fqy( i, k, jp1 ) = vel*flux4( u(i,k,j-2), u(i,k,j-1), &
904 u(i,k,j ), u(i,k,j+1), &
911 ! y flux-divergence into tendency
913 ! (j > j_start) will miss the u(,,jds) tendency
914 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
916 DO i = i_start, i_end
917 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
918 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
921 ! This would be seen by (j > j_start) but we need to zero out the NP tendency
922 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
924 DO i = i_start, i_end
925 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
926 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
931 IF (j > j_start) THEN
934 DO i = i_start, i_end
935 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
936 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
950 ELSE IF ( horz_order == 3 ) THEN
952 ! As with the 5th and 6th order flux chioces, the 3rd and 4th order
953 ! code is EXACTLY the same EXCEPT for the flux operator.
955 ! determine boundary mods for flux operators
956 ! We degrade the flux operators from 3rd/4th order
957 ! to second order one gridpoint in from the boundaries for
958 ! all boundary conditions except periodic and symmetry - these
959 ! conditions have boundary zone data fill for correct application
960 ! of the higher order flux stencils
967 IF( config_flags%periodic_x .or. &
968 config_flags%symmetric_xs .or. &
969 (its > ids+2) ) degrade_xs = .false.
970 IF( config_flags%periodic_x .or. &
971 config_flags%symmetric_xe .or. &
972 (ite < ide-1) ) degrade_xe = .false.
973 IF( config_flags%periodic_y .or. &
974 config_flags%symmetric_ys .or. &
975 (jts > jds+2) ) degrade_ys = .false.
976 IF( config_flags%periodic_y .or. &
977 config_flags%symmetric_ye .or. &
978 (jte < jde-3) ) degrade_ye = .false.
980 !--------------- x - advection first
985 j_end = MIN(jte,jde-1)
987 ! 3rd or 4th order flux has a 5 point stencil, so compute
988 ! bounds so we can switch to second order flux close to the boundary
995 i_start_f = i_start+1
1005 DO j = j_start, j_end
1008 DO i = i_start_f, i_end_f
1009 vel = 0.5*(ru(i,k,j)+ru(i-1,k,j))
1010 fqx( i, k ) = vel*flux3( u(i-2,k,j), u(i-1,k,j), &
1011 u(i ,k,j), u(i+1,k,j), vel )
1015 ! second order flux close to boundaries (if not periodic or symmetric)
1016 ! specified uses upstream normal wind at boundaries
1018 IF( degrade_xs ) THEN
1022 IF (specified .AND. u(i,k,j) .LT. 0.)ub = u(i,k,j)
1023 fqx(i, k) = 0.25*(ru(i,k,j)+ru(i-1,k,j)) &
1028 IF( degrade_xe ) THEN
1032 IF (specified .AND. u(i-1,k,j) .GT. 0.)ub = u(i-1,k,j)
1033 fqx(i, k) = 0.25*(ru(i,k,j)+ru(i-1,k,j)) &
1038 ! x flux-divergence into tendency
1041 DO i = i_start, i_end
1042 mrdx=msfux(i,j)*rdx ! ADT eqn 44, 1st term on RHS
1043 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
1052 IF ( config_flags%open_xs .or. specified ) i_start = MAX(ids+1,its)
1053 IF ( config_flags%open_xe .or. specified ) i_end = MIN(ide-1,ite)
1054 IF ( config_flags%periodic_x ) i_start = its
1055 IF ( config_flags%periodic_x ) i_end = ite
1058 j_end = MIN(jte,jde-1)
1060 ! 3rd or 4th order flux has a 5 point stencil, so compute
1061 ! bounds so we can switch to second order flux close to the boundary
1066 !CJM these may not work with tiling because they define j_start and end in terms of domain dim
1069 j_start_f = j_start+1
1077 IF(config_flags%polar) j_end = MIN(jte,jde-1)
1079 ! j flux loop for v flux of u momentum
1084 DO j = j_start, j_end+1
1086 IF ( (j < j_start_f) .and. degrade_ys) THEN
1088 DO i = i_start, i_end
1089 fqy(i, k, jp1) = 0.25*(rv(i,k,j_start)+rv(i-1,k,j_start)) &
1090 *(u(i,k,j_start)+u(i,k,j_start-1))
1093 ELSE IF ((j > j_end_f) .and. degrade_ye) THEN
1095 DO i = i_start, i_end
1096 ! Assumes j>j_end_f is ONLY j_end+1 ...
1097 ! fqy(i, k, jp1) = 0.25*(rv(i,k,j_end+1)+rv(i-1,k,j_end+1)) &
1098 ! *(u(i,k,j_end+1)+u(i,k,j_end))
1099 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i-1,k,j)) &
1100 *(u(i,k,j)+u(i,k,j-1))
1104 ! 3rd or 4th order flux
1106 DO i = i_start, i_end
1107 vel = 0.5*(rv(i,k,j)+rv(i-1,k,j))
1108 fqy( i, k, jp1 ) = vel*flux3( u(i,k,j-2), u(i,k,j-1), &
1109 u(i,k,j ), u(i,k,j+1), &
1116 ! y flux-divergence into tendency
1118 ! (j > j_start) will miss the u(,,jds) tendency
1119 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
1121 DO i = i_start, i_end
1122 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
1123 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
1126 ! This would be seen by (j > j_start) but we need to zero out the NP tendency
1127 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
1129 DO i = i_start, i_end
1130 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
1131 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
1136 IF (j > j_start) THEN
1139 DO i = i_start, i_end
1140 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
1141 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
1155 ELSE IF ( horz_order == 2 ) THEN
1160 j_end = MIN(jte,jde-1)
1162 IF ( config_flags%open_xs ) i_start = MAX(ids+1,its)
1163 IF ( config_flags%open_xe ) i_end = MIN(ide-1,ite)
1164 IF ( specified ) i_start = MAX(ids+2,its)
1165 IF ( specified ) i_end = MIN(ide-2,ite)
1166 IF ( config_flags%periodic_x ) i_start = its
1167 IF ( config_flags%periodic_x ) i_end = ite
1169 DO j = j_start, j_end
1171 DO i = i_start, i_end
1172 mrdx=msfux(i,j)*rdx ! ADT eqn 44, 1st term on RHS
1173 tendency(i,k,j)=tendency(i,k,j)-mrdx*0.25 &
1174 *((ru(i+1,k,j)+ru(i,k,j))*(u(i+1,k,j)+u(i,k,j)) &
1175 -(ru(i,k,j)+ru(i-1,k,j))*(u(i,k,j)+u(i-1,k,j)))
1180 IF ( specified .AND. its .LE. ids+1 .AND. .NOT. config_flags%periodic_x ) THEN
1181 DO j = j_start, j_end
1184 mrdx=msfux(i,j)*rdx ! ADT eqn 44, 1st term on RHS
1186 IF (u(i,k,j) .LT. 0.) ub = u(i,k,j)
1187 tendency(i,k,j)=tendency(i,k,j)-mrdx*0.25 &
1188 *((ru(i+1,k,j)+ru(i,k,j))*(u(i+1,k,j)+u(i,k,j)) &
1189 -(ru(i,k,j)+ru(i-1,k,j))*(u(i,k,j)+ub))
1193 IF ( specified .AND. ite .GE. ide-1 .AND. .NOT. config_flags%periodic_x ) THEN
1194 DO j = j_start, j_end
1197 mrdx=msfux(i,j)*rdx ! ADT eqn 44, 1st term on RHS
1199 IF (u(i,k,j) .GT. 0.) ub = u(i,k,j)
1200 tendency(i,k,j)=tendency(i,k,j)-mrdx*0.25 &
1201 *((ru(i+1,k,j)+ru(i,k,j))*(ub+u(i,k,j)) &
1202 -(ru(i,k,j)+ru(i-1,k,j))*(u(i,k,j)+u(i-1,k,j)))
1207 IF ( config_flags%open_ys .or. specified ) j_start = MAX(jds+1,jts)
1208 IF ( config_flags%open_ye .or. specified ) j_end = MIN(jde-2,jte)
1210 DO j = j_start, j_end
1212 DO i = i_start, i_end
1213 mrdy=msfux(i,j)*rdy ! ADT eqn 44, 1st term on RHS
1214 ! Comments for polar boundary condition
1215 ! Flow is only from one side for points next to poles
1216 IF ( (config_flags%polar) .AND. (j == jds) ) THEN
1217 tendency(i,k,j)=tendency(i,k,j)-mrdy*0.25 &
1218 *(rv(i,k,j+1)+rv(i-1,k,j+1))*(u(i,k,j+1)+u(i,k,j))
1219 ELSE IF ( (config_flags%polar) .AND. (j == jde-1) ) THEN
1220 tendency(i,k,j)=tendency(i,k,j)+mrdy*0.25 &
1221 *(rv(i,k,j)+rv(i-1,k,j))*(u(i,k,j)+u(i,k,j-1))
1223 tendency(i,k,j)=tendency(i,k,j)-mrdy*0.25 &
1224 *((rv(i,k,j+1)+rv(i-1,k,j+1))*(u(i,k,j+1)+u(i,k,j)) &
1225 -(rv(i,k,j)+rv(i-1,k,j))*(u(i,k,j)+u(i,k,j-1)))
1231 ELSE IF ( horz_order == 0 ) THEN
1233 ! Just in case we want to turn horizontal advection off, we can do it
1237 WRITE ( wrf_err_message , * ) 'module_advect: advect_u_6a: h_order not known ',horz_order
1238 CALL wrf_error_fatal ( TRIM( wrf_err_message ) )
1240 ENDIF horizontal_order_test
1242 ! radiative lateral boundary condition in x for normal velocity (u)
1244 IF ( (config_flags%open_xs) .and. its == ids ) THEN
1247 j_end = MIN(jte,jde-1)
1249 DO j = j_start, j_end
1251 ub = MIN(ru(its,k,j)-cb*(c1(k)*mut(its,j)+c2(k)), 0.)
1252 tendency(its,k,j) = tendency(its,k,j) &
1253 - rdx*ub*(u_old(its+1,k,j) - u_old(its,k,j))
1259 IF ( (config_flags%open_xe) .and. ite == ide ) THEN
1262 j_end = MIN(jte,jde-1)
1264 DO j = j_start, j_end
1266 ub = MAX(ru(ite,k,j)+cb*(c1(k)*mut(ite-1,j)+c2(k)), 0.)
1267 tendency(ite,k,j) = tendency(ite,k,j) &
1268 - rdx*ub*(u_old(ite,k,j) - u_old(ite-1,k,j))
1274 ! pick up the rest of the horizontal radiation boundary conditions.
1275 ! (these are the computations that don't require 'cb')
1276 ! first, set to index ranges
1279 i_end = MIN(ite,ide)
1283 IF (config_flags%open_xs) THEN
1284 i_start = MAX(ids+1, its)
1287 IF (config_flags%open_xe) THEN
1288 i_end = MIN(ite,ide-1)
1292 IF( (config_flags%open_ys) .and. (jts == jds)) THEN
1294 DO i = i_start, i_end
1296 mrdy=msfux(i,jts)*rdy ! ADT eqn 44, 2nd term on RHS
1298 im = MAX( imin, i-1 )
1302 vw = 0.5*(rv(ip,k,jts)+rv(im,k,jts))
1304 dvm = rv(ip,k,jts+1)-rv(ip,k,jts)
1305 dvp = rv(im,k,jts+1)-rv(im,k,jts)
1306 tendency(i,k,jts)=tendency(i,k,jts)-mrdy*( &
1307 vb*(u_old(i,k,jts+1)-u_old(i,k,jts)) &
1308 +0.5*u(i,k,jts)*(dvm+dvp))
1314 IF( (config_flags%open_ye) .and. (jte == jde)) THEN
1316 DO i = i_start, i_end
1318 mrdy=msfux(i,jte-1)*rdy ! ADT eqn 44, 2nd term on RHS
1320 im = MAX( imin, i-1 )
1324 vw = 0.5*(rv(ip,k,jte)+rv(im,k,jte))
1326 dvm = rv(ip,k,jte)-rv(ip,k,jte-1)
1327 dvp = rv(im,k,jte)-rv(im,k,jte-1)
1328 tendency(i,k,jte-1)=tendency(i,k,jte-1)-mrdy*( &
1329 vb*(u_old(i,k,jte-1)-u_old(i,k,jte-2)) &
1330 +0.5*u(i,k,jte-1)*(dvm+dvp))
1336 !-------------------- vertical advection
1337 ! ADT eqn 44 has 3rd term on RHS = -(1/my) partial d/dz (rho u w)
1338 ! Here we have: - partial d/dz (u*rom) = - partial d/dz (u rho w / my)
1339 ! Since 'my' (map scale factor in y-direction) isn't a function of z,
1340 ! this is what we need, so leave unchanged in advect_u
1345 j_end = min(jte,jde-1)
1347 ! IF ( config_flags%open_xs ) i_start = MAX(ids+1,its)
1348 ! IF ( config_flags%open_xe ) i_end = MIN(ide-1,ite)
1350 IF ( config_flags%open_ys .or. specified ) i_start = MAX(ids+1,its)
1351 IF ( config_flags%open_ye .or. specified ) i_end = MIN(ide-1,ite)
1352 IF ( config_flags%periodic_x ) i_start = its
1353 IF ( config_flags%periodic_x ) i_end = ite
1355 DO i = i_start, i_end
1360 vert_order_test : IF (vert_order == 6) THEN
1362 DO j = j_start, j_end
1365 DO i = i_start, i_end
1366 vel=0.5*(rom(i-1,k,j)+rom(i,k,j))
1367 vflux(i,k) = vel*flux6( &
1368 u(i,k-3,j), u(i,k-2,j), u(i,k-1,j), &
1369 u(i,k ,j), u(i,k+1,j), u(i,k+2,j), -vel )
1373 DO i = i_start, i_end
1376 vflux(i,k)=0.5*(rom(i,k,j)+rom(i-1,k,j)) &
1377 *(fzm(k)*u(i,k,j)+fzp(k)*u(i,k-1,j))
1379 vel=0.5*(rom(i,k,j)+rom(i-1,k,j))
1380 vflux(i,k) = vel*flux4( &
1381 u(i,k-2,j), u(i,k-1,j), &
1382 u(i,k ,j), u(i,k+1,j), -vel )
1384 vel=0.5*(rom(i,k,j)+rom(i-1,k,j))
1385 vflux(i,k) = vel*flux4( &
1386 u(i,k-2,j), u(i,k-1,j), &
1387 u(i,k ,j), u(i,k+1,j), -vel )
1389 vflux(i,k)=0.5*(rom(i,k,j)+rom(i-1,k,j)) &
1390 *(fzm(k)*u(i,k,j)+fzp(k)*u(i,k-1,j))
1394 DO i = i_start, i_end
1395 tendency(i,k,j)=tendency(i,k,j)-rdzw(k)*(vflux(i,k+1)-vflux(i,k))
1400 ELSE IF (vert_order == 5) THEN
1402 DO j = j_start, j_end
1405 DO i = i_start, i_end
1406 vel=0.5*(rom(i-1,k,j)+rom(i,k,j))
1407 vflux(i,k) = vel*flux5( &
1408 u(i,k-3,j), u(i,k-2,j), u(i,k-1,j), &
1409 u(i,k ,j), u(i,k+1,j), u(i,k+2,j), -vel )
1413 DO i = i_start, i_end
1416 vflux(i,k)=0.5*(rom(i,k,j)+rom(i-1,k,j)) &
1417 *(fzm(k)*u(i,k,j)+fzp(k)*u(i,k-1,j))
1419 vel=0.5*(rom(i,k,j)+rom(i-1,k,j))
1420 vflux(i,k) = vel*flux3( &
1421 u(i,k-2,j), u(i,k-1,j), &
1422 u(i,k ,j), u(i,k+1,j), -vel )
1424 vel=0.5*(rom(i,k,j)+rom(i-1,k,j))
1425 vflux(i,k) = vel*flux3( &
1426 u(i,k-2,j), u(i,k-1,j), &
1427 u(i,k ,j), u(i,k+1,j), -vel )
1429 vflux(i,k)=0.5*(rom(i,k,j)+rom(i-1,k,j)) &
1430 *(fzm(k)*u(i,k,j)+fzp(k)*u(i,k-1,j))
1434 DO i = i_start, i_end
1435 tendency(i,k,j)=tendency(i,k,j)-rdzw(k)*(vflux(i,k+1)-vflux(i,k))
1440 ELSE IF (vert_order == 4) THEN
1442 DO j = j_start, j_end
1445 DO i = i_start, i_end
1446 vel=0.5*(rom(i-1,k,j)+rom(i,k,j))
1447 vflux(i,k) = vel*flux4( &
1448 u(i,k-2,j), u(i,k-1,j), &
1449 u(i,k ,j), u(i,k+1,j), -vel )
1453 DO i = i_start, i_end
1456 vflux(i,k)=0.5*(rom(i,k,j)+rom(i-1,k,j)) &
1457 *(fzm(k)*u(i,k,j)+fzp(k)*u(i,k-1,j))
1459 vflux(i,k)=0.5*(rom(i,k,j)+rom(i-1,k,j)) &
1460 *(fzm(k)*u(i,k,j)+fzp(k)*u(i,k-1,j))
1464 DO i = i_start, i_end
1465 tendency(i,k,j)=tendency(i,k,j)-rdzw(k)*(vflux(i,k+1)-vflux(i,k))
1470 ELSE IF (vert_order == 3) THEN
1472 DO j = j_start, j_end
1475 DO i = i_start, i_end
1476 vel=0.5*(rom(i-1,k,j)+rom(i,k,j))
1477 vflux(i,k) = vel*flux3( &
1478 u(i,k-2,j), u(i,k-1,j), &
1479 u(i,k ,j), u(i,k+1,j), -vel )
1483 DO i = i_start, i_end
1486 vflux(i,k)=0.5*(rom(i,k,j)+rom(i-1,k,j)) &
1487 *(fzm(k)*u(i,k,j)+fzp(k)*u(i,k-1,j))
1489 vflux(i,k)=0.5*(rom(i,k,j)+rom(i-1,k,j)) &
1490 *(fzm(k)*u(i,k,j)+fzp(k)*u(i,k-1,j))
1494 DO i = i_start, i_end
1495 tendency(i,k,j)=tendency(i,k,j)-rdzw(k)*(vflux(i,k+1)-vflux(i,k))
1500 ELSE IF (vert_order == 2) THEN
1502 DO j = j_start, j_end
1504 DO i = i_start, i_end
1505 vflux(i,k)=0.5*(rom(i,k,j)+rom(i-1,k,j)) &
1506 *(fzm(k)*u(i,k,j)+fzp(k)*u(i,k-1,j))
1512 DO i = i_start, i_end
1513 tendency(i,k,j)=tendency(i,k,j)-rdzw(k)*(vflux(i,k+1)-vflux(i,k))
1521 WRITE ( wrf_err_message , * ) 'module_advect: advect_u_6a: v_order not known ',vert_order
1522 CALL wrf_error_fatal ( TRIM( wrf_err_message ) )
1524 ENDIF vert_order_test
1526 END SUBROUTINE advect_u
1528 !-------------------------------------------------------------------------------
1530 SUBROUTINE advect_v ( v, v_old, tendency, &
1533 mut, time_step, config_flags, &
1534 msfux, msfuy, msfvx, msfvy, &
1538 ids, ide, jds, jde, kds, kde, &
1539 ims, ime, jms, jme, kms, kme, &
1540 its, ite, jts, jte, kts, kte )
1546 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
1548 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
1549 ims, ime, jms, jme, kms, kme, &
1550 its, ite, jts, jte, kts, kte
1552 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: v, &
1558 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut
1559 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
1561 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
1568 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
1574 REAL , INTENT(IN ) :: rdx, &
1576 INTEGER , INTENT(IN ) :: time_step
1581 INTEGER :: i, j, k, itf, jtf, ktf
1582 INTEGER :: i_start, i_end, j_start, j_end
1583 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
1584 INTEGER :: jmin, jmax, jp, jm, imin, imax
1586 REAL :: mrdx, mrdy, ub, vb, uw, vw, dup, dum
1587 REAL , DIMENSION(its:ite, kts:kte) :: vflux
1590 REAL, DIMENSION( its:ite+1, kts:kte ) :: fqx
1591 REAL, DIMENSION( its:ite, kts:kte, 2 ) :: fqy
1593 INTEGER :: horz_order
1594 INTEGER :: vert_order
1596 LOGICAL :: degrade_xs, degrade_ys
1597 LOGICAL :: degrade_xe, degrade_ye
1599 INTEGER :: jp1, jp0, jtmp
1602 ! definition of flux operators, 3rd, 4th, 5th or 6th order
1604 REAL :: flux3, flux4, flux5, flux6
1605 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel
1607 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
1608 ( 7.*(q_i + q_im1) - (q_ip1 + q_im2) )/12.0
1610 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
1611 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
1612 sign(1,time_step)*sign(1.,ua)*((q_ip1 - q_im2)-3.*(q_i-q_im1))/12.0
1614 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
1615 ( 37.*(q_i+q_im1) - 8.*(q_ip1+q_im2) &
1616 +(q_ip2+q_im3) )/60.0
1618 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
1619 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
1620 -sign(1,time_step)*sign(1.,ua)*( &
1621 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )/60.0
1625 LOGICAL :: specified
1628 if(config_flags%specified .or. config_flags%nested) specified = .true.
1630 ! set order for the advection schemes
1633 horz_order = config_flags%h_mom_adv_order
1634 vert_order = config_flags%v_mom_adv_order
1637 ! here is the choice of flux operators
1640 horizontal_order_test : IF( horz_order == 6 ) THEN
1642 ! determine boundary mods for flux operators
1643 ! We degrade the flux operators from 3rd/4th order
1644 ! to second order one gridpoint in from the boundaries for
1645 ! all boundary conditions except periodic and symmetry - these
1646 ! conditions have boundary zone data fill for correct application
1647 ! of the higher order flux stencils
1654 IF( config_flags%periodic_x .or. &
1655 config_flags%symmetric_xs .or. &
1656 (its > ids+3) ) degrade_xs = .false.
1657 IF( config_flags%periodic_x .or. &
1658 config_flags%symmetric_xe .or. &
1659 (ite < ide-3) ) degrade_xe = .false.
1660 IF( config_flags%periodic_y .or. &
1661 config_flags%symmetric_ys .or. &
1662 (jts > jds+3) ) degrade_ys = .false.
1663 IF( config_flags%periodic_y .or. &
1664 config_flags%symmetric_ye .or. &
1665 (jte < jde-3) ) degrade_ye = .false.
1667 !--------------- y - advection first
1670 i_end = MIN(ite,ide-1)
1674 ! higher order flux has a 5 or 7 point stencil, so compute
1675 ! bounds so we can switch to second order flux close to the boundary
1681 j_start = MAX(jts,jds+1)
1686 j_end = MIN(jte,jde-1)
1690 ! compute fluxes, 5th or 6th order
1695 j_loop_y_flux_6 : DO j = j_start, j_end+1
1697 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN
1700 DO i = i_start, i_end
1701 vel = 0.5*(rv(i,k,j)+rv(i,k,j-1))
1702 fqy( i, k, jp1 ) = vel*flux6( &
1703 v(i,k,j-3), v(i,k,j-2), v(i,k,j-1), &
1704 v(i,k,j ), v(i,k,j+1), v(i,k,j+2), vel )
1708 ! we must be close to some boundary where we need to reduce the order of the stencil
1709 ! specified uses upstream normal wind at boundaries
1711 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
1714 DO i = i_start, i_end
1716 IF (specified .AND. v(i,k,j) .LT. 0.)vb = v(i,k,j)
1717 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i,k,j-1)) &
1722 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
1725 DO i = i_start, i_end
1726 vel = 0.5*(rv(i,k,j)+rv(i,k,j-1))
1727 fqy( i, k, jp1 ) = vel*flux4( &
1728 v(i,k,j-2),v(i,k,j-1),v(i,k,j),v(i,k,j+1),vel )
1733 ELSE IF ( j == jde ) THEN ! 2nd order flux next to north boundary
1736 DO i = i_start, i_end
1738 IF (specified .AND. v(i,k,j-1) .GT. 0.)vb = v(i,k,j-1)
1739 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i,k,j-1)) &
1744 ELSE IF ( j == jde-1 ) THEN ! 3rd or 4th order flux 2 in from north boundary
1747 DO i = i_start, i_end
1748 vel = 0.5*(rv(i,k,j)+rv(i,k,j-1))
1749 fqy( i, k, jp1 ) = vel*flux4( &
1750 v(i,k,j-2),v(i,k,j-1),v(i,k,j),v(i,k,j+1),vel )
1756 ! y flux-divergence into tendency
1758 ! Comments on polar boundary conditions
1759 ! No advection over the poles means tendencies (held from jds [S. pole]
1760 ! to jde [N pole], i.e., on v grid) must be zero at poles
1761 ! [tendency(jds) and tendency(jde)=0]
1762 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
1764 DO i = i_start, i_end
1765 tendency(i,k,j-1) = 0.
1768 ! If j_end were set to jde in a special if statement apart from
1769 ! degrade_ye, then we would hit the next conditional. But since
1770 ! we want the tendency to be zero anyway, not looping to jde+1
1771 ! will produce the same effect.
1772 ELSE IF( config_flags%polar .AND. (j == jde+1) ) THEN
1774 DO i = i_start, i_end
1775 tendency(i,k,j-1) = 0.
1780 IF(j > j_start) THEN
1783 DO i = i_start, i_end
1784 mrdy=msfvy(i,j-1)*rdy ! ADT eqn 45, 2nd term on RHS
1785 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
1797 ENDDO j_loop_y_flux_6
1799 ! next, x - flux divergence
1802 i_end = MIN(ite,ide-1)
1806 ! Polar boundary conditions are like open or specified
1807 IF ( config_flags%open_ys .or. specified .or. config_flags%polar ) j_start = MAX(jds+1,jts)
1808 IF ( config_flags%open_ye .or. specified .or. config_flags%polar ) j_end = MIN(jde-1,jte)
1810 ! higher order flux has a 5 or 7 point stencil, so compute
1811 ! bounds so we can switch to second order flux close to the boundary
1817 i_start = MAX(ids+1,its)
1818 ! i_start_f = i_start+2
1819 i_start_f = MIN(i_start+2,ids+3)
1823 i_end = MIN(ide-2,ite)
1829 DO j = j_start, j_end
1831 ! 5th or 6th order flux
1834 DO i = i_start_f, i_end_f
1835 vel = 0.5*(ru(i,k,j)+ru(i,k,j-1))
1836 fqx( i, k ) = vel*flux6( v(i-3,k,j), v(i-2,k,j), &
1837 v(i-1,k,j), v(i ,k,j), &
1838 v(i+1,k,j), v(i+2,k,j), &
1843 ! lower order fluxes close to boundaries (if not periodic or symmetric)
1845 IF( degrade_xs ) THEN
1847 DO i=i_start,i_start_f-1
1849 IF(i == ids+1) THEN ! second order
1851 fqx(i,k) = 0.25*(ru(i,k,j)+ru(i,k,j-1)) &
1852 *(v(i,k,j)+v(i-1,k,j))
1856 IF(i == ids+2) THEN ! third order
1858 vel = 0.5*(ru(i,k,j)+ru(i,k,j-1))
1859 fqx( i,k ) = vel*flux4( v(i-2,k,j), v(i-1,k,j), &
1860 v(i ,k,j), v(i+1,k,j), &
1869 IF( degrade_xe ) THEN
1871 DO i = i_end_f+1, i_end+1
1873 IF( i == ide-1 ) THEN ! second order flux next to the boundary
1875 fqx(i,k) = 0.25*(ru(i_end+1,k,j)+ru(i_end+1,k,j-1)) &
1876 *(v(i_end+1,k,j)+v(i_end,k,j))
1880 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
1882 vel = 0.5*(ru(i,k,j)+ru(i,k,j-1))
1883 fqx( i,k ) = vel*flux4( v(i-2,k,j), v(i-1,k,j), &
1884 v(i ,k,j), v(i+1,k,j), &
1893 ! x flux-divergence into tendency
1896 DO i = i_start, i_end
1897 mrdx=msfvy(i,j)*rdx ! ADT eqn 45, 1st term on RHS
1898 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
1904 ELSE IF( horz_order == 5 ) THEN
1906 ! 5th order horizontal flux calculation
1907 ! This code is EXACTLY the same as the 6th order code
1908 ! EXCEPT the 5th order and 3rd operators are used in
1909 ! place of the 6th and 4th order operators
1911 ! determine boundary mods for flux operators
1912 ! We degrade the flux operators from 3rd/4th order
1913 ! to second order one gridpoint in from the boundaries for
1914 ! all boundary conditions except periodic and symmetry - these
1915 ! conditions have boundary zone data fill for correct application
1916 ! of the higher order flux stencils
1923 IF( config_flags%periodic_x .or. &
1924 config_flags%symmetric_xs .or. &
1925 (its > ids+3) ) degrade_xs = .false.
1926 IF( config_flags%periodic_x .or. &
1927 config_flags%symmetric_xe .or. &
1928 (ite < ide-3) ) degrade_xe = .false.
1929 IF( config_flags%periodic_y .or. &
1930 config_flags%symmetric_ys .or. &
1931 (jts > jds+3) ) degrade_ys = .false.
1932 IF( config_flags%periodic_y .or. &
1933 config_flags%symmetric_ye .or. &
1934 (jte < jde-3) ) degrade_ye = .false.
1936 !--------------- y - advection first
1939 i_end = MIN(ite,ide-1)
1943 ! higher order flux has a 5 or 7 point stencil, so compute
1944 ! bounds so we can switch to second order flux close to the boundary
1950 j_start = MAX(jts,jds+1)
1955 j_end = MIN(jte,jde-1)
1959 ! compute fluxes, 5th or 6th order
1964 j_loop_y_flux_5 : DO j = j_start, j_end+1
1966 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN
1969 DO i = i_start, i_end
1970 vel = 0.5*(rv(i,k,j)+rv(i,k,j-1))
1971 fqy( i, k, jp1 ) = vel*flux5( &
1972 v(i,k,j-3), v(i,k,j-2), v(i,k,j-1), &
1973 v(i,k,j ), v(i,k,j+1), v(i,k,j+2), vel )
1977 ! we must be close to some boundary where we need to reduce the order of the stencil
1978 ! specified uses upstream normal wind at boundaries
1980 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
1983 DO i = i_start, i_end
1985 IF (specified .AND. v(i,k,j) .LT. 0.)vb = v(i,k,j)
1986 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i,k,j-1)) &
1991 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
1994 DO i = i_start, i_end
1995 vel = 0.5*(rv(i,k,j)+rv(i,k,j-1))
1996 fqy( i, k, jp1 ) = vel*flux3( &
1997 v(i,k,j-2),v(i,k,j-1),v(i,k,j),v(i,k,j+1),vel )
2002 ELSE IF ( j == jde ) THEN ! 2nd order flux next to north boundary
2005 DO i = i_start, i_end
2007 IF (specified .AND. v(i,k,j-1) .GT. 0.)vb = v(i,k,j-1)
2008 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i,k,j-1)) &
2013 ELSE IF ( j == jde-1 ) THEN ! 3rd or 4th order flux 2 in from north boundary
2016 DO i = i_start, i_end
2017 vel = 0.5*(rv(i,k,j)+rv(i,k,j-1))
2018 fqy( i, k, jp1 ) = vel*flux3( &
2019 v(i,k,j-2),v(i,k,j-1),v(i,k,j),v(i,k,j+1),vel )
2025 ! y flux-divergence into tendency
2027 ! Comments on polar boundary conditions
2028 ! No advection over the poles means tendencies (held from jds [S. pole]
2029 ! to jde [N pole], i.e., on v grid) must be zero at poles
2030 ! [tendency(jds) and tendency(jde)=0]
2031 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
2033 DO i = i_start, i_end
2034 tendency(i,k,j-1) = 0.
2037 ! If j_end were set to jde in a special if statement apart from
2038 ! degrade_ye, then we would hit the next conditional. But since
2039 ! we want the tendency to be zero anyway, not looping to jde+1
2040 ! will produce the same effect.
2041 ELSE IF( config_flags%polar .AND. (j == jde+1) ) THEN
2043 DO i = i_start, i_end
2044 tendency(i,k,j-1) = 0.
2049 IF(j > j_start) THEN
2052 DO i = i_start, i_end
2053 mrdy=msfvy(i,j-1)*rdy ! ADT eqn 45, 2nd term on RHS
2054 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
2066 ENDDO j_loop_y_flux_5
2068 ! next, x - flux divergence
2071 i_end = MIN(ite,ide-1)
2075 ! Polar boundary conditions are like open or specified
2076 IF ( config_flags%open_ys .or. specified .or. config_flags%polar ) j_start = MAX(jds+1,jts)
2077 IF ( config_flags%open_ye .or. specified .or. config_flags%polar ) j_end = MIN(jde-1,jte)
2079 ! higher order flux has a 5 or 7 point stencil, so compute
2080 ! bounds so we can switch to second order flux close to the boundary
2086 i_start = MAX(ids+1,its)
2087 ! i_start_f = i_start+2
2088 i_start_f = MIN(i_start+2,ids+3)
2092 i_end = MIN(ide-2,ite)
2098 DO j = j_start, j_end
2100 ! 5th or 6th order flux
2103 DO i = i_start_f, i_end_f
2104 vel = 0.5*(ru(i,k,j)+ru(i,k,j-1))
2105 fqx( i, k ) = vel*flux5( v(i-3,k,j), v(i-2,k,j), &
2106 v(i-1,k,j), v(i ,k,j), &
2107 v(i+1,k,j), v(i+2,k,j), &
2112 ! lower order fluxes close to boundaries (if not periodic or symmetric)
2114 IF( degrade_xs ) THEN
2116 DO i=i_start,i_start_f-1
2118 IF(i == ids+1) THEN ! second order
2120 fqx(i,k) = 0.25*(ru(i,k,j)+ru(i,k,j-1)) &
2121 *(v(i,k,j)+v(i-1,k,j))
2125 IF(i == ids+2) THEN ! third order
2127 vel = 0.5*(ru(i,k,j)+ru(i,k,j-1))
2128 fqx( i,k ) = vel*flux3( v(i-2,k,j), v(i-1,k,j), &
2129 v(i ,k,j), v(i+1,k,j), &
2138 IF( degrade_xe ) THEN
2140 DO i = i_end_f+1, i_end+1
2142 IF( i == ide-1 ) THEN ! second order flux next to the boundary
2144 fqx(i,k) = 0.25*(ru(i_end+1,k,j)+ru(i_end+1,k,j-1)) &
2145 *(v(i_end+1,k,j)+v(i_end,k,j))
2149 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
2151 vel = 0.5*(ru(i,k,j)+ru(i,k,j-1))
2152 fqx( i,k ) = vel*flux3( v(i-2,k,j), v(i-1,k,j), &
2153 v(i ,k,j), v(i+1,k,j), &
2162 ! x flux-divergence into tendency
2165 DO i = i_start, i_end
2166 mrdx=msfvy(i,j)*rdx ! ADT eqn 45, 1st term on RHS
2167 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
2173 ELSE IF( horz_order == 4 ) THEN
2175 ! determine boundary mods for flux operators
2176 ! We degrade the flux operators from 3rd/4th order
2177 ! to second order one gridpoint in from the boundaries for
2178 ! all boundary conditions except periodic and symmetry - these
2179 ! conditions have boundary zone data fill for correct application
2180 ! of the higher order flux stencils
2187 IF( config_flags%periodic_x .or. &
2188 config_flags%symmetric_xs .or. &
2189 (its > ids+2) ) degrade_xs = .false.
2190 IF( config_flags%periodic_x .or. &
2191 config_flags%symmetric_xe .or. &
2192 (ite < ide-2) ) degrade_xe = .false.
2193 IF( config_flags%periodic_y .or. &
2194 config_flags%symmetric_ys .or. &
2195 (jts > jds+2) ) degrade_ys = .false.
2196 IF( config_flags%periodic_y .or. &
2197 config_flags%symmetric_ye .or. &
2198 (jte < jde-2) ) degrade_ye = .false.
2200 !--------------- y - advection first
2206 i_end = MIN(ite,ide-1)
2210 ! 3rd or 4th order flux has a 5 point stencil, so compute
2211 ! bounds so we can switch to second order flux close to the boundary
2216 !CJM May not work with tiling because defined in terms of domain dims
2219 j_start_f = j_start+1
2228 ! specified uses upstream normal wind at boundaries
2233 DO j = j_start, j_end+1
2235 IF ((j == j_start) .and. degrade_ys) THEN
2237 DO i = i_start, i_end
2239 IF (specified .AND. v(i,k,j) .LT. 0.)vb = v(i,k,j)
2240 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i,k,j-1)) &
2244 ELSE IF ((j == j_end+1) .and. degrade_ye) THEN
2246 DO i = i_start, i_end
2248 IF (specified .AND. v(i,k,j-1) .GT. 0.)vb = v(i,k,j-1)
2249 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i,k,j-1)) &
2255 DO i = i_start, i_end
2256 vel = 0.5*(rv(i,k,j)+rv(i,k,j-1))
2257 fqy( i,k,jp1 ) = vel*flux4( v(i,k,j-2), v(i,k,j-1), &
2258 v(i,k,j ), v(i,k,j+1), &
2264 ! Comments on polar boundary conditions
2265 ! No advection over the poles means tendencies (held from jds [S. pole]
2266 ! to jde [N pole], i.e., on v grid) must be zero at poles
2267 ! [tendency(jds) and tendency(jde)=0]
2268 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
2270 DO i = i_start, i_end
2271 tendency(i,k,j-1) = 0.
2274 ! If j_end were set to jde in a special if statement apart from
2275 ! degrade_ye, then we would hit the next conditional. But since
2276 ! we want the tendency to be zero anyway, not looping to jde+1
2277 ! will produce the same effect.
2278 ELSE IF( config_flags%polar .AND. (j == jde+1) ) THEN
2280 DO i = i_start, i_end
2281 tendency(i,k,j-1) = 0.
2286 IF( j > j_start) THEN
2288 DO i = i_start, i_end
2289 mrdy=msfvy(i,j-1)*rdy ! ADT eqn 45, 2nd term on RHS
2290 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
2304 ! next, x - flux divergence
2308 i_end = MIN(ite,ide-1)
2312 ! Polar boundary conditions are like open or specified
2313 IF ( config_flags%open_ys .or. specified .or. config_flags%polar ) j_start = MAX(jds+1,jts)
2314 IF ( config_flags%open_ye .or. specified .or. config_flags%polar ) j_end = MIN(jde-1,jte)
2316 ! 3rd or 4th order flux has a 5 point stencil, so compute
2317 ! bounds so we can switch to second order flux close to the boundary
2324 i_start_f = i_start+1
2334 DO j = j_start, j_end
2336 ! 3rd or 4th order flux
2339 DO i = i_start_f, i_end_f
2340 vel = 0.5*(ru(i,k,j)+ru(i,k,j-1))
2341 fqx( i, k ) = vel*flux4( v(i-2,k,j), v(i-1,k,j), &
2342 v(i ,k,j), v(i+1,k,j), &
2347 ! second order flux close to boundaries (if not periodic or symmetric)
2349 IF( degrade_xs ) THEN
2351 fqx(i_start,k) = 0.25*(ru(i_start,k,j)+ru(i_start,k,j-1)) &
2352 *(v(i_start,k,j)+v(i_start-1,k,j))
2356 IF( degrade_xe ) THEN
2358 fqx(i_end+1,k) = 0.25*(ru(i_end+1,k,j)+ru(i_end+1,k,j-1)) &
2359 *(v(i_end+1,k,j)+v(i_end,k,j))
2363 ! x flux-divergence into tendency
2366 DO i = i_start, i_end
2367 mrdx=msfvy(i,j)*rdx ! ADT eqn 45, 1st term on RHS
2368 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
2374 ELSE IF( horz_order == 3 ) THEN
2376 ! determine boundary mods for flux operators
2377 ! We degrade the flux operators from 3rd/4th order
2378 ! to second order one gridpoint in from the boundaries for
2379 ! all boundary conditions except periodic and symmetry - these
2380 ! conditions have boundary zone data fill for correct application
2381 ! of the higher order flux stencils
2388 IF( config_flags%periodic_x .or. &
2389 config_flags%symmetric_xs .or. &
2390 (its > ids+2) ) degrade_xs = .false.
2391 IF( config_flags%periodic_x .or. &
2392 config_flags%symmetric_xe .or. &
2393 (ite < ide-2) ) degrade_xe = .false.
2394 IF( config_flags%periodic_y .or. &
2395 config_flags%symmetric_ys .or. &
2396 (jts > jds+2) ) degrade_ys = .false.
2397 IF( config_flags%periodic_y .or. &
2398 config_flags%symmetric_ye .or. &
2399 (jte < jde-2) ) degrade_ye = .false.
2401 !--------------- y - advection first
2407 i_end = MIN(ite,ide-1)
2411 ! 3rd or 4th order flux has a 5 point stencil, so compute
2412 ! bounds so we can switch to second order flux close to the boundary
2417 !CJM May not work with tiling because defined in terms of domain dims
2420 j_start_f = j_start+1
2429 ! specified uses upstream normal wind at boundaries
2434 DO j = j_start, j_end+1
2436 IF ((j == j_start) .and. degrade_ys) THEN
2438 DO i = i_start, i_end
2440 IF (specified .AND. v(i,k,j) .LT. 0.)vb = v(i,k,j)
2441 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i,k,j-1)) &
2445 ELSE IF ((j == j_end+1) .and. degrade_ye) THEN
2447 DO i = i_start, i_end
2449 IF (specified .AND. v(i,k,j-1) .GT. 0.)vb = v(i,k,j-1)
2450 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i,k,j-1)) &
2456 DO i = i_start, i_end
2457 vel = 0.5*(rv(i,k,j)+rv(i,k,j-1))
2458 fqy( i,k,jp1 ) = vel*flux3( v(i,k,j-2), v(i,k,j-1), &
2459 v(i,k,j ), v(i,k,j+1), &
2465 ! Comments on polar boundary conditions
2466 ! No advection over the poles means tendencies (held from jds [S. pole]
2467 ! to jde [N pole], i.e., on v grid) must be zero at poles
2468 ! [tendency(jds) and tendency(jde)=0]
2469 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
2471 DO i = i_start, i_end
2472 tendency(i,k,j-1) = 0.
2475 ! If j_end were set to jde in a special if statement apart from
2476 ! degrade_ye, then we would hit the next conditional. But since
2477 ! we want the tendency to be zero anyway, not looping to jde+1
2478 ! will produce the same effect.
2479 ELSE IF( config_flags%polar .AND. (j == jde+1) ) THEN
2481 DO i = i_start, i_end
2482 tendency(i,k,j-1) = 0.
2487 IF( j > j_start) THEN
2489 DO i = i_start, i_end
2490 mrdy=msfvy(i,j-1)*rdy ! ADT eqn 45, 2nd term on RHS
2491 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
2505 ! next, x - flux divergence
2509 i_end = MIN(ite,ide-1)
2513 ! Polar boundary conditions are like open or specified
2514 IF ( config_flags%open_ys .or. specified .or. config_flags%polar ) j_start = MAX(jds+1,jts)
2515 IF ( config_flags%open_ye .or. specified .or. config_flags%polar ) j_end = MIN(jde-1,jte)
2517 ! 3rd or 4th order flux has a 5 point stencil, so compute
2518 ! bounds so we can switch to second order flux close to the boundary
2525 i_start_f = i_start+1
2535 DO j = j_start, j_end
2537 ! 3rd or 4th order flux
2540 DO i = i_start_f, i_end_f
2541 vel = 0.5*(ru(i,k,j)+ru(i,k,j-1))
2542 fqx( i, k ) = vel*flux3( v(i-2,k,j), v(i-1,k,j), &
2543 v(i ,k,j), v(i+1,k,j), &
2548 ! second order flux close to boundaries (if not periodic or symmetric)
2550 IF( degrade_xs ) THEN
2552 fqx(i_start,k) = 0.25*(ru(i_start,k,j)+ru(i_start,k,j-1)) &
2553 *(v(i_start,k,j)+v(i_start-1,k,j))
2557 IF( degrade_xe ) THEN
2559 fqx(i_end+1,k) = 0.25*(ru(i_end+1,k,j)+ru(i_end+1,k,j-1)) &
2560 *(v(i_end+1,k,j)+v(i_end,k,j))
2564 ! x flux-divergence into tendency
2567 DO i = i_start, i_end
2568 mrdx=msfvy(i,j)*rdx ! ADT eqn 45, 1st term on RHS
2569 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
2575 ELSE IF( horz_order == 2 ) THEN
2579 i_end = MIN(ite,ide-1)
2583 IF ( config_flags%open_ys ) j_start = MAX(jds+1,jts)
2584 IF ( config_flags%open_ye ) j_end = MIN(jde-1,jte)
2585 IF ( specified ) j_start = MAX(jds+2,jts)
2586 IF ( specified ) j_end = MIN(jde-2,jte)
2587 IF ( config_flags%polar ) j_start = MAX(jds+1,jts)
2588 IF ( config_flags%polar ) j_end = MIN(jde-1,jte)
2590 DO j = j_start, j_end
2592 DO i = i_start, i_end
2594 mrdy=msfvy(i,j)*rdy ! ADT eqn 45, 2nd term on RHS
2596 tendency(i,k,j)=tendency(i,k,j) -mrdy*0.25 &
2597 *((rv(i,k,j+1)+rv(i,k,j ))*(v(i,k,j+1)+v(i,k,j )) &
2598 -(rv(i,k,j )+rv(i,k,j-1))*(v(i,k,j )+v(i,k,j-1)))
2604 ! Comments on polar boundary conditions
2605 ! tendencies = 0 at poles, and polar points do not contribute at points
2607 IF (config_flags%polar) THEN
2608 IF (jts == jds) THEN
2610 DO i = i_start, i_end
2611 tendency(i,k,jds) = 0.
2615 IF (jte == jde) THEN
2617 DO i = i_start, i_end
2618 tendency(i,k,jde) = 0.
2624 ! specified uses upstream normal wind at boundaries
2626 IF ( specified .AND. jts .LE. jds+1 ) THEN
2629 DO i = i_start, i_end
2630 mrdy=msfvy(i,j)*rdy ! ADT eqn 45, 2nd term on RHS
2632 IF (v(i,k,j) .LT. 0.) vb = v(i,k,j)
2634 tendency(i,k,j)=tendency(i,k,j) -mrdy*0.25 &
2635 *((rv(i,k,j+1)+rv(i,k,j ))*(v(i,k,j+1)+v(i,k,j )) &
2636 -(rv(i,k,j )+rv(i,k,j-1))*(v(i,k,j )+vb))
2642 IF ( specified .AND. jte .GE. jde-1 ) THEN
2645 DO i = i_start, i_end
2647 mrdy=msfvy(i,j)*rdy ! ADT eqn 45, 2nd term on RHS
2649 IF (v(i,k,j) .GT. 0.) vb = v(i,k,j)
2651 tendency(i,k,j)=tendency(i,k,j) -mrdy*0.25 &
2652 *((rv(i,k,j+1)+rv(i,k,j ))*(vb+v(i,k,j )) &
2653 -(rv(i,k,j )+rv(i,k,j-1))*(v(i,k,j )+v(i,k,j-1)))
2659 IF ( .NOT. config_flags%periodic_x ) THEN
2660 IF ( config_flags%open_xs .or. specified ) i_start = MAX(ids+1,its)
2661 IF ( config_flags%open_xe .or. specified ) i_end = MIN(ide-2,ite)
2663 IF ( config_flags%polar ) j_start = MAX(jds+1,jts)
2664 IF ( config_flags%polar ) j_end = MIN(jde-1,jte)
2666 DO j = j_start, j_end
2668 DO i = i_start, i_end
2670 mrdx=msfvy(i,j)*rdx ! ADT eqn 45, 1st term on RHS
2672 tendency(i,k,j)=tendency(i,k,j)-mrdx*0.25 &
2673 *((ru(i+1,k,j)+ru(i+1,k,j-1))*(v(i+1,k,j)+v(i ,k,j)) &
2674 -(ru(i ,k,j)+ru(i ,k,j-1))*(v(i ,k,j)+v(i-1,k,j)))
2680 ELSE IF ( horz_order == 0 ) THEN
2682 ! Just in case we want to turn horizontal advection off, we can do it
2687 WRITE ( wrf_err_message , * ) 'module_advect: advect_v_6a: h_order not known ',horz_order
2688 CALL wrf_error_fatal ( TRIM( wrf_err_message ) )
2690 ENDIF horizontal_order_test
2692 ! Comments on polar boundary condition
2693 ! Force tendency=0 at NP and SP
2694 ! We keep setting this everywhere, but it can't hurt...
2695 IF ( config_flags%polar .AND. (jts == jds) ) THEN
2698 tendency(i,k,jts)=0.
2702 IF ( config_flags%polar .AND. (jte == jde) ) THEN
2705 tendency(i,k,jte)=0.
2710 ! radiative lateral boundary condition in y for normal velocity (v)
2712 IF ( (config_flags%open_ys) .and. jts == jds ) THEN
2715 i_end = MIN(ite,ide-1)
2717 DO i = i_start, i_end
2719 vb = MIN(rv(i,k,jts)-cb*(c1(k)*mut(i,jts)+c2(k)), 0.)
2720 tendency(i,k,jts) = tendency(i,k,jts) &
2721 - rdy*vb*(v_old(i,k,jts+1) - v_old(i,k,jts))
2727 IF ( (config_flags%open_ye) .and. jte == jde ) THEN
2730 i_end = MIN(ite,ide-1)
2732 DO i = i_start, i_end
2734 vb = MAX(rv(i,k,jte)+cb*(c1(k)*mut(i,jte-1)+c2(k)), 0.)
2735 tendency(i,k,jte) = tendency(i,k,jte) &
2736 - rdy*vb*(v_old(i,k,jte) - v_old(i,k,jte-1))
2742 ! pick up the rest of the horizontal radiation boundary conditions.
2743 ! (these are the computations that don't require 'cb'.
2744 ! first, set to index ranges
2747 j_end = MIN(jte,jde)
2752 IF (config_flags%open_ys) THEN
2753 j_start = MAX(jds+1, jts)
2756 IF (config_flags%open_ye) THEN
2757 j_end = MIN(jte,jde-1)
2761 ! compute x (u) conditions for v, w, or scalar
2763 IF( (config_flags%open_xs) .and. (its == ids)) THEN
2765 DO j = j_start, j_end
2767 mrdx=msfvy(its,j)*rdx ! ADT eqn 45, 1st term on RHS
2769 jm = MAX( jmin, j-1 )
2773 uw = 0.5*(ru(its,k,jp)+ru(its,k,jm))
2775 dup = ru(its+1,k,jp)-ru(its,k,jp)
2776 dum = ru(its+1,k,jm)-ru(its,k,jm)
2777 tendency(its,k,j)=tendency(its,k,j)-mrdx*( &
2778 ub*(v_old(its+1,k,j)-v_old(its,k,j)) &
2779 +0.5*v(its,k,j)*(dup+dum))
2785 IF( (config_flags%open_xe) .and. (ite == ide) ) THEN
2786 DO j = j_start, j_end
2788 mrdx=msfvy(ite-1,j)*rdx ! ADT eqn 45, 1st term on RHS
2790 jm = MAX( jmin, j-1 )
2794 uw = 0.5*(ru(ite,k,jp)+ru(ite,k,jm))
2796 dup = ru(ite,k,jp)-ru(ite-1,k,jp)
2797 dum = ru(ite,k,jm)-ru(ite-1,k,jm)
2799 ! tendency(ite-1,k,j)=tendency(ite-1,k,j)-mrdx*( &
2800 ! ub*(v_old(ite-1,k,j)-v_old(ite-2,k,j)) &
2801 ! +0.5*v(ite-1,k,j)* &
2802 ! ( ru(ite,k,jp)-ru(ite-1,k,jp) &
2803 ! +ru(ite,k,jm)-ru(ite-1,k,jm)) )
2804 tendency(ite-1,k,j)=tendency(ite-1,k,j)-mrdx*( &
2805 ub*(v_old(ite-1,k,j)-v_old(ite-2,k,j)) &
2806 +0.5*v(ite-1,k,j)*(dup+dum))
2813 !-------------------- vertical advection
2814 ! ADT eqn 45 has 3rd term on RHS = -(1/mx) partial d/dz (rho v w)
2815 ! Here we have: - partial d/dz (v*rom) = - partial d/dz (v rho w / my)
2816 ! We therefore need to make a correction for advect_v
2817 ! since 'my' (map scale factor in y direction) isn't a function of z,
2818 ! we can do this using *(my/mx) (see eqn. 45 for example)
2822 i_end = MIN(ite,ide-1)
2826 DO i = i_start, i_end
2831 ! Polar boundary conditions are like open or specified
2832 ! We don't want to calculate vertical v tendencies at the N or S pole
2833 IF ( config_flags%open_ys .or. specified .or. config_flags%polar ) j_start = MAX(jds+1,jts)
2834 IF ( config_flags%open_ye .or. specified .or. config_flags%polar ) j_end = MIN(jde-1,jte)
2836 vert_order_test : IF (vert_order == 6) THEN
2838 DO j = j_start, j_end
2842 DO i = i_start, i_end
2843 vel=0.5*(rom(i,k,j)+rom(i,k,j-1))
2844 vflux(i,k) = vel*flux6( &
2845 v(i,k-3,j), v(i,k-2,j), v(i,k-1,j), &
2846 v(i,k ,j), v(i,k+1,j), v(i,k+2,j), -vel )
2850 DO i = i_start, i_end
2852 vflux(i,k)=0.5*(rom(i,k,j)+rom(i,k,j-1)) &
2853 *(fzm(k)*v(i,k,j)+fzp(k)*v(i,k-1,j))
2855 vel=0.5*(rom(i,k,j)+rom(i,k,j-1))
2856 vflux(i,k) = vel*flux4( &
2857 v(i,k-2,j), v(i,k-1,j), &
2858 v(i,k ,j), v(i,k+1,j), -vel )
2860 vel=0.5*(rom(i,k,j)+rom(i,k,j-1))
2861 vflux(i,k) = vel*flux4( &
2862 v(i,k-2,j), v(i,k-1,j), &
2863 v(i,k ,j), v(i,k+1,j), -vel )
2865 vflux(i,k)=0.5*(rom(i,k,j)+rom(i,k,j-1)) &
2866 *(fzm(k)*v(i,k,j)+fzp(k)*v(i,k-1,j))
2872 DO i = i_start, i_end
2873 ! We are calculating vertical fluxes on v points,
2874 ! so we must mean msf_v_x/y variables
2875 tendency(i,k,j)=tendency(i,k,j)-(msfvy(i,j)/msfvx(i,j))*rdzw(k)*(vflux(i,k+1)-vflux(i,k)) ! ADT eqn 45, 3rd term on RHS
2881 ELSE IF (vert_order == 5) THEN
2883 DO j = j_start, j_end
2887 DO i = i_start, i_end
2888 vel=0.5*(rom(i,k,j)+rom(i,k,j-1))
2889 vflux(i,k) = vel*flux5( &
2890 v(i,k-3,j), v(i,k-2,j), v(i,k-1,j), &
2891 v(i,k ,j), v(i,k+1,j), v(i,k+2,j), -vel )
2895 DO i = i_start, i_end
2897 vflux(i,k)=0.5*(rom(i,k,j)+rom(i,k,j-1)) &
2898 *(fzm(k)*v(i,k,j)+fzp(k)*v(i,k-1,j))
2900 vel=0.5*(rom(i,k,j)+rom(i,k,j-1))
2901 vflux(i,k) = vel*flux3( &
2902 v(i,k-2,j), v(i,k-1,j), &
2903 v(i,k ,j), v(i,k+1,j), -vel )
2905 vel=0.5*(rom(i,k,j)+rom(i,k,j-1))
2906 vflux(i,k) = vel*flux3( &
2907 v(i,k-2,j), v(i,k-1,j), &
2908 v(i,k ,j), v(i,k+1,j), -vel )
2910 vflux(i,k)=0.5*(rom(i,k,j)+rom(i,k,j-1)) &
2911 *(fzm(k)*v(i,k,j)+fzp(k)*v(i,k-1,j))
2917 DO i = i_start, i_end
2918 ! We are calculating vertical fluxes on v points,
2919 ! so we must mean msf_v_x/y variables
2920 tendency(i,k,j)=tendency(i,k,j)-(msfvy(i,j)/msfvx(i,j))*rdzw(k)*(vflux(i,k+1)-vflux(i,k)) ! ADT eqn 45, 3rd term on RHS
2926 ELSE IF (vert_order == 4) THEN
2928 DO j = j_start, j_end
2932 DO i = i_start, i_end
2933 vel=0.5*(rom(i,k,j)+rom(i,k,j-1))
2934 vflux(i,k) = vel*flux4( &
2935 v(i,k-2,j), v(i,k-1,j), &
2936 v(i,k ,j), v(i,k+1,j), -vel )
2940 DO i = i_start, i_end
2942 vflux(i,k)=0.5*(rom(i,k,j)+rom(i,k,j-1)) &
2943 *(fzm(k)*v(i,k,j)+fzp(k)*v(i,k-1,j))
2945 vflux(i,k)=0.5*(rom(i,k,j)+rom(i,k,j-1)) &
2946 *(fzm(k)*v(i,k,j)+fzp(k)*v(i,k-1,j))
2952 DO i = i_start, i_end
2953 ! We are calculating vertical fluxes on v points,
2954 ! so we must mean msf_v_x/y variables
2955 tendency(i,k,j)=tendency(i,k,j)-(msfvy(i,j)/msfvx(i,j))*rdzw(k)*(vflux(i,k+1)-vflux(i,k)) ! ADT eqn 45, 3rd term on RHS
2961 ELSE IF (vert_order == 3) THEN
2963 DO j = j_start, j_end
2967 DO i = i_start, i_end
2968 vel=0.5*(rom(i,k,j)+rom(i,k,j-1))
2969 vflux(i,k) = vel*flux3( &
2970 v(i,k-2,j), v(i,k-1,j), &
2971 v(i,k ,j), v(i,k+1,j), -vel )
2975 DO i = i_start, i_end
2977 vflux(i,k)=0.5*(rom(i,k,j)+rom(i,k,j-1)) &
2978 *(fzm(k)*v(i,k,j)+fzp(k)*v(i,k-1,j))
2980 vflux(i,k)=0.5*(rom(i,k,j)+rom(i,k,j-1)) &
2981 *(fzm(k)*v(i,k,j)+fzp(k)*v(i,k-1,j))
2987 DO i = i_start, i_end
2988 ! We are calculating vertical fluxes on v points,
2989 ! so we must mean msf_v_x/y variables
2990 tendency(i,k,j)=tendency(i,k,j)-(msfvy(i,j)/msfvx(i,j))*rdzw(k)*(vflux(i,k+1)-vflux(i,k)) ! ADT eqn 45, 3rd term on RHS
2997 ELSE IF (vert_order == 2) THEN
2999 DO j = j_start, j_end
3001 DO i = i_start, i_end
3003 vflux(i,k)=0.5*(rom(i,k,j)+rom(i,k,j-1)) &
3004 *(fzm(k)*v(i,k,j)+fzp(k)*v(i,k-1,j))
3009 DO i = i_start, i_end
3010 ! We are calculating vertical fluxes on v points,
3011 ! so we must mean msf_v_x/y variables
3012 tendency(i,k,j)=tendency(i,k,j)-(msfvy(i,j)/msfvx(i,j))*rdzw(k)*(vflux(i,k+1)-vflux(i,k)) ! ADT eqn 45, 3rd term on RHS
3019 WRITE ( wrf_err_message , * ) 'module_advect: advect_v_6a: v_order not known ',vert_order
3020 CALL wrf_error_fatal ( TRIM( wrf_err_message ) )
3022 ENDIF vert_order_test
3024 END SUBROUTINE advect_v
3026 !-------------------------------------------------------------------
3029 SUBROUTINE advect_scalar ( field, field_old, tendency, &
3032 mut, time_step, config_flags, &
3033 msfux, msfuy, msfvx, msfvy, &
3037 ids, ide, jds, jde, kds, kde, &
3038 ims, ime, jms, jme, kms, kme, &
3039 its, ite, jts, jte, kts, kte )
3045 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
3047 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
3048 ims, ime, jms, jme, kms, kme, &
3049 its, ite, jts, jte, kts, kte
3051 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: field, &
3057 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut
3058 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
3060 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
3067 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
3073 REAL , INTENT(IN ) :: rdx, &
3075 INTEGER , INTENT(IN ) :: time_step
3080 INTEGER :: i, j, k, itf, jtf, ktf
3081 INTEGER :: i_start, i_end, j_start, j_end
3082 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
3083 INTEGER :: jmin, jmax, jp, jm, imin, imax
3085 REAL :: mrdx, mrdy, ub, vb, uw, vw
3086 REAL , DIMENSION(its:ite, kts:kte) :: vflux
3089 REAL, DIMENSION( its:ite+1, kts:kte ) :: fqx
3090 REAL, DIMENSION( its:ite, kts:kte, 2 ) :: fqy
3092 INTEGER :: horz_order, vert_order
3094 LOGICAL :: degrade_xs, degrade_ys
3095 LOGICAL :: degrade_xe, degrade_ye
3097 INTEGER :: jp1, jp0, jtmp
3100 ! definition of flux operators, 3rd, 4th, 5th or 6th order
3102 REAL :: flux3, flux4, flux5, flux6
3103 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel
3105 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
3106 ( 7.*(q_i + q_im1) - (q_ip1 + q_im2) )/12.0
3108 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
3109 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
3110 sign(1,time_step)*sign(1.,ua)*((q_ip1 - q_im2)-3.*(q_i-q_im1))/12.0
3112 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
3113 ( 37.*(q_i+q_im1) - 8.*(q_ip1+q_im2) &
3114 +(q_ip2+q_im3) )/60.0
3116 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
3117 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
3118 -sign(1,time_step)*sign(1.,ua)*( &
3119 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )/60.0
3122 LOGICAL :: specified
3125 if(config_flags%specified .or. config_flags%nested) specified = .true.
3127 ! set order for the advection schemes
3130 horz_order = config_flags%h_sca_adv_order
3131 vert_order = config_flags%v_sca_adv_order
3133 ! begin with horizontal flux divergence
3134 ! here is the choice of flux operators
3137 horizontal_order_test : IF( horz_order == 6 ) THEN
3139 ! determine boundary mods for flux operators
3140 ! We degrade the flux operators from 3rd/4th order
3141 ! to second order one gridpoint in from the boundaries for
3142 ! all boundary conditions except periodic and symmetry - these
3143 ! conditions have boundary zone data fill for correct application
3144 ! of the higher order flux stencils
3151 IF( config_flags%periodic_x .or. &
3152 config_flags%symmetric_xs .or. &
3153 (its > ids+3) ) degrade_xs = .false.
3154 IF( config_flags%periodic_x .or. &
3155 config_flags%symmetric_xe .or. &
3156 (ite < ide-3) ) degrade_xe = .false.
3157 IF( config_flags%periodic_y .or. &
3158 config_flags%symmetric_ys .or. &
3159 (jts > jds+3) ) degrade_ys = .false.
3160 IF( config_flags%periodic_y .or. &
3161 config_flags%symmetric_ye .or. &
3162 (jte < jde-4) ) degrade_ye = .false.
3164 !--------------- y - advection first
3168 i_end = MIN(ite,ide-1)
3170 j_end = MIN(jte,jde-1)
3172 ! higher order flux has a 5 or 7 point stencil, so compute
3173 ! bounds so we can switch to second order flux close to the boundary
3179 j_start = MAX(jts,jds+1)
3184 j_end = MIN(jte,jde-2)
3188 IF(config_flags%polar) j_end = MIN(jte,jde-1)
3190 ! compute fluxes, 5th or 6th order
3195 j_loop_y_flux_6 : DO j = j_start, j_end+1
3197 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN ! use full stencil
3200 DO i = i_start, i_end
3202 fqy( i, k, jp1 ) = vel*flux6( &
3203 field(i,k,j-3), field(i,k,j-2), field(i,k,j-1), &
3204 field(i,k,j ), field(i,k,j+1), field(i,k,j+2), vel )
3209 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
3212 DO i = i_start, i_end
3213 fqy(i,k, jp1) = 0.5*rv(i,k,j)* &
3214 (field(i,k,j)+field(i,k,j-1))
3219 ELSE IF ( j == jds+2 ) THEN ! 4th order flux 2 in from south boundary
3222 DO i = i_start, i_end
3224 fqy( i, k, jp1 ) = vel*flux4( &
3225 field(i,k,j-2),field(i,k,j-1),field(i,k,j),field(i,k,j+1),vel )
3229 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
3232 DO i = i_start, i_end
3233 fqy(i, k, jp1) = 0.5*rv(i,k,j)* &
3234 (field(i,k,j)+field(i,k,j-1))
3238 ELSE IF ( j == jde-2 ) THEN ! 3rd or 4th order flux 2 in from north boundary
3241 DO i = i_start, i_end
3243 fqy( i, k, jp1) = vel*flux4( &
3244 field(i,k,j-2),field(i,k,j-1), &
3245 field(i,k,j),field(i,k,j+1),vel )
3251 ! y flux-divergence into tendency
3253 ! Comments on polar boundary conditions
3254 ! Same process as for advect_u - tendencies run from jds to jde-1
3255 ! (latitudes are as for u grid, longitudes are displaced)
3256 ! Therefore: flow is only from one side for points next to poles
3257 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
3259 DO i = i_start, i_end
3260 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
3261 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
3264 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
3266 DO i = i_start, i_end
3267 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
3268 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
3273 IF(j > j_start) THEN
3276 DO i = i_start, i_end
3277 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
3278 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
3290 ENDDO j_loop_y_flux_6
3292 ! next, x - flux divergence
3295 i_end = MIN(ite,ide-1)
3298 j_end = MIN(jte,jde-1)
3300 ! higher order flux has a 5 or 7 point stencil, so compute
3301 ! bounds so we can switch to second order flux close to the boundary
3307 i_start = MAX(ids+1,its)
3308 ! i_start_f = i_start+2
3309 i_start_f = MIN(i_start+2,ids+3)
3313 i_end = MIN(ide-2,ite)
3319 DO j = j_start, j_end
3321 ! 5th or 6th order flux
3324 DO i = i_start_f, i_end_f
3326 fqx( i,k ) = vel*flux6( field(i-3,k,j), field(i-2,k,j), &
3327 field(i-1,k,j), field(i ,k,j), &
3328 field(i+1,k,j), field(i+2,k,j), &
3333 ! lower order fluxes close to boundaries (if not periodic or symmetric)
3335 IF( degrade_xs ) THEN
3337 DO i=i_start,i_start_f-1
3339 IF(i == ids+1) THEN ! second order
3341 fqx(i,k) = 0.5*(ru(i,k,j)) &
3342 *(field(i,k,j)+field(i-1,k,j))
3346 IF(i == ids+2) THEN ! third order
3349 fqx( i,k ) = vel*flux4( field(i-2,k,j), field(i-1,k,j), &
3350 field(i ,k,j), field(i+1,k,j), &
3359 IF( degrade_xe ) THEN
3361 DO i = i_end_f+1, i_end+1
3363 IF( i == ide-1 ) THEN ! second order flux next to the boundary
3365 fqx(i,k) = 0.5*(ru(i,k,j)) &
3366 *(field(i,k,j)+field(i-1,k,j))
3370 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
3373 fqx( i,k ) = vel*flux4( field(i-2,k,j), field(i-1,k,j), &
3374 field(i ,k,j), field(i+1,k,j), &
3383 ! x flux-divergence into tendency
3386 DO i = i_start, i_end
3387 mrdx=msftx(i,j)*rdx ! see ADT eqn 48 [rho->rho*q] dividing by my, 1st term RHS
3388 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
3394 ELSE IF( horz_order == 5 ) THEN
3396 ! determine boundary mods for flux operators
3397 ! We degrade the flux operators from 3rd/4th order
3398 ! to second order one gridpoint in from the boundaries for
3399 ! all boundary conditions except periodic and symmetry - these
3400 ! conditions have boundary zone data fill for correct application
3401 ! of the higher order flux stencils
3408 IF( config_flags%periodic_x .or. &
3409 config_flags%symmetric_xs .or. &
3410 (its > ids+3) ) degrade_xs = .false.
3411 IF( config_flags%periodic_x .or. &
3412 config_flags%symmetric_xe .or. &
3413 (ite < ide-3) ) degrade_xe = .false.
3414 IF( config_flags%periodic_y .or. &
3415 config_flags%symmetric_ys .or. &
3416 (jts > jds+3) ) degrade_ys = .false.
3417 IF( config_flags%periodic_y .or. &
3418 config_flags%symmetric_ye .or. &
3419 (jte < jde-4) ) degrade_ye = .false.
3421 !--------------- y - advection first
3425 i_end = MIN(ite,ide-1)
3427 j_end = MIN(jte,jde-1)
3429 ! higher order flux has a 5 or 7 point stencil, so compute
3430 ! bounds so we can switch to second order flux close to the boundary
3436 j_start = MAX(jts,jds+1)
3441 j_end = MIN(jte,jde-2)
3445 IF(config_flags%polar) j_end = MIN(jte,jde-1)
3447 ! compute fluxes, 5th or 6th order
3452 j_loop_y_flux_5 : DO j = j_start, j_end+1
3454 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN ! use full stencil
3457 DO i = i_start, i_end
3459 fqy( i, k, jp1 ) = vel*flux5( &
3460 field(i,k,j-3), field(i,k,j-2), field(i,k,j-1), &
3461 field(i,k,j ), field(i,k,j+1), field(i,k,j+2), vel )
3466 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
3469 DO i = i_start, i_end
3470 fqy(i,k, jp1) = 0.5*rv(i,k,j)* &
3471 (field(i,k,j)+field(i,k,j-1))
3476 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
3479 DO i = i_start, i_end
3481 fqy( i, k, jp1 ) = vel*flux3( &
3482 field(i,k,j-2),field(i,k,j-1),field(i,k,j),field(i,k,j+1),vel )
3486 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
3489 DO i = i_start, i_end
3490 fqy(i, k, jp1) = 0.5*rv(i,k,j)* &
3491 (field(i,k,j)+field(i,k,j-1))
3495 ELSE IF ( j == jde-2 ) THEN ! 3rd or 4th order flux 2 in from north boundary
3498 DO i = i_start, i_end
3500 fqy( i, k, jp1) = vel*flux3( &
3501 field(i,k,j-2),field(i,k,j-1), &
3502 field(i,k,j),field(i,k,j+1),vel )
3508 ! y flux-divergence into tendency
3510 ! Comments on polar boundary conditions
3511 ! Same process as for advect_u - tendencies run from jds to jde-1
3512 ! (latitudes are as for u grid, longitudes are displaced)
3513 ! Therefore: flow is only from one side for points next to poles
3514 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
3516 DO i = i_start, i_end
3517 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
3518 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
3521 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
3523 DO i = i_start, i_end
3524 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
3525 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
3530 IF(j > j_start) THEN
3533 DO i = i_start, i_end
3534 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
3535 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
3547 ENDDO j_loop_y_flux_5
3549 ! next, x - flux divergence
3552 i_end = MIN(ite,ide-1)
3555 j_end = MIN(jte,jde-1)
3557 ! higher order flux has a 5 or 7 point stencil, so compute
3558 ! bounds so we can switch to second order flux close to the boundary
3564 i_start = MAX(ids+1,its)
3565 ! i_start_f = i_start+2
3566 i_start_f = MIN(i_start+2,ids+3)
3570 i_end = MIN(ide-2,ite)
3576 DO j = j_start, j_end
3578 ! 5th or 6th order flux
3581 DO i = i_start_f, i_end_f
3583 fqx( i,k ) = vel*flux5( field(i-3,k,j), field(i-2,k,j), &
3584 field(i-1,k,j), field(i ,k,j), &
3585 field(i+1,k,j), field(i+2,k,j), &
3590 ! lower order fluxes close to boundaries (if not periodic or symmetric)
3592 IF( degrade_xs ) THEN
3594 DO i=i_start,i_start_f-1
3596 IF(i == ids+1) THEN ! second order
3598 fqx(i,k) = 0.5*(ru(i,k,j)) &
3599 *(field(i,k,j)+field(i-1,k,j))
3603 IF(i == ids+2) THEN ! third order
3606 fqx( i,k ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
3607 field(i ,k,j), field(i+1,k,j), &
3616 IF( degrade_xe ) THEN
3618 DO i = i_end_f+1, i_end+1
3620 IF( i == ide-1 ) THEN ! second order flux next to the boundary
3622 fqx(i,k) = 0.5*(ru(i,k,j)) &
3623 *(field(i,k,j)+field(i-1,k,j))
3627 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
3630 fqx( i,k ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
3631 field(i ,k,j), field(i+1,k,j), &
3640 ! x flux-divergence into tendency
3643 DO i = i_start, i_end
3644 mrdx=msftx(i,j)*rdx ! see ADT eqn 48 [rho->rho*q] dividing by my, 1st term RHS
3645 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
3652 ELSE IF( horz_order == 4 ) THEN
3659 IF( config_flags%periodic_x .or. &
3660 config_flags%symmetric_xs .or. &
3661 (its > ids+2) ) degrade_xs = .false.
3662 IF( config_flags%periodic_x .or. &
3663 config_flags%symmetric_xe .or. &
3664 (ite < ide-2) ) degrade_xe = .false.
3665 IF( config_flags%periodic_y .or. &
3666 config_flags%symmetric_ys .or. &
3667 (jts > jds+2) ) degrade_ys = .false.
3668 IF( config_flags%periodic_y .or. &
3669 config_flags%symmetric_ye .or. &
3670 (jte < jde-3) ) degrade_ye = .false.
3672 ! begin flux computations
3673 ! start with x flux divergence
3678 i_end = MIN(ite,ide-1)
3680 j_end = MIN(jte,jde-1)
3682 ! 3rd or 4th order flux has a 5 point stencil, so compute
3683 ! bounds so we can switch to second order flux close to the boundary
3690 i_start_f = i_start+1
3700 DO j = j_start, j_end
3702 ! 3rd or 4th order flux
3705 DO i = i_start_f, i_end_f
3707 fqx( i, k) = ru(i,k,j)*flux4( field(i-2,k,j), field(i-1,k,j), &
3708 field(i ,k,j), field(i+1,k,j), &
3713 ! second order flux close to boundaries (if not periodic or symmetric)
3715 IF( degrade_xs ) THEN
3717 fqx(i_start, k) = 0.5*ru(i_start,k,j) &
3718 *(field(i_start,k,j)+field(i_start-1,k,j))
3722 IF( degrade_xe ) THEN
3724 fqx(i_end+1,k ) = 0.5*ru(i_end+1,k,j) &
3725 *(field(i_end+1,k,j)+field(i_end,k,j))
3729 ! x flux-divergence into tendency
3732 DO i = i_start, i_end
3733 mrdx=msftx(i,j)*rdx ! see ADT eqn 48 [rho->rho*q] dividing by my, 1st term RHS
3734 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
3741 ! next -> y flux divergence calculation
3744 i_end = MIN(ite,ide-1)
3746 j_end = MIN(jte,jde-1)
3748 ! 3rd or 4th order flux has a 5 point stencil, so compute
3749 ! bounds so we can switch to second order flux close to the boundary
3756 j_start_f = j_start+1
3764 IF(config_flags%polar) j_end = MIN(jte,jde-1)
3769 DO j = j_start, j_end+1
3771 IF ((j < j_start_f) .and. degrade_ys) THEN
3773 DO i = i_start, i_end
3774 fqy(i,k,jp1) = 0.5*rv(i,k,j_start) &
3775 *(field(i,k,j_start)+field(i,k,j_start-1))
3778 ELSE IF ((j > j_end_f) .and. degrade_ye) THEN
3780 DO i = i_start, i_end
3781 ! Assumes j>j_end_f is ONLY j_end+1 ...
3782 ! fqy(i,k,jp1) = 0.5*rv(i,k,j_end+1) &
3783 ! *(field(i,k,j_end+1)+field(i,k,j_end))
3784 fqy(i,k,jp1) = 0.5*rv(i,k,j) &
3785 *(field(i,k,j)+field(i,k,j-1))
3789 ! 3rd or 4th order flux
3791 DO i = i_start, i_end
3792 fqy( i, k, jp1 ) = rv(i,k,j)*flux4( field(i,k,j-2), field(i,k,j-1), &
3793 field(i,k,j ), field(i,k,j+1), &
3799 ! y flux-divergence into tendency
3801 ! Comments on polar boundary conditions
3802 ! Same process as for advect_u - tendencies run from jds to jde-1
3803 ! (latitudes are as for u grid, longitudes are displaced)
3804 ! Therefore: flow is only from one side for points next to poles
3805 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
3807 DO i = i_start, i_end
3808 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
3809 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
3812 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
3814 DO i = i_start, i_end
3815 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
3816 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
3821 IF ( j > j_start ) THEN
3824 DO i = i_start, i_end
3825 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
3826 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
3841 ELSE IF( horz_order == 3 ) THEN
3848 IF( config_flags%periodic_x .or. &
3849 config_flags%symmetric_xs .or. &
3850 (its > ids+2) ) degrade_xs = .false.
3851 IF( config_flags%periodic_x .or. &
3852 config_flags%symmetric_xe .or. &
3853 (ite < ide-2) ) degrade_xe = .false.
3854 IF( config_flags%periodic_y .or. &
3855 config_flags%symmetric_ys .or. &
3856 (jts > jds+2) ) degrade_ys = .false.
3857 IF( config_flags%periodic_y .or. &
3858 config_flags%symmetric_ye .or. &
3859 (jte < jde-3) ) degrade_ye = .false.
3861 ! begin flux computations
3862 ! start with x flux divergence
3867 i_end = MIN(ite,ide-1)
3869 j_end = MIN(jte,jde-1)
3871 ! 3rd or 4th order flux has a 5 point stencil, so compute
3872 ! bounds so we can switch to second order flux close to the boundary
3879 i_start_f = i_start+1
3889 DO j = j_start, j_end
3891 ! 3rd or 4th order flux
3894 DO i = i_start_f, i_end_f
3896 fqx( i, k) = ru(i,k,j)*flux3( field(i-2,k,j), field(i-1,k,j), &
3897 field(i ,k,j), field(i+1,k,j), &
3902 ! second order flux close to boundaries (if not periodic or symmetric)
3904 IF( degrade_xs ) THEN
3906 fqx(i_start, k) = 0.5*ru(i_start,k,j) &
3907 *(field(i_start,k,j)+field(i_start-1,k,j))
3911 IF( degrade_xe ) THEN
3913 fqx(i_end+1,k ) = 0.5*ru(i_end+1,k,j) &
3914 *(field(i_end+1,k,j)+field(i_end,k,j))
3918 ! x flux-divergence into tendency
3921 DO i = i_start, i_end
3922 mrdx=msftx(i,j)*rdx ! see ADT eqn 48 [rho->rho*q] dividing by my, 1st term RHS
3923 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
3930 ! next -> y flux divergence calculation
3933 i_end = MIN(ite,ide-1)
3935 j_end = MIN(jte,jde-1)
3937 ! 3rd or 4th order flux has a 5 point stencil, so compute
3938 ! bounds so we can switch to second order flux close to the boundary
3945 j_start_f = j_start+1
3953 IF(config_flags%polar) j_end = MIN(jte,jde-1)
3958 DO j = j_start, j_end+1
3960 IF ((j < j_start_f) .and. degrade_ys) THEN
3962 DO i = i_start, i_end
3963 fqy(i,k,jp1) = 0.5*rv(i,k,j_start) &
3964 *(field(i,k,j_start)+field(i,k,j_start-1))
3967 ELSE IF ((j > j_end_f) .and. degrade_ye) THEN
3969 DO i = i_start, i_end
3970 ! Assumes j>j_end_f is ONLY j_end+1 ...
3971 ! fqy(i,k,jp1) = 0.5*rv(i,k,j_end+1) &
3972 ! *(field(i,k,j_end+1)+field(i,k,j_end))
3973 fqy(i,k,jp1) = 0.5*rv(i,k,j) &
3974 *(field(i,k,j)+field(i,k,j-1))
3978 ! 3rd or 4th order flux
3980 DO i = i_start, i_end
3981 fqy( i, k, jp1 ) = rv(i,k,j)*flux3( field(i,k,j-2), field(i,k,j-1), &
3982 field(i,k,j ), field(i,k,j+1), &
3988 ! y flux-divergence into tendency
3990 ! Comments on polar boundary conditions
3991 ! Same process as for advect_u - tendencies run from jds to jde-1
3992 ! (latitudes are as for u grid, longitudes are displaced)
3993 ! Therefore: flow is only from one side for points next to poles
3994 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
3996 DO i = i_start, i_end
3997 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
3998 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
4001 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
4003 DO i = i_start, i_end
4004 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
4005 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
4010 IF ( j > j_start ) THEN
4013 DO i = i_start, i_end
4014 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
4015 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
4029 ELSE IF( horz_order == 2 ) THEN
4032 i_end = MIN(ite,ide-1)
4034 j_end = MIN(jte,jde-1)
4036 IF ( .NOT. config_flags%periodic_x ) THEN
4037 IF ( config_flags%open_xs .or. specified ) i_start = MAX(ids+1,its)
4038 IF ( config_flags%open_xe .or. specified ) i_end = MIN(ide-2,ite)
4041 DO j = j_start, j_end
4043 DO i = i_start, i_end
4044 mrdx=msftx(i,j)*rdx ! see ADT eqn 48 [rho->rho*q] dividing by my, 1st term RHS
4045 tendency(i,k,j)=tendency(i,k,j)-mrdx*0.5 &
4046 *(ru(i+1,k,j)*(field(i+1,k,j)+field(i ,k,j)) &
4047 -ru(i ,k,j)*(field(i ,k,j)+field(i-1,k,j)))
4053 i_end = MIN(ite,ide-1)
4055 ! Polar boundary conditions are like open or specified
4056 IF ( config_flags%open_ys .or. specified .or. config_flags%polar ) j_start = MAX(jds+1,jts)
4057 IF ( config_flags%open_ye .or. specified .or. config_flags%polar ) j_end = MIN(jde-2,jte)
4059 DO j = j_start, j_end
4061 DO i = i_start, i_end
4062 mrdy=msftx(i,j)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
4063 tendency(i,k,j)=tendency(i,k,j) -mrdy*0.5 &
4064 *(rv(i,k,j+1)*(field(i,k,j+1)+field(i,k,j )) &
4065 -rv(i,k,j )*(field(i,k,j )+field(i,k,j-1)))
4070 ! Polar boundary condtions
4071 ! These won't be covered in the loop above...
4072 IF (config_flags%polar) THEN
4073 IF (jts == jds) THEN
4075 DO i = i_start, i_end
4076 mrdy=msftx(i,jds)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
4077 tendency(i,k,jds)=tendency(i,k,jds) -mrdy*0.5 &
4078 *rv(i,k,jds+1)*(field(i,k,jds+1)+field(i,k,jds))
4082 IF (jte == jde) THEN
4084 DO i = i_start, i_end
4085 mrdy=msftx(i,jde-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
4086 tendency(i,k,jde-1)=tendency(i,k,jde-1) +mrdy*0.5 &
4087 *rv(i,k,jde-1)*(field(i,k,jde-1)+field(i,k,jde-2))
4093 ELSE IF ( horz_order == 0 ) THEN
4095 ! Just in case we want to turn horizontal advection off, we can do it
4099 WRITE ( wrf_err_message , * ) 'module_advect: advect_scalar_6a, h_order not known ',horz_order
4100 CALL wrf_error_fatal ( TRIM( wrf_err_message ) )
4102 ENDIF horizontal_order_test
4104 ! pick up the rest of the horizontal radiation boundary conditions.
4105 ! (these are the computations that don't require 'cb'.
4106 ! first, set to index ranges
4109 i_end = MIN(ite,ide-1)
4111 j_end = MIN(jte,jde-1)
4113 ! compute x (u) conditions for v, w, or scalar
4115 IF( (config_flags%open_xs) .and. (its == ids) ) THEN
4117 DO j = j_start, j_end
4119 ub = MIN( 0.5*(ru(its,k,j)+ru(its+1,k,j)), 0. )
4120 tendency(its,k,j) = tendency(its,k,j) &
4122 ub*( field_old(its+1,k,j) &
4123 - field_old(its ,k,j) ) + &
4124 field(its,k,j)*(ru(its+1,k,j)-ru(its,k,j)) &
4131 IF( (config_flags%open_xe) .and. (ite == ide) ) THEN
4133 DO j = j_start, j_end
4135 ub = MAX( 0.5*(ru(ite-1,k,j)+ru(ite,k,j)), 0. )
4136 tendency(i_end,k,j) = tendency(i_end,k,j) &
4138 ub*( field_old(i_end ,k,j) &
4139 - field_old(i_end-1,k,j) ) + &
4140 field(i_end,k,j)*(ru(ite,k,j)-ru(ite-1,k,j)) &
4147 IF( (config_flags%open_ys) .and. (jts == jds) ) THEN
4149 DO i = i_start, i_end
4151 vb = MIN( 0.5*(rv(i,k,jts)+rv(i,k,jts+1)), 0. )
4152 tendency(i,k,jts) = tendency(i,k,jts) &
4154 vb*( field_old(i,k,jts+1) &
4155 - field_old(i,k,jts ) ) + &
4156 field(i,k,jts)*(rv(i,k,jts+1)-rv(i,k,jts)) &
4163 IF( (config_flags%open_ye) .and. (jte == jde)) THEN
4165 DO i = i_start, i_end
4167 vb = MAX( 0.5*(rv(i,k,jte-1)+rv(i,k,jte)), 0. )
4168 tendency(i,k,j_end) = tendency(i,k,j_end) &
4170 vb*( field_old(i,k,j_end ) &
4171 - field_old(i,k,j_end-1) ) + &
4172 field(i,k,j_end)*(rv(i,k,jte)-rv(i,k,jte-1)) &
4180 !-------------------- vertical advection
4181 ! Scalar equation has 3rd term on RHS = - partial d/dz (q rho w /my)
4182 ! Here we have: - partial d/dz (q*rom) = - partial d/dz (q rho w / my)
4183 ! So we don't need to make a correction for advect_scalar
4186 i_end = MIN(ite,ide-1)
4188 j_end = MIN(jte,jde-1)
4190 DO i = i_start, i_end
4195 vert_order_test : IF (vert_order == 6) THEN
4197 DO j = j_start, j_end
4200 DO i = i_start, i_end
4202 vflux(i,k) = vel*flux6( &
4203 field(i,k-3,j), field(i,k-2,j), field(i,k-1,j), &
4204 field(i,k ,j), field(i,k+1,j), field(i,k+2,j), -vel )
4208 DO i = i_start, i_end
4211 vflux(i,k)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
4215 vflux(i,k) = vel*flux4( &
4216 field(i,k-2,j), field(i,k-1,j), &
4217 field(i,k ,j), field(i,k+1,j), -vel )
4220 vflux(i,k) = vel*flux4( &
4221 field(i,k-2,j), field(i,k-1,j), &
4222 field(i,k ,j), field(i,k+1,j), -vel )
4225 vflux(i,k)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
4229 DO i = i_start, i_end
4230 tendency(i,k,j)=tendency(i,k,j)-rdzw(k)*(vflux(i,k+1)-vflux(i,k))
4236 ELSE IF (vert_order == 5) THEN
4238 DO j = j_start, j_end
4241 DO i = i_start, i_end
4243 vflux(i,k) = vel*flux5( &
4244 field(i,k-3,j), field(i,k-2,j), field(i,k-1,j), &
4245 field(i,k ,j), field(i,k+1,j), field(i,k+2,j), -vel )
4249 DO i = i_start, i_end
4252 vflux(i,k)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
4256 vflux(i,k) = vel*flux3( &
4257 field(i,k-2,j), field(i,k-1,j), &
4258 field(i,k ,j), field(i,k+1,j), -vel )
4261 vflux(i,k) = vel*flux3( &
4262 field(i,k-2,j), field(i,k-1,j), &
4263 field(i,k ,j), field(i,k+1,j), -vel )
4266 vflux(i,k)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
4270 DO i = i_start, i_end
4271 tendency(i,k,j)=tendency(i,k,j)-rdzw(k)*(vflux(i,k+1)-vflux(i,k))
4277 ELSE IF (vert_order == 4) THEN
4279 DO j = j_start, j_end
4282 DO i = i_start, i_end
4284 vflux(i,k) = vel*flux4( &
4285 field(i,k-2,j), field(i,k-1,j), &
4286 field(i,k ,j), field(i,k+1,j), -vel )
4290 DO i = i_start, i_end
4293 vflux(i,k)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
4295 vflux(i,k)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
4299 DO i = i_start, i_end
4300 tendency(i,k,j)=tendency(i,k,j)-rdzw(k)*(vflux(i,k+1)-vflux(i,k))
4306 ELSE IF (vert_order == 3) THEN
4308 DO j = j_start, j_end
4311 DO i = i_start, i_end
4313 vflux(i,k) = vel*flux3( &
4314 field(i,k-2,j), field(i,k-1,j), &
4315 field(i,k ,j), field(i,k+1,j), -vel )
4319 DO i = i_start, i_end
4322 vflux(i,k)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
4324 vflux(i,k)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
4328 DO i = i_start, i_end
4329 tendency(i,k,j)=tendency(i,k,j)-rdzw(k)*(vflux(i,k+1)-vflux(i,k))
4335 ELSE IF (vert_order == 2) THEN
4337 DO j = j_start, j_end
4339 DO i = i_start, i_end
4340 vflux(i,k)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
4345 DO i = i_start, i_end
4346 tendency(i,k,j)=tendency(i,k,j)-rdzw(k)*(vflux(i,k+1)-vflux(i,k))
4354 WRITE (wrf_err_message,*) ' advect_scalar_6a, v_order not known ',vert_order
4355 CALL wrf_error_fatal ( wrf_err_message )
4357 ENDIF vert_order_test
4359 END SUBROUTINE advect_scalar
4360 #if ( ! defined(ADVECT_KERNEL) )
4362 !---------------------------------------------------------------------------------
4364 SUBROUTINE advect_w ( w, w_old, tendency, &
4367 mut, time_step, config_flags, &
4368 msfux, msfuy, msfvx, msfvy, &
4372 ids, ide, jds, jde, kds, kde, &
4373 ims, ime, jms, jme, kms, kme, &
4374 its, ite, jts, jte, kts, kte )
4380 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
4382 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
4383 ims, ime, jms, jme, kms, kme, &
4384 its, ite, jts, jte, kts, kte
4386 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: w, &
4392 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut
4393 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
4395 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
4402 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
4408 REAL , INTENT(IN ) :: rdx, &
4410 INTEGER , INTENT(IN ) :: time_step
4415 INTEGER :: i, j, k, itf, jtf, ktf
4416 INTEGER :: i_start, i_end, j_start, j_end
4417 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
4418 INTEGER :: jmin, jmax, jp, jm, imin, imax
4420 REAL :: mrdx, mrdy, ub, vb, uw, vw
4421 REAL , DIMENSION(its:ite, kts:kte) :: vflux
4423 INTEGER :: horz_order, vert_order
4425 REAL, DIMENSION( its:ite+1, kts:kte ) :: fqx
4426 REAL, DIMENSION( its:ite, kts:kte, 2 ) :: fqy
4428 LOGICAL :: degrade_xs, degrade_ys
4429 LOGICAL :: degrade_xe, degrade_ye
4431 INTEGER :: jp1, jp0, jtmp
4433 ! definition of flux operators, 3rd, 4th, 5th or 6th order
4435 REAL :: flux3, flux4, flux5, flux6
4436 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel
4438 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
4439 ( 7.*(q_i + q_im1) - (q_ip1 + q_im2) )/12.0
4441 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
4442 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
4443 sign(1,time_step)*sign(1.,ua)*((q_ip1 - q_im2)-3.*(q_i-q_im1))/12.0
4445 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
4446 ( 37.*(q_i+q_im1) - 8.*(q_ip1+q_im2) &
4447 +(q_ip2+q_im3) )/60.0
4449 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
4450 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
4451 -sign(1,time_step)*sign(1.,ua)*( &
4452 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )/60.0
4455 LOGICAL :: specified
4458 if(config_flags%specified .or. config_flags%nested) specified = .true.
4460 ! set order for the advection scheme
4463 horz_order = config_flags%h_sca_adv_order
4464 vert_order = config_flags%v_sca_adv_order
4466 ! here is the choice of flux operators
4468 ! begin with horizontal flux divergence
4470 horizontal_order_test : IF( horz_order == 6 ) THEN
4472 ! determine boundary mods for flux operators
4473 ! We degrade the flux operators from 3rd/4th order
4474 ! to second order one gridpoint in from the boundaries for
4475 ! all boundary conditions except periodic and symmetry - these
4476 ! conditions have boundary zone data fill for correct application
4477 ! of the higher order flux stencils
4484 IF( config_flags%periodic_x .or. &
4485 config_flags%symmetric_xs .or. &
4486 (its > ids+3) ) degrade_xs = .false.
4487 IF( config_flags%periodic_x .or. &
4488 config_flags%symmetric_xe .or. &
4489 (ite < ide-3) ) degrade_xe = .false.
4490 IF( config_flags%periodic_y .or. &
4491 config_flags%symmetric_ys .or. &
4492 (jts > jds+3) ) degrade_ys = .false.
4493 IF( config_flags%periodic_y .or. &
4494 config_flags%symmetric_ye .or. &
4495 (jte < jde-4) ) degrade_ye = .false.
4497 !--------------- y - advection first
4500 i_end = MIN(ite,ide-1)
4502 j_end = MIN(jte,jde-1)
4504 ! higher order flux has a 5 or 7 point stencil, so compute
4505 ! bounds so we can switch to second order flux close to the boundary
4511 j_start = MAX(jts,jds+1)
4516 j_end = MIN(jte,jde-2)
4520 IF(config_flags%polar) j_end = MIN(jte,jde-1)
4522 ! compute fluxes, 5th or 6th order
4527 j_loop_y_flux_6 : DO j = j_start, j_end+1
4529 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN
4532 DO i = i_start, i_end
4533 vel = fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)
4534 fqy( i, k, jp1 ) = vel*flux6( &
4535 w(i,k,j-3), w(i,k,j-2), w(i,k,j-1), &
4536 w(i,k,j ), w(i,k,j+1), w(i,k,j+2), vel )
4541 DO i = i_start, i_end
4542 vel = (2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)
4543 fqy( i, k, jp1 ) = vel*flux6( &
4544 w(i,k,j-3), w(i,k,j-2), w(i,k,j-1), &
4545 w(i,k,j ), w(i,k,j+1), w(i,k,j+2), vel )
4548 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
4551 DO i = i_start, i_end
4552 fqy(i, k, jp1) = 0.5*(fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j))* &
4553 (w(i,k,j)+w(i,k,j-1))
4558 DO i = i_start, i_end
4559 fqy(i, k, jp1) = 0.5*((2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j))* &
4560 (w(i,k,j)+w(i,k,j-1))
4563 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
4566 DO i = i_start, i_end
4567 vel = fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)
4568 fqy( i, k, jp1 ) = vel*flux4( &
4569 w(i,k,j-2),w(i,k,j-1),w(i,k,j),w(i,k,j+1),vel )
4574 DO i = i_start, i_end
4575 vel = (2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)
4576 fqy( i, k, jp1 ) = vel*flux4( &
4577 w(i,k,j-2),w(i,k,j-1),w(i,k,j),w(i,k,j+1),vel )
4580 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
4583 DO i = i_start, i_end
4584 fqy(i, k, jp1) = 0.5*(fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j))* &
4585 (w(i,k,j)+w(i,k,j-1))
4590 DO i = i_start, i_end
4591 fqy(i, k, jp1) = 0.5*((2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j))* &
4592 (w(i,k,j)+w(i,k,j-1))
4595 ELSE IF ( j == jde-2 ) THEN ! 3rd or 4th order flux 2 in from north boundary
4598 DO i = i_start, i_end
4599 vel = fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)
4600 fqy( i, k, jp1 ) = vel*flux4( &
4601 w(i,k,j-2),w(i,k,j-1), &
4602 w(i,k,j),w(i,k,j+1),vel )
4607 DO i = i_start, i_end
4608 vel = (2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)
4609 fqy( i, k, jp1 ) = vel*flux4( &
4610 w(i,k,j-2),w(i,k,j-1), &
4611 w(i,k,j),w(i,k,j+1),vel )
4616 ! y flux-divergence into tendency
4618 ! Comments for polar boundary conditions
4619 ! Same process as for advect_u - tendencies run from jds to jde-1
4620 ! (latitudes are as for u grid, longitudes are displaced)
4621 ! Therefore: flow is only from one side for points next to poles
4622 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
4624 DO i = i_start, i_end
4625 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
4626 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
4629 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
4631 DO i = i_start, i_end
4632 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
4633 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
4638 IF(j > j_start) THEN
4641 DO i = i_start, i_end
4642 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
4643 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
4655 ENDDO j_loop_y_flux_6
4657 ! next, x - flux divergence
4660 i_end = MIN(ite,ide-1)
4663 j_end = MIN(jte,jde-1)
4665 ! higher order flux has a 5 or 7 point stencil, so compute
4666 ! bounds so we can switch to second order flux close to the boundary
4672 i_start = MAX(ids+1,its)
4673 ! i_start_f = i_start+2
4674 i_start_f = MIN(i_start+2,ids+3)
4678 i_end = MIN(ide-2,ite)
4684 DO j = j_start, j_end
4686 ! 5th or 6th order flux
4689 DO i = i_start_f, i_end_f
4690 vel = fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)
4691 fqx( i,k ) = vel*flux6( w(i-3,k,j), w(i-2,k,j), &
4692 w(i-1,k,j), w(i ,k,j), &
4693 w(i+1,k,j), w(i+2,k,j), &
4699 DO i = i_start_f, i_end_f
4700 vel = (2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)
4701 fqx( i,k ) = vel*flux6( w(i-3,k,j), w(i-2,k,j), &
4702 w(i-1,k,j), w(i ,k,j), &
4703 w(i+1,k,j), w(i+2,k,j), &
4707 ! lower order fluxes close to boundaries (if not periodic or symmetric)
4709 IF( degrade_xs ) THEN
4711 DO i=i_start,i_start_f-1
4713 IF(i == ids+1) THEN ! second order
4715 fqx(i,k) = 0.5*(fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)) &
4716 *(w(i,k,j)+w(i-1,k,j))
4719 fqx(i,k) = 0.5*((2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)) &
4720 *(w(i,k,j)+w(i-1,k,j))
4723 IF(i == ids+2) THEN ! third order
4725 vel = fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)
4726 fqx( i,k ) = vel*flux4( w(i-2,k,j), w(i-1,k,j), &
4727 w(i ,k,j), w(i+1,k,j), &
4731 vel = (2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)
4732 fqx( i,k ) = vel*flux4( w(i-2,k,j), w(i-1,k,j), &
4733 w(i ,k,j), w(i+1,k,j), &
4741 IF( degrade_xe ) THEN
4743 DO i = i_end_f+1, i_end+1
4745 IF( i == ide-1 ) THEN ! second order flux next to the boundary
4747 fqx(i,k) = 0.5*(fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)) &
4748 *(w(i,k,j)+w(i-1,k,j))
4751 fqx(i,k) = 0.5*((2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)) &
4752 *(w(i,k,j)+w(i-1,k,j))
4755 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
4757 vel = fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)
4758 fqx( i,k ) = vel*flux4( w(i-2,k,j), w(i-1,k,j), &
4759 w(i ,k,j), w(i+1,k,j), &
4763 vel = (2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)
4764 fqx( i,k ) = vel*flux4( w(i-2,k,j), w(i-1,k,j), &
4765 w(i ,k,j), w(i+1,k,j), &
4773 ! x flux-divergence into tendency
4776 DO i = i_start, i_end
4777 mrdx=msftx(i,j)*rdx ! see ADT eqn 46 dividing by my, 1st term RHS
4778 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
4784 ELSE IF (horz_order == 5 ) THEN
4786 ! determine boundary mods for flux operators
4787 ! We degrade the flux operators from 3rd/4th order
4788 ! to second order one gridpoint in from the boundaries for
4789 ! all boundary conditions except periodic and symmetry - these
4790 ! conditions have boundary zone data fill for correct application
4791 ! of the higher order flux stencils
4798 IF( config_flags%periodic_x .or. &
4799 config_flags%symmetric_xs .or. &
4800 (its > ids+3) ) degrade_xs = .false.
4801 IF( config_flags%periodic_x .or. &
4802 config_flags%symmetric_xe .or. &
4803 (ite < ide-3) ) degrade_xe = .false.
4804 IF( config_flags%periodic_y .or. &
4805 config_flags%symmetric_ys .or. &
4806 (jts > jds+3) ) degrade_ys = .false.
4807 IF( config_flags%periodic_y .or. &
4808 config_flags%symmetric_ye .or. &
4809 (jte < jde-4) ) degrade_ye = .false.
4811 !--------------- y - advection first
4814 i_end = MIN(ite,ide-1)
4816 j_end = MIN(jte,jde-1)
4818 ! higher order flux has a 5 or 7 point stencil, so compute
4819 ! bounds so we can switch to second order flux close to the boundary
4825 j_start = MAX(jts,jds+1)
4830 j_end = MIN(jte,jde-2)
4834 IF(config_flags%polar) j_end = MIN(jte,jde-1)
4836 ! compute fluxes, 5th or 6th order
4841 j_loop_y_flux_5 : DO j = j_start, j_end+1
4843 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN
4846 DO i = i_start, i_end
4847 vel = fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)
4848 fqy( i, k, jp1 ) = vel*flux5( &
4849 w(i,k,j-3), w(i,k,j-2), w(i,k,j-1), &
4850 w(i,k,j ), w(i,k,j+1), w(i,k,j+2), vel )
4855 DO i = i_start, i_end
4856 vel = (2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)
4857 fqy( i, k, jp1 ) = vel*flux5( &
4858 w(i,k,j-3), w(i,k,j-2), w(i,k,j-1), &
4859 w(i,k,j ), w(i,k,j+1), w(i,k,j+2), vel )
4862 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
4865 DO i = i_start, i_end
4866 fqy(i, k, jp1) = 0.5*(fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j))* &
4867 (w(i,k,j)+w(i,k,j-1))
4872 DO i = i_start, i_end
4873 fqy(i, k, jp1) = 0.5*((2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j))* &
4874 (w(i,k,j)+w(i,k,j-1))
4877 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
4880 DO i = i_start, i_end
4881 vel = fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)
4882 fqy( i, k, jp1 ) = vel*flux3( &
4883 w(i,k,j-2),w(i,k,j-1),w(i,k,j),w(i,k,j+1),vel )
4888 DO i = i_start, i_end
4889 vel = (2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)
4890 fqy( i, k, jp1 ) = vel*flux3( &
4891 w(i,k,j-2),w(i,k,j-1),w(i,k,j),w(i,k,j+1),vel )
4894 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
4897 DO i = i_start, i_end
4898 fqy(i, k, jp1) = 0.5*(fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j))* &
4899 (w(i,k,j)+w(i,k,j-1))
4904 DO i = i_start, i_end
4905 fqy(i, k, jp1) = 0.5*((2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j))* &
4906 (w(i,k,j)+w(i,k,j-1))
4909 ELSE IF ( j == jde-2 ) THEN ! 3rd or 4th order flux 2 in from north boundary
4912 DO i = i_start, i_end
4913 vel = fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)
4914 fqy( i, k, jp1 ) = vel*flux3( &
4915 w(i,k,j-2),w(i,k,j-1), &
4916 w(i,k,j),w(i,k,j+1),vel )
4921 DO i = i_start, i_end
4922 vel = (2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)
4923 fqy( i, k, jp1 ) = vel*flux3( &
4924 w(i,k,j-2),w(i,k,j-1), &
4925 w(i,k,j),w(i,k,j+1),vel )
4930 ! y flux-divergence into tendency
4932 ! Comments for polar boundary conditions
4933 ! Same process as for advect_u - tendencies run from jds to jde-1
4934 ! (latitudes are as for u grid, longitudes are displaced)
4935 ! Therefore: flow is only from one side for points next to poles
4936 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
4938 DO i = i_start, i_end
4939 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
4940 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
4943 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
4945 DO i = i_start, i_end
4946 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
4947 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
4952 IF(j > j_start) THEN
4955 DO i = i_start, i_end
4956 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
4957 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
4969 ENDDO j_loop_y_flux_5
4971 ! next, x - flux divergence
4974 i_end = MIN(ite,ide-1)
4977 j_end = MIN(jte,jde-1)
4979 ! higher order flux has a 5 or 7 point stencil, so compute
4980 ! bounds so we can switch to second order flux close to the boundary
4986 i_start = MAX(ids+1,its)
4987 ! i_start_f = i_start+2
4988 i_start_f = MIN(i_start+2,ids+3)
4992 i_end = MIN(ide-2,ite)
4998 DO j = j_start, j_end
5000 ! 5th or 6th order flux
5003 DO i = i_start_f, i_end_f
5004 vel = fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)
5005 fqx( i,k ) = vel*flux5( w(i-3,k,j), w(i-2,k,j), &
5006 w(i-1,k,j), w(i ,k,j), &
5007 w(i+1,k,j), w(i+2,k,j), &
5013 DO i = i_start_f, i_end_f
5014 vel = (2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)
5015 fqx( i,k ) = vel*flux5( w(i-3,k,j), w(i-2,k,j), &
5016 w(i-1,k,j), w(i ,k,j), &
5017 w(i+1,k,j), w(i+2,k,j), &
5021 ! lower order fluxes close to boundaries (if not periodic or symmetric)
5023 IF( degrade_xs ) THEN
5025 DO i=i_start,i_start_f-1
5027 IF(i == ids+1) THEN ! second order
5029 fqx(i,k) = 0.5*(fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)) &
5030 *(w(i,k,j)+w(i-1,k,j))
5033 fqx(i,k) = 0.5*((2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)) &
5034 *(w(i,k,j)+w(i-1,k,j))
5037 IF(i == ids+2) THEN ! third order
5039 vel = fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)
5040 fqx( i,k ) = vel*flux3( w(i-2,k,j), w(i-1,k,j), &
5041 w(i ,k,j), w(i+1,k,j), &
5045 vel = (2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)
5046 fqx( i,k ) = vel*flux3( w(i-2,k,j), w(i-1,k,j), &
5047 w(i ,k,j), w(i+1,k,j), &
5055 IF( degrade_xe ) THEN
5057 DO i = i_end_f+1, i_end+1
5059 IF( i == ide-1 ) THEN ! second order flux next to the boundary
5061 fqx(i,k) = 0.5*(fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)) &
5062 *(w(i,k,j)+w(i-1,k,j))
5065 fqx(i,k) = 0.5*((2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)) &
5066 *(w(i,k,j)+w(i-1,k,j))
5069 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
5071 vel = fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)
5072 fqx( i,k ) = vel*flux3( w(i-2,k,j), w(i-1,k,j), &
5073 w(i ,k,j), w(i+1,k,j), &
5077 vel = (2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)
5078 fqx( i,k ) = vel*flux3( w(i-2,k,j), w(i-1,k,j), &
5079 w(i ,k,j), w(i+1,k,j), &
5087 ! x flux-divergence into tendency
5090 DO i = i_start, i_end
5091 mrdx=msftx(i,j)*rdx ! see ADT eqn 46 dividing by my, 1st term RHS
5092 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
5098 ELSE IF ( horz_order == 4 ) THEN
5105 IF( config_flags%periodic_x .or. &
5106 config_flags%symmetric_xs .or. &
5107 (its > ids+2) ) degrade_xs = .false.
5108 IF( config_flags%periodic_x .or. &
5109 config_flags%symmetric_xe .or. &
5110 (ite < ide-2) ) degrade_xe = .false.
5111 IF( config_flags%periodic_y .or. &
5112 config_flags%symmetric_ys .or. &
5113 (jts > jds+2) ) degrade_ys = .false.
5114 IF( config_flags%periodic_y .or. &
5115 config_flags%symmetric_ye .or. &
5116 (jte < jde-3) ) degrade_ye = .false.
5118 ! begin flux computations
5119 ! start with x flux divergence
5126 i_end = MIN(ite,ide-1)
5128 j_end = MIN(jte,jde-1)
5130 ! 3rd or 4th order flux has a 5 point stencil, so compute
5131 ! bounds so we can switch to second order flux close to the boundary
5138 i_start_f = i_start+1
5148 DO j = j_start, j_end
5151 DO i = i_start_f, i_end_f
5152 vel = fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)
5153 fqx( i, k ) = vel*flux4( w(i-2,k,j), w(i-1,k,j), &
5154 w(i ,k,j), w(i+1,k,j), &
5160 DO i = i_start_f, i_end_f
5161 vel = (2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)
5162 fqx( i, k ) = vel*flux4( w(i-2,k,j), w(i-1,k,j), &
5163 w(i ,k,j), w(i+1,k,j), &
5166 ! second order flux close to boundaries (if not periodic or symmetric)
5168 IF( degrade_xs ) THEN
5171 0.5*(fzm(k)*ru(i_start,k,j)+fzp(k)*ru(i_start,k-1,j)) &
5172 *(w(i_start,k,j)+w(i_start-1,k,j))
5176 0.5*((2.-fzm(k-1))*ru(i_start,k-1,j)-fzp(k-1)*ru(i_start,k-2,j)) &
5177 *(w(i_start,k,j)+w(i_start-1,k,j))
5180 IF( degrade_xe ) THEN
5183 0.5*(fzm(k)*ru(i_end+1,k,j)+fzp(k)*ru(i_end+1,k-1,j)) &
5184 *(w(i_end+1,k,j)+w(i_end,k,j))
5188 0.5*((2.-fzm(k-1))*ru(i_end+1,k-1,j)-fzp(k-1)*ru(i_end+1,k-2,j)) &
5189 *(w(i_end+1,k,j)+w(i_end,k,j))
5192 ! x flux-divergence into tendency
5195 DO i = i_start, i_end
5196 mrdx=msftx(i,j)*rdx ! see ADT eqn 46 dividing by my, 1st term RHS
5197 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
5203 ! next -> y flux divergence calculation
5206 i_end = MIN(ite,ide-1)
5208 j_end = MIN(jte,jde-1)
5211 ! 3rd or 4th order flux has a 5 point stencil, so compute
5212 ! bounds so we can switch to second order flux close to the boundary
5219 j_start_f = j_start+1
5227 IF(config_flags%polar) j_end = MIN(jte,jde-1)
5232 DO j = j_start, j_end+1
5234 IF ((j < j_start_f) .and. degrade_ys) THEN
5236 DO i = i_start, i_end
5238 0.5*(fzm(k)*rv(i,k,j_start)+fzp(k)*rv(i,k-1,j_start)) &
5239 *(w(i,k,j_start)+w(i,k,j_start-1))
5243 DO i = i_start, i_end
5245 0.5*((2.-fzm(k-1))*rv(i,k-1,j_start)-fzp(k-1)*rv(i,k-2,j_start)) &
5246 *(w(i,k,j_start)+w(i,k,j_start-1))
5248 ELSE IF ((j > j_end_f) .and. degrade_ye) THEN
5250 DO i = i_start, i_end
5251 ! Assumes j>j_end_f is ONLY j_end+1 ...
5252 ! fqy(i, k, jp1) = &
5253 ! 0.5*(fzm(k)*rv(i,k,j_end+1)+fzp(k)*rv(i,k-1,j_end+1)) &
5254 ! *(w(i,k,j_end+1)+w(i,k,j_end))
5256 0.5*(fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)) &
5257 *(w(i,k,j)+w(i,k,j-1))
5261 DO i = i_start, i_end
5262 ! Assumes j>j_end_f is ONLY j_end+1 ...
5263 ! fqy(i, k, jp1) = &
5264 ! 0.5*((2.-fzm(k-1))*rv(i,k-1,j_end+1)-fzp(k-1)*rv(i,k-2,j_end+1)) &
5265 ! *(w(i,k,j_end+1)+w(i,k,j_end))
5267 0.5*((2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)) &
5268 *(w(i,k,j)+w(i,k,j-1))
5271 ! 3rd or 4th order flux
5273 DO i = i_start, i_end
5274 vel = fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)
5275 fqy( i, k, jp1 ) = vel*flux4( w(i,k,j-2), w(i,k,j-1), &
5276 w(i,k,j ), w(i,k,j+1), &
5281 DO i = i_start, i_end
5282 vel = (2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)
5283 fqy( i, k, jp1 ) = vel*flux4( w(i,k,j-2), w(i,k,j-1), &
5284 w(i,k,j ), w(i,k,j+1), &
5289 ! y flux-divergence into tendency
5291 ! Comments for polar boundary conditions
5292 ! Same process as for advect_u - tendencies run from jds to jde-1
5293 ! (latitudes are as for u grid, longitudes are displaced)
5294 ! Therefore: flow is only from one side for points next to poles
5295 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
5297 DO i = i_start, i_end
5298 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
5299 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
5302 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
5304 DO i = i_start, i_end
5305 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
5306 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
5311 IF( j > j_start ) THEN
5314 DO i = i_start, i_end
5315 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
5316 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
5330 ELSE IF ( horz_order == 3 ) THEN
5337 IF( config_flags%periodic_x .or. &
5338 config_flags%symmetric_xs .or. &
5339 (its > ids+2) ) degrade_xs = .false.
5340 IF( config_flags%periodic_x .or. &
5341 config_flags%symmetric_xe .or. &
5342 (ite < ide-2) ) degrade_xe = .false.
5343 IF( config_flags%periodic_y .or. &
5344 config_flags%symmetric_ys .or. &
5345 (jts > jds+2) ) degrade_ys = .false.
5346 IF( config_flags%periodic_y .or. &
5347 config_flags%symmetric_ye .or. &
5348 (jte < jde-3) ) degrade_ye = .false.
5350 ! begin flux computations
5351 ! start with x flux divergence
5358 i_end = MIN(ite,ide-1)
5360 j_end = MIN(jte,jde-1)
5362 ! 3rd or 4th order flux has a 5 point stencil, so compute
5363 ! bounds so we can switch to second order flux close to the boundary
5370 i_start_f = i_start+1
5380 DO j = j_start, j_end
5383 DO i = i_start_f, i_end_f
5384 vel = fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)
5385 fqx( i, k ) = vel*flux3( w(i-2,k,j), w(i-1,k,j), &
5386 w(i ,k,j), w(i+1,k,j), &
5391 DO i = i_start_f, i_end_f
5392 vel = (2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)
5393 fqx( i, k ) = vel*flux3( w(i-2,k,j), w(i-1,k,j), &
5394 w(i ,k,j), w(i+1,k,j), &
5398 ! second order flux close to boundaries (if not periodic or symmetric)
5400 IF( degrade_xs ) THEN
5403 0.5*(fzm(k)*ru(i_start,k,j)+fzp(k)*ru(i_start,k-1,j)) &
5404 *(w(i_start,k,j)+w(i_start-1,k,j))
5408 0.5*((2.-fzm(k-1))*ru(i_start,k-1,j)-fzp(k-1)*ru(i_start,k-2,j)) &
5409 *(w(i_start,k,j)+w(i_start-1,k,j))
5412 IF( degrade_xe ) THEN
5415 0.5*(fzm(k)*ru(i_end+1,k,j)+fzp(k)*ru(i_end+1,k-1,j)) &
5416 *(w(i_end+1,k,j)+w(i_end,k,j))
5420 0.5*((2.-fzm(k-1))*ru(i_end+1,k-1,j)-fzp(k-1)*ru(i_end+1,k-2,j)) &
5421 *(w(i_end+1,k,j)+w(i_end,k,j))
5424 ! x flux-divergence into tendency
5427 DO i = i_start, i_end
5428 mrdx=msftx(i,j)*rdx ! see ADT eqn 46 dividing by my, 1st term RHS
5429 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
5435 ! next -> y flux divergence calculation
5438 i_end = MIN(ite,ide-1)
5440 j_end = MIN(jte,jde-1)
5443 ! 3rd or 4th order flux has a 5 point stencil, so compute
5444 ! bounds so we can switch to second order flux close to the boundary
5451 j_start_f = j_start+1
5459 IF(config_flags%polar) j_end = MIN(jte,jde-1)
5464 DO j = j_start, j_end+1
5466 IF ((j < j_start_f) .and. degrade_ys) THEN
5468 DO i = i_start, i_end
5470 0.5*(fzm(k)*rv(i,k,j_start)+fzp(k)*rv(i,k-1,j_start)) &
5471 *(w(i,k,j_start)+w(i,k,j_start-1))
5475 DO i = i_start, i_end
5477 0.5*((2.-fzm(k-1))*rv(i,k-1,j_start)-fzp(k-1)*rv(i,k-2,j_start)) &
5478 *(w(i,k,j_start)+w(i,k,j_start-1))
5480 ELSE IF ((j > j_end_f) .and. degrade_ye) THEN
5482 DO i = i_start, i_end
5483 ! Assumes j>j_end_f is ONLY j_end+1 ...
5484 ! fqy(i, k, jp1) = &
5485 ! 0.5*(fzm(k)*rv(i,k,j_end+1)+fzp(k)*rv(i,k-1,j_end+1)) &
5486 ! *(w(i,k,j_end+1)+w(i,k,j_end))
5488 0.5*(fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)) &
5489 *(w(i,k,j)+w(i,k,j-1))
5493 DO i = i_start, i_end
5494 ! Assumes j>j_end_f is ONLY j_end+1 ...
5495 ! fqy(i, k, jp1) = &
5496 ! 0.5*((2.-fzm(k-1))*rv(i,k-1,j_end+1)-fzp(k-1)*rv(i,k-2,j_end+1)) &
5497 ! *(w(i,k,j_end+1)+w(i,k,j_end))
5499 0.5*((2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)) &
5500 *(w(i,k,j)+w(i,k,j-1))
5503 ! 3rd or 4th order flux
5505 DO i = i_start, i_end
5506 vel = fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)
5507 fqy( i, k, jp1 ) = vel*flux3( w(i,k,j-2), w(i,k,j-1), &
5508 w(i,k,j ), w(i,k,j+1), &
5513 DO i = i_start, i_end
5514 vel = (2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)
5515 fqy( i, k, jp1 ) = vel*flux3( w(i,k,j-2), w(i,k,j-1), &
5516 w(i,k,j ), w(i,k,j+1), &
5521 ! y flux-divergence into tendency
5523 ! Comments for polar boundary conditions
5524 ! Same process as for advect_u - tendencies run from jds to jde-1
5525 ! (latitudes are as for u grid, longitudes are displaced)
5526 ! Therefore: flow is only from one side for points next to poles
5527 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
5529 DO i = i_start, i_end
5530 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
5531 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
5534 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
5536 DO i = i_start, i_end
5537 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
5538 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
5543 IF( j > j_start ) THEN
5546 DO i = i_start, i_end
5547 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
5548 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
5562 ELSE IF (horz_order == 2 ) THEN
5565 i_end = MIN(ite,ide-1)
5567 j_end = MIN(jte,jde-1)
5569 IF ( .NOT. config_flags%periodic_x ) THEN
5570 IF ( config_flags%open_xs .or. specified ) i_start = MAX(ids+1,its)
5571 IF ( config_flags%open_xe .or. specified ) i_end = MIN(ide-2,ite)
5574 DO j = j_start, j_end
5576 DO i = i_start, i_end
5578 mrdx=msftx(i,j)*rdx ! see ADT eqn 46 dividing by my, 1st term RHS
5580 tendency(i,k,j)=tendency(i,k,j)-mrdx*0.5 &
5581 *((fzm(k)*ru(i+1,k,j)+fzp(k)*ru(i+1,k-1,j)) &
5582 *(w(i+1,k,j)+w(i,k,j)) &
5583 -(fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)) &
5584 *(w(i,k,j)+w(i-1,k,j)))
5590 DO i = i_start, i_end
5592 mrdx=msftx(i,j)*rdx ! see ADT eqn 46 dividing by my, 1st term RHS
5594 tendency(i,k,j)=tendency(i,k,j)-mrdx*0.5 &
5595 *(((2.-fzm(k-1))*ru(i+1,k-1,j)-fzp(k-1)*ru(i+1,k-2,j)) &
5596 *(w(i+1,k,j)+w(i,k,j)) &
5597 -((2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)) &
5598 *(w(i,k,j)+w(i-1,k,j)))
5605 i_end = MIN(ite,ide-1)
5606 ! Polar boundary conditions are like open or specified
5607 IF ( config_flags%open_ys .or. specified .or. config_flags%polar ) j_start = MAX(jds+1,jts)
5608 IF ( config_flags%open_ye .or. specified .or. config_flags%polar ) j_end = MIN(jde-2,jte)
5610 DO j = j_start, j_end
5612 DO i = i_start, i_end
5614 mrdy=msftx(i,j)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
5616 tendency(i,k,j)=tendency(i,k,j) -mrdy*0.5 &
5617 *((fzm(k)*rv(i,k,j+1)+fzp(k)*rv(i,k-1,j+1))* &
5618 (w(i,k,j+1)+w(i,k,j)) &
5619 -(fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)) &
5620 *(w(i,k,j)+w(i,k,j-1)))
5626 DO i = i_start, i_end
5628 mrdy=msftx(i,j)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
5630 tendency(i,k,j)=tendency(i,k,j) -mrdy*0.5 &
5631 *(((2.-fzm(k-1))*rv(i,k-1,j+1)-fzp(k-1)*rv(i,k-2,j+1))* &
5632 (w(i,k,j+1)+w(i,k,j)) &
5633 -((2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)) &
5634 *(w(i,k,j)+w(i,k,j-1)))
5640 ! Polar boundary condition ... not covered in above j-loop
5641 IF (config_flags%polar) THEN
5642 IF (jts == jds) THEN
5644 DO i = i_start, i_end
5645 mrdy=msftx(i,jds)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
5646 tendency(i,k,jds)=tendency(i,k,jds) -mrdy*0.5 &
5647 *((fzm(k)*rv(i,k,jds+1)+fzp(k)*rv(i,k-1,jds+1))* &
5648 (w(i,k,jds+1)+w(i,k,jds)))
5652 DO i = i_start, i_end
5653 mrdy=msftx(i,jds)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
5654 tendency(i,k,jds)=tendency(i,k,jds) -mrdy*0.5 &
5655 *((2.-fzm(k-1))*rv(i,k-1,jds+1)-fzp(k-1)*rv(i,k-2,jds+1))* &
5656 (w(i,k,jds+1)+w(i,k,jds))
5659 IF (jte == jde) THEN
5661 DO i = i_start, i_end
5662 mrdy=msftx(i,jde-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
5663 tendency(i,k,jde-1)=tendency(i,k,jde-1) +mrdy*0.5 &
5664 *((fzm(k)*rv(i,k,jde-1)+fzp(k)*rv(i,k-1,jde-1))* &
5665 (w(i,k,jde-1)+w(i,k,jde-2)))
5669 DO i = i_start, i_end
5670 mrdy=msftx(i,jde-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
5671 tendency(i,k,jde-1)=tendency(i,k,jde-1) +mrdy*0.5 &
5672 *((2.-fzm(k-1))*rv(i,k-1,jde-1)-fzp(k-1)*rv(i,k-2,jde-1)) &
5673 *(w(i,k,jde-1)+w(i,k,jde-2))
5678 ELSE IF ( horz_order == 0 ) THEN
5680 ! Just in case we want to turn horizontal advection off, we can do it
5684 WRITE ( wrf_err_message ,*) ' advect_w_6a, h_order not known ',horz_order
5685 CALL wrf_error_fatal ( wrf_err_message )
5687 ENDIF horizontal_order_test
5690 ! pick up the the horizontal radiation boundary conditions.
5691 ! (these are the computations that don't require 'cb'.
5692 ! first, set to index ranges
5696 i_end = MIN(ite,ide-1)
5698 j_end = MIN(jte,jde-1)
5700 IF( (config_flags%open_xs) .and. (its == ids)) THEN
5702 DO j = j_start, j_end
5705 uw = 0.5*(fzm(k)*(ru(its,k ,j)+ru(its+1,k ,j)) + &
5706 fzp(k)*(ru(its,k-1,j)+ru(its+1,k-1,j)) )
5709 tendency(its,k,j) = tendency(its,k,j) &
5711 ub*(w_old(its+1,k,j) - w_old(its,k,j)) + &
5713 fzm(k)*(ru(its+1,k ,j)-ru(its,k ,j))+ &
5714 fzp(k)*(ru(its+1,k-1,j)-ru(its,k-1,j))) &
5720 DO j = j_start, j_end
5722 uw = 0.5*( (2.-fzm(k-1))*(ru(its,k-1,j)+ru(its+1,k-1,j)) &
5723 -fzp(k-1)*(ru(its,k-2,j)+ru(its+1,k-2,j)) )
5726 tendency(its,k,j) = tendency(its,k,j) &
5728 ub*(w_old(its+1,k,j) - w_old(its,k,j)) + &
5730 (2.-fzm(k-1))*(ru(its+1,k-1,j)-ru(its,k-1,j))- &
5731 fzp(k-1)*(ru(its+1,k-2,j)-ru(its,k-2,j))) &
5737 IF( (config_flags%open_xe) .and. (ite == ide)) THEN
5739 DO j = j_start, j_end
5742 uw = 0.5*(fzm(k)*(ru(ite-1,k ,j)+ru(ite,k ,j)) + &
5743 fzp(k)*(ru(ite-1,k-1,j)+ru(ite,k-1,j)) )
5746 tendency(i_end,k,j) = tendency(i_end,k,j) &
5748 ub*(w_old(i_end,k,j) - w_old(i_end-1,k,j)) + &
5750 fzm(k)*(ru(ite,k ,j)-ru(ite-1,k ,j)) + &
5751 fzp(k)*(ru(ite,k-1,j)-ru(ite-1,k-1,j))) &
5757 DO j = j_start, j_end
5759 uw = 0.5*( (2.-fzm(k-1))*(ru(ite-1,k-1,j)+ru(ite,k-1,j)) &
5760 -fzp(k-1)*(ru(ite-1,k-2,j)+ru(ite,k-2,j)) )
5763 tendency(i_end,k,j) = tendency(i_end,k,j) &
5765 ub*(w_old(i_end,k,j) - w_old(i_end-1,k,j)) + &
5767 (2.-fzm(k-1))*(ru(ite,k-1,j)-ru(ite-1,k-1,j)) - &
5768 fzp(k-1)*(ru(ite,k-2,j)-ru(ite-1,k-2,j))) &
5775 IF( (config_flags%open_ys) .and. (jts == jds)) THEN
5777 DO i = i_start, i_end
5780 vw = 0.5*( fzm(k)*(rv(i,k ,jts)+rv(i,k ,jts+1)) + &
5781 fzp(k)*(rv(i,k-1,jts)+rv(i,k-1,jts+1)) )
5784 tendency(i,k,jts) = tendency(i,k,jts) &
5786 vb*(w_old(i,k,jts+1) - w_old(i,k,jts)) + &
5788 fzm(k)*(rv(i,k ,jts+1)-rv(i,k ,jts))+ &
5789 fzp(k)*(rv(i,k-1,jts+1)-rv(i,k-1,jts))) &
5795 DO i = i_start, i_end
5796 vw = 0.5*( (2.-fzm(k-1))*(rv(i,k-1,jts)+rv(i,k-1,jts+1)) &
5797 -fzp(k-1)*(rv(i,k-2,jts)+rv(i,k-2,jts+1)) )
5800 tendency(i,k,jts) = tendency(i,k,jts) &
5802 vb*(w_old(i,k,jts+1) - w_old(i,k,jts)) + &
5804 (2.-fzm(k-1))*(rv(i,k-1,jts+1)-rv(i,k-1,jts))- &
5805 fzp(k-1)*(rv(i,k-2,jts+1)-rv(i,k-2,jts))) &
5811 IF( (config_flags%open_ye) .and. (jte == jde) ) THEN
5813 DO i = i_start, i_end
5816 vw = 0.5*( fzm(k)*(rv(i,k ,jte-1)+rv(i,k ,jte)) + &
5817 fzp(k)*(rv(i,k-1,jte-1)+rv(i,k-1,jte)) )
5820 tendency(i,k,j_end) = tendency(i,k,j_end) &
5822 vb*(w_old(i,k,j_end) - w_old(i,k,j_end-1)) + &
5824 fzm(k)*(rv(i,k ,jte)-rv(i,k ,jte-1))+ &
5825 fzp(k)*(rv(i,k-1,jte)-rv(i,k-1,jte-1))) &
5831 DO i = i_start, i_end
5833 vw = 0.5*( (2.-fzm(k-1))*(rv(i,k-1,jte-1)+rv(i,k-1,jte)) &
5834 -fzp(k-1)*(rv(i,k-2,jte-1)+rv(i,k-2,jte)) )
5837 tendency(i,k,j_end) = tendency(i,k,j_end) &
5839 vb*(w_old(i,k,j_end) - w_old(i,k,j_end-1)) + &
5841 (2.-fzm(k-1))*(rv(i,k-1,jte)-rv(i,k-1,jte-1))- &
5842 fzp(k-1)*(rv(i,k-2,jte)-rv(i,k-2,jte-1))) &
5848 !-------------------- vertical advection
5849 ! ADT eqn 46 has 3rd term on RHS (dividing through by my) = - partial d/dz (w rho w /my)
5850 ! Here we have: - partial d/dz (w*rom) = - partial d/dz (w rho w / my)
5851 ! Therefore we don't need to make a correction for advect_w
5854 i_end = MIN(ite,ide-1)
5856 j_end = MIN(jte,jde-1)
5858 DO i = i_start, i_end
5863 vert_order_test : IF (vert_order == 6) THEN
5865 DO j = j_start, j_end
5868 DO i = i_start, i_end
5869 vel=0.5*(rom(i,k,j)+rom(i,k-1,j))
5870 vflux(i,k) = vel*flux6( &
5871 w(i,k-3,j), w(i,k-2,j), w(i,k-1,j), &
5872 w(i,k ,j), w(i,k+1,j), w(i,k+2,j), -vel )
5876 DO i = i_start, i_end
5879 vflux(i,k)=0.25*(rom(i,k,j)+rom(i,k-1,j))*(w(i,k,j)+w(i,k-1,j))
5882 vel=0.5*(rom(i,k,j)+rom(i,k-1,j))
5883 vflux(i,k) = vel*flux4( &
5884 w(i,k-2,j), w(i,k-1,j), &
5885 w(i,k ,j), w(i,k+1,j), -vel )
5888 vel=0.5*(rom(i,k,j)+rom(i,k-1,j))
5889 vflux(i,k) = vel*flux4( &
5890 w(i,k-2,j), w(i,k-1,j), &
5891 w(i,k ,j), w(i,k+1,j), -vel )
5894 vflux(i,k)=0.25*(rom(i,k,j)+rom(i,k-1,j))*(w(i,k,j)+w(i,k-1,j))
5899 DO i = i_start, i_end
5900 tendency(i,k,j)=tendency(i,k,j)-rdzu(k)*(vflux(i,k+1)-vflux(i,k))
5904 ! pick up flux contribution for w at the lid. wcs, 13 march 2004
5906 DO i = i_start, i_end
5907 tendency(i,k,j)=tendency(i,k,j)+2.*rdzu(k-1)*(vflux(i,k))
5912 ELSE IF (vert_order == 5) THEN
5914 DO j = j_start, j_end
5917 DO i = i_start, i_end
5918 vel=0.5*(rom(i,k,j)+rom(i,k-1,j))
5919 vflux(i,k) = vel*flux5( &
5920 w(i,k-3,j), w(i,k-2,j), w(i,k-1,j), &
5921 w(i,k ,j), w(i,k+1,j), w(i,k+2,j), -vel )
5925 DO i = i_start, i_end
5928 vflux(i,k)=0.25*(rom(i,k,j)+rom(i,k-1,j))*(w(i,k,j)+w(i,k-1,j))
5931 vel=0.5*(rom(i,k,j)+rom(i,k-1,j))
5932 vflux(i,k) = vel*flux3( &
5933 w(i,k-2,j), w(i,k-1,j), &
5934 w(i,k ,j), w(i,k+1,j), -vel )
5936 vel=0.5*(rom(i,k,j)+rom(i,k-1,j))
5937 vflux(i,k) = vel*flux3( &
5938 w(i,k-2,j), w(i,k-1,j), &
5939 w(i,k ,j), w(i,k+1,j), -vel )
5942 vflux(i,k)=0.25*(rom(i,k,j)+rom(i,k-1,j))*(w(i,k,j)+w(i,k-1,j))
5947 DO i = i_start, i_end
5948 tendency(i,k,j)=tendency(i,k,j)-rdzu(k)*(vflux(i,k+1)-vflux(i,k))
5952 ! pick up flux contribution for w at the lid, wcs. 13 march 2004
5954 DO i = i_start, i_end
5955 tendency(i,k,j)=tendency(i,k,j)+2.*rdzu(k-1)*(vflux(i,k))
5960 ELSE IF (vert_order == 4) THEN
5962 DO j = j_start, j_end
5965 DO i = i_start, i_end
5966 vel=0.5*(rom(i,k,j)+rom(i,k-1,j))
5967 vflux(i,k) = vel*flux4( &
5968 w(i,k-2,j), w(i,k-1,j), &
5969 w(i,k ,j), w(i,k+1,j), -vel )
5973 DO i = i_start, i_end
5976 vflux(i,k)=0.25*(rom(i,k,j)+rom(i,k-1,j))*(w(i,k,j)+w(i,k-1,j))
5978 vflux(i,k)=0.25*(rom(i,k,j)+rom(i,k-1,j))*(w(i,k,j)+w(i,k-1,j))
5983 DO i = i_start, i_end
5984 tendency(i,k,j)=tendency(i,k,j)-rdzu(k)*(vflux(i,k+1)-vflux(i,k))
5988 ! pick up flux contribution for w at the lid, wcs. 13 march 2004
5990 DO i = i_start, i_end
5991 tendency(i,k,j)=tendency(i,k,j)+2.*rdzu(k-1)*(vflux(i,k))
5996 ELSE IF (vert_order == 3) THEN
5998 DO j = j_start, j_end
6002 DO i = i_start, i_end
6003 vel=0.5*(rom(i,k,j)+rom(i,k-1,j))
6004 vflux(i,k) = vel*flux3( &
6005 w(i,k-2,j), w(i,k-1,j), &
6006 w(i,k ,j), w(i,k+1,j), -vel )
6010 DO i = i_start, i_end
6013 vflux(i,k)=0.25*(rom(i,k,j)+rom(i,k-1,j))*(w(i,k,j)+w(i,k-1,j))
6015 vflux(i,k)=0.25*(rom(i,k,j)+rom(i,k-1,j))*(w(i,k,j)+w(i,k-1,j))
6020 DO i = i_start, i_end
6021 tendency(i,k,j)=tendency(i,k,j)-rdzu(k)*(vflux(i,k+1)-vflux(i,k))
6025 ! pick up flux contribution for w at the lid, wcs. 13 march 2004
6027 DO i = i_start, i_end
6028 tendency(i,k,j)=tendency(i,k,j)+2.*rdzu(k-1)*(vflux(i,k))
6033 ELSE IF (vert_order == 2) THEN
6035 DO j = j_start, j_end
6037 DO i = i_start, i_end
6039 vflux(i,k)=0.25*(rom(i,k,j)+rom(i,k-1,j))*(w(i,k,j)+w(i,k-1,j))
6043 DO i = i_start, i_end
6044 tendency(i,k,j)=tendency(i,k,j)-rdzu(k)*(vflux(i,k+1)-vflux(i,k))
6049 ! pick up flux contribution for w at the lid, wcs. 13 march 2004
6051 DO i = i_start, i_end
6052 tendency(i,k,j)=tendency(i,k,j)+2.*rdzu(k-1)*(vflux(i,k))
6059 WRITE (wrf_err_message ,*) ' advect_w, v_order not known ',vert_order
6060 CALL wrf_error_fatal ( wrf_err_message )
6062 ENDIF vert_order_test
6064 END SUBROUTINE advect_w
6066 !----------------------------------------------------------------
6069 SUBROUTINE advect_scalar_pd ( field, field_old, tendency, &
6070 h_tendency, z_tendency, &
6074 time_step, config_flags, &
6076 msfux, msfuy, msfvx, msfvy, &
6079 rdx, rdy, rdzw, dt, &
6080 ids, ide, jds, jde, kds, kde, &
6081 ims, ime, jms, jme, kms, kme, &
6082 its, ite, jts, jte, kts, kte )
6084 ! this is a first cut at a positive definite advection option
6085 ! for scalars in WRF. This version is memory intensive ->
6086 ! we save 3d arrays of x, y and z both high and low order fluxes
6087 ! (six in all). Alternatively, we could sweep in a direction
6088 ! and lower the cost considerably.
6090 ! uses the Smolarkiewicz MWR 1989 approach, with addition of first-order
6093 ! WCS, 3 December 2002, 24 February 2003
6099 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
6101 LOGICAL , INTENT(IN ) :: tenddec ! tendency flag
6103 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
6104 ims, ime, jms, jme, kms, kme, &
6105 its, ite, jts, jte, kts, kte
6107 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: field, &
6113 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut, mub, mu_old
6114 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
6115 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT( OUT) :: h_tendency, z_tendency
6117 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
6124 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
6130 REAL , INTENT(IN ) :: rdx, &
6133 INTEGER , INTENT(IN ) :: time_step
6137 INTEGER :: i, j, k, itf, jtf, ktf
6138 INTEGER :: i_start, i_end, j_start, j_end
6139 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
6140 INTEGER :: jmin, jmax, jp, jm, imin, imax
6142 REAL :: mrdx, mrdy, ub, vb, uw, vw, mu
6144 ! storage for high and low order fluxes
6146 REAL, DIMENSION( its-1:ite+2, kts:kte, jts-1:jte+2 ) :: fqx, fqy, fqz
6148 REAL, DIMENSION( its-1:ite+2, kts:kte, jts-1:jte+2 ) :: fqxl, fqyl, fqzl
6150 INTEGER :: horz_order, vert_order
6152 LOGICAL :: degrade_xs, degrade_ys
6153 LOGICAL :: degrade_xe, degrade_ye
6155 INTEGER :: jp1, jp0, jtmp
6157 REAL,DIMENSION( its-1:ite+2, kts:kte, jts-1:jte+2 ) :: flux_out, ph_low
6159 !REAL :: flux_out, ph_low, scale
6160 REAL, PARAMETER :: eps=1.e-20
6163 ! definition of flux operators, 3rd, 4th, 5th or 6th order
6165 REAL :: flux3, flux4, flux5, flux6, flux_upwind
6166 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel, cr
6168 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
6169 (7./12.)*(q_i + q_im1) - (1./12.)*(q_ip1 + q_im2)
6171 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
6172 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
6173 sign(1,time_step)*sign(1.,ua)*(1./12.)*((q_ip1 - q_im2)-3.*(q_i-q_im1))
6175 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
6176 (37./60.)*(q_i+q_im1) - (2./15.)*(q_ip1+q_im2) &
6177 +(1./60.)*(q_ip2+q_im3)
6179 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
6180 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
6181 -sign(1,time_step)*sign(1.,ua)*(1./60.)*( &
6182 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )
6184 flux_upwind(q_im1, q_i, cr ) = 0.5*min( 1.0,(cr+abs(cr)))*q_im1 &
6185 +0.5*max(-1.0,(cr-abs(cr)))*q_i
6187 ! flux_upwind(q_im1, q_i, cr ) = 0.5*(1.+sign(1.,cr))*q_im1 &
6188 ! +0.5*(1.-sign(1.,cr))*q_i
6189 ! flux_upwind(q_im1, q_i, cr ) = 0.
6193 LOGICAL, PARAMETER :: pd_limit = .true.
6195 ! set order for the advection schemes
6197 ! write(6,*) ' in pd advection routine '
6199 ! Empty arrays just in case:
6200 IF (config_flags%polar) THEN
6210 horz_order = config_flags%h_sca_adv_order
6211 vert_order = config_flags%v_sca_adv_order
6213 ! determine boundary mods for flux operators
6214 ! We degrade the flux operators from 3rd/4th order
6215 ! to second order one gridpoint in from the boundaries for
6216 ! all boundary conditions except periodic and symmetry - these
6217 ! conditions have boundary zone data fill for correct application
6218 ! of the higher order flux stencils
6225 ! begin with horizontal flux divergence
6226 ! here is the choice of flux operators
6229 horizontal_order_test : IF( horz_order == 6 ) THEN
6231 IF( config_flags%periodic_x .or. &
6232 config_flags%symmetric_xs .or. &
6233 (its > ids+3) ) degrade_xs = .false.
6234 IF( config_flags%periodic_x .or. &
6235 config_flags%symmetric_xe .or. &
6236 (ite < ide-4) ) degrade_xe = .false.
6237 IF( config_flags%periodic_y .or. &
6238 config_flags%symmetric_ys .or. &
6239 (jts > jds+3) ) degrade_ys = .false.
6240 IF( config_flags%periodic_y .or. &
6241 config_flags%symmetric_ye .or. &
6242 (jte < jde-4) ) degrade_ye = .false.
6244 !--------------- y - advection first
6246 !-- y flux compute; these bounds are for periodic and sym b.c.
6250 i_end = MIN(ite,ide-1)+1
6252 j_end = MIN(jte,jde-1)+1
6256 !-- modify loop bounds if open or specified
6258 ! IF(degrade_xs) i_start = MAX(its-1,ids-1)
6259 ! IF(degrade_xe) i_end = MIN(ite+1,ide-2)
6260 IF(degrade_xs) i_start = MAX(its-1,ids)
6261 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
6264 j_start = MAX(jts-1,jds+1)
6269 j_end = MIN(jte+1,jde-2)
6273 ! compute fluxes, 6th order
6275 j_loop_y_flux_6 : DO j = j_start, j_end+1
6277 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN ! use full stencil
6280 DO i = i_start, i_end
6282 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
6283 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
6286 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
6288 fqy( i, k, j ) = vel*flux6( &
6289 field(i,k,j-3), field(i,k,j-2), field(i,k,j-1), &
6290 field(i,k,j ), field(i,k,j+1), field(i,k,j+2), vel )
6292 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
6297 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
6300 DO i = i_start, i_end
6302 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
6303 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
6306 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
6308 fqy(i,k, j) = 0.5*rv(i,k,j)* &
6309 (field(i,k,j)+field(i,k,j-1))
6311 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
6316 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
6319 DO i = i_start, i_end
6321 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
6322 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
6325 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
6327 fqy( i, k, j ) = vel*flux4( &
6328 field(i,k,j-2),field(i,k,j-1),field(i,k,j),field(i,k,j+1),vel )
6329 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
6334 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
6337 DO i = i_start, i_end
6339 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
6340 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
6343 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
6345 fqy(i, k, j ) = 0.5*rv(i,k,j)* &
6346 (field(i,k,j)+field(i,k,j-1))
6347 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
6352 ELSE IF ( j == jde-2 ) THEN ! 3rd or 4th order flux 2 in from north boundary
6355 DO i = i_start, i_end
6357 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
6358 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
6361 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
6363 fqy( i, k, j) = vel*flux4( &
6364 field(i,k,j-2),field(i,k,j-1), &
6365 field(i,k,j),field(i,k,j+1),vel )
6366 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
6373 ENDDO j_loop_y_flux_6
6377 !-- these bounds are for periodic and sym conditions
6380 i_end = MIN(ite,ide-1)+1
6385 j_end = MIN(jte,jde-1)+1
6387 !-- modify loop bounds for open and specified b.c
6389 ! IF(degrade_ys) j_start = MAX(jts-1,jds+1)
6390 ! IF(degrade_ye) j_end = MIN(jte+1,jde-2)
6391 IF(degrade_ys) j_start = MAX(jts-1,jds)
6392 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
6395 i_start = MAX(ids+1,its-1)
6400 i_end = MIN(ide-2,ite+1)
6406 DO j = j_start, j_end
6411 DO i = i_start_f, i_end_f
6413 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
6414 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
6417 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
6419 fqx( i,k,j ) = vel*flux6( field(i-3,k,j), field(i-2,k,j), &
6420 field(i-1,k,j), field(i ,k,j), &
6421 field(i+1,k,j), field(i+2,k,j), &
6423 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
6428 ! lower order fluxes close to boundaries (if not periodic or symmetric)
6430 IF( degrade_xs ) THEN
6432 DO i=i_start,i_start_f-1
6434 IF(i == ids+1) THEN ! second order
6436 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
6437 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
6440 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
6441 fqx(i,k,j) = 0.5*(ru(i,k,j)) &
6442 *(field(i,k,j)+field(i-1,k,j))
6443 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
6447 IF(i == ids+2) THEN ! fourth order
6449 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
6450 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
6453 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
6454 fqx( i,k,j ) = vel*flux4( field(i-2,k,j), field(i-1,k,j), &
6455 field(i ,k,j), field(i+1,k,j), &
6457 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
6465 IF( degrade_xe ) THEN
6467 DO i = i_end_f+1, i_end+1
6469 IF( i == ide-1 ) THEN ! second order flux next to the boundary
6471 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
6472 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
6475 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
6476 fqx(i,k,j) = 0.5*(ru(i,k,j)) &
6477 *(field(i,k,j)+field(i-1,k,j))
6478 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
6483 IF( i == ide-2 ) THEN ! fourth order flux one in from the boundary
6485 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
6486 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
6489 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
6490 fqx( i,k,j ) = vel*flux4( field(i-2,k,j), field(i-1,k,j), &
6491 field(i ,k,j), field(i+1,k,j), &
6493 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
6501 ENDDO ! enddo for outer J loop
6503 !--- end of 6th order horizontal flux calculation
6505 ELSE IF( horz_order == 5 ) THEN
6507 IF( config_flags%periodic_x .or. &
6508 config_flags%symmetric_xs .or. &
6509 (its > ids+3) ) degrade_xs = .false.
6510 IF( config_flags%periodic_x .or. &
6511 config_flags%symmetric_xe .or. &
6512 (ite < ide-4) ) degrade_xe = .false.
6513 IF( config_flags%periodic_y .or. &
6514 config_flags%symmetric_ys .or. &
6515 (jts > jds+3) ) degrade_ys = .false.
6516 IF( config_flags%periodic_y .or. &
6517 config_flags%symmetric_ye .or. &
6518 (jte < jde-4) ) degrade_ye = .false.
6520 !--------------- y - advection first
6522 !-- y flux compute; these bounds are for periodic and sym b.c.
6526 i_end = MIN(ite,ide-1)+1
6528 j_end = MIN(jte,jde-1)+1
6532 !-- modify loop bounds if open or specified
6534 ! IF(degrade_xs) i_start = MAX(its-1,ids-1)
6535 ! IF(degrade_xe) i_end = MIN(ite+1,ide-2)
6536 IF(degrade_xs) i_start = MAX(its-1,ids)
6537 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
6540 j_start = MAX(jts-1,jds+1)
6545 j_end = MIN(jte+1,jde-2)
6549 ! compute fluxes, 5th order
6551 j_loop_y_flux_5 : DO j = j_start, j_end+1
6553 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN ! use full stencil
6556 DO i = i_start, i_end
6558 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
6559 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
6562 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
6564 fqy( i, k, j ) = vel*flux5( &
6565 field(i,k,j-3), field(i,k,j-2), field(i,k,j-1), &
6566 field(i,k,j ), field(i,k,j+1), field(i,k,j+2), vel )
6568 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
6573 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
6576 DO i = i_start, i_end
6578 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
6579 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
6582 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
6584 fqy(i,k, j) = 0.5*rv(i,k,j)* &
6585 (field(i,k,j)+field(i,k,j-1))
6587 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
6592 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
6595 DO i = i_start, i_end
6597 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
6598 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
6601 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
6603 fqy( i, k, j ) = vel*flux3( &
6604 field(i,k,j-2),field(i,k,j-1),field(i,k,j),field(i,k,j+1),vel )
6605 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
6610 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
6613 DO i = i_start, i_end
6615 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
6616 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
6619 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
6621 fqy(i, k, j ) = 0.5*rv(i,k,j)* &
6622 (field(i,k,j)+field(i,k,j-1))
6623 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
6628 ELSE IF ( j == jde-2 ) THEN ! 3rd or 4th order flux 2 in from north boundary
6631 DO i = i_start, i_end
6633 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
6634 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
6637 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
6639 fqy( i, k, j) = vel*flux3( &
6640 field(i,k,j-2),field(i,k,j-1), &
6641 field(i,k,j),field(i,k,j+1),vel )
6642 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
6649 ENDDO j_loop_y_flux_5
6653 !-- these bounds are for periodic and sym conditions
6656 i_end = MIN(ite,ide-1)+1
6661 j_end = MIN(jte,jde-1)+1
6663 !-- modify loop bounds for open and specified b.c
6665 ! IF(degrade_ys) j_start = MAX(jts-1,jds+1)
6666 ! IF(degrade_ye) j_end = MIN(jte+1,jde-2)
6667 IF(degrade_ys) j_start = MAX(jts-1,jds)
6668 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
6671 i_start = MAX(ids+1,its-1)
6676 i_end = MIN(ide-2,ite+1)
6682 DO j = j_start, j_end
6687 DO i = i_start_f, i_end_f
6689 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
6690 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
6693 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
6695 fqx( i,k,j ) = vel*flux5( field(i-3,k,j), field(i-2,k,j), &
6696 field(i-1,k,j), field(i ,k,j), &
6697 field(i+1,k,j), field(i+2,k,j), &
6699 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
6704 ! lower order fluxes close to boundaries (if not periodic or symmetric)
6706 IF( degrade_xs ) THEN
6708 DO i=i_start,i_start_f-1
6710 IF(i == ids+1) THEN ! second order
6712 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
6713 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
6716 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
6717 fqx(i,k,j) = 0.5*(ru(i,k,j)) &
6718 *(field(i,k,j)+field(i-1,k,j))
6719 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
6723 IF(i == ids+2) THEN ! third order
6725 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
6726 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
6729 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
6730 fqx( i,k,j ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
6731 field(i ,k,j), field(i+1,k,j), &
6733 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
6741 IF( degrade_xe ) THEN
6743 DO i = i_end_f+1, i_end+1
6745 IF( i == ide-1 ) THEN ! second order flux next to the boundary
6747 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
6748 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
6751 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
6752 fqx(i,k,j) = 0.5*(ru(i,k,j)) &
6753 *(field(i,k,j)+field(i-1,k,j))
6754 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
6759 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
6761 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
6762 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
6765 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
6766 fqx( i,k,j ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
6767 field(i ,k,j), field(i+1,k,j), &
6769 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
6777 ENDDO ! enddo for outer J loop
6779 !--- end of 5th order horizontal flux calculation
6781 ELSE IF( horz_order == 4 ) THEN
6783 IF( config_flags%periodic_x .or. &
6784 config_flags%symmetric_xs .or. &
6785 (its > ids+1) ) degrade_xs = .false.
6786 IF( config_flags%periodic_x .or. &
6787 config_flags%symmetric_xe .or. &
6788 (ite < ide-2) ) degrade_xe = .false.
6789 IF( config_flags%periodic_y .or. &
6790 config_flags%symmetric_ys .or. &
6791 (jts > jds+1) ) degrade_ys = .false.
6792 IF( config_flags%periodic_y .or. &
6793 config_flags%symmetric_ye .or. &
6794 (jte < jde-2) ) degrade_ye = .false.
6796 !--------------- y - advection first
6798 !-- y flux compute; these bounds are for periodic and sym b.c.
6802 i_end = MIN(ite,ide-1)+1
6804 j_end = MIN(jte,jde-1)+1
6808 !-- modify loop bounds if open or specified
6810 IF(degrade_xs) i_start = its
6811 IF(degrade_xe) i_end = MIN(ite,ide-1)
6814 j_start = MAX(jts,jds+1)
6819 j_end = MIN(jte,jde-2)
6823 ! compute fluxes, 4th order
6825 j_loop_y_flux_4 : DO j = j_start, j_end+1
6827 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN ! use full stencil
6830 DO i = i_start, i_end
6832 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
6833 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
6836 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
6838 fqy( i, k, j ) = vel*flux4( field(i,k,j-2), field(i,k,j-1), &
6839 field(i,k,j ), field(i,k,j+1), vel )
6841 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
6846 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
6849 DO i = i_start, i_end
6851 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
6852 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
6855 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
6857 fqy(i,k, j) = 0.5*rv(i,k,j)* &
6858 (field(i,k,j)+field(i,k,j-1))
6860 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
6865 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
6868 DO i = i_start, i_end
6870 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
6871 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
6874 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
6876 fqy(i, k, j ) = 0.5*rv(i,k,j)* &
6877 (field(i,k,j)+field(i,k,j-1))
6878 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
6885 ENDDO j_loop_y_flux_4
6889 !-- these bounds are for periodic and sym conditions
6892 i_end = MIN(ite,ide-1)+1
6897 j_end = MIN(jte,jde-1)+1
6899 !-- modify loop bounds for open and specified b.c
6901 IF(degrade_ys) j_start = jts
6902 IF(degrade_ye) j_end = MIN(jte,jde-1)
6905 i_start = MAX(ids+1,its)
6906 i_start_f = i_start+1
6910 i_end = MIN(ide-2,ite)
6916 DO j = j_start, j_end
6921 DO i = i_start_f, i_end_f
6923 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
6924 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
6927 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
6929 fqx( i,k,j ) = vel*flux4( field(i-2,k,j), field(i-1,k,j), &
6930 field(i ,k,j), field(i+1,k,j), vel )
6931 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
6936 ! lower order fluxes close to boundaries (if not periodic or symmetric)
6938 IF( degrade_xs ) THEN
6939 IF( i_start == ids+1 ) THEN ! second order flux next to the boundary
6943 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
6944 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
6947 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
6949 fqx(i,k,j) = 0.5*(ru(i,k,j)) &
6950 *(field(i,k,j)+field(i-1,k,j))
6952 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
6958 IF( degrade_xe ) THEN
6959 IF( i_end == ide-2 ) THEN ! second order flux next to the boundary
6962 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
6963 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
6966 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
6967 fqx(i,k,j) = 0.5*(ru(i,k,j)) &
6968 *(field(i,k,j)+field(i-1,k,j))
6969 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
6975 ENDDO ! enddo for outer J loop
6977 !--- end of 4th order horizontal flux calculation
6979 ELSE IF( horz_order == 3 ) THEN
6981 IF( config_flags%periodic_x .or. &
6982 config_flags%symmetric_xs .or. &
6983 (its > ids+2) ) degrade_xs = .false.
6984 IF( config_flags%periodic_x .or. &
6985 config_flags%symmetric_xe .or. &
6986 (ite < ide-1) ) degrade_xe = .false.
6987 IF( config_flags%periodic_y .or. &
6988 config_flags%symmetric_ys .or. &
6989 (jts > jds+2) ) degrade_ys = .false.
6990 IF( config_flags%periodic_y .or. &
6991 config_flags%symmetric_ye .or. &
6992 (jte < jde-1) ) degrade_ye = .false.
6994 !--------------- y - advection first
6996 !-- y flux compute; these bounds are for periodic and sym b.c.
7000 i_end = MIN(ite,ide-1)+1
7002 j_end = MIN(jte,jde-1)+1
7006 !-- modify loop bounds if open or specified
7008 IF(degrade_xs) i_start = its
7009 IF(degrade_xe) i_end = MIN(ite,ide-1)
7012 j_start = MAX(jts,jds+1)
7017 j_end = MIN(jte,jde-2)
7021 ! compute fluxes, 3rd order
7023 j_loop_y_flux_3 : DO j = j_start, j_end+1
7025 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN ! use full stencil
7028 DO i = i_start, i_end
7030 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
7031 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
7034 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
7036 fqy( i, k, j ) = vel*flux3( field(i,k,j-2), field(i,k,j-1), &
7037 field(i,k,j ), field(i,k,j+1), vel )
7039 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
7044 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
7047 DO i = i_start, i_end
7049 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
7050 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
7053 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
7055 fqy(i,k, j) = 0.5*rv(i,k,j)* &
7056 (field(i,k,j)+field(i,k,j-1))
7058 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
7063 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
7066 DO i = i_start, i_end
7068 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
7069 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
7072 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
7074 fqy(i, k, j ) = 0.5*rv(i,k,j)* &
7075 (field(i,k,j)+field(i,k,j-1))
7076 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
7083 ENDDO j_loop_y_flux_3
7087 !-- these bounds are for periodic and sym conditions
7090 i_end = MIN(ite,ide-1)+1
7095 j_end = MIN(jte,jde-1)+1
7097 !-- modify loop bounds for open and specified b.c
7099 IF(degrade_ys) j_start = jts
7100 IF(degrade_ye) j_end = MIN(jte,jde-1)
7103 i_start = MAX(ids+1,its)
7104 i_start_f = i_start+1
7108 i_end = MIN(ide-2,ite)
7114 DO j = j_start, j_end
7119 DO i = i_start_f, i_end_f
7121 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
7122 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
7125 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
7127 fqx( i,k,j ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
7128 field(i ,k,j), field(i+1,k,j), vel )
7129 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
7134 ! lower order fluxes close to boundaries (if not periodic or symmetric)
7136 IF( degrade_xs ) THEN
7138 IF( i_start == ids+1 ) THEN ! second order flux next to the boundary
7142 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
7143 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
7146 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
7148 fqx(i,k,j) = 0.5*(ru(i,k,j)) &
7149 *(field(i,k,j)+field(i-1,k,j))
7151 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
7157 IF( degrade_xe ) THEN
7158 IF( i_end == ide-2 ) THEN ! second order flux next to the boundary
7161 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
7162 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
7165 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
7166 fqx(i,k,j) = 0.5*(ru(i,k,j)) &
7167 *(field(i,k,j)+field(i-1,k,j))
7168 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
7174 ENDDO ! enddo for outer J loop
7176 !--- end of 3rd order horizontal flux calculation
7179 ELSE IF( horz_order == 2 ) THEN
7181 IF( config_flags%periodic_x .or. &
7182 config_flags%symmetric_xs .or. &
7183 (its > ids+1) ) degrade_xs = .false.
7184 IF( config_flags%periodic_x .or. &
7185 config_flags%symmetric_xe .or. &
7186 (ite < ide-2) ) degrade_xe = .false.
7187 IF( config_flags%periodic_y .or. &
7188 config_flags%symmetric_ys .or. &
7189 (jts > jds+1) ) degrade_ys = .false.
7190 IF( config_flags%periodic_y .or. &
7191 config_flags%symmetric_ye .or. &
7192 (jte < jde-2) ) degrade_ye = .false.
7194 !-- y flux compute; these bounds are for periodic and sym b.c.
7198 i_end = MIN(ite,ide-1)+1
7200 j_end = MIN(jte,jde-1)+1
7202 !-- modify loop bounds if open or specified
7204 IF(degrade_xs) i_start = its
7205 IF(degrade_xe) i_end = MIN(ite,ide-1)
7206 IF(degrade_ys) j_start = MAX(jts,jds+1)
7207 IF(degrade_ye) j_end = MIN(jte,jde-2)
7209 ! compute fluxes, 2nd order, y flux
7211 DO j = j_start, j_end+1
7213 DO i = i_start, i_end
7214 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
7215 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
7218 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
7220 fqy(i,k, j) = 0.5*rv(i,k,j)* &
7221 (field(i,k,j)+field(i,k,j-1))
7223 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
7230 DO j = j_start, j_end
7232 DO i = i_start, i_end+1
7233 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
7234 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
7237 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
7238 fqx( i,k,j ) = 0.5*ru(i,k,j)* &
7239 (field(i,k,j)+field(i-1,k,j))
7241 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
7246 !--- end of 2nd order horizontal flux calculation
7250 WRITE ( wrf_err_message , * ) 'module_advect: advect_scalar_pd, h_order not known ',horz_order
7251 CALL wrf_error_fatal ( TRIM( wrf_err_message ) )
7253 ENDIF horizontal_order_test
7255 ! pick up the rest of the horizontal radiation boundary conditions.
7256 ! (these are the computations that don't require 'cb'.
7257 ! first, set to index ranges
7260 i_end = MIN(ite,ide-1)
7262 j_end = MIN(jte,jde-1)
7264 ! compute x (u) conditions for v, w, or scalar
7266 IF( (config_flags%open_xs) .and. (its == ids) ) THEN
7268 DO j = j_start, j_end
7270 ub = MIN( 0.5*(ru(its,k,j)+ru(its+1,k,j)), 0. )
7271 tendency(its,k,j) = tendency(its,k,j) &
7273 ub*( field_old(its+1,k,j) &
7274 - field_old(its ,k,j) ) + &
7275 field(its,k,j)*(ru(its+1,k,j)-ru(its,k,j)) &
7282 IF( (config_flags%open_xe) .and. (ite == ide) ) THEN
7284 DO j = j_start, j_end
7286 ub = MAX( 0.5*(ru(ite-1,k,j)+ru(ite,k,j)), 0. )
7287 tendency(i_end,k,j) = tendency(i_end,k,j) &
7289 ub*( field_old(i_end ,k,j) &
7290 - field_old(i_end-1,k,j) ) + &
7291 field(i_end,k,j)*(ru(ite,k,j)-ru(ite-1,k,j)) &
7298 IF( (config_flags%open_ys) .and. (jts == jds) ) THEN
7300 DO i = i_start, i_end
7302 vb = MIN( 0.5*(rv(i,k,jts)+rv(i,k,jts+1)), 0. )
7303 tendency(i,k,jts) = tendency(i,k,jts) &
7305 vb*( field_old(i,k,jts+1) &
7306 - field_old(i,k,jts ) ) + &
7307 field(i,k,jts)*(rv(i,k,jts+1)-rv(i,k,jts)) &
7314 IF( (config_flags%open_ye) .and. (jte == jde)) THEN
7316 DO i = i_start, i_end
7318 vb = MAX( 0.5*(rv(i,k,jte-1)+rv(i,k,jte)), 0. )
7319 tendency(i,k,j_end) = tendency(i,k,j_end) &
7321 vb*( field_old(i,k,j_end ) &
7322 - field_old(i,k,j_end-1) ) + &
7323 field(i,k,j_end)*(rv(i,k,jte)-rv(i,k,jte-1)) &
7330 IF( (config_flags%polar) .and. (jts == jds) ) THEN
7332 ! Assuming rv(i,k,jds) = 0.
7333 DO i = i_start, i_end
7335 vb = MIN( 0.5*rv(i,k,jts+1), 0. )
7336 tendency(i,k,jts) = tendency(i,k,jts) &
7338 vb*( field_old(i,k,jts+1) &
7339 - field_old(i,k,jts ) ) + &
7340 field(i,k,jts)*rv(i,k,jts+1) &
7347 IF( (config_flags%polar) .and. (jte == jde)) THEN
7349 ! Assuming rv(i,k,jde) = 0.
7350 DO i = i_start, i_end
7352 vb = MAX( 0.5*rv(i,k,jte-1), 0. )
7353 tendency(i,k,j_end) = tendency(i,k,j_end) &
7355 vb*( field_old(i,k,j_end ) &
7356 - field_old(i,k,j_end-1) ) + &
7357 field(i,k,j_end)*(-rv(i,k,jte-1)) &
7364 !-------------------- vertical advection
7366 !-- loop bounds for periodic or sym conditions
7369 i_end = MIN(ite,ide-1)+1
7371 j_end = MIN(jte,jde-1)+1
7373 !-- loop bounds for open or specified conditions
7375 IF(degrade_xs) i_start = MAX(its-1,ids)
7376 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
7377 IF(degrade_ys) j_start = MAX(jts-1,jds)
7378 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
7380 vert_order_test : IF (vert_order == 6) THEN
7382 DO j = j_start, j_end
7384 DO i = i_start, i_end
7392 DO i = i_start, i_end
7393 dz = 2./(rdzw(k)+rdzw(k-1))
7394 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7397 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7399 fqz(i,k,j) = vel*flux6( field(i,k-3,j), field(i,k-2,j), field(i,k-1,j), &
7400 field(i,k ,j), field(i,k+1,j), field(i,k+2,j), -vel )
7401 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7405 DO i = i_start, i_end
7408 dz = 2./(rdzw(k)+rdzw(k-1))
7409 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7412 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7413 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7414 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7417 dz = 2./(rdzw(k)+rdzw(k-1))
7418 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7421 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7423 fqz(i,k,j) = vel*flux4( &
7424 field(i,k-2,j), field(i,k-1,j), &
7425 field(i,k ,j), field(i,k+1,j), -vel )
7426 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7429 dz = 2./(rdzw(k)+rdzw(k-1))
7430 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7433 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7435 fqz(i,k,j) = vel*flux4( &
7436 field(i,k-2,j), field(i,k-1,j), &
7437 field(i,k ,j), field(i,k+1,j), -vel )
7438 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7441 dz = 2./(rdzw(k)+rdzw(k-1))
7442 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7445 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7446 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7447 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7453 ELSE IF (vert_order == 5) THEN
7455 DO j = j_start, j_end
7457 DO i = i_start, i_end
7465 DO i = i_start, i_end
7466 dz = 2./(rdzw(k)+rdzw(k-1))
7467 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7470 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7472 fqz(i,k,j) = vel*flux5( field(i,k-3,j), field(i,k-2,j), field(i,k-1,j), &
7473 field(i,k ,j), field(i,k+1,j), field(i,k+2,j), -vel )
7474 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7478 DO i = i_start, i_end
7481 dz = 2./(rdzw(k)+rdzw(k-1))
7482 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7485 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7486 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7487 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7490 dz = 2./(rdzw(k)+rdzw(k-1))
7491 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7494 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7496 fqz(i,k,j) = vel*flux3( &
7497 field(i,k-2,j), field(i,k-1,j), &
7498 field(i,k ,j), field(i,k+1,j), -vel )
7499 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7502 dz = 2./(rdzw(k)+rdzw(k-1))
7503 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7506 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7508 fqz(i,k,j) = vel*flux3( &
7509 field(i,k-2,j), field(i,k-1,j), &
7510 field(i,k ,j), field(i,k+1,j), -vel )
7511 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7514 dz = 2./(rdzw(k)+rdzw(k-1))
7515 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7518 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7519 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7520 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7526 ELSE IF (vert_order == 4) THEN
7528 DO j = j_start, j_end
7530 DO i = i_start, i_end
7538 DO i = i_start, i_end
7540 dz = 2./(rdzw(k)+rdzw(k-1))
7541 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7544 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7546 fqz(i,k,j) = vel*flux4( &
7547 field(i,k-2,j), field(i,k-1,j), &
7548 field(i,k ,j), field(i,k+1,j), -vel )
7549 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7553 DO i = i_start, i_end
7556 dz = 2./(rdzw(k)+rdzw(k-1))
7557 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7560 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7561 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7562 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7565 dz = 2./(rdzw(k)+rdzw(k-1))
7566 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7569 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7570 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7571 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7577 ELSE IF (vert_order == 3) THEN
7579 DO j = j_start, j_end
7581 DO i = i_start, i_end
7590 DO i = i_start, i_end
7592 dz = 2./(rdzw(k)+rdzw(k-1))
7593 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7596 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7598 fqz(i,k,j) = vel*flux3( &
7599 field(i,k-2,j), field(i,k-1,j), &
7600 field(i,k ,j), field(i,k+1,j), -vel )
7601 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7605 DO i = i_start, i_end
7608 dz = 2./(rdzw(k)+rdzw(k-1))
7609 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7612 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7613 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7614 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7617 dz = 2./(rdzw(k)+rdzw(k-1))
7618 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7621 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7622 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7623 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7629 ELSE IF (vert_order == 2) THEN
7631 DO j = j_start, j_end
7633 DO i = i_start, i_end
7641 DO i = i_start, i_end
7643 dz = 2./(rdzw(k)+rdzw(k-1))
7644 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7647 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7648 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7649 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7658 WRITE (wrf_err_message,*) ' advect_scalar_pd, v_order not known ',vert_order
7659 CALL wrf_error_fatal ( wrf_err_message )
7661 ENDIF vert_order_test
7665 ! positive definite filter
7668 i_end = MIN(ite,ide-1)+1
7670 j_end = MIN(jte,jde-1)+1
7672 !-- loop bounds for open or specified conditions
7674 IF(degrade_xs) i_start = MAX(its-1,ids)
7675 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
7676 IF(degrade_ys) j_start = MAX(jts-1,jds)
7677 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
7679 IF(config_flags%specified .or. config_flags%nested) THEN
7680 IF (degrade_xs) i_start = MAX(its-1,ids+1)
7681 IF (degrade_xe) i_end = MIN(ite+1,ide-2)
7682 IF (degrade_ys) j_start = MAX(jts-1,jds+1)
7683 IF (degrade_ye) j_end = MIN(jte+1,jde-2)
7686 IF(config_flags%open_xs) THEN
7687 IF (degrade_xs) i_start = MAX(its-1,ids+1)
7689 IF(config_flags%open_xe) THEN
7690 IF (degrade_xe) i_end = MIN(ite+1,ide-2)
7692 IF(config_flags%open_ys) THEN
7693 IF (degrade_ys) j_start = MAX(jts-1,jds+1)
7695 IF(config_flags%open_ye) THEN
7696 IF (degrade_ye) j_end = MIN(jte+1,jde-2)
7699 ! We don't want to change j_start and j_end
7700 ! for polar BC's since we want to calculate
7701 ! fluxes for directions other than y at the
7704 !-- here is the limiter...
7715 ph_low(i,k,j) = ((c1(k)*mub(i,j)+c2(k))+(c1(k)*mu_old(i,j)))*field_old(i,k,j) &
7716 - dt*( msftx(i,j)*msfty(i,j)*( &
7717 rdx*(fqxl(i+1,k,j)-fqxl(i,k,j)) + &
7718 rdy*(fqyl(i,k,j+1)-fqyl(i,k,j)) ) &
7719 +msfty(i,j)*rdzw(k)*(fqzl(i,k+1,j)-fqzl(i,k,j)) )
7730 flux_out(i,k,j) = dt*( (msftx(i,j)*msfty(i,j))*( &
7731 rdx*( max(0.,fqx (i+1,k,j)) &
7732 -min(0.,fqx (i ,k,j)) ) &
7733 +rdy*( max(0.,fqy (i,k,j+1)) &
7734 -min(0.,fqy (i,k,j )) ) ) &
7735 +msfty(i,j)*rdzw(k)*( min(0.,fqz (i,k+1,j)) &
7736 -max(0.,fqz (i,k ,j)) ) )
7746 IF( flux_out(i,k,j) .gt. ph_low(i,k,j) ) THEN
7747 scale = max(0.,ph_low(i,k,j)/(flux_out(i,k,j)+eps))
7748 IF( fqx (i+1,k,j) .gt. 0.) fqx(i+1,k,j) = scale*fqx(i+1,k,j)
7749 IF( fqx (i ,k,j) .lt. 0.) fqx(i ,k,j) = scale*fqx(i ,k,j)
7750 IF( fqy (i,k,j+1) .gt. 0.) fqy(i,k,j+1) = scale*fqy(i,k,j+1)
7751 IF( fqy (i,k,j ) .lt. 0.) fqy(i,k,j ) = scale*fqy(i,k,j )
7752 ! note: z flux is opposite sign in mass coordinate because
7753 ! vertical coordinate decreases with increasing k
7754 IF( fqz (i,k+1,j) .lt. 0.) fqz(i,k+1,j) = scale*fqz(i,k+1,j)
7755 IF( fqz (i,k ,j) .gt. 0.) fqz(i,k ,j) = scale*fqz(i,k ,j)
7765 ! add in the pd-limited flux divergence
7768 i_end = MIN(ite,ide-1)
7770 j_end = MIN(jte,jde-1)
7772 DO j = j_start, j_end
7775 DO i = i_start, i_end
7777 tendency (i,k,j) = tendency(i,k,j) &
7778 -rdzw(k)*( fqz (i,k+1,j)-fqz (i,k,j) &
7779 +fqzl(i,k+1,j)-fqzl(i,k,j))
7786 DO j = j_start, j_end
7788 DO i = i_start, i_end
7790 z_tendency (i,k,j) = 0. -rdzw(k)*( fqz (i,k+1,j)-fqz (i,k,j) &
7791 +fqzl(i,k+1,j)-fqzl(i,k,j))
7800 IF(degrade_xs) i_start = MAX(its,ids+1)
7801 IF(degrade_xe) i_end = MIN(ite,ide-2)
7803 DO j = j_start, j_end
7806 DO i = i_start, i_end
7808 ! Un-"canceled" map scale factor, ADT Eq. 48
7809 tendency (i,k,j) = tendency(i,k,j) &
7810 - msftx(i,j)*( rdx*( fqx (i+1,k,j)-fqx (i,k,j) &
7811 +fqxl(i+1,k,j)-fqxl(i,k,j)) )
7818 DO j = j_start, j_end
7820 DO i = i_start, i_end
7822 h_tendency (i,k,j) = 0. &
7823 - msftx(i,j)*( rdx*( fqx (i+1,k,j)-fqx (i,k,j) &
7824 +fqxl(i+1,k,j)-fqxl(i,k,j)) )
7834 i_end = MIN(ite,ide-1)
7835 IF(degrade_ys) j_start = MAX(jts,jds+1)
7836 IF(degrade_ye) j_end = MIN(jte,jde-2)
7838 DO j = j_start, j_end
7841 DO i = i_start, i_end
7843 ! Un-"canceled" map scale factor, ADT Eq. 48
7844 ! It is correct to use msftx (and not msfty), per W. Skamarock, 20080606
7845 tendency (i,k,j) = tendency(i,k,j) &
7846 - msftx(i,j)*( rdy*( fqy (i,k,j+1)-fqy (i,k,j) &
7847 +fqyl(i,k,j+1)-fqyl(i,k,j)) )
7854 DO j = j_start, j_end
7856 DO i = i_start, i_end
7858 h_tendency (i,k,j) = h_tendency (i,k,j) &
7859 - msftx(i,j)*( rdy*( fqy (i,k,j+1)-fqy (i,k,j) &
7860 +fqyl(i,k,j+1)-fqyl(i,k,j)) )
7867 END SUBROUTINE advect_scalar_pd
7869 !----------------------------------------------------------------
7871 SUBROUTINE advect_scalar_weno ( field, field_old, tendency, &
7874 mut, time_step, config_flags, &
7875 msfux, msfuy, msfvx, msfvy, &
7879 ids, ide, jds, jde, kds, kde, &
7880 ims, ime, jms, jme, kms, kme, &
7881 its, ite, jts, jte, kts, kte )
7883 ! 5th-order WENO (Weighted Essentially Non-Oscillatory) scheme adapted from COMMAS.
7884 ! See Jiang and Shu, 1996, J. Comp. Phys. v. 126, 202-223;
7885 ! Shu 2003, Int. J. Comp. Fluid Dyn. v. 17 107-118; Also used by Bryan 2005, Mon. Wea. Rev.
7891 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
7893 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
7894 ims, ime, jms, jme, kms, kme, &
7895 its, ite, jts, jte, kts, kte
7897 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: field, &
7903 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut
7904 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
7906 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
7913 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
7919 REAL , INTENT(IN ) :: rdx, &
7921 INTEGER , INTENT(IN ) :: time_step
7926 INTEGER :: i, j, k, itf, jtf, ktf
7927 INTEGER :: i_start, i_end, j_start, j_end
7928 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
7929 INTEGER :: jmin, jmax, jp, jm, imin, imax
7931 INTEGER , PARAMETER :: is=0, js=0, ks=0
7933 REAL :: mrdx, mrdy, ub, vb, vw
7934 REAL , DIMENSION(its:ite, kts:kte) :: vflux
7937 REAL, DIMENSION( its-is:ite+1, kts:kte ) :: fqx
7938 ! REAL, DIMENSION( its:ite+1, kts:kte ) :: fqx
7939 REAL, DIMENSION( its:ite, kts:kte, 2 ) :: fqy
7941 INTEGER :: horz_order, vert_order
7943 LOGICAL :: degrade_xs, degrade_ys
7944 LOGICAL :: degrade_xe, degrade_ye
7946 INTEGER :: jp1, jp0, jtmp
7949 real :: ue,uw,vs,vn,wb,wt
7950 real, parameter :: f30 = 7./12., f31 = 1./12.
7951 real, parameter :: f50 = 37./60., f51 = 2./15., f52 = 1./60.
7957 real :: qim2, qim1, qi, qip1, qip2
7958 double precision :: beta0, beta1, beta2, f0, f1, f2, wi0, wi1, wi2, sumwk
7959 double precision, parameter :: gi0 = 1.d0/10.d0, gi1 = 6.d0/10.d0, gi2 = 3.d0/10.d0, eps=1.0d-28
7960 integer, parameter :: pw = 2
7963 ! definition of flux operators, 3rd, 4th, 5th or 6th order
7965 REAL :: flux3, flux4, flux5, flux6
7966 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel
7968 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
7969 (7./12.)*(q_i + q_im1) - (1./12.)*(q_ip1 + q_im2)
7971 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
7972 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
7973 sign(1.,ua)*(1./12.)*((q_ip1 - q_im2)-3.*(q_i-q_im1))
7975 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
7976 (37./60.)*(q_i+q_im1) - (2./15.)*(q_ip1+q_im2) &
7977 +(1./60.)*(q_ip2+q_im3)
7979 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
7980 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
7981 -sign(1,time_step)*sign(1.,ua)*(1./60.)*( &
7982 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )
7984 LOGICAL :: specified
7987 if(config_flags%specified .or. config_flags%nested) specified = .true.
7989 ! set order for the advection schemes
7992 horz_order = 5 ! config_flags%h_sca_adv_order
7993 vert_order = 5 ! config_flags%v_sca_adv_order
7995 ! begin with horizontal flux divergence
7996 ! here is the choice of flux operators
8000 IF( horz_order == 5 ) THEN
8002 ! determine boundary mods for flux operators
8003 ! We degrade the flux operators from 3rd/4th order
8004 ! to second order one gridpoint in from the boundaries for
8005 ! all boundary conditions except periodic and symmetry - these
8006 ! conditions have boundary zone data fill for correct application
8007 ! of the higher order flux stencils
8014 IF( config_flags%periodic_x .or. &
8015 config_flags%symmetric_xs .or. &
8016 (its > ids+3) ) degrade_xs = .false.
8017 IF( config_flags%periodic_x .or. &
8018 config_flags%symmetric_xe .or. &
8019 (ite < ide-3) ) degrade_xe = .false.
8020 IF( config_flags%periodic_y .or. &
8021 config_flags%symmetric_ys .or. &
8022 (jts > jds+3) ) degrade_ys = .false.
8023 IF( config_flags%periodic_y .or. &
8024 config_flags%symmetric_ye .or. &
8025 (jte < jde-4) ) degrade_ye = .false.
8027 !--------------- y - advection first
8031 i_end = MIN(ite,ide-1)
8038 IF ( config_flags%open_xs .or. specified ) i_start = MAX(ids+1,its)
8039 IF ( config_flags%open_xe .or. specified ) i_end = MIN(ide-1,ite)
8040 IF ( config_flags%periodic_x ) i_start = its
8041 IF ( config_flags%periodic_x ) i_end = ite
8045 j_end = MIN(jte,jde-1)
8047 ! higher order flux has a 5 or 7 point stencil, so compute
8048 ! bounds so we can switch to second order flux close to the boundary
8054 j_start = MAX(jts,jds+1)
8059 j_end = MIN(jte,jde-2)
8063 IF(config_flags%polar) j_end = MIN(jte,jde-1)
8065 ! compute fluxes, 5th or 6th order
8070 j_loop_y_flux_5 : DO j = j_start, j_end+1
8072 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN ! use full stencil
8075 DO i = i_start, i_end
8077 vel = 0.5*( rv(i,k,j) + rv(i-is,k-ks,j-js) )
8079 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
8080 qip2 = field(i,k,j+1)
8081 qip1 = field(i,k,j )
8083 qim1 = field(i,k,j-2)
8084 qim2 = field(i,k,j-3)
8086 qip2 = field(i,k,j-2)
8087 qip1 = field(i,k,j-1)
8089 qim1 = field(i,k,j+1)
8090 qim2 = field(i,k,j+2)
8093 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
8094 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
8095 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
8097 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
8098 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
8099 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
8101 wi0 = gi0 / (eps + beta0)**pw
8102 wi1 = gi1 / (eps + beta1)**pw
8103 wi2 = gi2 / (eps + beta2)**pw
8105 sumwk = wi0 + wi1 + wi2
8107 fqy( i, k, jp1 ) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
8109 ! fqy( i, k, jp1 ) = vel*flux5( &
8110 ! field(i,k,j-3), field(i,k,j-2), field(i,k,j-1), &
8111 ! field(i,k,j ), field(i,k,j+1), field(i,k,j+2), vel )
8116 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
8119 DO i = i_start, i_end
8120 fqy(i,k, jp1) = 0.5*rv(i,k,j)* &
8121 ! fqy(i,k, jp1) = 0.5*0.5*( rv(i,k,j) + rv(i-is,k-ks,j-js) )* &
8122 (field(i,k,j)+field(i,k,j-1))
8127 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
8130 DO i = i_start, i_end
8131 ! vel = 0.5*( rv(i,k,j) + rv(i-is,k-ks,j-js) )
8133 fqy( i, k, jp1 ) = vel*flux3( &
8134 field(i,k,j-2),field(i,k,j-1),field(i,k,j),field(i,k,j+1),vel )
8138 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
8141 DO i = i_start, i_end
8142 ! fqy(i, k, jp1) = 0.5*0.5*( rv(i,k,j) + rv(i-is,k-ks,j-js) )* &
8143 fqy(i, k, jp1) = 0.5*rv(i,k,j)* &
8144 (field(i,k,j)+field(i,k,j-1))
8148 ELSE IF ( j == jde-2 ) THEN ! 3rd or 4th order flux 2 in from north boundary
8151 DO i = i_start, i_end
8153 ! vel = 0.5*( rv(i,k,j) + rv(i-is,k-ks,j-js) )
8154 fqy( i, k, jp1) = vel*flux3( &
8155 field(i,k,j-2),field(i,k,j-1), &
8156 field(i,k,j),field(i,k,j+1),vel )
8162 ! y flux-divergence into tendency
8165 ! Comments on polar boundary conditions
8166 ! Same process as for advect_u - tendencies run from jds to jde-1
8167 ! (latitudes are as for u grid, longitudes are displaced)
8168 ! Therefore: flow is only from one side for points next to poles
8169 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
8171 DO i = i_start, i_end
8172 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
8173 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
8176 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
8178 DO i = i_start, i_end
8179 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
8180 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
8185 IF(j > j_start) THEN
8188 DO i = i_start, i_end
8189 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
8190 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
8196 ELSEIF ( is == 1 ) THEN
8198 ! (j > j_start) will miss the u(,,jds) tendency
8199 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
8201 DO i = i_start, i_end
8202 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
8203 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
8206 ! This would be seen by (j > j_start) but we need to zero out the NP tendency
8207 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
8209 DO i = i_start, i_end
8210 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
8211 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
8216 IF(j > j_start) THEN
8219 DO i = i_start, i_end
8220 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
8221 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
8235 ENDDO j_loop_y_flux_5
8237 ! next, x - flux divergence
8240 i_end = MIN(ite,ide-1)
8243 j_end = MIN(jte,jde-1)
8245 ! higher order flux has a 5 or 7 point stencil, so compute
8246 ! bounds so we can switch to second order flux close to the boundary
8252 i_start = MAX(ids+1,its)
8253 ! i_start_f = i_start+2
8254 i_start_f = MIN(i_start+2,ids+3)
8258 i_end = MIN(ide-2,ite)
8264 DO j = j_start, j_end
8266 ! 5th or 6th order flux
8269 DO i = i_start_f, i_end_f
8271 vel = 0.5*( ru(i,k,j) + ru(i-is,k-ks,j-js) )
8274 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
8275 qip2 = field(i+1,k,j)
8276 qip1 = field(i, k,j)
8278 qim1 = field(i-2,k,j)
8279 qim2 = field(i-3,k,j)
8281 qip2 = field(i-2,k,j)
8282 qip1 = field(i-1,k,j)
8284 qim1 = field(i+1,k,j)
8285 qim2 = field(i+2,k,j)
8288 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
8289 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
8290 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
8292 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
8293 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
8294 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
8296 wi0 = gi0 / (eps + beta0)**pw
8297 wi1 = gi1 / (eps + beta1)**pw
8298 wi2 = gi2 / (eps + beta2)**pw
8300 sumwk = wi0 + wi1 + wi2
8302 fqx(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
8304 ! fqx( i,k ) = vel*flux5( field(i-3,k,j), field(i-2,k,j), &
8305 ! field(i-1,k,j), field(i ,k,j), &
8306 ! field(i+1,k,j), field(i+2,k,j), &
8311 ! lower order fluxes close to boundaries (if not periodic or symmetric)
8313 IF( degrade_xs ) THEN
8315 DO i=i_start,i_start_f-1
8317 IF(i == ids+1) THEN ! second order
8319 fqx(i,k) = 0.5*(ru(i,k,j)) &
8320 *(field(i,k,j)+field(i-1,k,j))
8324 IF(i == ids+2) THEN ! third order
8327 fqx( i,k ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
8328 field(i ,k,j), field(i+1,k,j), &
8337 IF( degrade_xe ) THEN
8339 DO i = i_end_f+1, i_end+1
8341 IF( i == ide-1 ) THEN ! second order flux next to the boundary
8343 fqx(i,k) = 0.5*(ru(i,k,j)) &
8344 *(field(i,k,j)+field(i-1,k,j))
8348 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
8351 fqx( i,k ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
8352 field(i ,k,j), field(i+1,k,j), &
8361 ! x flux-divergence into tendency
8365 DO i = i_start, i_end
8366 mrdx=msftx(i,j)*rdx ! see ADT eqn 48 [rho->rho*q] dividing by my, 1st term RHS
8367 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
8370 ELSEIF ( is == 1 ) THEN
8372 DO i = i_start, i_end
8373 mrdx=msfux(i,j)*rdx ! ADT eqn 44, 1st term on RHS
8374 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
8385 ! pick up the rest of the horizontal radiation boundary conditions.
8386 ! (these are the computations that don't require 'cb'.
8387 ! first, set to index ranges
8390 i_end = MIN(ite,ide-1)
8392 j_end = MIN(jte,jde-1)
8394 ! compute x (u) conditions for v, w, or scalar
8396 IF( (config_flags%open_xs) .and. (its == ids) ) THEN
8398 DO j = j_start, j_end
8400 ub = MIN( 0.5*(ru(its,k,j)+ru(its+1,k,j)), 0. )
8401 tendency(its,k,j) = tendency(its,k,j) &
8403 ub*( field_old(its+1,k,j) &
8404 - field_old(its ,k,j) ) + &
8405 field(its,k,j)*(ru(its+1,k,j)-ru(its,k,j)) &
8412 IF( (config_flags%open_xe) .and. (ite == ide) ) THEN
8414 DO j = j_start, j_end
8416 ub = MAX( 0.5*(ru(ite-1,k,j)+ru(ite,k,j)), 0. )
8417 tendency(i_end,k,j) = tendency(i_end,k,j) &
8419 ub*( field_old(i_end ,k,j) &
8420 - field_old(i_end-1,k,j) ) + &
8421 field(i_end,k,j)*(ru(ite,k,j)-ru(ite-1,k,j)) &
8428 IF( (config_flags%open_ys) .and. (jts == jds) ) THEN
8430 DO i = i_start, i_end
8432 vb = MIN( 0.5*(rv(i,k,jts)+rv(i,k,jts+1)), 0. )
8433 tendency(i,k,jts) = tendency(i,k,jts) &
8435 vb*( field_old(i,k,jts+1) &
8436 - field_old(i,k,jts ) ) + &
8437 field(i,k,jts)*(rv(i,k,jts+1)-rv(i,k,jts)) &
8444 IF( (config_flags%open_ye) .and. (jte == jde)) THEN
8446 DO i = i_start, i_end
8448 vb = MAX( 0.5*(rv(i,k,jte-1)+rv(i,k,jte)), 0. )
8449 tendency(i,k,j_end) = tendency(i,k,j_end) &
8451 vb*( field_old(i,k,j_end ) &
8452 - field_old(i,k,j_end-1) ) + &
8453 field(i,k,j_end)*(rv(i,k,jte)-rv(i,k,jte-1)) &
8461 !-------------------- vertical advection
8462 ! Scalar equation has 3rd term on RHS = - partial d/dz (q rho w /my)
8463 ! Here we have: - partial d/dz (q*rom) = - partial d/dz (q rho w / my)
8464 ! So we don't need to make a correction for advect_scalar
8467 i_end = MIN(ite,ide-1)
8469 j_end = MIN(jte,jde-1)
8471 DO i = i_start, i_end
8478 DO j = j_start, j_end
8481 DO i = i_start, i_end
8483 vel = 0.5*( rom(i,k,j) + rom(i-is,k-ks,j-js) )
8485 IF( -vel*sign(1,time_step) .ge. 0.0 ) THEN
8486 qip2 = field(i,k+1,j)
8487 qip1 = field(i,k ,j)
8489 qim1 = field(i,k-2,j)
8490 qim2 = field(i,k-3,j)
8492 qip2 = field(i,k-2,j)
8493 qip1 = field(i,k-1,j)
8495 qim1 = field(i,k+1,j)
8496 qim2 = field(i,k+2,j)
8499 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
8500 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
8501 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
8503 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
8504 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
8505 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
8507 wi0 = gi0 / (eps + beta0)**pw
8508 wi1 = gi1 / (eps + beta1)**pw
8509 wi2 = gi2 / (eps + beta2)**pw
8511 sumwk = wi0 + wi1 + wi2
8513 vflux(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
8515 ! vflux(i,k) = vel*flux5( &
8516 ! field(i,k-3,j), field(i,k-2,j), field(i,k-1,j), &
8517 ! field(i,k ,j), field(i,k+1,j), field(i,k+2,j), -vel )
8521 DO i = i_start, i_end
8524 vflux(i,k)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
8528 vflux(i,k) = vel*flux3( &
8529 field(i,k-2,j), field(i,k-1,j), &
8530 field(i,k ,j), field(i,k+1,j), -vel )
8533 vflux(i,k) = vel*flux3( &
8534 field(i,k-2,j), field(i,k-1,j), &
8535 field(i,k ,j), field(i,k+1,j), -vel )
8538 vflux(i,k)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
8542 DO i = i_start, i_end
8543 tendency(i,k,j)=tendency(i,k,j)-rdzw(k)*(vflux(i,k+1)-vflux(i,k))
8551 END SUBROUTINE advect_scalar_weno
8553 !---------------------------------------------------------------------------------
8555 SUBROUTINE advect_scalar_wenopd ( field, field_old, tendency, &
8559 time_step, config_flags, &
8560 msfux, msfuy, msfvx, msfvy, &
8563 rdx, rdy, rdzw, dt, &
8564 ids, ide, jds, jde, kds, kde, &
8565 ims, ime, jms, jme, kms, kme, &
8566 its, ite, jts, jte, kts, kte )
8568 ! this is a first cut at a positive definite advection option
8569 ! for scalars in WRF. This version is memory intensive ->
8570 ! we save 3d arrays of x, y and z both high and low order fluxes
8571 ! (six in all). Alternatively, we could sweep in a direction
8572 ! and lower the cost considerably.
8574 ! uses the Smolarkiewicz MWR 1989 approach, with addition of first-order
8577 ! WCS, 3 December 2002, 24 February 2003
8580 ! ERM Dec. 2011: replaced 5th-order fluxes with 5th-order WENO (Weighted
8581 ! Essentially Non-Oscillatory) scheme
8582 ! See Jiang and Shu, 1996, J. Comp. Phys. v. 126, 202-223;
8583 ! Shu 2003, Int. J. Comp. Fluid Dyn. v. 17 107-118;
8590 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
8592 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
8593 ims, ime, jms, jme, kms, kme, &
8594 its, ite, jts, jte, kts, kte
8596 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: field, &
8602 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut, mub, mu_old
8603 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
8605 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
8612 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
8618 REAL , INTENT(IN ) :: rdx, &
8621 INTEGER , INTENT(IN ) :: time_step
8625 INTEGER :: i, j, k, itf, jtf, ktf
8626 INTEGER :: i_start, i_end, j_start, j_end
8627 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
8628 INTEGER :: jmin, jmax, jp, jm, imin, imax
8630 REAL :: mrdx, mrdy, ub, vb, uw, vw, mu
8632 ! storage for high and low order fluxes
8634 REAL, DIMENSION( its-1:ite+2, kts:kte, jts-1:jte+2 ) :: fqx, fqy, fqz
8635 REAL, DIMENSION( its-1:ite+2, kts:kte, jts-1:jte+2 ) :: fqxl, fqyl, fqzl
8637 INTEGER :: horz_order, vert_order
8639 LOGICAL :: degrade_xs, degrade_ys
8640 LOGICAL :: degrade_xe, degrade_ye
8642 INTEGER :: jp1, jp0, jtmp
8644 REAL,DIMENSION( its-1:ite+2, kts:kte, jts-1:jte+2 ) :: flux_out, ph_low
8646 REAL, PARAMETER :: eps=1.e-20
8649 real :: ue,vs,vn,wb,wt
8650 real, parameter :: f30 = 7./12., f31 = 1./12.
8651 real, parameter :: f50 = 37./60., f51 = 2./15., f52 = 1./60.
8653 real :: qim2, qim1, qi, qip1, qip2
8654 double precision :: beta0, beta1, beta2, f0, f1, f2, wi0, wi1, wi2, sumwk
8655 double precision, parameter :: gi0 = 1.d0/10.d0, gi1 = 6.d0/10.d0, gi2 = 3.d0/10.d0, eps1=1.0d-28
8656 integer, parameter :: pw = 2
8659 ! definition of flux operators, 3rd, 4th, 5th or 6th order
8661 REAL :: flux3, flux4, flux5, flux6, flux_upwind
8662 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel, cr
8664 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
8665 (7./12.)*(q_i + q_im1) - (1./12.)*(q_ip1 + q_im2)
8667 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
8668 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
8669 sign(1,time_step)*sign(1.,ua)*(1./12.)*((q_ip1 - q_im2)-3.*(q_i-q_im1))
8671 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
8672 (37./60.)*(q_i+q_im1) - (2./15.)*(q_ip1+q_im2) &
8673 +(1./60.)*(q_ip2+q_im3)
8675 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
8676 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
8677 -sign(1,time_step)*sign(1.,ua)*(1./60.)*( &
8678 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )
8680 flux_upwind(q_im1, q_i, cr ) = 0.5*min( 1.0,(cr+abs(cr)))*q_im1 &
8681 +0.5*max(-1.0,(cr-abs(cr)))*q_i
8683 ! flux_upwind(q_im1, q_i, cr ) = 0.5*(1.+sign(1.,cr))*q_im1 &
8684 ! +0.5*(1.-sign(1.,cr))*q_i
8685 ! flux_upwind(q_im1, q_i, cr ) = 0.
8689 LOGICAL, PARAMETER :: pd_limit = .true.
8691 ! set order for the advection schemes
8693 ! write(6,*) ' in pd advection routine '
8695 ! Empty arrays just in case:
8696 IF (config_flags%polar) THEN
8706 horz_order = config_flags%h_sca_adv_order
8707 vert_order = config_flags%v_sca_adv_order
8709 ! determine boundary mods for flux operators
8710 ! We degrade the flux operators from 3rd/4th order
8711 ! to second order one gridpoint in from the boundaries for
8712 ! all boundary conditions except periodic and symmetry - these
8713 ! conditions have boundary zone data fill for correct application
8714 ! of the higher order flux stencils
8721 ! begin with horizontal flux divergence
8722 ! here is the choice of flux operators
8725 ! horizontal_order_test : IF( horz_order == 6 ) THEN
8727 ! ELSE IF( horz_order == 5 ) THEN
8729 IF( config_flags%periodic_x .or. &
8730 config_flags%symmetric_xs .or. &
8731 (its > ids+3) ) degrade_xs = .false.
8732 IF( config_flags%periodic_x .or. &
8733 config_flags%symmetric_xe .or. &
8734 (ite < ide-4) ) degrade_xe = .false.
8735 IF( config_flags%periodic_y .or. &
8736 config_flags%symmetric_ys .or. &
8737 (jts > jds+3) ) degrade_ys = .false.
8738 IF( config_flags%periodic_y .or. &
8739 config_flags%symmetric_ye .or. &
8740 (jte < jde-4) ) degrade_ye = .false.
8742 !--------------- y - advection first
8744 !-- y flux compute; these bounds are for periodic and sym b.c.
8748 i_end = MIN(ite,ide-1)+1
8750 j_end = MIN(jte,jde-1)+1
8754 !-- modify loop bounds if open or specified
8756 ! IF(degrade_xs) i_start = MAX(its-1,ids-1)
8757 ! IF(degrade_xe) i_end = MIN(ite+1,ide-2)
8758 IF(degrade_xs) i_start = MAX(its-1,ids)
8759 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
8762 j_start = MAX(jts-1,jds+1)
8767 j_end = MIN(jte+1,jde-2)
8771 ! compute fluxes, 5th order
8773 j_loop_y_flux_5 : DO j = j_start, j_end+1
8775 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN ! use full stencil
8778 DO i = i_start, i_end
8780 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
8781 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
8784 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
8786 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
8787 qip2 = field(i,k,j+1)
8788 qip1 = field(i,k,j )
8790 qim1 = field(i,k,j-2)
8791 qim2 = field(i,k,j-3)
8793 qip2 = field(i,k,j-2)
8794 qip1 = field(i,k,j-1)
8796 qim1 = field(i,k,j+1)
8797 qim2 = field(i,k,j+2)
8800 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
8801 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
8802 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
8804 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
8805 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
8806 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
8808 wi0 = gi0 / (eps1 + beta0)**pw
8809 wi1 = gi1 / (eps1 + beta1)**pw
8810 wi2 = gi2 / (eps1 + beta2)**pw
8812 sumwk = wi0 + wi1 + wi2
8814 fqy( i, k, j ) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
8816 ! fqy( i, k, j ) = vel*flux5( &
8817 ! field(i,k,j-3), field(i,k,j-2), field(i,k,j-1), &
8818 ! field(i,k,j ), field(i,k,j+1), field(i,k,j+2), vel )
8820 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
8825 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
8828 DO i = i_start, i_end
8830 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
8831 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
8834 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
8836 fqy(i,k, j) = 0.5*rv(i,k,j)* &
8837 (field(i,k,j)+field(i,k,j-1))
8839 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
8844 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
8847 DO i = i_start, i_end
8849 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
8850 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
8853 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
8855 fqy( i, k, j ) = vel*flux3( &
8856 field(i,k,j-2),field(i,k,j-1),field(i,k,j),field(i,k,j+1),vel )
8857 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
8862 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
8865 DO i = i_start, i_end
8867 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
8868 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
8871 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
8873 fqy(i, k, j ) = 0.5*rv(i,k,j)* &
8874 (field(i,k,j)+field(i,k,j-1))
8875 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
8880 ELSE IF ( j == jde-2 ) THEN ! 3rd or 4th order flux 2 in from north boundary
8883 DO i = i_start, i_end
8885 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
8886 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
8889 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
8891 fqy( i, k, j) = vel*flux3( &
8892 field(i,k,j-2),field(i,k,j-1), &
8893 field(i,k,j),field(i,k,j+1),vel )
8894 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
8901 ENDDO j_loop_y_flux_5
8905 !-- these bounds are for periodic and sym conditions
8908 i_end = MIN(ite,ide-1)+1
8913 j_end = MIN(jte,jde-1)+1
8915 !-- modify loop bounds for open and specified b.c
8917 ! IF(degrade_ys) j_start = MAX(jts-1,jds+1)
8918 ! IF(degrade_ye) j_end = MIN(jte+1,jde-2)
8919 IF(degrade_ys) j_start = MAX(jts-1,jds)
8920 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
8923 i_start = MAX(ids+1,its-1)
8928 i_end = MIN(ide-2,ite+1)
8934 DO j = j_start, j_end
8939 DO i = i_start_f, i_end_f
8941 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
8942 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
8945 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
8948 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
8949 qip2 = field(i+1,k,j)
8950 qip1 = field(i, k,j)
8952 qim1 = field(i-2,k,j)
8953 qim2 = field(i-3,k,j)
8955 qip2 = field(i-2,k,j)
8956 qip1 = field(i-1,k,j)
8958 qim1 = field(i+1,k,j)
8959 qim2 = field(i+2,k,j)
8962 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
8963 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
8964 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
8966 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
8967 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
8968 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
8970 wi0 = gi0 / (eps1 + beta0)**pw
8971 wi1 = gi1 / (eps1 + beta1)**pw
8972 wi2 = gi2 / (eps1 + beta2)**pw
8974 sumwk = wi0 + wi1 + wi2
8976 fqx(i,k,j) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
8978 ! fqx( i,k,j ) = vel*flux5( field(i-3,k,j), field(i-2,k,j), &
8979 ! field(i-1,k,j), field(i ,k,j), &
8980 ! field(i+1,k,j), field(i+2,k,j), &
8982 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
8987 ! lower order fluxes close to boundaries (if not periodic or symmetric)
8989 IF( degrade_xs ) THEN
8991 DO i=i_start,i_start_f-1
8993 IF(i == ids+1) THEN ! second order
8995 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
8996 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
8999 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9000 fqx(i,k,j) = 0.5*(ru(i,k,j)) &
9001 *(field(i,k,j)+field(i-1,k,j))
9002 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9006 IF(i == ids+2) THEN ! third order
9008 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
9009 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
9012 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9013 fqx( i,k,j ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
9014 field(i ,k,j), field(i+1,k,j), &
9016 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9024 IF( degrade_xe ) THEN
9026 DO i = i_end_f+1, i_end+1
9028 IF( i == ide-1 ) THEN ! second order flux next to the boundary
9030 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
9031 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
9034 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9035 fqx(i,k,j) = 0.5*(ru(i,k,j)) &
9036 *(field(i,k,j)+field(i-1,k,j))
9037 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9042 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
9044 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
9045 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
9048 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9049 fqx( i,k,j ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
9050 field(i ,k,j), field(i+1,k,j), &
9052 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9060 ENDDO ! enddo for outer J loop
9062 !--- end of 5th order horizontal flux calculation
9066 ! WRITE ( wrf_err_message , * ) 'module_advect: advect_scalar_pd, h_order not known ',horz_order
9067 ! CALL wrf_error_fatal ( TRIM( wrf_err_message ) )
9069 ! ENDIF horizontal_order_test
9071 ! pick up the rest of the horizontal radiation boundary conditions.
9072 ! (these are the computations that don't require 'cb'.
9073 ! first, set to index ranges
9076 i_end = MIN(ite,ide-1)
9078 j_end = MIN(jte,jde-1)
9080 ! compute x (u) conditions for v, w, or scalar
9082 IF( (config_flags%open_xs) .and. (its == ids) ) THEN
9084 DO j = j_start, j_end
9086 ub = MIN( 0.5*(ru(its,k,j)+ru(its+1,k,j)), 0. )
9087 tendency(its,k,j) = tendency(its,k,j) &
9089 ub*( field_old(its+1,k,j) &
9090 - field_old(its ,k,j) ) + &
9091 field(its,k,j)*(ru(its+1,k,j)-ru(its,k,j)) &
9098 IF( (config_flags%open_xe) .and. (ite == ide) ) THEN
9100 DO j = j_start, j_end
9102 ub = MAX( 0.5*(ru(ite-1,k,j)+ru(ite,k,j)), 0. )
9103 tendency(i_end,k,j) = tendency(i_end,k,j) &
9105 ub*( field_old(i_end ,k,j) &
9106 - field_old(i_end-1,k,j) ) + &
9107 field(i_end,k,j)*(ru(ite,k,j)-ru(ite-1,k,j)) &
9114 IF( (config_flags%open_ys) .and. (jts == jds) ) THEN
9116 DO i = i_start, i_end
9118 vb = MIN( 0.5*(rv(i,k,jts)+rv(i,k,jts+1)), 0. )
9119 tendency(i,k,jts) = tendency(i,k,jts) &
9121 vb*( field_old(i,k,jts+1) &
9122 - field_old(i,k,jts ) ) + &
9123 field(i,k,jts)*(rv(i,k,jts+1)-rv(i,k,jts)) &
9130 IF( (config_flags%open_ye) .and. (jte == jde)) THEN
9132 DO i = i_start, i_end
9134 vb = MAX( 0.5*(rv(i,k,jte-1)+rv(i,k,jte)), 0. )
9135 tendency(i,k,j_end) = tendency(i,k,j_end) &
9137 vb*( field_old(i,k,j_end ) &
9138 - field_old(i,k,j_end-1) ) + &
9139 field(i,k,j_end)*(rv(i,k,jte)-rv(i,k,jte-1)) &
9146 IF( (config_flags%polar) .and. (jts == jds) ) THEN
9148 ! Assuming rv(i,k,jds) = 0.
9149 DO i = i_start, i_end
9151 vb = MIN( 0.5*rv(i,k,jts+1), 0. )
9152 tendency(i,k,jts) = tendency(i,k,jts) &
9154 vb*( field_old(i,k,jts+1) &
9155 - field_old(i,k,jts ) ) + &
9156 field(i,k,jts)*rv(i,k,jts+1) &
9163 IF( (config_flags%polar) .and. (jte == jde)) THEN
9165 ! Assuming rv(i,k,jde) = 0.
9166 DO i = i_start, i_end
9168 vb = MAX( 0.5*rv(i,k,jte-1), 0. )
9169 tendency(i,k,j_end) = tendency(i,k,j_end) &
9171 vb*( field_old(i,k,j_end ) &
9172 - field_old(i,k,j_end-1) ) + &
9173 field(i,k,j_end)*(-rv(i,k,jte-1)) &
9180 !-------------------- vertical advection
9182 !-- loop bounds for periodic or sym conditions
9185 i_end = MIN(ite,ide-1)+1
9187 j_end = MIN(jte,jde-1)+1
9189 !-- loop bounds for open or specified conditions
9191 IF(degrade_xs) i_start = MAX(its-1,ids)
9192 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
9193 IF(degrade_ys) j_start = MAX(jts-1,jds)
9194 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
9196 ! vert_order_test : IF (vert_order == 6) THEN
9199 ! ELSE IF (vert_order == 5) THEN
9201 DO j = j_start, j_end
9203 DO i = i_start, i_end
9211 DO i = i_start, i_end
9212 dz = 2./(rdzw(k)+rdzw(k-1))
9213 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
9216 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
9219 IF( -vel*sign(1,time_step) .ge. 0.0 ) THEN
9220 qip2 = field(i,k+1,j)
9221 qip1 = field(i,k ,j)
9223 qim1 = field(i,k-2,j)
9224 qim2 = field(i,k-3,j)
9226 qip2 = field(i,k-2,j)
9227 qip1 = field(i,k-1,j)
9229 qim1 = field(i,k+1,j)
9230 qim2 = field(i,k+2,j)
9233 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
9234 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
9235 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
9237 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
9238 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
9239 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
9241 wi0 = gi0 / (eps1 + beta0)**pw
9242 wi1 = gi1 / (eps1 + beta1)**pw
9243 wi2 = gi2 / (eps1 + beta2)**pw
9245 sumwk = wi0 + wi1 + wi2
9247 fqz(i,k,j) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
9249 ! fqz(i,k,j) = vel*flux5( field(i,k-3,j), field(i,k-2,j), field(i,k-1,j), &
9250 ! field(i,k ,j), field(i,k+1,j), field(i,k+2,j), -vel )
9251 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
9255 DO i = i_start, i_end
9258 dz = 2./(rdzw(k)+rdzw(k-1))
9259 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
9262 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
9263 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
9264 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
9267 dz = 2./(rdzw(k)+rdzw(k-1))
9268 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
9271 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
9273 fqz(i,k,j) = vel*flux3( &
9274 field(i,k-2,j), field(i,k-1,j), &
9275 field(i,k ,j), field(i,k+1,j), -vel )
9276 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
9279 dz = 2./(rdzw(k)+rdzw(k-1))
9280 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
9283 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
9285 fqz(i,k,j) = vel*flux3( &
9286 field(i,k-2,j), field(i,k-1,j), &
9287 field(i,k ,j), field(i,k+1,j), -vel )
9288 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
9291 dz = 2./(rdzw(k)+rdzw(k-1))
9292 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
9295 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
9296 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
9297 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
9306 ! WRITE (wrf_err_message,*) ' advect_scalar_pd, v_order not known ',vert_order
9307 ! CALL wrf_error_fatal ( wrf_err_message )
9309 ! ENDIF vert_order_test
9313 ! positive definite filter
9316 i_end = MIN(ite,ide-1)+1
9318 j_end = MIN(jte,jde-1)+1
9320 !-- loop bounds for open or specified conditions
9322 IF(degrade_xs) i_start = MAX(its-1,ids)
9323 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
9324 IF(degrade_ys) j_start = MAX(jts-1,jds)
9325 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
9327 IF(config_flags%specified .or. config_flags%nested) THEN
9328 IF (degrade_xs) i_start = MAX(its-1,ids+1)
9329 IF (degrade_xe) i_end = MIN(ite+1,ide-2)
9330 IF (degrade_ys) j_start = MAX(jts-1,jds+1)
9331 IF (degrade_ye) j_end = MIN(jte+1,jde-2)
9334 IF(config_flags%open_xs) THEN
9335 IF (degrade_xs) i_start = MAX(its-1,ids+1)
9337 IF(config_flags%open_xe) THEN
9338 IF (degrade_xe) i_end = MIN(ite+1,ide-2)
9340 IF(config_flags%open_ys) THEN
9341 IF (degrade_ys) j_start = MAX(jts-1,jds+1)
9343 IF(config_flags%open_ye) THEN
9344 IF (degrade_ye) j_end = MIN(jte+1,jde-2)
9347 ! We don't want to change j_start and j_end
9348 ! for polar BC's since we want to calculate
9349 ! fluxes for directions other than y at the
9352 !-- here is the limiter...
9363 ph_low(i,k,j) = ((c1(k)*mub(i,j)+c2(k))+(c1(k)*mu_old(i,j)))*field_old(i,k,j) &
9364 - dt*( msftx(i,j)*msfty(i,j)*( &
9365 rdx*(fqxl(i+1,k,j)-fqxl(i,k,j)) + &
9366 rdy*(fqyl(i,k,j+1)-fqyl(i,k,j)) ) &
9367 +msfty(i,j)*rdzw(k)*(fqzl(i,k+1,j)-fqzl(i,k,j)) )
9378 flux_out(i,k,j) = dt*( (msftx(i,j)*msfty(i,j))*( &
9379 rdx*( max(0.,fqx (i+1,k,j)) &
9380 -min(0.,fqx (i ,k,j)) ) &
9381 +rdy*( max(0.,fqy (i,k,j+1)) &
9382 -min(0.,fqy (i,k,j )) ) ) &
9383 +msfty(i,j)*rdzw(k)*( min(0.,fqz (i,k+1,j)) &
9384 -max(0.,fqz (i,k ,j)) ) )
9395 IF( flux_out(i,k,j) .gt. ph_low(i,k,j) ) THEN
9397 scale = max(0.,ph_low(i,k,j)/(flux_out(i,k,j)+eps))
9398 IF( fqx (i+1,k,j) .gt. 0.) fqx(i+1,k,j) = scale*fqx(i+1,k,j)
9399 IF( fqx (i ,k,j) .lt. 0.) fqx(i ,k,j) = scale*fqx(i ,k,j)
9400 IF( fqy (i,k,j+1) .gt. 0.) fqy(i,k,j+1) = scale*fqy(i,k,j+1)
9401 IF( fqy (i,k,j ) .lt. 0.) fqy(i,k,j ) = scale*fqy(i,k,j )
9402 ! note: z flux is opposite sign in mass coordinate because
9403 ! vertical coordinate decreases with increasing k
9404 IF( fqz (i,k+1,j) .lt. 0.) fqz(i,k+1,j) = scale*fqz(i,k+1,j)
9405 IF( fqz (i,k ,j) .gt. 0.) fqz(i,k ,j) = scale*fqz(i,k ,j)
9415 ! add in the pd-limited flux divergence
9418 i_end = MIN(ite,ide-1)
9420 j_end = MIN(jte,jde-1)
9422 DO j = j_start, j_end
9424 DO i = i_start, i_end
9426 tendency (i,k,j) = tendency(i,k,j) &
9427 -rdzw(k)*( fqz (i,k+1,j)-fqz (i,k,j) &
9428 +fqzl(i,k+1,j)-fqzl(i,k,j))
9436 IF(degrade_xs) i_start = MAX(its,ids+1)
9437 IF(degrade_xe) i_end = MIN(ite,ide-2)
9439 DO j = j_start, j_end
9441 DO i = i_start, i_end
9443 ! Un-"canceled" map scale factor, ADT Eq. 48
9444 tendency (i,k,j) = tendency(i,k,j) &
9445 - msftx(i,j)*( rdx*( fqx (i+1,k,j)-fqx (i,k,j) &
9446 +fqxl(i+1,k,j)-fqxl(i,k,j)) )
9455 i_end = MIN(ite,ide-1)
9456 IF(degrade_ys) j_start = MAX(jts,jds+1)
9457 IF(degrade_ye) j_end = MIN(jte,jde-2)
9459 DO j = j_start, j_end
9461 DO i = i_start, i_end
9463 ! Un-"canceled" map scale factor, ADT Eq. 48
9464 ! It is correct to use msftx (and not msfty), per W. Skamarock, 20080606
9465 tendency (i,k,j) = tendency(i,k,j) &
9466 - msftx(i,j)*( rdy*( fqy (i,k,j+1)-fqy (i,k,j) &
9467 +fqyl(i,k,j+1)-fqyl(i,k,j)) )
9473 END SUBROUTINE advect_scalar_wenopd
9475 !----------------------------------------------------------------
9477 SUBROUTINE advect_scalar_mono ( field, field_old, tendency, &
9478 h_tendency, z_tendency, &
9479 ru, rv, rom, romI, &
9484 msfux, msfuy, msfvx, msfvy, &
9487 rdx, rdy, rdzw, dt, &
9488 ids, ide, jds, jde, kds, kde, &
9489 ims, ime, jms, jme, kms, kme, &
9490 its, ite, jts, jte, kts, kte )
9492 ! monotonic advection option
9493 ! for scalars in WRF RK3 advection. This version is memory intensive ->
9494 ! we save 3d arrays of x, y and z both high and low order fluxes
9495 ! (six in all). Alternatively, we could sweep in a direction
9496 ! and lower the cost considerably.
9498 ! uses the Smolarkiewicz MWR 1989 approach, with addition of first-order
9505 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
9507 LOGICAL , INTENT(IN ) :: tenddec ! tendency flag
9509 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
9510 ims, ime, jms, jme, kms, kme, &
9511 its, ite, jts, jte, kts, kte
9513 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: field, &
9520 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut, mub, mu_old
9521 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
9522 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT( OUT) :: h_tendency, z_tendency
9524 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
9531 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
9537 REAL , INTENT(IN ) :: rdx, &
9543 INTEGER :: i, j, k, itf, jtf, ktf
9544 INTEGER :: i_start, i_end, j_start, j_end
9545 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
9546 INTEGER :: jmin, jmax, jp, jm, imin, imax
9548 REAL :: mrdx, mrdy, ub, vb, uw, vw, mu, ieva_corr
9549 REAL , DIMENSION(its:ite, kts:kte) :: vflux
9552 ! storage for high and low order fluxes
9554 REAL, DIMENSION( its-2:ite+2, kts:kte, jts-2:jte+2 ) :: fqx, fqy, fqz
9555 REAL, DIMENSION( its-2:ite+2, kts:kte, jts-2:jte+2 ) :: fqxl, fqyl, fqzl
9556 REAL, DIMENSION( its-2:ite+2, kts:kte, jts-2:jte+2 ) :: qmin, qmax
9557 REAL, DIMENSION( its-2:ite+2, kts:kte, jts-2:jte+2 ) :: scale_in, scale_out
9560 INTEGER :: horz_order, vert_order
9562 LOGICAL :: degrade_xs, degrade_ys
9563 LOGICAL :: degrade_xe, degrade_ye
9565 INTEGER :: jp1, jp0, jtmp
9567 REAL :: flux_out, ph_low, flux_in, ph_hi, scale
9568 REAL, PARAMETER :: eps=1.e-20
9571 ! definition of flux operators, 3rd, 4rth, 5th or 6th order
9573 REAL :: flux3, flux4, flux5, flux6, flux_upwind
9574 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel, cr
9576 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
9577 (7./12.)*(q_i + q_im1) - (1./12.)*(q_ip1 + q_im2)
9579 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
9580 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
9581 sign(1.,ua)*(1./12.)*((q_ip1 - q_im2)-3.*(q_i-q_im1))
9583 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
9584 (37./60.)*(q_i+q_im1) - (2./15.)*(q_ip1+q_im2) &
9585 +(1./60.)*(q_ip2+q_im3)
9587 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
9588 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
9589 -sign(1.,ua)*(1./60.)*( &
9590 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )
9592 ! flux_upwind(q_im1, q_i, cr ) = 0.
9593 flux_upwind(q_im1, q_i, cr ) = 0.5*(1.+sign(1.,cr))*q_im1 &
9594 +0.5*(1.-sign(1.,cr))*q_i
9596 LOGICAL, PARAMETER :: mono_limit = .true.
9598 ! set order for the advection schemes
9601 horz_order = config_flags%h_sca_adv_order
9602 vert_order = config_flags%v_sca_adv_order
9607 qmin(i,k,j) = field_old(i,k,j)
9608 qmax(i,k,j) = field_old(i,k,j)
9609 scale_in(i,k,j) = 1.
9610 scale_out(i,k,j) = 1.
9621 ! begin with horizontal flux divergence
9622 ! here is the choice of flux operators
9625 horizontal_order_test : IF( horz_order == 5 ) THEN
9627 ! determine boundary mods for flux operators
9628 ! We degrade the flux operators from 3rd/4rth order
9629 ! to second order one gridpoint in from the boundaries for
9630 ! all boundary conditions except periodic and symmetry - these
9631 ! conditions have boundary zone data fill for correct application
9632 ! of the higher order flux stencils
9639 IF( config_flags%periodic_x .or. &
9640 config_flags%symmetric_xs .or. &
9641 (its > ids+3) ) degrade_xs = .false.
9642 IF( config_flags%periodic_x .or. &
9643 config_flags%symmetric_xe .or. &
9644 (ite < ide-4) ) degrade_xe = .false.
9645 IF( config_flags%periodic_y .or. &
9646 config_flags%symmetric_ys .or. &
9647 (jts > jds+3) ) degrade_ys = .false.
9648 IF( config_flags%periodic_y .or. &
9649 config_flags%symmetric_ye .or. &
9650 (jte < jde-4) ) degrade_ye = .false.
9652 !--------------- y - advection first
9654 !-- y flux compute; these bounds are for periodic and sym b.c.
9658 i_end = MIN(ite,ide-1)+1
9660 j_end = MIN(jte,jde-1)+1
9664 !-- modify loop bounds if open or specified
9667 ! IF(degrade_xs) i_start = its
9668 ! IF(degrade_xe) i_end = MIN(ite,ide-1)
9669 IF(degrade_xs) i_start = MAX(its-1,ids)
9670 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
9673 ! IF(degrade_ys) then
9674 ! j_start = MAX(jts,jds+1)
9678 ! IF(degrade_ye) then
9679 ! j_end = MIN(jte,jde-2)
9684 j_start = MAX(jts-1,jds+1)
9689 j_end = MIN(jte+1,jde-2)
9693 ! compute fluxes, 5th order
9695 j_loop_y_flux_5 : DO j = j_start, j_end+1
9697 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN ! use full stencil
9700 DO i = i_start, i_end
9704 fqyl(i,k,j) = vel*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), vel)
9706 fqy( i, k, j ) = vel*flux5( &
9707 field(i,k,j-3), field(i,k,j-2), field(i,k,j-1), &
9708 field(i,k,j ), field(i,k,j+1), field(i,k,j+2), vel )
9710 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
9713 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k,j-1))
9714 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k,j-1))
9716 qmax(i,k,j-1) = amax1(qmax(i,k,j-1),field_old(i,k,j))
9717 qmin(i,k,j-1) = amin1(qmin(i,k,j-1),field_old(i,k,j))
9723 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
9726 DO i = i_start, i_end
9730 fqyl(i,k,j) = vel*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
9732 fqy(i,k, j) = 0.5*rv(i,k,j)* &
9733 (field(i,k,j)+field(i,k,j-1))
9735 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
9738 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k,j-1))
9739 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k,j-1))
9741 qmax(i,k,j-1) = amax1(qmax(i,k,j-1),field_old(i,k,j))
9742 qmin(i,k,j-1) = amin1(qmin(i,k,j-1),field_old(i,k,j))
9748 ELSE IF ( j == jds+2 ) THEN ! third of 4rth order flux 2 in from south boundary
9751 DO i = i_start, i_end
9755 fqyl(i,k,j) = vel*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
9757 fqy( i, k, j ) = vel*flux3( &
9758 field(i,k,j-2),field(i,k,j-1),field(i,k,j),field(i,k,j+1),vel )
9759 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
9762 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k,j-1))
9763 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k,j-1))
9765 qmax(i,k,j-1) = amax1(qmax(i,k,j-1),field_old(i,k,j))
9766 qmin(i,k,j-1) = amin1(qmin(i,k,j-1),field_old(i,k,j))
9772 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
9775 DO i = i_start, i_end
9779 fqyl(i,k,j) = vel*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
9781 fqy(i, k, j ) = 0.5*rv(i,k,j)* &
9782 (field(i,k,j)+field(i,k,j-1))
9783 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
9786 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k,j-1))
9787 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k,j-1))
9789 qmax(i,k,j-1) = amax1(qmax(i,k,j-1),field_old(i,k,j))
9790 qmin(i,k,j-1) = amin1(qmin(i,k,j-1),field_old(i,k,j))
9796 ELSE IF ( j == jde-2 ) THEN ! 3rd or 4rth order flux 2 in from north boundary
9799 DO i = i_start, i_end
9803 fqyl(i,k,j) = vel*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
9805 fqy( i, k, j) = vel*flux3( &
9806 field(i,k,j-2),field(i,k,j-1), &
9807 field(i,k,j),field(i,k,j+1),vel )
9808 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
9811 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k,j-1))
9812 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k,j-1))
9814 qmax(i,k,j-1) = amax1(qmax(i,k,j-1),field_old(i,k,j))
9815 qmin(i,k,j-1) = amin1(qmin(i,k,j-1),field_old(i,k,j))
9823 ENDDO j_loop_y_flux_5
9827 !-- these bounds are for periodic and sym conditions
9830 i_end = MIN(ite,ide-1)+1
9835 j_end = MIN(jte,jde-1)+1
9837 !-- modify loop bounds for open and specified b.c
9840 ! IF(degrade_ys) j_start = jts
9841 ! IF(degrade_ye) j_end = MIN(jte,jde-1)
9842 IF(degrade_ys) j_start = MAX(jts-1,jds)
9843 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
9846 ! IF(degrade_xs) then
9847 ! i_start = MAX(ids+1,its)
9848 ! i_start_f = i_start+2
9851 ! IF(degrade_xe) then
9852 ! i_end = MIN(ide-2,ite)
9857 i_start = MAX(ids+1,its-1)
9862 i_end = MIN(ide-2,ite+1)
9868 DO j = j_start, j_end
9870 ! 5th or 6th order flux
9873 DO i = i_start_f, i_end_f
9877 fqxl(i,k,j) = vel*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9879 fqx( i,k,j ) = vel*flux5( field(i-3,k,j), field(i-2,k,j), &
9880 field(i-1,k,j), field(i ,k,j), &
9881 field(i+1,k,j), field(i+2,k,j), &
9883 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9886 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i-1,k,j))
9887 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i-1,k,j))
9889 qmax(i-1,k,j) = amax1(qmax(i-1,k,j),field_old(i,k,j))
9890 qmin(i-1,k,j) = amin1(qmin(i-1,k,j),field_old(i,k,j))
9896 ! lower order fluxes close to boundaries (if not periodic or symmetric)
9898 ! WCS 20090218 degrade_xs and xe recoded
9900 IF( degrade_xs ) THEN
9902 DO i=i_start,i_start_f-1
9904 IF(i == ids+1) THEN ! second order
9908 fqxl(i,k,j) = vel*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9910 fqx(i,k,j) = 0.5*(ru(i,k,j)) &
9911 *(field(i,k,j)+field(i-1,k,j))
9913 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9916 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i-1,k,j))
9917 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i-1,k,j))
9919 qmax(i-1,k,j) = amax1(qmax(i-1,k,j),field_old(i,k,j))
9920 qmin(i-1,k,j) = amin1(qmin(i-1,k,j),field_old(i,k,j))
9925 IF(i == ids+2) THEN ! third order
9929 fqxl(i,k,j) = vel*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9930 fqx( i,k,j ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
9931 field(i ,k,j), field(i+1,k,j), &
9933 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9936 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i-1,k,j))
9937 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i-1,k,j))
9939 qmax(i-1,k,j) = amax1(qmax(i-1,k,j),field_old(i,k,j))
9940 qmin(i-1,k,j) = amin1(qmin(i-1,k,j),field_old(i,k,j))
9949 IF( degrade_xe ) THEN
9951 DO i = i_end_f+1, i_end+1
9953 IF( i == ide-1 ) THEN ! second order flux next to the boundary
9957 fqxl(i,k,j) = vel*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9958 fqx(i,k,j) = 0.5*(ru(i,k,j)) &
9959 *(field(i,k,j)+field(i-1,k,j))
9960 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9963 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i-1,k,j))
9964 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i-1,k,j))
9966 qmax(i-1,k,j) = amax1(qmax(i-1,k,j),field_old(i,k,j))
9967 qmin(i-1,k,j) = amin1(qmin(i-1,k,j),field_old(i,k,j))
9972 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
9976 fqxl(i,k,j) = vel*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9977 fqx( i,k,j ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
9978 field(i ,k,j), field(i+1,k,j), &
9980 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9983 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i-1,k,j))
9984 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i-1,k,j))
9986 qmax(i-1,k,j) = amax1(qmax(i-1,k,j),field_old(i,k,j))
9987 qmin(i-1,k,j) = amin1(qmin(i-1,k,j),field_old(i,k,j))
9994 ENDDO ! enddo for outer J loop
9998 WRITE ( wrf_err_message , * ) 'module_advect: advect_scalar_mono, h_order not known ',horz_order
9999 CALL wrf_error_fatal ( TRIM( wrf_err_message ) )
10001 ENDIF horizontal_order_test
10003 ! pick up the rest of the horizontal radiation boundary conditions.
10004 ! (these are the computations that don't require 'cb'.
10005 ! first, set to index ranges
10008 i_end = MIN(ite,ide-1)
10010 j_end = MIN(jte,jde-1)
10012 ! compute x (u) conditions for v, w, or scalar
10014 IF( (config_flags%open_xs) .and. (its == ids) ) THEN
10016 DO j = j_start, j_end
10018 ub = MIN( 0.5*(ru(its,k,j)+ru(its+1,k,j)), 0. )
10019 tendency(its,k,j) = tendency(its,k,j) &
10021 ub*( field_old(its+1,k,j) &
10022 - field_old(its ,k,j) ) + &
10023 field(its,k,j)*(ru(its+1,k,j)-ru(its,k,j)) &
10030 IF( (config_flags%open_xe) .and. (ite == ide) ) THEN
10032 DO j = j_start, j_end
10034 ub = MAX( 0.5*(ru(ite-1,k,j)+ru(ite,k,j)), 0. )
10035 tendency(i_end,k,j) = tendency(i_end,k,j) &
10037 ub*( field_old(i_end ,k,j) &
10038 - field_old(i_end-1,k,j) ) + &
10039 field(i_end,k,j)*(ru(ite,k,j)-ru(ite-1,k,j)) &
10046 IF( (config_flags%open_ys) .and. (jts == jds) ) THEN
10048 DO i = i_start, i_end
10050 vb = MIN( 0.5*(rv(i,k,jts)+rv(i,k,jts+1)), 0. )
10051 tendency(i,k,jts) = tendency(i,k,jts) &
10053 vb*( field_old(i,k,jts+1) &
10054 - field_old(i,k,jts ) ) + &
10055 field(i,k,jts)*(rv(i,k,jts+1)-rv(i,k,jts)) &
10062 IF( (config_flags%open_ye) .and. (jte == jde)) THEN
10064 DO i = i_start, i_end
10066 vb = MAX( 0.5*(rv(i,k,jte-1)+rv(i,k,jte)), 0. )
10067 tendency(i,k,j_end) = tendency(i,k,j_end) &
10069 vb*( field_old(i,k,j_end ) &
10070 - field_old(i,k,j_end-1) ) + &
10071 field(i,k,j_end)*(rv(i,k,jte)-rv(i,k,jte-1)) &
10078 !-------------------- vertical advection
10080 !-- loop bounds for periodic or sym conditions
10083 i_end = MIN(ite,ide-1)+1
10085 j_end = MIN(jte,jde-1)+1
10087 !-- loop bounds for open or specified conditions
10090 ! IF(degrade_xs) i_start = its
10091 ! IF(degrade_xe) i_end = MIN(ite,ide-1)
10092 ! IF(degrade_ys) j_start = jts
10093 ! IF(degrade_ye) j_end = MIN(jte,jde-1)
10095 IF(degrade_xs) i_start = MAX(its-1,ids)
10096 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
10097 IF(degrade_ys) j_start = MAX(jts-1,jds)
10098 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
10101 vert_order_test : IF (vert_order == 3) THEN
10103 DO j = j_start, j_end
10105 DO i = i_start, i_end
10113 DO i = i_start, i_end
10117 fqzl(i,k,j) = vel*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
10119 fqz(i,k,j) = vel*flux3( &
10120 field(i,k-2,j), field(i,k-1,j), &
10121 field(i,k ,j), field(i,k+1,j), -vel )
10122 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
10125 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k-1,j))
10126 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k-1,j))
10128 qmax(i,k-1,j) = amax1(qmax(i,k-1,j),field_old(i,k,j))
10129 qmin(i,k-1,j) = amin1(qmin(i,k-1,j),field_old(i,k,j))
10135 DO i = i_start, i_end
10140 fqzl(i,k,j) = vel*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
10141 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
10142 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
10145 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k-1,j))
10146 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k-1,j))
10148 qmax(i,k-1,j) = amax1(qmax(i,k-1,j),field_old(i,k,j))
10149 qmin(i,k-1,j) = amin1(qmin(i,k-1,j),field_old(i,k,j))
10155 fqzl(i,k,j) = vel*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
10156 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
10157 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
10160 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k-1,j))
10161 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k-1,j))
10163 qmax(i,k-1,j) = amax1(qmax(i,k-1,j),field_old(i,k,j))
10164 qmin(i,k-1,j) = amin1(qmin(i,k-1,j),field_old(i,k,j))
10170 ELSE IF (vert_order == 5) THEN
10172 DO j = j_start, j_end
10174 DO i = i_start, i_end
10182 DO i = i_start, i_end
10186 fqzl(i,k,j) = vel*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
10188 fqz(i,k,j) = vel*flux5( &
10189 field(i,k-3,j), field(i,k-2,j), field(i,k-1,j), &
10190 field(i,k ,j), field(i,k+1,j), field(i,k+2,j), -vel )
10191 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
10194 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k-1,j))
10195 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k-1,j))
10197 qmax(i,k-1,j) = amax1(qmax(i,k-1,j),field_old(i,k,j))
10198 qmin(i,k-1,j) = amin1(qmin(i,k-1,j),field_old(i,k,j))
10204 DO i = i_start, i_end
10209 fqzl(i,k,j) = vel*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
10210 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
10211 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
10214 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k-1,j))
10215 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k-1,j))
10217 qmax(i,k-1,j) = amax1(qmax(i,k-1,j),field_old(i,k,j))
10218 qmin(i,k-1,j) = amin1(qmin(i,k-1,j),field_old(i,k,j))
10224 fqzl(i,k,j) = vel*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
10225 fqz(i,k,j)= vel*flux3(field(i,k-2,j), field(i,k-1,j), &
10226 field(i,k ,j), field(i,k+1,j), -vel )
10227 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
10230 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k-1,j))
10231 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k-1,j))
10233 qmax(i,k-1,j) = amax1(qmax(i,k-1,j),field_old(i,k,j))
10234 qmin(i,k-1,j) = amin1(qmin(i,k-1,j),field_old(i,k,j))
10240 fqzl(i,k,j) = vel*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
10241 fqz(i,k,j)= vel*flux3( field(i,k-2,j), field(i,k-1,j), &
10242 field(i,k ,j), field(i,k+1,j), -vel )
10243 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
10246 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k-1,j))
10247 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k-1,j))
10249 qmax(i,k-1,j) = amax1(qmax(i,k-1,j),field_old(i,k,j))
10250 qmin(i,k-1,j) = amin1(qmin(i,k-1,j),field_old(i,k,j))
10256 fqzl(i,k,j) = vel*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
10257 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
10258 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
10261 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k-1,j))
10262 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k-1,j))
10264 qmax(i,k-1,j) = amax1(qmax(i,k-1,j),field_old(i,k,j))
10265 qmin(i,k-1,j) = amin1(qmin(i,k-1,j),field_old(i,k,j))
10274 WRITE (wrf_err_message,*) ' advect_scalar_mono, v_order not known ',vert_order
10275 CALL wrf_error_fatal ( wrf_err_message )
10277 ENDIF vert_order_test
10279 IF (mono_limit) THEN
10284 i_end = MIN(ite,ide-1)+1
10286 j_end = MIN(jte,jde-1)+1
10290 !-- loop bounds for open or specified conditions
10292 ! IF(degrade_xs) i_start = its
10293 ! IF(degrade_xe) i_end = MIN(ite,ide-1)
10294 ! IF(degrade_ys) j_start = jts
10295 ! IF(degrade_ye) j_end = MIN(jte,jde-1)
10297 ! IF(config_flags%specified .or. config_flags%nested) THEN
10298 ! IF (degrade_xs) i_start = MAX(its,ids+1)
10299 ! IF (degrade_xe) i_end = MIN(ite,ide-2)
10300 ! IF (degrade_ys) j_start = MAX(jts,jds+1)
10301 ! IF (degrade_ye) j_end = MIN(jte,jde-2)
10304 ! IF(config_flags%open_xs) THEN
10305 ! IF (degrade_xs) i_start = MAX(its,ids+1)
10307 ! IF(config_flags%open_xe) THEN
10308 ! IF (degrade_xe) i_end = MIN(ite,ide-2)
10310 ! IF(config_flags%open_ys) THEN
10311 ! IF (degrade_ys) j_start = MAX(jts,jds+1)
10313 ! IF(config_flags%open_ye) THEN
10314 ! IF (degrade_ye) j_end = MIN(jte,jde-2)
10317 IF(degrade_xs) i_start = MAX(its-1,ids)
10318 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
10319 IF(degrade_ys) j_start = MAX(jts-1,jds)
10320 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
10322 IF(config_flags%specified .or. config_flags%nested) THEN
10323 IF (degrade_xs) i_start = MAX(its-1,ids+1)
10324 IF (degrade_xe) i_end = MIN(ite+1,ide-2)
10325 IF (degrade_ys) j_start = MAX(jts-1,jds+1)
10326 IF (degrade_ye) j_end = MIN(jte+1,jde-2)
10329 IF(config_flags%open_xs) THEN
10330 IF (degrade_xs) i_start = MAX(its-1,ids+1)
10332 IF(config_flags%open_xe) THEN
10333 IF (degrade_xe) i_end = MIN(ite+1,ide-2)
10335 IF(config_flags%open_ys) THEN
10336 IF (degrade_ys) j_start = MAX(jts-1,jds+1)
10338 IF(config_flags%open_ye) THEN
10339 IF (degrade_ye) j_end = MIN(jte+1,jde-2)
10342 !-- here is the limiter...
10344 DO j=j_start, j_end
10346 DO i=i_start, i_end
10348 ! ----------------------------------------------------------------------------------------------
10350 ! We need to correct for the partial divergence created by the IEVA scheme.
10351 ! If there is no implicit vertical advection, this term == 1.0.
10352 ! Else, it rescales the qmax & qmin value to reflect the partial divergence present in both the
10353 ! low-order and high-order fluxes because the VV field is partioned.
10354 ! ----------------------------------------------------------------------------------------------
10356 ieva_corr = (c1(k)*mut(i,j)+c2(k))+dt*msfty(i,j)*rdzw(k)*(romI(i,k+1,j)-romI(i,k,j))
10358 ! ----------------------------------------------------------------------------------------------
10360 ph_upwind = ((c1(k)*mub(i,j)+c2(k))+(c1(k)*mu_old(i,j)))*field_old(i,k,j) &
10361 - dt*( msftx(i,j)*msfty(i,j)*( &
10362 rdx*(fqxl(i+1,k,j)-fqxl(i,k,j)) + &
10363 rdy*(fqyl(i,k,j+1)-fqyl(i,k,j)) ) &
10364 +msfty(i,j)*rdzw(k)*(fqzl(i,k+1,j)-fqzl(i,k,j)) )
10366 flux_in = -dt*( (msftx(i,j)*msfty(i,j))*( &
10367 rdx*( min(0.,fqx (i+1,k,j)) &
10368 -max(0.,fqx (i ,k,j)) ) &
10369 +rdy*( min(0.,fqy (i,k,j+1)) &
10370 -max(0.,fqy (i,k,j )) ) ) &
10371 +msfty(i,j)*rdzw(k)*( max(0.,fqz (i,k+1,j)) &
10372 -min(0.,fqz (i,k ,j)) ) )
10374 ph_hi = ieva_corr*qmax(i,k,j) - ph_upwind
10376 IF( flux_in .gt. ph_hi ) scale_in(i,k,j) = max(0.,ph_hi/(flux_in+eps))
10379 flux_out = dt*( (msftx(i,j)*msfty(i,j))*( &
10380 rdx*( max(0.,fqx (i+1,k,j)) &
10381 -min(0.,fqx (i ,k,j)) ) &
10382 +rdy*( max(0.,fqy (i,k,j+1)) &
10383 -min(0.,fqy (i,k,j )) ) ) &
10384 +msfty(i,j)*rdzw(k)*( min(0.,fqz (i,k+1,j)) &
10385 -max(0.,fqz (i,k ,j)) ) )
10387 ph_low = ph_upwind - ieva_corr*qmin(i,k,j)
10389 IF( flux_out .gt. ph_low ) scale_out(i,k,j) = max(0.,ph_low/(flux_out+eps))
10395 DO j=j_start, j_end
10397 DO i=i_start, i_end+1
10398 IF( fqx (i,k,j) .gt. 0.) then
10399 fqx(i,k,j) = min(scale_in(i,k,j),scale_out(i-1,k,j))*fqx(i,k,j)
10401 fqx(i,k,j) = min(scale_out(i,k,j),scale_in(i-1,k,j))*fqx(i,k,j)
10407 DO j=j_start, j_end+1
10409 DO i=i_start, i_end
10410 IF( fqy (i,k,j) .gt. 0.) then
10411 fqy(i,k,j) = min(scale_in(i,k,j),scale_out(i,k,j-1))*fqy(i,k,j)
10413 fqy(i,k,j) = min(scale_out(i,k,j),scale_in(i,k,j-1))*fqy(i,k,j)
10419 DO j=j_start, j_end
10421 DO i=i_start, i_end
10422 IF( fqz (i,k,j) .lt. 0.) then
10423 fqz(i,k,j) = min(scale_in(i,k,j),scale_out(i,k-1,j))*fqz(i,k,j)
10425 fqz(i,k,j) = min(scale_out(i,k,j),scale_in(i,k-1,j))*fqz(i,k,j)
10433 ! add in the mono-limited flux divergence
10434 ! we need to fix this for open b.c set ***********
10437 i_end = MIN(ite,ide-1)
10439 j_end = MIN(jte,jde-1)
10441 DO j = j_start, j_end
10443 DO i = i_start, i_end
10445 tendency (i,k,j) = tendency(i,k,j) &
10446 -rdzw(k)*( fqz (i,k+1,j)-fqz (i,k,j) &
10447 +fqzl(i,k+1,j)-fqzl(i,k,j))
10454 DO j = j_start, j_end
10456 DO i = i_start, i_end
10458 z_tendency (i,k,j) = 0. -rdzw(k)*( fqz (i,k+1,j)-fqz (i,k,j) &
10459 +fqzl(i,k+1,j)-fqzl(i,k,j))
10466 ! x flux divergence
10470 ! IF(degrade_xs) i_start = i_start + 1
10471 ! IF(degrade_xe) i_end = i_end - 1
10473 IF(degrade_xs) i_start = MAX(its,ids+1)
10474 IF(degrade_xe) i_end = MIN(ite,ide-2)
10476 DO j = j_start, j_end
10478 DO i = i_start, i_end
10480 ! Un-"canceled" map scale factor, ADT Eq. 48
10481 tendency (i,k,j) = tendency(i,k,j) &
10482 - msftx(i,j)*( rdx*( fqx (i+1,k,j)-fqx (i,k,j) &
10483 +fqxl(i+1,k,j)-fqxl(i,k,j)) )
10490 DO j = j_start, j_end
10492 DO i = i_start, i_end
10494 h_tendency (i,k,j) = 0. &
10495 - msftx(i,j)*( rdx*( fqx (i+1,k,j)-fqx (i,k,j) &
10496 +fqxl(i+1,k,j)-fqxl(i,k,j)) )
10503 ! y flux divergence
10506 i_end = MIN(ite,ide-1)
10509 ! IF(degrade_ys) j_start = j_start + 1
10510 ! IF(degrade_ye) j_end = j_end - 1
10512 IF(degrade_ys) j_start = MAX(jts,jds+1)
10513 IF(degrade_ye) j_end = MIN(jte,jde-2)
10515 DO j = j_start, j_end
10517 DO i = i_start, i_end
10519 ! Un-"canceled" map scale factor, ADT Eq. 48
10520 tendency (i,k,j) = tendency(i,k,j) &
10521 - msftx(i,j)*( rdy*( fqy (i,k,j+1)-fqy (i,k,j) &
10522 +fqyl(i,k,j+1)-fqyl(i,k,j)) )
10529 DO j = j_start, j_end
10531 DO i = i_start, i_end
10533 h_tendency (i,k,j) = h_tendency (i,k,j) &
10534 - msftx(i,j)*( rdy*( fqy (i,k,j+1)-fqy (i,k,j) &
10535 +fqyl(i,k,j+1)-fqyl(i,k,j)) )
10542 END SUBROUTINE advect_scalar_mono
10544 !-----------------------------------------------------------
10546 #if ( defined(ADVECT_KERNEL) )
10548 END MODULE advection_kernel
10549 !================================================================
10550 !================================================================
10552 USE advection_kernel
10554 INTEGER , PARAMETER :: MAX_SCALARS = 1
10555 TYPE(grid_config_rec_type) :: config_flags
10556 LOGICAL :: tenddec = .false.
10557 INTEGER :: ids, ide, jds, jde, kds, kde, &
10558 ims, ime, jms, jme, kms, kme, &
10559 its, ite, jts, jte, kts, kte
10560 REAL , DIMENSION( :,:,:,: ) , ALLOCATABLE :: field, &
10562 REAL , DIMENSION( :,:,: ) , ALLOCATABLE :: ru, &
10566 REAL , DIMENSION( :,: ), ALLOCATABLE :: mut, mub, mu_old
10567 REAL , DIMENSION( :,:,: ), ALLOCATABLE :: tendency
10568 REAL , DIMENSION( :,:,: ), ALLOCATABLE :: h_tendency, z_tendency
10569 REAL , DIMENSION( :,: ), ALLOCATABLE :: msfux, &
10575 REAL , DIMENSION( : ), ALLOCATABLE :: fzm, &
10578 rdzw, znw,dnw, rdnw, dn, rdn
10582 INTEGER :: time_step, im
10583 INTEGER :: i, j, k, n, loop
10585 config_flags%scalar_adv_opt = 2
10587 PRINT *,'Init dimensions'
10588 ids = 1; ide = 91; jds = 1; jde = 3; kds = 1; kde =10
10589 ims = -5; ime = 96; jms = -5; jme = 8; kms = 1; kme = 10
10590 its = 1; ite = 91; jts = 1; jte = 3; kts = 1; kte = 10
10591 PRINT *,'ALLOCATE two 4d fields'
10592 PRINT *,(ime-ims+1)*(kme-kms+1)*(jme-jms+1)*MAX_SCALARS
10593 ALLOCATE ( field(ims:ime , kms:kme , jms:jme, MAX_SCALARS ) )
10594 ALLOCATE ( field_old(ims:ime , kms:kme , jms:jme, MAX_SCALARS ) )
10595 PRINT *,'ALLOCATE three 3d fields U, V, W'
10596 PRINT *,(ime-ims+1)*(kme-kms+1)*(jme-jms+1)
10597 ALLOCATE ( ru(ims:ime , kms:kme , jms:jme ) )
10598 ALLOCATE ( rv(ims:ime , kms:kme , jms:jme ) )
10599 ALLOCATE ( rom(ims:ime , kms:kme , jms:jme ) )
10600 ALLOCATE ( romI(ims:ime , kms:kme , jms:jme ) )
10601 PRINT *,'ALLOCATE three 2d MU fields'
10602 PRINT *,(ime-ims+1)*(jme-jms+1)
10603 ALLOCATE ( mut(ims:ime , jms:jme) )
10604 ALLOCATE ( mub(ims:ime , jms:jme) )
10605 ALLOCATE ( mu_old(ims:ime , jms:jme) )
10606 PRINT *,'ALLOCATE three 3d tendency'
10607 PRINT *,(ime-ims+1)*(kme-kms+1)*(jme-jms+1)
10608 ALLOCATE ( tendency( ims:ime , kms:kme , jms:jme ) )
10609 ALLOCATE ( h_tendency( ims:ime , kms:kme , jms:jme ) )
10610 ALLOCATE ( z_tendency( ims:ime , kms:kme , jms:jme ) )
10611 PRINT *,'ALLOCATE six 2d map factors'
10612 PRINT *,(ime-ims+1)*(jme-jms+1)
10613 ALLOCATE ( msfux( ims:ime , jms:jme ) )
10614 ALLOCATE ( msfuy( ims:ime , jms:jme ) )
10615 ALLOCATE ( msfvx( ims:ime , jms:jme ) )
10616 ALLOCATE ( msfvy( ims:ime , jms:jme ) )
10617 ALLOCATE ( msftx( ims:ime , jms:jme ) )
10618 ALLOCATE ( msfty( ims:ime , jms:jme ) )
10619 PRINT *,'ALLOCATE 1d arrays'
10620 ALLOCATE ( fzm( kms:kme ) )
10621 ALLOCATE ( fzp( kms:kme ) )
10622 ALLOCATE ( rdzw( kms:kme ) )
10623 ALLOCATE ( znw( kms:kme ) )
10624 ALLOCATE ( dnw( kms:kme ) )
10625 ALLOCATE (rdnw( kms:kme ) )
10626 ALLOCATE ( dn ( kms:kme ) )
10627 ALLOCATE (rdn ( kms:kme ) )
10628 ALLOCATE ( c1 ( kms:kme ) )
10629 ALLOCATE ( c2 ( kms:kme ) )
10630 PRINT *,'CALL init'
10631 CALL init ( config_flags)
10632 CALL tophat ( field , MAX_SCALARS ,&
10633 ids, ide, jds, jde, kds, kde, &
10634 ims, ime, jms, jme, kms, kme, &
10635 its, ite, jts, jte, kts, kte )
10636 CALL tophat ( field_old , MAX_SCALARS , &
10637 ids, ide, jds, jde, kds, kde, &
10638 ims, ime, jms, jme, kms, kme, &
10639 its, ite, jts, jte, kts, kte )
10658 znw(k) = 1 - (real(k)-kts)/(real(kte)-kts)
10661 rdzw(k) = 1./(znw(k)-znw(k+1))
10664 dnw(k) = znw(k+1) - znw(k)
10665 rdnw(k) = 1./dnw(k)
10668 dn(k) = 0.5*(dnw(k)+dnw(k-1))
10670 fzp(k) = .5* dnw(k )/dn(k)
10671 fzm(k) = .5* dnw(k-1)/dn(k)
10674 c1(k) = 1. ! This is d(B)/d(eta), so assuming no hyb coord
10675 c2(k) = 0. ! This (1 - c1)*(p00 - ptop)
10683 ! Loop over advection enough times to get some meaningful timings.
10684 CALL column ( 0 , field(:,1,2,1) , its, ite )
10686 ! A representative number of times to call the advection in a time period.
10687 IF ( loop .EQ. ((loop)/200)*200 )THEN
10688 PRINT *,'LOOP over scalars',loop
10690 DO im = 1 , MAX_SCALARS
10693 CALL advect_scalar ( field(ims,kms,jms,im), &
10694 field_old(ims,kms,jms,im), &
10695 tendency(ims,kms,jms), &
10696 ru, rv, rom, c1, c2, &
10697 mut, time_step/3, config_flags,&
10698 msfux, msfuy, msfvx, msfvy, &
10702 ids, ide, jds, jde, kds, kde, &
10703 ims, ime, jms, jme, kms, kme, &
10704 its, ite, jts, jte, kts, kte )
10705 DO n = 1 , MAX_SCALARS
10706 field(:,:,:,n) = field_old(:,:,:,n) + dt * tendency(:,:,:) / 3.
10710 CALL advect_scalar ( field(ims,kms,jms,im), &
10711 field_old(ims,kms,jms,im), &
10712 tendency(ims,kms,jms), &
10713 ru, rv, rom, c1, c2, &
10714 mut, time_step/2, config_flags,&
10715 msfux, msfuy, msfvx, msfvy, &
10719 ids, ide, jds, jde, kds, kde, &
10720 ims, ime, jms, jme, kms, kme, &
10721 its, ite, jts, jte, kts, kte )
10722 DO n = 1 , MAX_SCALARS
10723 field(:,:,:,n) = field_old(:,:,:,n) + dt * tendency(:,:,:) / 2.
10727 IF (config_flags%scalar_adv_opt .EQ. 0 ) THEN
10728 CALL advect_scalar ( field(ims,kms,jms,im), &
10729 field_old(ims,kms,jms,im), &
10730 tendency(ims,kms,jms), &
10731 ru, rv, rom, c1, c2, &
10732 mut, time_step, config_flags, &
10733 msfux, msfuy, msfvx, msfvy, &
10737 ids, ide, jds, jde, kds, kde, &
10738 ims, ime, jms, jme, kms, kme, &
10739 its, ite, jts, jte, kts, kte )
10740 ELSE IF (config_flags%scalar_adv_opt .EQ. 1 ) THEN
10741 CALL advect_scalar_pd ( field(ims,kms,jms,im), &
10742 field_old(ims,kms,jms,im), &
10743 tendency(ims,kms,jms), &
10744 h_tendency(ims,kms,jms), &
10745 z_tendency(ims,kms,jms), &
10746 ru, rv, rom, c1, c2, &
10747 mut, mub, mu_old, &
10748 time_step, config_flags, tenddec, &
10749 msfux, msfuy, msfvx, msfvy, &
10750 msftx, msfty, fzm, fzp, &
10751 rdx, rdy, rdzw,dt, &
10752 ids, ide, jds, jde, kds, kde, &
10753 ims, ime, jms, jme, kms, kme, &
10754 its, ite, jts, jte, kts, kte )
10755 ELSE IF (config_flags%scalar_adv_opt .EQ. 2 ) THEN
10756 CALL advect_scalar_mono ( field(ims,kms,jms,im), &
10757 field_old(ims,kms,jms,im), &
10758 tendency(ims,kms,jms), &
10759 h_tendency(ims,kms,jms), &
10760 z_tendency(ims,kms,jms), &
10761 ru, rv, rom, romI, &
10763 mut, mub, mu_old, &
10764 config_flags, tenddec, &
10765 msfux, msfuy, msfvx, msfvy, &
10766 msftx, msfty, fzm, fzp, &
10767 rdx, rdy, rdzw,dt, &
10768 ids, ide, jds, jde, kds, kde, &
10769 ims, ime, jms, jme, kms, kme, &
10770 its, ite, jts, jte, kts, kte )
10771 ELSE IF (config_flags%scalar_adv_opt .EQ. 3 ) THEN
10772 CALL advect_scalar_weno ( field(ims,kms,jms,im), &
10773 field_old(ims,kms,jms,im), &
10774 tendency(ims,kms,jms), &
10777 mut, time_step, config_flags, &
10778 msfux, msfuy, msfvx, msfvy, &
10782 ids, ide, jds, jde, kds, kde, &
10783 ims, ime, jms, jme, kms, kme, &
10784 its, ite, jts, jte, kts, kte )
10785 ELSE IF (config_flags%scalar_adv_opt .EQ. 4 ) THEN
10786 CALL advect_scalar_wenopd ( field(ims,kms,jms,im), &
10787 field_old(ims,kms,jms,im), &
10788 tendency(ims,kms,jms), &
10791 mut, mub, mu_old, &
10792 time_step, config_flags, &
10793 msfux, msfuy, msfvx, msfvy, &
10796 rdx, rdy, rdzw, dt, &
10797 ids, ide, jds, jde, kds, kde, &
10798 ims, ime, jms, jme, kms, kme, &
10799 its, ite, jts, jte, kts, kte )
10801 DO n = 1 , MAX_SCALARS
10802 field(:,:,:,n) = field_old(:,:,:,n) + dt * ( tendency(:,:,:) )
10806 field (:,k,:,:) = field (:,2,:,:)
10809 field (:,:,2,:) = field (:,:,1,:)
10810 field (:,:,3,:) = field (:,:,1,:)
10812 field (ite+0,:,:,:) = field(ids+0,:,:,:)
10813 field (ite+1,:,:,:) = field(ids+1,:,:,:)
10814 field (ite+2,:,:,:) = field(ids+2,:,:,:)
10815 field (ite+3,:,:,:) = field(ids+3,:,:,:)
10816 field (ite+4,:,:,:) = field(ids+4,:,:,:)
10817 field (ids-0,:,:,:) = field(ite-0,:,:,:)
10818 field (ids-1,:,:,:) = field(ite-1,:,:,:)
10819 field (ids-2,:,:,:) = field(ite-2,:,:,:)
10820 field (ids-3,:,:,:) = field(ite-3,:,:,:)
10821 field (ids-4,:,:,:) = field(ite-4,:,:,:)
10825 IF ( loop .EQ. (loop/200)*200 ) THEN
10826 CALL column ( loop , field(:,1,2,1) , its, ite )
10832 print *,'=============================== '
10834 print *,'Lines to input to gnuplot'
10836 print *,"set terminal x11"
10837 IF (config_flags%scalar_adv_opt .EQ. 0 ) THEN
10838 print *,'set title "Scalar Advection" font ",20"'
10839 ELSE IF (config_flags%scalar_adv_opt .EQ. 1 ) THEN
10840 print *,'set title "PD Advection" font ",20"'
10841 ELSE IF (config_flags%scalar_adv_opt .EQ. 2 ) THEN
10842 print *,'set title "Mono Advection" font ",20"'
10843 ELSE IF (config_flags%scalar_adv_opt .EQ. 3 ) THEN
10844 print *,'set title "WENO Advection" font ",20"'
10845 ELSE IF (config_flags%scalar_adv_opt .EQ. 4 ) THEN
10846 print *,'set title "WENO PD Advection" font ",20"'
10848 print *,"set yrange[-20:120]"
10849 print *,"plot [0:90] '000000.txt' with lines , '000200.txt' with lines , '000400.txt' with lines , '000600.txt' with lines , '000800.txt' with lines , '001000.txt' with lines "
10850 print *,"plot [0:90] '000000.txt' with lines , '001200.txt' with lines , '001400.txt' with lines , '001600.txt' with lines , '001800.txt' with lines , '002000.txt' with lines "
10854 #if ( !defined(ADVECT_KERNEL) )
10856 !---------------------------------------------------------------------------------
10858 SUBROUTINE advect_weno_u ( u, u_old, tendency, &
10861 mut, time_step, config_flags, &
10862 msfux, msfuy, msfvx, msfvy, &
10866 ids, ide, jds, jde, kds, kde, &
10867 ims, ime, jms, jme, kms, kme, &
10868 its, ite, jts, jte, kts, kte )
10871 ! 5th-order WENO (Weighted Essentially Non-Oscillatory) scheme adapted from COMMAS.
10872 ! See Jiang and Shu, 1996, J. Comp. Phys. v. 126, 202-223;
10873 ! Shu 2003, Int. J. Comp. Fluid Dyn. v. 17 107-118; Also used by Bryan 2005, Mon. Wea. Rev.
10880 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
10882 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
10883 ims, ime, jms, jme, kms, kme, &
10884 its, ite, jts, jte, kts, kte
10886 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: u, &
10892 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut
10893 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
10895 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
10902 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
10908 REAL , INTENT(IN ) :: rdx, &
10910 INTEGER , INTENT(IN ) :: time_step
10914 INTEGER :: i, j, k, itf, jtf, ktf
10915 INTEGER :: i_start, i_end, j_start, j_end
10916 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
10917 INTEGER :: jmin, jmax, jp, jm, imin, imax, im, ip
10918 INTEGER :: jp1, jp0, jtmp
10921 real :: ue,vs,vn,wb,wt
10922 real, parameter :: f30 = 7./12., f31 = 1./12.
10923 real, parameter :: f50 = 37./60., f51 = 2./15., f52 = 1./60.
10929 real :: qim2, qim1, qi, qip1, qip2
10930 double precision :: beta0, beta1, beta2, f0, f1, f2, wi0, wi1, wi2, sumwk
10931 double precision, parameter :: gi0 = 1.d0/10.d0, gi1 = 6.d0/10.d0, gi2 = 3.d0/10.d0, eps=1.0d-18
10932 integer, parameter :: pw = 2
10935 INTEGER :: horz_order, vert_order
10937 REAL :: mrdx, mrdy, ub, vb, uw, vw, dvm, dvp
10938 REAL , DIMENSION(its:ite, kts:kte) :: vflux
10941 REAL, DIMENSION( its-1:ite+1, kts:kte ) :: fqx
10942 REAL, DIMENSION( its:ite, kts:kte, 2) :: fqy
10944 LOGICAL :: degrade_xs, degrade_ys
10945 LOGICAL :: degrade_xe, degrade_ye
10947 ! definition of flux operators, 3rd, 4th, 5th or 6th order
10949 REAL :: flux3, flux4, flux5, flux6
10950 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel
10952 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
10953 ( 7.*(q_i + q_im1) - (q_ip1 + q_im2) )/12.0
10955 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
10956 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
10957 sign(1,time_step)*sign(1.,ua)*((q_ip1 - q_im2)-3.*(q_i-q_im1))/12.0
10959 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
10960 ( 37.*(q_i+q_im1) - 8.*(q_ip1+q_im2) &
10961 +(q_ip2+q_im3) )/60.0
10963 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
10964 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
10965 -sign(1,time_step)*sign(1.,ua)*( &
10966 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )/60.0
10969 LOGICAL :: specified
10971 specified = .false.
10972 if(config_flags%specified .or. config_flags%nested) specified = .true.
10974 ! set order for vertical and horzontal flux operators
10976 horz_order = config_flags%h_mom_adv_order
10977 vert_order = config_flags%v_mom_adv_order
10981 ! begin with horizontal flux divergence
10983 ! horizontal_order_test : IF( horz_order == 6 ) THEN
10985 ! ELSE IF( horz_order == 5 ) THEN
10987 ! 5th order horizontal flux calculation
10988 ! This code is EXACTLY the same as the 6th order code
10989 ! EXCEPT the 5th order and 3rd operators are used in
10990 ! place of the 6th and 4th order operators
10992 ! determine boundary mods for flux operators
10993 ! We degrade the flux operators from 3rd/4th order
10994 ! to second order one gridpoint in from the boundaries for
10995 ! all boundary conditions except periodic and symmetry - these
10996 ! conditions have boundary zone data fill for correct application
10997 ! of the higher order flux stencils
10999 degrade_xs = .true.
11000 degrade_xe = .true.
11001 degrade_ys = .true.
11002 degrade_ye = .true.
11004 IF( config_flags%periodic_x .or. &
11005 config_flags%symmetric_xs .or. &
11006 (its > ids+3) ) degrade_xs = .false.
11007 IF( config_flags%periodic_x .or. &
11008 config_flags%symmetric_xe .or. &
11009 (ite < ide-2) ) degrade_xe = .false.
11010 IF( config_flags%periodic_y .or. &
11011 config_flags%symmetric_ys .or. &
11012 (jts > jds+3) ) degrade_ys = .false.
11013 IF( config_flags%periodic_y .or. &
11014 config_flags%symmetric_ye .or. &
11015 (jte < jde-4) ) degrade_ye = .false.
11017 !--------------- y - advection first
11021 IF ( config_flags%open_xs .or. specified ) i_start = MAX(ids+1,its)
11022 IF ( config_flags%open_xe .or. specified ) i_end = MIN(ide-1,ite)
11023 IF ( config_flags%periodic_x ) i_start = its
11024 IF ( config_flags%periodic_x ) i_end = ite
11027 j_end = MIN(jte,jde-1)
11029 ! higher order flux has a 5 or 7 point stencil, so compute
11030 ! bounds so we can switch to second order flux close to the boundary
11032 j_start_f = j_start
11035 IF(degrade_ys) then
11036 j_start = MAX(jts,jds+1)
11040 IF(degrade_ye) then
11041 j_end = MIN(jte,jde-2)
11045 IF(config_flags%polar) j_end = MIN(jte,jde-1)
11047 ! compute fluxes, 5th or 6th order
11052 j_loop_y_flux_5 : DO j = j_start, j_end+1
11054 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN ! use full stencil
11057 DO i = i_start, i_end
11058 vel = 0.5*(rv(i,k,j)+rv(i-1,k,j))
11060 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
11074 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
11075 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
11076 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
11078 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
11079 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
11080 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
11082 wi0 = gi0 / (eps + beta0)**pw
11083 wi1 = gi1 / (eps + beta1)**pw
11084 wi2 = gi2 / (eps + beta2)**pw
11086 sumwk = wi0 + wi1 + wi2
11088 fqy( i, k, jp1 ) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
11090 ! fqy( i, k, jp1 ) = vel*flux5( &
11091 ! u(i,k,j-3), u(i,k,j-2), u(i,k,j-1), &
11092 ! u(i,k,j ), u(i,k,j+1), u(i,k,j+2), vel )
11096 ! we must be close to some boundary where we need to reduce the order of the stencil
11098 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
11101 DO i = i_start, i_end
11102 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i-1,k,j)) &
11103 *(u(i,k,j)+u(i,k,j-1))
11107 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
11110 DO i = i_start, i_end
11111 vel = 0.5*(rv(i,k,j)+rv(i-1,k,j))
11112 fqy( i, k, jp1 ) = vel*flux3( &
11113 u(i,k,j-2),u(i,k,j-1), u(i,k,j),u(i,k,j+1),vel )
11117 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
11120 DO i = i_start, i_end
11121 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i-1,k,j)) &
11122 *(u(i,k,j)+u(i,k,j-1))
11126 ELSE IF ( j == jde-2 ) THEN ! 3rd order flux 2 in from north boundary
11129 DO i = i_start, i_end
11130 vel = 0.5*(rv(i,k,j)+rv(i-1,k,j))
11131 fqy( i, k, jp1 ) = vel*flux3( &
11132 u(i,k,j-2),u(i,k,j-1), &
11133 u(i,k,j),u(i,k,j+1),vel )
11139 ! y flux-divergence into tendency
11141 ! (j > j_start) will miss the u(,,jds) tendency
11142 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
11144 DO i = i_start, i_end
11145 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
11146 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
11149 ! This would be seen by (j > j_start) but we need to zero out the NP tendency
11150 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
11152 DO i = i_start, i_end
11153 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
11154 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
11159 IF(j > j_start) THEN
11162 DO i = i_start, i_end
11163 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
11164 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
11177 ENDDO j_loop_y_flux_5
11179 ! next, x - flux divergence
11185 j_end = MIN(jte,jde-1)
11187 ! higher order flux has a 5 or 7 point stencil, so compute
11188 ! bounds so we can switch to second order flux close to the boundary
11190 i_start_f = i_start
11193 IF(degrade_xs) then
11194 i_start = MAX(ids+1,its)
11198 IF(degrade_xe) then
11199 i_end = MIN(ide-1,ite)
11205 DO j = j_start, j_end
11207 ! 5th or 6th order flux
11210 DO i = i_start_f, i_end_f
11211 vel = 0.5*(ru(i,k,j)+ru(i-1,k,j))
11213 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
11227 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
11228 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
11229 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
11231 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
11232 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
11233 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
11235 wi0 = gi0 / (eps + beta0)**pw
11236 wi1 = gi1 / (eps + beta1)**pw
11237 wi2 = gi2 / (eps + beta2)**pw
11239 sumwk = wi0 + wi1 + wi2
11241 fqx(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
11243 ! fqx( i,k ) = vel*flux5( u(i-3,k,j), u(i-2,k,j), &
11244 ! u(i-1,k,j), u(i ,k,j), &
11245 ! u(i+1,k,j), u(i+2,k,j), &
11250 ! lower order fluxes close to boundaries (if not periodic or symmetric)
11251 ! specified uses upstream normal wind at boundaries
11253 IF( degrade_xs ) THEN
11255 IF( i_start == ids+1 ) THEN ! second order flux next to the boundary
11259 IF (specified .AND. u(i,k,j) .LT. 0.)ub = u(i,k,j)
11260 fqx(i, k) = 0.25*(ru(i,k,j)+ru(i-1,k,j)) &
11267 vel = 0.5*(ru(i,k,j)+ru(i-1,k,j))
11268 fqx( i, k ) = vel*flux3( u(i-2,k,j), u(i-1,k,j), &
11269 u(i ,k,j), u(i+1,k,j), &
11275 IF( degrade_xe ) THEN
11277 IF( i_end == ide-1 ) THEN ! second order flux next to the boundary
11281 IF (specified .AND. u(i-1,k,j) .GT. 0.)ub = u(i-1,k,j)
11282 fqx(i, k) = 0.25*(ru(i,k,j)+ru(i-1,k,j)) &
11289 vel = 0.5*(ru(i,k,j)+ru(i-1,k,j))
11290 fqx( i,k ) = vel*flux3( u(i-2,k,j), u(i-1,k,j), &
11291 u(i ,k,j), u(i+1,k,j), &
11297 ! x flux-divergence into tendency
11300 DO i = i_start, i_end
11301 mrdx=msfux(i,j)*rdx ! ADT eqn 44, 1st term on RHS
11302 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
11309 ! radiative lateral boundary condition in x for normal velocity (u)
11311 IF ( (config_flags%open_xs) .and. its == ids ) THEN
11314 j_end = MIN(jte,jde-1)
11316 DO j = j_start, j_end
11318 ub = MIN(ru(its,k,j)-cb*(c1(k)*mut(its,j)+c2(k)), 0.)
11319 tendency(its,k,j) = tendency(its,k,j) &
11320 - rdx*ub*(u_old(its+1,k,j) - u_old(its,k,j))
11326 IF ( (config_flags%open_xe) .and. ite == ide ) THEN
11329 j_end = MIN(jte,jde-1)
11331 DO j = j_start, j_end
11333 ub = MAX(ru(ite,k,j)+cb*(c1(k)*mut(ite-1,j)+c2(k)), 0.)
11334 tendency(ite,k,j) = tendency(ite,k,j) &
11335 - rdx*ub*(u_old(ite,k,j) - u_old(ite-1,k,j))
11341 ! pick up the rest of the horizontal radiation boundary conditions.
11342 ! (these are the computations that don't require 'cb')
11343 ! first, set to index ranges
11346 i_end = MIN(ite,ide)
11350 IF (config_flags%open_xs) THEN
11351 i_start = MAX(ids+1, its)
11354 IF (config_flags%open_xe) THEN
11355 i_end = MIN(ite,ide-1)
11359 IF( (config_flags%open_ys) .and. (jts == jds)) THEN
11361 DO i = i_start, i_end
11363 mrdy=msfux(i,jts)*rdy ! ADT eqn 44, 2nd term on RHS
11364 ip = MIN( imax, i )
11365 im = MAX( imin, i-1 )
11369 vw = 0.5*(rv(ip,k,jts)+rv(im,k,jts))
11371 dvm = rv(ip,k,jts+1)-rv(ip,k,jts)
11372 dvp = rv(im,k,jts+1)-rv(im,k,jts)
11373 tendency(i,k,jts)=tendency(i,k,jts)-mrdy*( &
11374 vb*(u_old(i,k,jts+1)-u_old(i,k,jts)) &
11375 +0.5*u(i,k,jts)*(dvm+dvp))
11381 IF( (config_flags%open_ye) .and. (jte == jde)) THEN
11383 DO i = i_start, i_end
11385 mrdy=msfux(i,jte-1)*rdy ! ADT eqn 44, 2nd term on RHS
11386 ip = MIN( imax, i )
11387 im = MAX( imin, i-1 )
11391 vw = 0.5*(rv(ip,k,jte)+rv(im,k,jte))
11393 dvm = rv(ip,k,jte)-rv(ip,k,jte-1)
11394 dvp = rv(im,k,jte)-rv(im,k,jte-1)
11395 tendency(i,k,jte-1)=tendency(i,k,jte-1)-mrdy*( &
11396 vb*(u_old(i,k,jte-1)-u_old(i,k,jte-2)) &
11397 +0.5*u(i,k,jte-1)*(dvm+dvp))
11403 !-------------------- vertical advection
11404 ! ADT eqn 44 has 3rd term on RHS = -(1/my) partial d/dz (rho u w)
11405 ! Here we have: - partial d/dz (u*rom) = - partial d/dz (u rho w / my)
11406 ! Since 'my' (map scale factor in y-direction) isn't a function of z,
11407 ! this is what we need, so leave unchanged in advect_u
11412 j_end = min(jte,jde-1)
11414 ! IF ( config_flags%open_xs ) i_start = MAX(ids+1,its)
11415 ! IF ( config_flags%open_xe ) i_end = MIN(ide-1,ite)
11417 IF ( config_flags%open_ys .or. specified ) i_start = MAX(ids+1,its)
11418 IF ( config_flags%open_ye .or. specified ) i_end = MIN(ide-1,ite)
11419 IF ( config_flags%periodic_x ) i_start = its
11420 IF ( config_flags%periodic_x ) i_end = ite
11422 DO i = i_start, i_end
11427 ! vert_order_test : IF (vert_order == 6) THEN
11429 ! ELSE IF (vert_order == 5) THEN
11431 DO j = j_start, j_end
11434 DO i = i_start, i_end
11435 vel=0.5*(rom(i-1,k,j)+rom(i,k,j))
11437 IF( -vel*sign(1,time_step) .ge. 0.0 ) THEN
11451 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
11452 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
11453 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
11455 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
11456 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
11457 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
11459 wi0 = gi0 / (eps + beta0)**pw
11460 wi1 = gi1 / (eps + beta1)**pw
11461 wi2 = gi2 / (eps + beta2)**pw
11463 sumwk = wi0 + wi1 + wi2
11465 vflux(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
11467 ! vflux(i,k) = vel*flux5( &
11468 ! u(i,k-3,j), u(i,k-2,j), u(i,k-1,j), &
11469 ! u(i,k ,j), u(i,k+1,j), u(i,k+2,j), -vel )
11473 DO i = i_start, i_end
11476 vflux(i,k)=0.5*(rom(i,k,j)+rom(i-1,k,j)) &
11477 *(fzm(k)*u(i,k,j)+fzp(k)*u(i,k-1,j))
11479 vel=0.5*(rom(i,k,j)+rom(i-1,k,j))
11480 vflux(i,k) = vel*flux3( &
11481 u(i,k-2,j), u(i,k-1,j), &
11482 u(i,k ,j), u(i,k+1,j), -vel )
11484 vel=0.5*(rom(i,k,j)+rom(i-1,k,j))
11485 vflux(i,k) = vel*flux3( &
11486 u(i,k-2,j), u(i,k-1,j), &
11487 u(i,k ,j), u(i,k+1,j), -vel )
11489 vflux(i,k)=0.5*(rom(i,k,j)+rom(i-1,k,j)) &
11490 *(fzm(k)*u(i,k,j)+fzp(k)*u(i,k-1,j))
11494 DO i = i_start, i_end
11495 tendency(i,k,j)=tendency(i,k,j)-rdzw(k)*(vflux(i,k+1)-vflux(i,k))
11501 END SUBROUTINE advect_weno_u
11503 !-------------------------------------------------------------------------------
11505 SUBROUTINE advect_weno_v ( v, v_old, tendency, &
11508 mut, time_step, config_flags, &
11509 msfux, msfuy, msfvx, msfvy, &
11513 ids, ide, jds, jde, kds, kde, &
11514 ims, ime, jms, jme, kms, kme, &
11515 its, ite, jts, jte, kts, kte )
11518 ! 5th-order WENO (Weighted Essentially Non-Oscillatory) scheme adapted from COMMAS.
11519 ! See Jiang and Shu, 1996, J. Comp. Phys. v. 126, 202-223;
11520 ! Shu 2003, Int. J. Comp. Fluid Dyn. v. 17 107-118; Also used by Bryan 2005, Mon. Wea. Rev.
11527 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
11529 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
11530 ims, ime, jms, jme, kms, kme, &
11531 its, ite, jts, jte, kts, kte
11533 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: v, &
11539 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut
11540 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
11542 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
11549 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
11555 REAL , INTENT(IN ) :: rdx, &
11557 INTEGER , INTENT(IN ) :: time_step
11562 INTEGER :: i, j, k, itf, jtf, ktf
11563 INTEGER :: i_start, i_end, j_start, j_end
11564 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
11565 INTEGER :: jmin, jmax, jp, jm, imin, imax
11568 real :: ue,vs,vn,wb,wt
11569 real, parameter :: f30 = 7./12., f31 = 1./12.
11570 real, parameter :: f50 = 37./60., f51 = 2./15., f52 = 1./60.
11576 real :: qim2, qim1, qi, qip1, qip2
11577 double precision :: beta0, beta1, beta2, f0, f1, f2, wi0, wi1, wi2, sumwk
11578 double precision, parameter :: gi0 = 1.d0/10.d0, gi1 = 6.d0/10.d0, gi2 = 3.d0/10.d0, eps=1.0d-18
11579 integer, parameter :: pw = 2
11582 REAL :: mrdx, mrdy, ub, vb, uw, vw, dup, dum
11583 REAL , DIMENSION(its:ite, kts:kte) :: vflux
11586 REAL, DIMENSION( its:ite+1, kts:kte ) :: fqx
11587 REAL, DIMENSION( its:ite, kts:kte, 2 ) :: fqy
11589 INTEGER :: horz_order
11590 INTEGER :: vert_order
11592 LOGICAL :: degrade_xs, degrade_ys
11593 LOGICAL :: degrade_xe, degrade_ye
11595 INTEGER :: jp1, jp0, jtmp
11598 ! definition of flux operators, 3rd, 4th, 5th or 6th order
11600 REAL :: flux3, flux4, flux5, flux6
11601 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel
11603 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
11604 ( 7.*(q_i + q_im1) - (q_ip1 + q_im2) )/12.0
11606 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
11607 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
11608 sign(1,time_step)*sign(1.,ua)*((q_ip1 - q_im2)-3.*(q_i-q_im1))/12.0
11610 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
11611 ( 37.*(q_i+q_im1) - 8.*(q_ip1+q_im2) &
11612 +(q_ip2+q_im3) )/60.0
11614 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
11615 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
11616 -sign(1,time_step)*sign(1.,ua)*( &
11617 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )/60.0
11621 LOGICAL :: specified
11623 specified = .false.
11624 if(config_flags%specified .or. config_flags%nested) specified = .true.
11626 ! set order for the advection schemes
11629 horz_order = config_flags%h_mom_adv_order
11630 vert_order = config_flags%v_mom_adv_order
11633 ! here is the choice of flux operators
11636 ! horizontal_order_test : IF( horz_order == 6 ) THEN
11637 ! ELSE IF( horz_order == 5 ) THEN
11639 ! 5th order horizontal flux calculation
11640 ! This code is EXACTLY the same as the 6th order code
11641 ! EXCEPT the 5th order and 3rd operators are used in
11642 ! place of the 6th and 4th order operators
11644 ! determine boundary mods for flux operators
11645 ! We degrade the flux operators from 3rd/4th order
11646 ! to second order one gridpoint in from the boundaries for
11647 ! all boundary conditions except periodic and symmetry - these
11648 ! conditions have boundary zone data fill for correct application
11649 ! of the higher order flux stencils
11651 degrade_xs = .true.
11652 degrade_xe = .true.
11653 degrade_ys = .true.
11654 degrade_ye = .true.
11656 IF( config_flags%periodic_x .or. &
11657 config_flags%symmetric_xs .or. &
11658 (its > ids+3) ) degrade_xs = .false.
11659 IF( config_flags%periodic_x .or. &
11660 config_flags%symmetric_xe .or. &
11661 (ite < ide-3) ) degrade_xe = .false.
11662 IF( config_flags%periodic_y .or. &
11663 config_flags%symmetric_ys .or. &
11664 (jts > jds+3) ) degrade_ys = .false.
11665 IF( config_flags%periodic_y .or. &
11666 config_flags%symmetric_ye .or. &
11667 (jte < jde-3) ) degrade_ye = .false.
11669 !--------------- y - advection first
11672 i_end = MIN(ite,ide-1)
11676 ! higher order flux has a 5 or 7 point stencil, so compute
11677 ! bounds so we can switch to second order flux close to the boundary
11679 j_start_f = j_start
11682 IF(degrade_ys) then
11683 j_start = MAX(jts,jds+1)
11687 IF(degrade_ye) then
11688 j_end = MIN(jte,jde-1)
11692 ! compute fluxes, 5th or 6th order
11697 j_loop_y_flux_5 : DO j = j_start, j_end+1
11699 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN
11702 DO i = i_start, i_end
11703 vel = 0.5*(rv(i,k,j)+rv(i,k,j-1))
11705 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
11719 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
11720 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
11721 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
11723 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
11724 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
11725 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
11727 wi0 = gi0 / (eps + beta0)**pw
11728 wi1 = gi1 / (eps + beta1)**pw
11729 wi2 = gi2 / (eps + beta2)**pw
11731 sumwk = wi0 + wi1 + wi2
11733 fqy( i, k, jp1 ) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
11737 ! fqy( i, k, jp1 ) = vel*flux5( &
11738 ! v(i,k,j-3), v(i,k,j-2), v(i,k,j-1), &
11739 ! v(i,k,j ), v(i,k,j+1), v(i,k,j+2), vel )
11743 ! we must be close to some boundary where we need to reduce the order of the stencil
11744 ! specified uses upstream normal wind at boundaries
11746 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
11749 DO i = i_start, i_end
11751 IF (specified .AND. v(i,k,j) .LT. 0.)vb = v(i,k,j)
11752 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i,k,j-1)) &
11757 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
11760 DO i = i_start, i_end
11761 vel = 0.5*(rv(i,k,j)+rv(i,k,j-1))
11762 fqy( i, k, jp1 ) = vel*flux3( &
11763 v(i,k,j-2),v(i,k,j-1),v(i,k,j),v(i,k,j+1),vel )
11768 ELSE IF ( j == jde ) THEN ! 2nd order flux next to north boundary
11771 DO i = i_start, i_end
11773 IF (specified .AND. v(i,k,j-1) .GT. 0.)vb = v(i,k,j-1)
11774 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i,k,j-1)) &
11779 ELSE IF ( j == jde-1 ) THEN ! 3rd or 4th order flux 2 in from north boundary
11782 DO i = i_start, i_end
11783 vel = 0.5*(rv(i,k,j)+rv(i,k,j-1))
11784 fqy( i, k, jp1 ) = vel*flux3( &
11785 v(i,k,j-2),v(i,k,j-1),v(i,k,j),v(i,k,j+1),vel )
11791 ! y flux-divergence into tendency
11793 ! Comments on polar boundary conditions
11794 ! No advection over the poles means tendencies (held from jds [S. pole]
11795 ! to jde [N pole], i.e., on v grid) must be zero at poles
11796 ! [tendency(jds) and tendency(jde)=0]
11797 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
11799 DO i = i_start, i_end
11800 tendency(i,k,j-1) = 0.
11803 ! If j_end were set to jde in a special if statement apart from
11804 ! degrade_ye, then we would hit the next conditional. But since
11805 ! we want the tendency to be zero anyway, not looping to jde+1
11806 ! will produce the same effect.
11807 ELSE IF( config_flags%polar .AND. (j == jde+1) ) THEN
11809 DO i = i_start, i_end
11810 tendency(i,k,j-1) = 0.
11815 IF(j > j_start) THEN
11818 DO i = i_start, i_end
11819 mrdy=msfvy(i,j-1)*rdy ! ADT eqn 45, 2nd term on RHS
11820 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
11832 ENDDO j_loop_y_flux_5
11834 ! next, x - flux divergence
11837 i_end = MIN(ite,ide-1)
11841 ! Polar boundary conditions are like open or specified
11842 IF ( config_flags%open_ys .or. specified .or. config_flags%polar ) j_start = MAX(jds+1,jts)
11843 IF ( config_flags%open_ye .or. specified .or. config_flags%polar ) j_end = MIN(jde-1,jte)
11845 ! higher order flux has a 5 or 7 point stencil, so compute
11846 ! bounds so we can switch to second order flux close to the boundary
11848 i_start_f = i_start
11851 IF(degrade_xs) then
11852 i_start = MAX(ids+1,its)
11853 ! i_start_f = i_start+2
11854 i_start_f = MIN(i_start+2,ids+3)
11857 IF(degrade_xe) then
11858 i_end = MIN(ide-2,ite)
11864 DO j = j_start, j_end
11866 ! 5th or 6th order flux
11869 DO i = i_start_f, i_end_f
11870 vel = 0.5*(ru(i,k,j)+ru(i,k,j-1))
11872 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
11886 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
11887 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
11888 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
11890 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
11891 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
11892 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
11894 wi0 = gi0 / (eps + beta0)**pw
11895 wi1 = gi1 / (eps + beta1)**pw
11896 wi2 = gi2 / (eps + beta2)**pw
11898 sumwk = wi0 + wi1 + wi2
11900 fqx(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
11902 ! fqx( i, k ) = vel*flux5( v(i-3,k,j), v(i-2,k,j), &
11903 ! v(i-1,k,j), v(i ,k,j), &
11904 ! v(i+1,k,j), v(i+2,k,j), &
11909 ! lower order fluxes close to boundaries (if not periodic or symmetric)
11911 IF( degrade_xs ) THEN
11913 DO i=i_start,i_start_f-1
11915 IF(i == ids+1) THEN ! second order
11917 fqx(i,k) = 0.25*(ru(i,k,j)+ru(i,k,j-1)) &
11918 *(v(i,k,j)+v(i-1,k,j))
11922 IF(i == ids+2) THEN ! third order
11924 vel = 0.5*(ru(i,k,j)+ru(i,k,j-1))
11925 fqx( i,k ) = vel*flux3( v(i-2,k,j), v(i-1,k,j), &
11926 v(i ,k,j), v(i+1,k,j), &
11935 IF( degrade_xe ) THEN
11937 DO i = i_end_f+1, i_end+1
11939 IF( i == ide-1 ) THEN ! second order flux next to the boundary
11941 fqx(i,k) = 0.25*(ru(i_end+1,k,j)+ru(i_end+1,k,j-1)) &
11942 *(v(i_end+1,k,j)+v(i_end,k,j))
11946 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
11948 vel = 0.5*(ru(i,k,j)+ru(i,k,j-1))
11949 fqx( i,k ) = vel*flux3( v(i-2,k,j), v(i-1,k,j), &
11950 v(i ,k,j), v(i+1,k,j), &
11959 ! x flux-divergence into tendency
11962 DO i = i_start, i_end
11963 mrdx=msfvy(i,j)*rdx ! ADT eqn 45, 1st term on RHS
11964 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
11971 ! Comments on polar boundary condition
11972 ! Force tendency=0 at NP and SP
11973 ! We keep setting this everywhere, but it can't hurt...
11974 IF ( config_flags%polar .AND. (jts == jds) ) THEN
11977 tendency(i,k,jts)=0.
11981 IF ( config_flags%polar .AND. (jte == jde) ) THEN
11984 tendency(i,k,jte)=0.
11989 ! radiative lateral boundary condition in y for normal velocity (v)
11991 IF ( (config_flags%open_ys) .and. jts == jds ) THEN
11994 i_end = MIN(ite,ide-1)
11996 DO i = i_start, i_end
11998 vb = MIN(rv(i,k,jts)-cb*(c1(k)*mut(i,jts)+c2(k)), 0.)
11999 tendency(i,k,jts) = tendency(i,k,jts) &
12000 - rdy*vb*(v_old(i,k,jts+1) - v_old(i,k,jts))
12006 IF ( (config_flags%open_ye) .and. jte == jde ) THEN
12009 i_end = MIN(ite,ide-1)
12011 DO i = i_start, i_end
12013 vb = MAX(rv(i,k,jte)+cb*(c1(k)*mut(i,jte-1)+c2(k)), 0.)
12014 tendency(i,k,jte) = tendency(i,k,jte) &
12015 - rdy*vb*(v_old(i,k,jte) - v_old(i,k,jte-1))
12021 ! pick up the rest of the horizontal radiation boundary conditions.
12022 ! (these are the computations that don't require 'cb'.
12023 ! first, set to index ranges
12026 j_end = MIN(jte,jde)
12031 IF (config_flags%open_ys) THEN
12032 j_start = MAX(jds+1, jts)
12035 IF (config_flags%open_ye) THEN
12036 j_end = MIN(jte,jde-1)
12040 ! compute x (u) conditions for v, w, or scalar
12042 IF( (config_flags%open_xs) .and. (its == ids)) THEN
12044 DO j = j_start, j_end
12046 mrdx=msfvy(its,j)*rdx ! ADT eqn 45, 1st term on RHS
12047 jp = MIN( jmax, j )
12048 jm = MAX( jmin, j-1 )
12052 uw = 0.5*(ru(its,k,jp)+ru(its,k,jm))
12054 dup = ru(its+1,k,jp)-ru(its,k,jp)
12055 dum = ru(its+1,k,jm)-ru(its,k,jm)
12056 tendency(its,k,j)=tendency(its,k,j)-mrdx*( &
12057 ub*(v_old(its+1,k,j)-v_old(its,k,j)) &
12058 +0.5*v(its,k,j)*(dup+dum))
12064 IF( (config_flags%open_xe) .and. (ite == ide) ) THEN
12065 DO j = j_start, j_end
12067 mrdx=msfvy(ite-1,j)*rdx ! ADT eqn 45, 1st term on RHS
12068 jp = MIN( jmax, j )
12069 jm = MAX( jmin, j-1 )
12073 uw = 0.5*(ru(ite,k,jp)+ru(ite,k,jm))
12075 dup = ru(ite,k,jp)-ru(ite-1,k,jp)
12076 dum = ru(ite,k,jm)-ru(ite-1,k,jm)
12078 ! tendency(ite-1,k,j)=tendency(ite-1,k,j)-mrdx*( &
12079 ! ub*(v_old(ite-1,k,j)-v_old(ite-2,k,j)) &
12080 ! +0.5*v(ite-1,k,j)* &
12081 ! ( ru(ite,k,jp)-ru(ite-1,k,jp) &
12082 ! +ru(ite,k,jm)-ru(ite-1,k,jm)) )
12083 tendency(ite-1,k,j)=tendency(ite-1,k,j)-mrdx*( &
12084 ub*(v_old(ite-1,k,j)-v_old(ite-2,k,j)) &
12085 +0.5*v(ite-1,k,j)*(dup+dum))
12092 !-------------------- vertical advection
12093 ! ADT eqn 45 has 3rd term on RHS = -(1/mx) partial d/dz (rho v w)
12094 ! Here we have: - partial d/dz (v*rom) = - partial d/dz (v rho w / my)
12095 ! We therefore need to make a correction for advect_v
12096 ! since 'my' (map scale factor in y direction) isn't a function of z,
12097 ! we can do this using *(my/mx) (see eqn. 45 for example)
12101 i_end = MIN(ite,ide-1)
12105 DO i = i_start, i_end
12110 ! Polar boundary conditions are like open or specified
12111 ! We don't want to calculate vertical v tendencies at the N or S pole
12112 IF ( config_flags%open_ys .or. specified .or. config_flags%polar ) j_start = MAX(jds+1,jts)
12113 IF ( config_flags%open_ye .or. specified .or. config_flags%polar ) j_end = MIN(jde-1,jte)
12115 ! vert_order_test : IF (vert_order == 6) THEN
12117 ! ELSE IF (vert_order == 5) THEN
12119 DO j = j_start, j_end
12123 DO i = i_start, i_end
12124 vel=0.5*(rom(i,k,j)+rom(i,k,j-1))
12126 IF( -vel*sign(1,time_step) .ge. 0.0 ) THEN
12140 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
12141 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
12142 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
12144 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
12145 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
12146 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
12148 wi0 = gi0 / (eps + beta0)**pw
12149 wi1 = gi1 / (eps + beta1)**pw
12150 wi2 = gi2 / (eps + beta2)**pw
12152 sumwk = wi0 + wi1 + wi2
12154 vflux(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
12157 ! vflux(i,k) = vel*flux5( &
12158 ! v(i,k-3,j), v(i,k-2,j), v(i,k-1,j), &
12159 ! v(i,k ,j), v(i,k+1,j), v(i,k+2,j), -vel )
12163 DO i = i_start, i_end
12165 vflux(i,k)=0.5*(rom(i,k,j)+rom(i,k,j-1)) &
12166 *(fzm(k)*v(i,k,j)+fzp(k)*v(i,k-1,j))
12168 vel=0.5*(rom(i,k,j)+rom(i,k,j-1))
12169 vflux(i,k) = vel*flux3( &
12170 v(i,k-2,j), v(i,k-1,j), &
12171 v(i,k ,j), v(i,k+1,j), -vel )
12173 vel=0.5*(rom(i,k,j)+rom(i,k,j-1))
12174 vflux(i,k) = vel*flux3( &
12175 v(i,k-2,j), v(i,k-1,j), &
12176 v(i,k ,j), v(i,k+1,j), -vel )
12178 vflux(i,k)=0.5*(rom(i,k,j)+rom(i,k,j-1)) &
12179 *(fzm(k)*v(i,k,j)+fzp(k)*v(i,k-1,j))
12185 DO i = i_start, i_end
12186 ! We are calculating vertical fluxes on v points,
12187 ! so we must mean msf_v_x/y variables
12188 tendency(i,k,j)=tendency(i,k,j)-(msfvy(i,j)/msfvx(i,j))*rdzw(k)*(vflux(i,k+1)-vflux(i,k)) ! ADT eqn 45, 3rd term on RHS
12195 END SUBROUTINE advect_weno_v
12198 !---------------------------------------------------------------------------------
12200 SUBROUTINE advect_weno_w ( w, w_old, tendency, &
12203 mut, time_step, config_flags, &
12204 msfux, msfuy, msfvx, msfvy, &
12208 ids, ide, jds, jde, kds, kde, &
12209 ims, ime, jms, jme, kms, kme, &
12210 its, ite, jts, jte, kts, kte )
12213 ! 5th-order WENO (Weighted Essentially Non-Oscillatory) scheme adapted from COMMAS.
12214 ! See Jiang and Shu, 1996, J. Comp. Phys. v. 126, 202-223;
12215 ! Shu 2003, Int. J. Comp. Fluid Dyn. v. 17 107-118; Also used by Bryan 2005, Mon. Wea. Rev.
12222 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
12224 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
12225 ims, ime, jms, jme, kms, kme, &
12226 its, ite, jts, jte, kts, kte
12228 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: w, &
12234 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut
12235 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
12237 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
12244 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
12250 REAL , INTENT(IN ) :: rdx, &
12252 INTEGER , INTENT(IN ) :: time_step
12257 INTEGER :: i, j, k, itf, jtf, ktf
12258 INTEGER :: i_start, i_end, j_start, j_end
12259 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
12260 INTEGER :: jmin, jmax, jp, jm, imin, imax
12262 REAL :: mrdx, mrdy, ub, vb, uw, vw
12263 REAL , DIMENSION(its:ite, kts:kte) :: vflux
12266 real :: ue,vs,vn,wb,wt
12267 real, parameter :: f30 = 7./12., f31 = 1./12.
12268 real, parameter :: f50 = 37./60., f51 = 2./15., f52 = 1./60.
12274 real :: qim2, qim1, qi, qip1, qip2
12275 double precision :: beta0, beta1, beta2, f0, f1, f2, wi0, wi1, wi2, sumwk
12276 double precision, parameter :: gi0 = 1.d0/10.d0, gi1 = 6.d0/10.d0, gi2 = 3.d0/10.d0, eps=1.0d-18
12277 integer, parameter :: pw = 2
12281 INTEGER :: horz_order, vert_order
12283 REAL, DIMENSION( its:ite+1, kts:kte ) :: fqx
12284 REAL, DIMENSION( its:ite, kts:kte, 2 ) :: fqy
12286 LOGICAL :: degrade_xs, degrade_ys
12287 LOGICAL :: degrade_xe, degrade_ye
12289 INTEGER :: jp1, jp0, jtmp
12291 ! definition of flux operators, 3rd, 4th, 5th or 6th order
12293 REAL :: flux3, flux4, flux5, flux6
12294 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel
12296 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
12297 ( 7.*(q_i + q_im1) - (q_ip1 + q_im2) )/12.0
12299 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
12300 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
12301 sign(1,time_step)*sign(1.,ua)*((q_ip1 - q_im2)-3.*(q_i-q_im1))/12.0
12303 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
12304 ( 37.*(q_i+q_im1) - 8.*(q_ip1+q_im2) &
12305 +(q_ip2+q_im3) )/60.0
12307 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
12308 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
12309 -sign(1,time_step)*sign(1.,ua)*( &
12310 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )/60.0
12313 LOGICAL :: specified
12315 specified = .false.
12316 if(config_flags%specified .or. config_flags%nested) specified = .true.
12318 ! set order for the advection scheme
12321 horz_order = config_flags%h_sca_adv_order
12322 vert_order = config_flags%v_sca_adv_order
12324 ! here is the choice of flux operators
12326 ! begin with horizontal flux divergence
12328 ! horizontal_order_test : IF( horz_order == 6 ) THEN
12329 ! ELSE IF (horz_order == 5 ) THEN
12331 ! determine boundary mods for flux operators
12332 ! We degrade the flux operators from 3rd/4th order
12333 ! to second order one gridpoint in from the boundaries for
12334 ! all boundary conditions except periodic and symmetry - these
12335 ! conditions have boundary zone data fill for correct application
12336 ! of the higher order flux stencils
12338 degrade_xs = .true.
12339 degrade_xe = .true.
12340 degrade_ys = .true.
12341 degrade_ye = .true.
12343 IF( config_flags%periodic_x .or. &
12344 config_flags%symmetric_xs .or. &
12345 (its > ids+3) ) degrade_xs = .false.
12346 IF( config_flags%periodic_x .or. &
12347 config_flags%symmetric_xe .or. &
12348 (ite < ide-3) ) degrade_xe = .false.
12349 IF( config_flags%periodic_y .or. &
12350 config_flags%symmetric_ys .or. &
12351 (jts > jds+3) ) degrade_ys = .false.
12352 IF( config_flags%periodic_y .or. &
12353 config_flags%symmetric_ye .or. &
12354 (jte < jde-4) ) degrade_ye = .false.
12356 !--------------- y - advection first
12359 i_end = MIN(ite,ide-1)
12361 j_end = MIN(jte,jde-1)
12363 ! higher order flux has a 5 or 7 point stencil, so compute
12364 ! bounds so we can switch to second order flux close to the boundary
12366 j_start_f = j_start
12369 IF(degrade_ys) then
12370 j_start = MAX(jts,jds+1)
12374 IF(degrade_ye) then
12375 j_end = MIN(jte,jde-2)
12379 IF(config_flags%polar) j_end = MIN(jte,jde-1)
12381 ! compute fluxes, 5th or 6th order
12386 j_loop_y_flux_5 : DO j = j_start, j_end+1
12388 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN
12391 DO i = i_start, i_end
12392 vel = fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)
12394 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
12408 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
12409 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
12410 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
12412 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
12413 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
12414 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
12416 wi0 = gi0 / (eps + beta0)**pw
12417 wi1 = gi1 / (eps + beta1)**pw
12418 wi2 = gi2 / (eps + beta2)**pw
12420 sumwk = wi0 + wi1 + wi2
12422 fqy( i, k, jp1 ) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
12424 ! fqy( i, k, jp1 ) = vel*flux5( &
12425 ! w(i,k,j-3), w(i,k,j-2), w(i,k,j-1), &
12426 ! w(i,k,j ), w(i,k,j+1), w(i,k,j+2), vel )
12431 DO i = i_start, i_end
12432 vel = (2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)
12434 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
12448 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
12449 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
12450 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
12452 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
12453 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
12454 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
12456 wi0 = gi0 / (eps + beta0)**pw
12457 wi1 = gi1 / (eps + beta1)**pw
12458 wi2 = gi2 / (eps + beta2)**pw
12460 sumwk = wi0 + wi1 + wi2
12462 fqy( i, k, jp1 ) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
12464 ! fqy( i, k, jp1 ) = vel*flux5( &
12465 ! w(i,k,j-3), w(i,k,j-2), w(i,k,j-1), &
12466 ! w(i,k,j ), w(i,k,j+1), w(i,k,j+2), vel )
12469 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
12472 DO i = i_start, i_end
12473 fqy(i, k, jp1) = 0.5*(fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j))* &
12474 (w(i,k,j)+w(i,k,j-1))
12479 DO i = i_start, i_end
12480 fqy(i, k, jp1) = 0.5*((2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j))* &
12481 (w(i,k,j)+w(i,k,j-1))
12484 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
12487 DO i = i_start, i_end
12488 vel = fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)
12489 fqy( i, k, jp1 ) = vel*flux3( &
12490 w(i,k,j-2),w(i,k,j-1),w(i,k,j),w(i,k,j+1),vel )
12495 DO i = i_start, i_end
12496 vel = (2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)
12497 fqy( i, k, jp1 ) = vel*flux3( &
12498 w(i,k,j-2),w(i,k,j-1),w(i,k,j),w(i,k,j+1),vel )
12501 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
12504 DO i = i_start, i_end
12505 fqy(i, k, jp1) = 0.5*(fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j))* &
12506 (w(i,k,j)+w(i,k,j-1))
12511 DO i = i_start, i_end
12512 fqy(i, k, jp1) = 0.5*((2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j))* &
12513 (w(i,k,j)+w(i,k,j-1))
12516 ELSE IF ( j == jde-2 ) THEN ! 3rd or 4th order flux 2 in from north boundary
12519 DO i = i_start, i_end
12520 vel = fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)
12521 fqy( i, k, jp1 ) = vel*flux3( &
12522 w(i,k,j-2),w(i,k,j-1), &
12523 w(i,k,j),w(i,k,j+1),vel )
12528 DO i = i_start, i_end
12529 vel = (2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)
12530 fqy( i, k, jp1 ) = vel*flux3( &
12531 w(i,k,j-2),w(i,k,j-1), &
12532 w(i,k,j),w(i,k,j+1),vel )
12537 ! y flux-divergence into tendency
12539 ! Comments for polar boundary conditions
12540 ! Same process as for advect_u - tendencies run from jds to jde-1
12541 ! (latitudes are as for u grid, longitudes are displaced)
12542 ! Therefore: flow is only from one side for points next to poles
12543 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
12545 DO i = i_start, i_end
12546 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
12547 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
12550 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
12552 DO i = i_start, i_end
12553 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
12554 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
12559 IF(j > j_start) THEN
12562 DO i = i_start, i_end
12563 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
12564 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
12576 ENDDO j_loop_y_flux_5
12578 ! next, x - flux divergence
12581 i_end = MIN(ite,ide-1)
12584 j_end = MIN(jte,jde-1)
12586 ! higher order flux has a 5 or 7 point stencil, so compute
12587 ! bounds so we can switch to second order flux close to the boundary
12589 i_start_f = i_start
12592 IF(degrade_xs) then
12593 i_start = MAX(ids+1,its)
12594 ! i_start_f = i_start+2
12595 i_start_f = MIN(i_start+2,ids+3)
12598 IF(degrade_xe) then
12599 i_end = MIN(ide-2,ite)
12605 DO j = j_start, j_end
12607 ! 5th or 6th order flux
12610 DO i = i_start_f, i_end_f
12611 vel = fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)
12613 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
12627 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
12628 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
12629 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
12631 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
12632 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
12633 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
12635 wi0 = gi0 / (eps + beta0)**pw
12636 wi1 = gi1 / (eps + beta1)**pw
12637 wi2 = gi2 / (eps + beta2)**pw
12639 sumwk = wi0 + wi1 + wi2
12641 fqx(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
12643 ! fqx( i,k ) = vel*flux5( w(i-3,k,j), w(i-2,k,j), &
12644 ! w(i-1,k,j), w(i ,k,j), &
12645 ! w(i+1,k,j), w(i+2,k,j), &
12651 DO i = i_start_f, i_end_f
12652 vel = (2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)
12654 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
12668 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
12669 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
12670 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
12672 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
12673 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
12674 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
12676 wi0 = gi0 / (eps + beta0)**pw
12677 wi1 = gi1 / (eps + beta1)**pw
12678 wi2 = gi2 / (eps + beta2)**pw
12680 sumwk = wi0 + wi1 + wi2
12682 fqx(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
12684 ! fqx( i,k ) = vel*flux5( w(i-3,k,j), w(i-2,k,j), &
12685 ! w(i-1,k,j), w(i ,k,j), &
12686 ! w(i+1,k,j), w(i+2,k,j), &
12690 ! lower order fluxes close to boundaries (if not periodic or symmetric)
12692 IF( degrade_xs ) THEN
12694 DO i=i_start,i_start_f-1
12696 IF(i == ids+1) THEN ! second order
12698 fqx(i,k) = 0.5*(fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)) &
12699 *(w(i,k,j)+w(i-1,k,j))
12702 fqx(i,k) = 0.5*((2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)) &
12703 *(w(i,k,j)+w(i-1,k,j))
12706 IF(i == ids+2) THEN ! third order
12708 vel = fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)
12709 fqx( i,k ) = vel*flux3( w(i-2,k,j), w(i-1,k,j), &
12710 w(i ,k,j), w(i+1,k,j), &
12714 vel = (2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)
12715 fqx( i,k ) = vel*flux3( w(i-2,k,j), w(i-1,k,j), &
12716 w(i ,k,j), w(i+1,k,j), &
12724 IF( degrade_xe ) THEN
12726 DO i = i_end_f+1, i_end+1
12728 IF( i == ide-1 ) THEN ! second order flux next to the boundary
12730 fqx(i,k) = 0.5*(fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)) &
12731 *(w(i,k,j)+w(i-1,k,j))
12734 fqx(i,k) = 0.5*((2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)) &
12735 *(w(i,k,j)+w(i-1,k,j))
12738 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
12740 vel = fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)
12741 fqx( i,k ) = vel*flux3( w(i-2,k,j), w(i-1,k,j), &
12742 w(i ,k,j), w(i+1,k,j), &
12746 vel = (2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)
12747 fqx( i,k ) = vel*flux3( w(i-2,k,j), w(i-1,k,j), &
12748 w(i ,k,j), w(i+1,k,j), &
12756 ! x flux-divergence into tendency
12759 DO i = i_start, i_end
12760 mrdx=msftx(i,j)*rdx ! see ADT eqn 46 dividing by my, 1st term RHS
12761 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
12768 ! pick up the the horizontal radiation boundary conditions.
12769 ! (these are the computations that don't require 'cb'.
12770 ! first, set to index ranges
12774 i_end = MIN(ite,ide-1)
12776 j_end = MIN(jte,jde-1)
12778 IF( (config_flags%open_xs) .and. (its == ids)) THEN
12780 DO j = j_start, j_end
12783 uw = 0.5*(fzm(k)*(ru(its,k ,j)+ru(its+1,k ,j)) + &
12784 fzp(k)*(ru(its,k-1,j)+ru(its+1,k-1,j)) )
12787 tendency(its,k,j) = tendency(its,k,j) &
12789 ub*(w_old(its+1,k,j) - w_old(its,k,j)) + &
12791 fzm(k)*(ru(its+1,k ,j)-ru(its,k ,j))+ &
12792 fzp(k)*(ru(its+1,k-1,j)-ru(its,k-1,j))) &
12798 DO j = j_start, j_end
12800 uw = 0.5*( (2.-fzm(k-1))*(ru(its,k-1,j)+ru(its+1,k-1,j)) &
12801 -fzp(k-1)*(ru(its,k-2,j)+ru(its+1,k-2,j)) )
12804 tendency(its,k,j) = tendency(its,k,j) &
12806 ub*(w_old(its+1,k,j) - w_old(its,k,j)) + &
12808 (2.-fzm(k-1))*(ru(its+1,k-1,j)-ru(its,k-1,j))- &
12809 fzp(k-1)*(ru(its+1,k-2,j)-ru(its,k-2,j))) &
12815 IF( (config_flags%open_xe) .and. (ite == ide)) THEN
12817 DO j = j_start, j_end
12820 uw = 0.5*(fzm(k)*(ru(ite-1,k ,j)+ru(ite,k ,j)) + &
12821 fzp(k)*(ru(ite-1,k-1,j)+ru(ite,k-1,j)) )
12824 tendency(i_end,k,j) = tendency(i_end,k,j) &
12826 ub*(w_old(i_end,k,j) - w_old(i_end-1,k,j)) + &
12828 fzm(k)*(ru(ite,k ,j)-ru(ite-1,k ,j)) + &
12829 fzp(k)*(ru(ite,k-1,j)-ru(ite-1,k-1,j))) &
12835 DO j = j_start, j_end
12837 uw = 0.5*( (2.-fzm(k-1))*(ru(ite-1,k-1,j)+ru(ite,k-1,j)) &
12838 -fzp(k-1)*(ru(ite-1,k-2,j)+ru(ite,k-2,j)) )
12841 tendency(i_end,k,j) = tendency(i_end,k,j) &
12843 ub*(w_old(i_end,k,j) - w_old(i_end-1,k,j)) + &
12845 (2.-fzm(k-1))*(ru(ite,k-1,j)-ru(ite-1,k-1,j)) - &
12846 fzp(k-1)*(ru(ite,k-2,j)-ru(ite-1,k-2,j))) &
12853 IF( (config_flags%open_ys) .and. (jts == jds)) THEN
12855 DO i = i_start, i_end
12858 vw = 0.5*( fzm(k)*(rv(i,k ,jts)+rv(i,k ,jts+1)) + &
12859 fzp(k)*(rv(i,k-1,jts)+rv(i,k-1,jts+1)) )
12862 tendency(i,k,jts) = tendency(i,k,jts) &
12864 vb*(w_old(i,k,jts+1) - w_old(i,k,jts)) + &
12866 fzm(k)*(rv(i,k ,jts+1)-rv(i,k ,jts))+ &
12867 fzp(k)*(rv(i,k-1,jts+1)-rv(i,k-1,jts))) &
12873 DO i = i_start, i_end
12874 vw = 0.5*( (2.-fzm(k-1))*(rv(i,k-1,jts)+rv(i,k-1,jts+1)) &
12875 -fzp(k-1)*(rv(i,k-2,jts)+rv(i,k-2,jts+1)) )
12878 tendency(i,k,jts) = tendency(i,k,jts) &
12880 vb*(w_old(i,k,jts+1) - w_old(i,k,jts)) + &
12882 (2.-fzm(k-1))*(rv(i,k-1,jts+1)-rv(i,k-1,jts))- &
12883 fzp(k-1)*(rv(i,k-2,jts+1)-rv(i,k-2,jts))) &
12889 IF( (config_flags%open_ye) .and. (jte == jde) ) THEN
12891 DO i = i_start, i_end
12894 vw = 0.5*( fzm(k)*(rv(i,k ,jte-1)+rv(i,k ,jte)) + &
12895 fzp(k)*(rv(i,k-1,jte-1)+rv(i,k-1,jte)) )
12898 tendency(i,k,j_end) = tendency(i,k,j_end) &
12900 vb*(w_old(i,k,j_end) - w_old(i,k,j_end-1)) + &
12902 fzm(k)*(rv(i,k ,jte)-rv(i,k ,jte-1))+ &
12903 fzp(k)*(rv(i,k-1,jte)-rv(i,k-1,jte-1))) &
12909 DO i = i_start, i_end
12911 vw = 0.5*( (2.-fzm(k-1))*(rv(i,k-1,jte-1)+rv(i,k-1,jte)) &
12912 -fzp(k-1)*(rv(i,k-2,jte-1)+rv(i,k-2,jte)) )
12915 tendency(i,k,j_end) = tendency(i,k,j_end) &
12917 vb*(w_old(i,k,j_end) - w_old(i,k,j_end-1)) + &
12919 (2.-fzm(k-1))*(rv(i,k-1,jte)-rv(i,k-1,jte-1))- &
12920 fzp(k-1)*(rv(i,k-2,jte)-rv(i,k-2,jte-1))) &
12926 !-------------------- vertical advection
12927 ! ADT eqn 46 has 3rd term on RHS (dividing through by my) = - partial d/dz (w rho w /my)
12928 ! Here we have: - partial d/dz (w*rom) = - partial d/dz (w rho w / my)
12929 ! Therefore we don't need to make a correction for advect_w
12932 i_end = MIN(ite,ide-1)
12934 j_end = MIN(jte,jde-1)
12936 DO i = i_start, i_end
12941 ! vert_order_test : IF (vert_order == 6) THEN
12943 ! ELSE IF (vert_order == 5) THEN
12945 DO j = j_start, j_end
12948 DO i = i_start, i_end
12949 vel=0.5*(rom(i,k,j)+rom(i,k-1,j))
12951 IF( -vel*sign(1,time_step) .ge. 0.0 ) THEN
12965 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
12966 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
12967 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
12969 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
12970 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
12971 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
12973 wi0 = gi0 / (eps + beta0)**pw
12974 wi1 = gi1 / (eps + beta1)**pw
12975 wi2 = gi2 / (eps + beta2)**pw
12977 sumwk = wi0 + wi1 + wi2
12979 vflux(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
12981 ! vflux(i,k) = vel*flux5( &
12982 ! w(i,k-3,j), w(i,k-2,j), w(i,k-1,j), &
12983 ! w(i,k ,j), w(i,k+1,j), w(i,k+2,j), -vel )
12987 DO i = i_start, i_end
12990 vflux(i,k)=0.25*(rom(i,k,j)+rom(i,k-1,j))*(w(i,k,j)+w(i,k-1,j))
12993 vel=0.5*(rom(i,k,j)+rom(i,k-1,j))
12994 vflux(i,k) = vel*flux3( &
12995 w(i,k-2,j), w(i,k-1,j), &
12996 w(i,k ,j), w(i,k+1,j), -vel )
12998 vel=0.5*(rom(i,k,j)+rom(i,k-1,j))
12999 vflux(i,k) = vel*flux3( &
13000 w(i,k-2,j), w(i,k-1,j), &
13001 w(i,k ,j), w(i,k+1,j), -vel )
13004 vflux(i,k)=0.25*(rom(i,k,j)+rom(i,k-1,j))*(w(i,k,j)+w(i,k-1,j))
13009 DO i = i_start, i_end
13010 tendency(i,k,j)=tendency(i,k,j)-rdzu(k)*(vflux(i,k+1)-vflux(i,k))
13014 ! pick up flux contribution for w at the lid, wcs. 13 march 2004
13016 DO i = i_start, i_end
13017 tendency(i,k,j)=tendency(i,k,j)+2.*rdzu(k-1)*(vflux(i,k))
13023 END SUBROUTINE advect_weno_w
13026 END MODULE module_advect_em