2 !WRF:MODEL_LAYER:DYNAMICS
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 !----------------------------------------------------------------
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
4150 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
4166 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 #ifndef 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
7301 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
7317 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.
7334 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.
7351 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 DO i = i_start, i_end
7420 dz = 2./(rdzw(k)+rdzw(k-1))
7421 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7424 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7426 fqz(i,k,j) = vel*flux4( &
7427 field(i,k-2,j), field(i,k-1,j), &
7428 field(i,k ,j), field(i,k+1,j), -vel )
7429 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7432 DO i = i_start, i_end
7435 dz = 2./(rdzw(k)+rdzw(k-1))
7436 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7439 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7441 fqz(i,k,j) = vel*flux4( &
7442 field(i,k-2,j), field(i,k-1,j), &
7443 field(i,k ,j), field(i,k+1,j), -vel )
7444 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7447 DO i = i_start, i_end
7450 dz = 2./(rdzw(k)+rdzw(k-1))
7451 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7454 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7455 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7456 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7462 ELSE IF (vert_order == 5) THEN
7464 DO j = j_start, j_end
7466 DO i = i_start, i_end
7474 DO i = i_start, i_end
7475 dz = 2./(rdzw(k)+rdzw(k-1))
7476 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7479 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7481 fqz(i,k,j) = vel*flux5( field(i,k-3,j), field(i,k-2,j), field(i,k-1,j), &
7482 field(i,k ,j), field(i,k+1,j), field(i,k+2,j), -vel )
7483 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7487 DO i = i_start, i_end
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)
7495 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7496 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7499 DO i = i_start, i_end
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 DO i = i_start, i_end
7517 dz = 2./(rdzw(k)+rdzw(k-1))
7518 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7521 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7523 fqz(i,k,j) = vel*flux3( &
7524 field(i,k-2,j), field(i,k-1,j), &
7525 field(i,k ,j), field(i,k+1,j), -vel )
7526 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7529 DO i = i_start, i_end
7532 dz = 2./(rdzw(k)+rdzw(k-1))
7533 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7536 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7537 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7538 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7544 ELSE IF (vert_order == 4) THEN
7546 DO j = j_start, j_end
7548 DO i = i_start, i_end
7556 DO i = i_start, i_end
7558 dz = 2./(rdzw(k)+rdzw(k-1))
7559 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7562 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7564 fqz(i,k,j) = vel*flux4( &
7565 field(i,k-2,j), field(i,k-1,j), &
7566 field(i,k ,j), field(i,k+1,j), -vel )
7567 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7571 DO i = i_start, i_end
7574 dz = 2./(rdzw(k)+rdzw(k-1))
7575 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7578 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7579 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7580 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7583 dz = 2./(rdzw(k)+rdzw(k-1))
7584 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7587 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7588 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7589 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7595 ELSE IF (vert_order == 3) THEN
7597 DO j = j_start, j_end
7599 DO i = i_start, i_end
7608 DO i = i_start, i_end
7610 dz = 2./(rdzw(k)+rdzw(k-1))
7611 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7614 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7616 fqz(i,k,j) = vel*flux3( &
7617 field(i,k-2,j), field(i,k-1,j), &
7618 field(i,k ,j), field(i,k+1,j), -vel )
7619 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7623 DO i = i_start, i_end
7626 dz = 2./(rdzw(k)+rdzw(k-1))
7627 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7630 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7631 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7632 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7635 dz = 2./(rdzw(k)+rdzw(k-1))
7636 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7639 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7640 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7641 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7647 ELSE IF (vert_order == 2) THEN
7649 DO j = j_start, j_end
7651 DO i = i_start, i_end
7659 DO i = i_start, i_end
7661 dz = 2./(rdzw(k)+rdzw(k-1))
7662 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
7665 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
7666 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
7667 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
7676 WRITE (wrf_err_message,*) ' advect_scalar_pd, v_order not known ',vert_order
7677 CALL wrf_error_fatal ( wrf_err_message )
7679 ENDIF vert_order_test
7683 ! positive definite filter
7686 i_end = MIN(ite,ide-1)+1
7688 j_end = MIN(jte,jde-1)+1
7690 !-- loop bounds for open or specified conditions
7692 IF(degrade_xs) i_start = MAX(its-1,ids)
7693 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
7694 IF(degrade_ys) j_start = MAX(jts-1,jds)
7695 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
7697 IF(config_flags%specified .or. config_flags%nested) THEN
7698 IF (degrade_xs) i_start = MAX(its-1,ids+1)
7699 IF (degrade_xe) i_end = MIN(ite+1,ide-2)
7700 IF (degrade_ys) j_start = MAX(jts-1,jds+1)
7701 IF (degrade_ye) j_end = MIN(jte+1,jde-2)
7704 IF(config_flags%open_xs) THEN
7705 IF (degrade_xs) i_start = MAX(its-1,ids+1)
7707 IF(config_flags%open_xe) THEN
7708 IF (degrade_xe) i_end = MIN(ite+1,ide-2)
7710 IF(config_flags%open_ys) THEN
7711 IF (degrade_ys) j_start = MAX(jts-1,jds+1)
7713 IF(config_flags%open_ye) THEN
7714 IF (degrade_ye) j_end = MIN(jte+1,jde-2)
7717 ! We don't want to change j_start and j_end
7718 ! for polar BC's since we want to calculate
7719 ! fluxes for directions other than y at the
7722 !-- here is the limiter...
7733 ph_low(i,k,j) = ((c1(k)*mub(i,j)+c2(k))+(c1(k)*mu_old(i,j)))*field_old(i,k,j) &
7734 - dt*( msftx(i,j)*msfty(i,j)*( &
7735 rdx*(fqxl(i+1,k,j)-fqxl(i,k,j)) + &
7736 rdy*(fqyl(i,k,j+1)-fqyl(i,k,j)) ) &
7737 +msfty(i,j)*rdzw(k)*(fqzl(i,k+1,j)-fqzl(i,k,j)) )
7748 flux_out(i,k,j) = dt*( (msftx(i,j)*msfty(i,j))*( &
7749 rdx*( max(0.,fqx (i+1,k,j)) &
7750 -min(0.,fqx (i ,k,j)) ) &
7751 +rdy*( max(0.,fqy (i,k,j+1)) &
7752 -min(0.,fqy (i,k,j )) ) ) &
7753 +msfty(i,j)*rdzw(k)*( min(0.,fqz (i,k+1,j)) &
7754 -max(0.,fqz (i,k ,j)) ) )
7764 IF( flux_out(i,k,j) .gt. ph_low(i,k,j) ) THEN
7765 scale = max(0.,ph_low(i,k,j)/(flux_out(i,k,j)+eps))
7766 IF( fqx (i+1,k,j) .gt. 0.) fqx(i+1,k,j) = scale*fqx(i+1,k,j)
7767 IF( fqx (i ,k,j) .lt. 0.) fqx(i ,k,j) = scale*fqx(i ,k,j)
7768 IF( fqy (i,k,j+1) .gt. 0.) fqy(i,k,j+1) = scale*fqy(i,k,j+1)
7769 IF( fqy (i,k,j ) .lt. 0.) fqy(i,k,j ) = scale*fqy(i,k,j )
7770 ! note: z flux is opposite sign in mass coordinate because
7771 ! vertical coordinate decreases with increasing k
7772 IF( fqz (i,k+1,j) .lt. 0.) fqz(i,k+1,j) = scale*fqz(i,k+1,j)
7773 IF( fqz (i,k ,j) .gt. 0.) fqz(i,k ,j) = scale*fqz(i,k ,j)
7783 ! add in the pd-limited flux divergence
7786 i_end = MIN(ite,ide-1)
7788 j_end = MIN(jte,jde-1)
7790 DO j = j_start, j_end
7793 DO i = i_start, i_end
7795 tendency (i,k,j) = tendency(i,k,j) &
7796 -rdzw(k)*( fqz (i,k+1,j)-fqz (i,k,j) &
7797 +fqzl(i,k+1,j)-fqzl(i,k,j))
7804 DO j = j_start, j_end
7806 DO i = i_start, i_end
7808 z_tendency (i,k,j) = 0. -rdzw(k)*( fqz (i,k+1,j)-fqz (i,k,j) &
7809 +fqzl(i,k+1,j)-fqzl(i,k,j))
7818 IF(degrade_xs) i_start = MAX(its,ids+1)
7819 IF(degrade_xe) i_end = MIN(ite,ide-2)
7821 DO j = j_start, j_end
7824 DO i = i_start, i_end
7826 ! Un-"canceled" map scale factor, ADT Eq. 48
7827 tendency (i,k,j) = tendency(i,k,j) &
7828 - msftx(i,j)*( rdx*( fqx (i+1,k,j)-fqx (i,k,j) &
7829 +fqxl(i+1,k,j)-fqxl(i,k,j)) )
7836 DO j = j_start, j_end
7838 DO i = i_start, i_end
7840 h_tendency (i,k,j) = 0. &
7841 - msftx(i,j)*( rdx*( fqx (i+1,k,j)-fqx (i,k,j) &
7842 +fqxl(i+1,k,j)-fqxl(i,k,j)) )
7852 i_end = MIN(ite,ide-1)
7853 IF(degrade_ys) j_start = MAX(jts,jds+1)
7854 IF(degrade_ye) j_end = MIN(jte,jde-2)
7856 DO j = j_start, j_end
7859 DO i = i_start, i_end
7861 ! Un-"canceled" map scale factor, ADT Eq. 48
7862 ! It is correct to use msftx (and not msfty), per W. Skamarock, 20080606
7863 tendency (i,k,j) = tendency(i,k,j) &
7864 - msftx(i,j)*( rdy*( fqy (i,k,j+1)-fqy (i,k,j) &
7865 +fqyl(i,k,j+1)-fqyl(i,k,j)) )
7872 DO j = j_start, j_end
7874 DO i = i_start, i_end
7876 h_tendency (i,k,j) = h_tendency (i,k,j) &
7877 - msftx(i,j)*( rdy*( fqy (i,k,j+1)-fqy (i,k,j) &
7878 +fqyl(i,k,j+1)-fqyl(i,k,j)) )
7885 END SUBROUTINE advect_scalar_pd
7887 !----------------------------------------------------------------
7889 SUBROUTINE advect_scalar_weno ( field, field_old, tendency, &
7892 mut, time_step, config_flags, &
7893 msfux, msfuy, msfvx, msfvy, &
7897 ids, ide, jds, jde, kds, kde, &
7898 ims, ime, jms, jme, kms, kme, &
7899 its, ite, jts, jte, kts, kte )
7901 ! 5th-order WENO (Weighted Essentially Non-Oscillatory) scheme adapted from COMMAS.
7902 ! See Jiang and Shu, 1996, J. Comp. Phys. v. 126, 202-223;
7903 ! Shu 2003, Int. J. Comp. Fluid Dyn. v. 17 107-118; Also used by Bryan 2005, Mon. Wea. Rev.
7909 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
7911 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
7912 ims, ime, jms, jme, kms, kme, &
7913 its, ite, jts, jte, kts, kte
7915 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: field, &
7921 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut
7922 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
7924 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
7931 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
7937 REAL , INTENT(IN ) :: rdx, &
7939 INTEGER , INTENT(IN ) :: time_step
7944 INTEGER :: i, j, k, itf, jtf, ktf
7945 INTEGER :: i_start, i_end, j_start, j_end
7946 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
7947 INTEGER :: jmin, jmax, jp, jm, imin, imax
7949 INTEGER , PARAMETER :: is=0, js=0, ks=0
7951 REAL :: mrdx, mrdy, ub, vb, vw
7952 REAL , DIMENSION(its:ite, kts:kte) :: vflux
7955 REAL, DIMENSION( its-is:ite+1, kts:kte ) :: fqx
7956 ! REAL, DIMENSION( its:ite+1, kts:kte ) :: fqx
7957 REAL, DIMENSION( its:ite, kts:kte, 2 ) :: fqy
7959 INTEGER :: horz_order, vert_order
7961 LOGICAL :: degrade_xs, degrade_ys
7962 LOGICAL :: degrade_xe, degrade_ye
7964 INTEGER :: jp1, jp0, jtmp
7967 real :: ue,uw,vs,vn,wb,wt
7968 real, parameter :: f30 = 7./12., f31 = 1./12.
7969 real, parameter :: f50 = 37./60., f51 = 2./15., f52 = 1./60.
7975 real :: qim2, qim1, qi, qip1, qip2
7976 double precision :: beta0, beta1, beta2, f0, f1, f2, wi0, wi1, wi2, sumwk
7977 double precision, parameter :: gi0 = 1.d0/10.d0, gi1 = 6.d0/10.d0, gi2 = 3.d0/10.d0, eps=1.0d-40
7978 integer, parameter :: pw = 2
7981 ! definition of flux operators, 3rd, 4th, 5th or 6th order
7983 REAL :: flux3, flux4, flux5, flux6
7984 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel
7986 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
7987 (7./12.)*(q_i + q_im1) - (1./12.)*(q_ip1 + q_im2)
7989 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
7990 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
7991 sign(1.,ua)*(1./12.)*((q_ip1 - q_im2)-3.*(q_i-q_im1))
7993 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
7994 (37./60.)*(q_i+q_im1) - (2./15.)*(q_ip1+q_im2) &
7995 +(1./60.)*(q_ip2+q_im3)
7997 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
7998 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
7999 -sign(1,time_step)*sign(1.,ua)*(1./60.)*( &
8000 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )
8002 LOGICAL :: specified
8005 if(config_flags%specified .or. config_flags%nested) specified = .true.
8007 ! set order for the advection schemes
8010 horz_order = 5 ! config_flags%h_sca_adv_order
8011 vert_order = 5 ! config_flags%v_sca_adv_order
8013 ! begin with horizontal flux divergence
8014 ! here is the choice of flux operators
8018 IF( horz_order == 5 ) THEN
8020 ! determine boundary mods for flux operators
8021 ! We degrade the flux operators from 3rd/4th order
8022 ! to second order one gridpoint in from the boundaries for
8023 ! all boundary conditions except periodic and symmetry - these
8024 ! conditions have boundary zone data fill for correct application
8025 ! of the higher order flux stencils
8032 IF( config_flags%periodic_x .or. &
8033 config_flags%symmetric_xs .or. &
8034 (its > ids+3) ) degrade_xs = .false.
8035 IF( config_flags%periodic_x .or. &
8036 config_flags%symmetric_xe .or. &
8037 (ite < ide-3) ) degrade_xe = .false.
8038 IF( config_flags%periodic_y .or. &
8039 config_flags%symmetric_ys .or. &
8040 (jts > jds+3) ) degrade_ys = .false.
8041 IF( config_flags%periodic_y .or. &
8042 config_flags%symmetric_ye .or. &
8043 (jte < jde-4) ) degrade_ye = .false.
8045 !--------------- y - advection first
8049 i_end = MIN(ite,ide-1)
8056 IF ( config_flags%open_xs .or. specified ) i_start = MAX(ids+1,its)
8057 IF ( config_flags%open_xe .or. specified ) i_end = MIN(ide-1,ite)
8058 IF ( config_flags%periodic_x ) i_start = its
8059 IF ( config_flags%periodic_x ) i_end = ite
8063 j_end = MIN(jte,jde-1)
8065 ! higher order flux has a 5 or 7 point stencil, so compute
8066 ! bounds so we can switch to second order flux close to the boundary
8072 j_start = MAX(jts,jds+1)
8077 j_end = MIN(jte,jde-2)
8081 IF(config_flags%polar) j_end = MIN(jte,jde-1)
8083 ! compute fluxes, 5th or 6th order
8088 j_loop_y_flux_5 : DO j = j_start, j_end+1
8090 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN ! use full stencil
8093 DO i = i_start, i_end
8095 vel = 0.5*( rv(i,k,j) + rv(i-is,k-ks,j-js) )
8097 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
8098 qip2 = field(i,k,j+1)
8099 qip1 = field(i,k,j )
8101 qim1 = field(i,k,j-2)
8102 qim2 = field(i,k,j-3)
8104 qip2 = field(i,k,j-2)
8105 qip1 = field(i,k,j-1)
8107 qim1 = field(i,k,j+1)
8108 qim2 = field(i,k,j+2)
8111 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
8112 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
8113 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
8115 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
8116 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
8117 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
8119 wi0 = gi0 / (eps + beta0)**pw
8120 wi1 = gi1 / (eps + beta1)**pw
8121 wi2 = gi2 / (eps + beta2)**pw
8123 sumwk = wi0 + wi1 + wi2
8125 fqy( i, k, jp1 ) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
8127 ! fqy( i, k, jp1 ) = vel*flux5( &
8128 ! field(i,k,j-3), field(i,k,j-2), field(i,k,j-1), &
8129 ! field(i,k,j ), field(i,k,j+1), field(i,k,j+2), vel )
8134 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
8137 DO i = i_start, i_end
8138 fqy(i,k, jp1) = 0.5*rv(i,k,j)* &
8139 ! fqy(i,k, jp1) = 0.5*0.5*( rv(i,k,j) + rv(i-is,k-ks,j-js) )* &
8140 (field(i,k,j)+field(i,k,j-1))
8145 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
8148 DO i = i_start, i_end
8149 ! vel = 0.5*( rv(i,k,j) + rv(i-is,k-ks,j-js) )
8151 fqy( i, k, jp1 ) = vel*flux3( &
8152 field(i,k,j-2),field(i,k,j-1),field(i,k,j),field(i,k,j+1),vel )
8156 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
8159 DO i = i_start, i_end
8160 ! fqy(i, k, jp1) = 0.5*0.5*( rv(i,k,j) + rv(i-is,k-ks,j-js) )* &
8161 fqy(i, k, jp1) = 0.5*rv(i,k,j)* &
8162 (field(i,k,j)+field(i,k,j-1))
8166 ELSE IF ( j == jde-2 ) THEN ! 3rd or 4th order flux 2 in from north boundary
8169 DO i = i_start, i_end
8171 ! vel = 0.5*( rv(i,k,j) + rv(i-is,k-ks,j-js) )
8172 fqy( i, k, jp1) = vel*flux3( &
8173 field(i,k,j-2),field(i,k,j-1), &
8174 field(i,k,j),field(i,k,j+1),vel )
8180 ! y flux-divergence into tendency
8183 ! Comments on polar boundary conditions
8184 ! Same process as for advect_u - tendencies run from jds to jde-1
8185 ! (latitudes are as for u grid, longitudes are displaced)
8186 ! Therefore: flow is only from one side for points next to poles
8187 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
8189 DO i = i_start, i_end
8190 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
8191 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
8194 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
8196 DO i = i_start, i_end
8197 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
8198 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
8203 IF(j > j_start) THEN
8206 DO i = i_start, i_end
8207 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 48 [rho->rho*q] dividing by my, 2nd term RHS
8208 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
8214 ELSEIF ( is == 1 ) THEN
8216 ! (j > j_start) will miss the u(,,jds) tendency
8217 IF ( config_flags%polar .AND. (j == jds+1) ) 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)
8224 ! This would be seen by (j > j_start) but we need to zero out the NP tendency
8225 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
8227 DO i = i_start, i_end
8228 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
8229 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
8234 IF(j > j_start) THEN
8237 DO i = i_start, i_end
8238 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
8239 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
8253 ENDDO j_loop_y_flux_5
8255 ! next, x - flux divergence
8258 i_end = MIN(ite,ide-1)
8261 j_end = MIN(jte,jde-1)
8263 ! higher order flux has a 5 or 7 point stencil, so compute
8264 ! bounds so we can switch to second order flux close to the boundary
8270 i_start = MAX(ids+1,its)
8271 ! i_start_f = i_start+2
8272 i_start_f = MIN(i_start+2,ids+3)
8276 i_end = MIN(ide-2,ite)
8282 DO j = j_start, j_end
8284 ! 5th or 6th order flux
8287 DO i = i_start_f, i_end_f
8289 vel = 0.5*( ru(i,k,j) + ru(i-is,k-ks,j-js) )
8292 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
8293 qip2 = field(i+1,k,j)
8294 qip1 = field(i, k,j)
8296 qim1 = field(i-2,k,j)
8297 qim2 = field(i-3,k,j)
8299 qip2 = field(i-2,k,j)
8300 qip1 = field(i-1,k,j)
8302 qim1 = field(i+1,k,j)
8303 qim2 = field(i+2,k,j)
8306 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
8307 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
8308 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
8310 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
8311 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
8312 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
8314 wi0 = gi0 / (eps + beta0)**pw
8315 wi1 = gi1 / (eps + beta1)**pw
8316 wi2 = gi2 / (eps + beta2)**pw
8318 sumwk = wi0 + wi1 + wi2
8320 fqx(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
8322 ! fqx( i,k ) = vel*flux5( field(i-3,k,j), field(i-2,k,j), &
8323 ! field(i-1,k,j), field(i ,k,j), &
8324 ! field(i+1,k,j), field(i+2,k,j), &
8329 ! lower order fluxes close to boundaries (if not periodic or symmetric)
8331 IF( degrade_xs ) THEN
8333 DO i=i_start,i_start_f-1
8335 IF(i == ids+1) THEN ! second order
8337 fqx(i,k) = 0.5*(ru(i,k,j)) &
8338 *(field(i,k,j)+field(i-1,k,j))
8342 IF(i == ids+2) THEN ! third order
8345 fqx( i,k ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
8346 field(i ,k,j), field(i+1,k,j), &
8355 IF( degrade_xe ) THEN
8357 DO i = i_end_f+1, i_end+1
8359 IF( i == ide-1 ) THEN ! second order flux next to the boundary
8361 fqx(i,k) = 0.5*(ru(i,k,j)) &
8362 *(field(i,k,j)+field(i-1,k,j))
8366 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
8369 fqx( i,k ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
8370 field(i ,k,j), field(i+1,k,j), &
8379 ! x flux-divergence into tendency
8383 DO i = i_start, i_end
8384 mrdx=msftx(i,j)*rdx ! see ADT eqn 48 [rho->rho*q] dividing by my, 1st term RHS
8385 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
8388 ELSEIF ( is == 1 ) THEN
8390 DO i = i_start, i_end
8391 mrdx=msfux(i,j)*rdx ! ADT eqn 44, 1st term on RHS
8392 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
8403 ! pick up the rest of the horizontal radiation boundary conditions.
8404 ! (these are the computations that don't require 'cb'.
8405 ! first, set to index ranges
8408 i_end = MIN(ite,ide-1)
8410 j_end = MIN(jte,jde-1)
8412 ! compute x (u) conditions for v, w, or scalar
8414 IF( (config_flags%open_xs) .and. (its == ids) ) THEN
8416 DO j = j_start, j_end
8418 ub = MIN( 0.5*(ru(its,k,j)+ru(its+1,k,j)), 0. )
8419 tendency(its,k,j) = tendency(its,k,j) &
8421 ub*( field_old(its+1,k,j) &
8422 - field_old(its ,k,j) ) + &
8423 field(its,k,j)*(ru(its+1,k,j)-ru(its,k,j)) &
8430 IF( (config_flags%open_xe) .and. (ite == ide) ) THEN
8432 DO j = j_start, j_end
8434 ub = MAX( 0.5*(ru(ite-1,k,j)+ru(ite,k,j)), 0. )
8435 tendency(i_end,k,j) = tendency(i_end,k,j) &
8437 ub*( field_old(i_end ,k,j) &
8438 - field_old(i_end-1,k,j) ) + &
8439 field(i_end,k,j)*(ru(ite,k,j)-ru(ite-1,k,j)) &
8446 IF( (config_flags%open_ys) .and. (jts == jds) ) THEN
8448 DO i = i_start, i_end
8450 vb = MIN( 0.5*(rv(i,k,jts)+rv(i,k,jts+1)), 0. )
8451 tendency(i,k,jts) = tendency(i,k,jts) &
8453 vb*( field_old(i,k,jts+1) &
8454 - field_old(i,k,jts ) ) + &
8455 field(i,k,jts)*(rv(i,k,jts+1)-rv(i,k,jts)) &
8462 IF( (config_flags%open_ye) .and. (jte == jde)) THEN
8464 DO i = i_start, i_end
8466 vb = MAX( 0.5*(rv(i,k,jte-1)+rv(i,k,jte)), 0. )
8467 tendency(i,k,j_end) = tendency(i,k,j_end) &
8469 vb*( field_old(i,k,j_end ) &
8470 - field_old(i,k,j_end-1) ) + &
8471 field(i,k,j_end)*(rv(i,k,jte)-rv(i,k,jte-1)) &
8479 !-------------------- vertical advection
8480 ! Scalar equation has 3rd term on RHS = - partial d/dz (q rho w /my)
8481 ! Here we have: - partial d/dz (q*rom) = - partial d/dz (q rho w / my)
8482 ! So we don't need to make a correction for advect_scalar
8485 i_end = MIN(ite,ide-1)
8487 j_end = MIN(jte,jde-1)
8489 DO i = i_start, i_end
8496 DO j = j_start, j_end
8499 DO i = i_start, i_end
8501 vel = 0.5*( rom(i,k,j) + rom(i-is,k-ks,j-js) )
8503 IF( -vel*sign(1,time_step) .ge. 0.0 ) THEN
8504 qip2 = field(i,k+1,j)
8505 qip1 = field(i,k ,j)
8507 qim1 = field(i,k-2,j)
8508 qim2 = field(i,k-3,j)
8510 qip2 = field(i,k-2,j)
8511 qip1 = field(i,k-1,j)
8513 qim1 = field(i,k+1,j)
8514 qim2 = field(i,k+2,j)
8517 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
8518 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
8519 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
8521 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
8522 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
8523 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
8525 wi0 = gi0 / (eps + beta0)**pw
8526 wi1 = gi1 / (eps + beta1)**pw
8527 wi2 = gi2 / (eps + beta2)**pw
8529 sumwk = wi0 + wi1 + wi2
8531 vflux(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
8533 ! vflux(i,k) = vel*flux5( &
8534 ! field(i,k-3,j), field(i,k-2,j), field(i,k-1,j), &
8535 ! field(i,k ,j), field(i,k+1,j), field(i,k+2,j), -vel )
8539 DO i = i_start, i_end
8542 vflux(i,k)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
8546 vflux(i,k) = vel*flux3( &
8547 field(i,k-2,j), field(i,k-1,j), &
8548 field(i,k ,j), field(i,k+1,j), -vel )
8551 vflux(i,k) = vel*flux3( &
8552 field(i,k-2,j), field(i,k-1,j), &
8553 field(i,k ,j), field(i,k+1,j), -vel )
8556 vflux(i,k)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
8560 DO i = i_start, i_end
8561 tendency(i,k,j)=tendency(i,k,j)-rdzw(k)*(vflux(i,k+1)-vflux(i,k))
8569 END SUBROUTINE advect_scalar_weno
8571 !---------------------------------------------------------------------------------
8573 SUBROUTINE advect_scalar_wenopd ( field, field_old, tendency, &
8577 time_step, config_flags, &
8578 msfux, msfuy, msfvx, msfvy, &
8581 rdx, rdy, rdzw, dt, &
8582 ids, ide, jds, jde, kds, kde, &
8583 ims, ime, jms, jme, kms, kme, &
8584 its, ite, jts, jte, kts, kte )
8586 ! this is a first cut at a positive definite advection option
8587 ! for scalars in WRF. This version is memory intensive ->
8588 ! we save 3d arrays of x, y and z both high and low order fluxes
8589 ! (six in all). Alternatively, we could sweep in a direction
8590 ! and lower the cost considerably.
8592 ! uses the Smolarkiewicz MWR 1989 approach, with addition of first-order
8595 ! WCS, 3 December 2002, 24 February 2003
8598 ! ERM Dec. 2011: replaced 5th-order fluxes with 5th-order WENO (Weighted
8599 ! Essentially Non-Oscillatory) scheme
8600 ! See Jiang and Shu, 1996, J. Comp. Phys. v. 126, 202-223;
8601 ! Shu 2003, Int. J. Comp. Fluid Dyn. v. 17 107-118;
8608 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
8610 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
8611 ims, ime, jms, jme, kms, kme, &
8612 its, ite, jts, jte, kts, kte
8614 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: field, &
8620 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut, mub, mu_old
8621 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
8623 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
8630 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
8636 REAL , INTENT(IN ) :: rdx, &
8639 INTEGER , INTENT(IN ) :: time_step
8643 INTEGER :: i, j, k, itf, jtf, ktf
8644 INTEGER :: i_start, i_end, j_start, j_end
8645 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
8646 INTEGER :: jmin, jmax, jp, jm, imin, imax
8648 REAL :: mrdx, mrdy, ub, vb, uw, vw, mu
8650 ! storage for high and low order fluxes
8652 REAL, DIMENSION( its-1:ite+2, kts:kte, jts-1:jte+2 ) :: fqx, fqy, fqz
8653 REAL, DIMENSION( its-1:ite+2, kts:kte, jts-1:jte+2 ) :: fqxl, fqyl, fqzl
8655 INTEGER :: horz_order, vert_order
8657 LOGICAL :: degrade_xs, degrade_ys
8658 LOGICAL :: degrade_xe, degrade_ye
8660 INTEGER :: jp1, jp0, jtmp
8662 REAL,DIMENSION( its-1:ite+2, kts:kte, jts-1:jte+2 ) :: flux_out, ph_low
8664 REAL, PARAMETER :: eps=1.e-20
8667 real :: ue,vs,vn,wb,wt
8668 real, parameter :: f30 = 7./12., f31 = 1./12.
8669 real, parameter :: f50 = 37./60., f51 = 2./15., f52 = 1./60.
8671 real :: qim2, qim1, qi, qip1, qip2
8672 double precision :: beta0, beta1, beta2, f0, f1, f2, wi0, wi1, wi2, sumwk
8673 double precision, parameter :: gi0 = 1.d0/10.d0, gi1 = 6.d0/10.d0, gi2 = 3.d0/10.d0, eps1=1.0d-40
8674 integer, parameter :: pw = 2
8677 ! definition of flux operators, 3rd, 4th, 5th or 6th order
8679 REAL :: flux3, flux4, flux5, flux6, flux_upwind
8680 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel, cr
8682 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
8683 (7./12.)*(q_i + q_im1) - (1./12.)*(q_ip1 + q_im2)
8685 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
8686 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
8687 sign(1,time_step)*sign(1.,ua)*(1./12.)*((q_ip1 - q_im2)-3.*(q_i-q_im1))
8689 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
8690 (37./60.)*(q_i+q_im1) - (2./15.)*(q_ip1+q_im2) &
8691 +(1./60.)*(q_ip2+q_im3)
8693 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
8694 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
8695 -sign(1,time_step)*sign(1.,ua)*(1./60.)*( &
8696 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )
8698 flux_upwind(q_im1, q_i, cr ) = 0.5*min( 1.0,(cr+abs(cr)))*q_im1 &
8699 +0.5*max(-1.0,(cr-abs(cr)))*q_i
8701 ! flux_upwind(q_im1, q_i, cr ) = 0.5*(1.+sign(1.,cr))*q_im1 &
8702 ! +0.5*(1.-sign(1.,cr))*q_i
8703 ! flux_upwind(q_im1, q_i, cr ) = 0.
8707 LOGICAL, PARAMETER :: pd_limit = .true.
8709 ! set order for the advection schemes
8711 ! write(6,*) ' in pd advection routine '
8713 ! Empty arrays just in case:
8714 IF (config_flags%polar) THEN
8724 horz_order = config_flags%h_sca_adv_order
8725 vert_order = config_flags%v_sca_adv_order
8727 ! determine boundary mods for flux operators
8728 ! We degrade the flux operators from 3rd/4th order
8729 ! to second order one gridpoint in from the boundaries for
8730 ! all boundary conditions except periodic and symmetry - these
8731 ! conditions have boundary zone data fill for correct application
8732 ! of the higher order flux stencils
8739 ! begin with horizontal flux divergence
8740 ! here is the choice of flux operators
8743 ! horizontal_order_test : IF( horz_order == 6 ) THEN
8745 ! ELSE IF( horz_order == 5 ) THEN
8747 IF( config_flags%periodic_x .or. &
8748 config_flags%symmetric_xs .or. &
8749 (its > ids+3) ) degrade_xs = .false.
8750 IF( config_flags%periodic_x .or. &
8751 config_flags%symmetric_xe .or. &
8752 (ite < ide-4) ) degrade_xe = .false.
8753 IF( config_flags%periodic_y .or. &
8754 config_flags%symmetric_ys .or. &
8755 (jts > jds+3) ) degrade_ys = .false.
8756 IF( config_flags%periodic_y .or. &
8757 config_flags%symmetric_ye .or. &
8758 (jte < jde-4) ) degrade_ye = .false.
8760 !--------------- y - advection first
8762 !-- y flux compute; these bounds are for periodic and sym b.c.
8766 i_end = MIN(ite,ide-1)+1
8768 j_end = MIN(jte,jde-1)+1
8772 !-- modify loop bounds if open or specified
8774 ! IF(degrade_xs) i_start = MAX(its-1,ids-1)
8775 ! IF(degrade_xe) i_end = MIN(ite+1,ide-2)
8776 IF(degrade_xs) i_start = MAX(its-1,ids)
8777 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
8780 j_start = MAX(jts-1,jds+1)
8785 j_end = MIN(jte+1,jde-2)
8789 ! compute fluxes, 5th order
8791 j_loop_y_flux_5 : DO j = j_start, j_end+1
8793 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN ! use full stencil
8796 DO i = i_start, i_end
8798 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
8799 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
8802 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
8804 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
8805 qip2 = field(i,k,j+1)
8806 qip1 = field(i,k,j )
8808 qim1 = field(i,k,j-2)
8809 qim2 = field(i,k,j-3)
8811 qip2 = field(i,k,j-2)
8812 qip1 = field(i,k,j-1)
8814 qim1 = field(i,k,j+1)
8815 qim2 = field(i,k,j+2)
8818 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
8819 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
8820 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
8822 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
8823 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
8824 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
8826 wi0 = gi0 / (eps1 + beta0)**pw
8827 wi1 = gi1 / (eps1 + beta1)**pw
8828 wi2 = gi2 / (eps1 + beta2)**pw
8830 sumwk = wi0 + wi1 + wi2
8832 fqy( i, k, j ) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
8834 ! fqy( i, k, j ) = vel*flux5( &
8835 ! field(i,k,j-3), field(i,k,j-2), field(i,k,j-1), &
8836 ! field(i,k,j ), field(i,k,j+1), field(i,k,j+2), vel )
8838 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
8843 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
8846 DO i = i_start, i_end
8848 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
8849 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
8852 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
8854 fqy(i,k, j) = 0.5*rv(i,k,j)* &
8855 (field(i,k,j)+field(i,k,j-1))
8857 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
8862 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south 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 ) = vel*flux3( &
8874 field(i,k,j-2),field(i,k,j-1),field(i,k,j),field(i,k,j+1),vel )
8875 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
8880 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to 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 ) = 0.5*rv(i,k,j)* &
8892 (field(i,k,j)+field(i,k,j-1))
8893 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
8898 ELSE IF ( j == jde-2 ) THEN ! 3rd or 4th order flux 2 in from north boundary
8901 DO i = i_start, i_end
8903 dy = 2./(msftx(i,j)+msftx(i,j-1))/rdy ! ADT eqn 48 d/dy
8904 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j-1)+c2(k)))
8907 fqyl(i,k,j) = mu*(dy/dt)*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
8909 fqy( i, k, j) = vel*flux3( &
8910 field(i,k,j-2),field(i,k,j-1), &
8911 field(i,k,j),field(i,k,j+1),vel )
8912 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
8919 ENDDO j_loop_y_flux_5
8923 !-- these bounds are for periodic and sym conditions
8926 i_end = MIN(ite,ide-1)+1
8931 j_end = MIN(jte,jde-1)+1
8933 !-- modify loop bounds for open and specified b.c
8935 ! IF(degrade_ys) j_start = MAX(jts-1,jds+1)
8936 ! IF(degrade_ye) j_end = MIN(jte+1,jde-2)
8937 IF(degrade_ys) j_start = MAX(jts-1,jds)
8938 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
8941 i_start = MAX(ids+1,its-1)
8946 i_end = MIN(ide-2,ite+1)
8952 DO j = j_start, j_end
8957 DO i = i_start_f, i_end_f
8959 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
8960 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
8963 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
8966 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
8967 qip2 = field(i+1,k,j)
8968 qip1 = field(i, k,j)
8970 qim1 = field(i-2,k,j)
8971 qim2 = field(i-3,k,j)
8973 qip2 = field(i-2,k,j)
8974 qip1 = field(i-1,k,j)
8976 qim1 = field(i+1,k,j)
8977 qim2 = field(i+2,k,j)
8980 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
8981 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
8982 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
8984 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
8985 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
8986 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
8988 wi0 = gi0 / (eps1 + beta0)**pw
8989 wi1 = gi1 / (eps1 + beta1)**pw
8990 wi2 = gi2 / (eps1 + beta2)**pw
8992 sumwk = wi0 + wi1 + wi2
8994 fqx(i,k,j) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
8996 ! fqx( i,k,j ) = vel*flux5( field(i-3,k,j), field(i-2,k,j), &
8997 ! field(i-1,k,j), field(i ,k,j), &
8998 ! field(i+1,k,j), field(i+2,k,j), &
9000 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9005 ! lower order fluxes close to boundaries (if not periodic or symmetric)
9007 IF( degrade_xs ) THEN
9009 DO i=i_start,i_start_f-1
9011 IF(i == ids+1) THEN ! second order
9013 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
9014 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
9017 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9018 fqx(i,k,j) = 0.5*(ru(i,k,j)) &
9019 *(field(i,k,j)+field(i-1,k,j))
9020 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9024 IF(i == ids+2) THEN ! third order
9026 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
9027 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
9030 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9031 fqx( i,k,j ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
9032 field(i ,k,j), field(i+1,k,j), &
9034 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9042 IF( degrade_xe ) THEN
9044 DO i = i_end_f+1, i_end+1
9046 IF( i == ide-1 ) THEN ! second order flux next to the boundary
9048 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
9049 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
9052 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9053 fqx(i,k,j) = 0.5*(ru(i,k,j)) &
9054 *(field(i,k,j)+field(i-1,k,j))
9055 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9060 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
9062 dx = 2./(msfty(i,j)+msfty(i-1,j))/rdx ! ADT eqn 48 d/dx
9063 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i-1,j)+c2(k)))
9066 fqxl(i,k,j) = mu*(dx/dt)*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9067 fqx( i,k,j ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
9068 field(i ,k,j), field(i+1,k,j), &
9070 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9078 ENDDO ! enddo for outer J loop
9080 !--- end of 5th order horizontal flux calculation
9084 ! WRITE ( wrf_err_message , * ) 'module_advect: advect_scalar_pd, h_order not known ',horz_order
9085 ! CALL wrf_error_fatal ( TRIM( wrf_err_message ) )
9087 ! ENDIF horizontal_order_test
9089 ! pick up the rest of the horizontal radiation boundary conditions.
9090 ! (these are the computations that don't require 'cb'.
9091 ! first, set to index ranges
9094 i_end = MIN(ite,ide-1)
9096 j_end = MIN(jte,jde-1)
9098 ! compute x (u) conditions for v, w, or scalar
9100 IF( (config_flags%open_xs) .and. (its == ids) ) THEN
9102 DO j = j_start, j_end
9104 ub = MIN( 0.5*(ru(its,k,j)+ru(its+1,k,j)), 0. )
9105 tendency(its,k,j) = tendency(its,k,j) &
9107 ub*( field_old(its+1,k,j) &
9108 - field_old(its ,k,j) ) + &
9109 field(its,k,j)*(ru(its+1,k,j)-ru(its,k,j)) &
9116 IF( (config_flags%open_xe) .and. (ite == ide) ) THEN
9118 DO j = j_start, j_end
9120 ub = MAX( 0.5*(ru(ite-1,k,j)+ru(ite,k,j)), 0. )
9121 tendency(i_end,k,j) = tendency(i_end,k,j) &
9123 ub*( field_old(i_end ,k,j) &
9124 - field_old(i_end-1,k,j) ) + &
9125 field(i_end,k,j)*(ru(ite,k,j)-ru(ite-1,k,j)) &
9132 IF( (config_flags%open_ys) .and. (jts == jds) ) THEN
9134 DO i = i_start, i_end
9136 vb = MIN( 0.5*(rv(i,k,jts)+rv(i,k,jts+1)), 0. )
9137 tendency(i,k,jts) = tendency(i,k,jts) &
9139 vb*( field_old(i,k,jts+1) &
9140 - field_old(i,k,jts ) ) + &
9141 field(i,k,jts)*(rv(i,k,jts+1)-rv(i,k,jts)) &
9148 IF( (config_flags%open_ye) .and. (jte == jde)) THEN
9150 DO i = i_start, i_end
9152 vb = MAX( 0.5*(rv(i,k,jte-1)+rv(i,k,jte)), 0. )
9153 tendency(i,k,j_end) = tendency(i,k,j_end) &
9155 vb*( field_old(i,k,j_end ) &
9156 - field_old(i,k,j_end-1) ) + &
9157 field(i,k,j_end)*(rv(i,k,jte)-rv(i,k,jte-1)) &
9164 IF( (config_flags%polar) .and. (jts == jds) ) THEN
9166 ! Assuming rv(i,k,jds) = 0.
9167 DO i = i_start, i_end
9169 vb = MIN( 0.5*rv(i,k,jts+1), 0. )
9170 tendency(i,k,jts) = tendency(i,k,jts) &
9172 vb*( field_old(i,k,jts+1) &
9173 - field_old(i,k,jts ) ) + &
9174 field(i,k,jts)*rv(i,k,jts+1) &
9181 IF( (config_flags%polar) .and. (jte == jde)) THEN
9183 ! Assuming rv(i,k,jde) = 0.
9184 DO i = i_start, i_end
9186 vb = MAX( 0.5*rv(i,k,jte-1), 0. )
9187 tendency(i,k,j_end) = tendency(i,k,j_end) &
9189 vb*( field_old(i,k,j_end ) &
9190 - field_old(i,k,j_end-1) ) + &
9191 field(i,k,j_end)*(-rv(i,k,jte-1)) &
9198 !-------------------- vertical advection
9200 !-- loop bounds for periodic or sym conditions
9203 i_end = MIN(ite,ide-1)+1
9205 j_end = MIN(jte,jde-1)+1
9207 !-- loop bounds for open or specified conditions
9209 IF(degrade_xs) i_start = MAX(its-1,ids)
9210 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
9211 IF(degrade_ys) j_start = MAX(jts-1,jds)
9212 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
9214 ! vert_order_test : IF (vert_order == 6) THEN
9217 ! ELSE IF (vert_order == 5) THEN
9219 DO j = j_start, j_end
9221 DO i = i_start, i_end
9229 DO i = i_start, i_end
9230 dz = 2./(rdzw(k)+rdzw(k-1))
9231 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
9234 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
9237 IF( -vel*sign(1,time_step) .ge. 0.0 ) THEN
9238 qip2 = field(i,k+1,j)
9239 qip1 = field(i,k ,j)
9241 qim1 = field(i,k-2,j)
9242 qim2 = field(i,k-3,j)
9244 qip2 = field(i,k-2,j)
9245 qip1 = field(i,k-1,j)
9247 qim1 = field(i,k+1,j)
9248 qim2 = field(i,k+2,j)
9251 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
9252 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
9253 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
9255 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
9256 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
9257 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
9259 wi0 = gi0 / (eps1 + beta0)**pw
9260 wi1 = gi1 / (eps1 + beta1)**pw
9261 wi2 = gi2 / (eps1 + beta2)**pw
9263 sumwk = wi0 + wi1 + wi2
9265 fqz(i,k,j) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
9267 ! fqz(i,k,j) = vel*flux5( field(i,k-3,j), field(i,k-2,j), field(i,k-1,j), &
9268 ! field(i,k ,j), field(i,k+1,j), field(i,k+2,j), -vel )
9269 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
9273 DO i = i_start, i_end
9276 dz = 2./(rdzw(k)+rdzw(k-1))
9277 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
9280 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
9281 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
9282 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
9285 dz = 2./(rdzw(k)+rdzw(k-1))
9286 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
9289 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
9291 fqz(i,k,j) = vel*flux3( &
9292 field(i,k-2,j), field(i,k-1,j), &
9293 field(i,k ,j), field(i,k+1,j), -vel )
9294 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
9297 dz = 2./(rdzw(k)+rdzw(k-1))
9298 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
9301 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
9303 fqz(i,k,j) = vel*flux3( &
9304 field(i,k-2,j), field(i,k-1,j), &
9305 field(i,k ,j), field(i,k+1,j), -vel )
9306 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
9309 dz = 2./(rdzw(k)+rdzw(k-1))
9310 mu = 0.5*((c1(k)*mut(i,j)+c2(k))+(c1(k)*mut(i,j)+c2(k)))
9313 fqzl(i,k,j) = mu*(dz/dt)*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
9314 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
9315 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
9324 ! WRITE (wrf_err_message,*) ' advect_scalar_pd, v_order not known ',vert_order
9325 ! CALL wrf_error_fatal ( wrf_err_message )
9327 ! ENDIF vert_order_test
9331 ! positive definite filter
9334 i_end = MIN(ite,ide-1)+1
9336 j_end = MIN(jte,jde-1)+1
9338 !-- loop bounds for open or specified conditions
9340 IF(degrade_xs) i_start = MAX(its-1,ids)
9341 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
9342 IF(degrade_ys) j_start = MAX(jts-1,jds)
9343 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
9345 IF(config_flags%specified .or. config_flags%nested) THEN
9346 IF (degrade_xs) i_start = MAX(its-1,ids+1)
9347 IF (degrade_xe) i_end = MIN(ite+1,ide-2)
9348 IF (degrade_ys) j_start = MAX(jts-1,jds+1)
9349 IF (degrade_ye) j_end = MIN(jte+1,jde-2)
9352 IF(config_flags%open_xs) THEN
9353 IF (degrade_xs) i_start = MAX(its-1,ids+1)
9355 IF(config_flags%open_xe) THEN
9356 IF (degrade_xe) i_end = MIN(ite+1,ide-2)
9358 IF(config_flags%open_ys) THEN
9359 IF (degrade_ys) j_start = MAX(jts-1,jds+1)
9361 IF(config_flags%open_ye) THEN
9362 IF (degrade_ye) j_end = MIN(jte+1,jde-2)
9365 ! We don't want to change j_start and j_end
9366 ! for polar BC's since we want to calculate
9367 ! fluxes for directions other than y at the
9370 !-- here is the limiter...
9381 ph_low(i,k,j) = ((c1(k)*mub(i,j)+c2(k))+(c1(k)*mu_old(i,j)))*field_old(i,k,j) &
9382 - dt*( msftx(i,j)*msfty(i,j)*( &
9383 rdx*(fqxl(i+1,k,j)-fqxl(i,k,j)) + &
9384 rdy*(fqyl(i,k,j+1)-fqyl(i,k,j)) ) &
9385 +msfty(i,j)*rdzw(k)*(fqzl(i,k+1,j)-fqzl(i,k,j)) )
9396 flux_out(i,k,j) = dt*( (msftx(i,j)*msfty(i,j))*( &
9397 rdx*( max(0.,fqx (i+1,k,j)) &
9398 -min(0.,fqx (i ,k,j)) ) &
9399 +rdy*( max(0.,fqy (i,k,j+1)) &
9400 -min(0.,fqy (i,k,j )) ) ) &
9401 +msfty(i,j)*rdzw(k)*( min(0.,fqz (i,k+1,j)) &
9402 -max(0.,fqz (i,k ,j)) ) )
9413 IF( flux_out(i,k,j) .gt. ph_low(i,k,j) ) THEN
9415 scale = max(0.,ph_low(i,k,j)/(flux_out(i,k,j)+eps))
9416 IF( fqx (i+1,k,j) .gt. 0.) fqx(i+1,k,j) = scale*fqx(i+1,k,j)
9417 IF( fqx (i ,k,j) .lt. 0.) fqx(i ,k,j) = scale*fqx(i ,k,j)
9418 IF( fqy (i,k,j+1) .gt. 0.) fqy(i,k,j+1) = scale*fqy(i,k,j+1)
9419 IF( fqy (i,k,j ) .lt. 0.) fqy(i,k,j ) = scale*fqy(i,k,j )
9420 ! note: z flux is opposite sign in mass coordinate because
9421 ! vertical coordinate decreases with increasing k
9422 IF( fqz (i,k+1,j) .lt. 0.) fqz(i,k+1,j) = scale*fqz(i,k+1,j)
9423 IF( fqz (i,k ,j) .gt. 0.) fqz(i,k ,j) = scale*fqz(i,k ,j)
9433 ! add in the pd-limited flux divergence
9436 i_end = MIN(ite,ide-1)
9438 j_end = MIN(jte,jde-1)
9440 DO j = j_start, j_end
9442 DO i = i_start, i_end
9444 tendency (i,k,j) = tendency(i,k,j) &
9445 -rdzw(k)*( fqz (i,k+1,j)-fqz (i,k,j) &
9446 +fqzl(i,k+1,j)-fqzl(i,k,j))
9454 IF(degrade_xs) i_start = MAX(its,ids+1)
9455 IF(degrade_xe) i_end = MIN(ite,ide-2)
9457 DO j = j_start, j_end
9459 DO i = i_start, i_end
9461 ! Un-"canceled" map scale factor, ADT Eq. 48
9462 tendency (i,k,j) = tendency(i,k,j) &
9463 - msftx(i,j)*( rdx*( fqx (i+1,k,j)-fqx (i,k,j) &
9464 +fqxl(i+1,k,j)-fqxl(i,k,j)) )
9473 i_end = MIN(ite,ide-1)
9474 IF(degrade_ys) j_start = MAX(jts,jds+1)
9475 IF(degrade_ye) j_end = MIN(jte,jde-2)
9477 DO j = j_start, j_end
9479 DO i = i_start, i_end
9481 ! Un-"canceled" map scale factor, ADT Eq. 48
9482 ! It is correct to use msftx (and not msfty), per W. Skamarock, 20080606
9483 tendency (i,k,j) = tendency(i,k,j) &
9484 - msftx(i,j)*( rdy*( fqy (i,k,j+1)-fqy (i,k,j) &
9485 +fqyl(i,k,j+1)-fqyl(i,k,j)) )
9491 END SUBROUTINE advect_scalar_wenopd
9493 !----------------------------------------------------------------
9495 SUBROUTINE advect_scalar_mono ( field, field_old, tendency, &
9496 h_tendency, z_tendency, &
9497 ru, rv, rom, romI, &
9502 msfux, msfuy, msfvx, msfvy, &
9505 rdx, rdy, rdzw, dt, &
9506 ids, ide, jds, jde, kds, kde, &
9507 ims, ime, jms, jme, kms, kme, &
9508 its, ite, jts, jte, kts, kte )
9510 ! monotonic advection option
9511 ! for scalars in WRF RK3 advection. This version is memory intensive ->
9512 ! we save 3d arrays of x, y and z both high and low order fluxes
9513 ! (six in all). Alternatively, we could sweep in a direction
9514 ! and lower the cost considerably.
9516 ! uses the Smolarkiewicz MWR 1989 approach, with addition of first-order
9523 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
9525 LOGICAL , INTENT(IN ) :: tenddec ! tendency flag
9527 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
9528 ims, ime, jms, jme, kms, kme, &
9529 its, ite, jts, jte, kts, kte
9531 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: field, &
9538 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut, mub, mu_old
9539 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
9540 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT( OUT) :: h_tendency, z_tendency
9542 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
9549 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
9555 REAL , INTENT(IN ) :: rdx, &
9561 INTEGER :: i, j, k, itf, jtf, ktf
9562 INTEGER :: i_start, i_end, j_start, j_end
9563 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
9564 INTEGER :: jmin, jmax, jp, jm, imin, imax
9566 REAL :: mrdx, mrdy, ub, vb, uw, vw, mu, ieva_corr
9567 REAL , DIMENSION(its:ite, kts:kte) :: vflux
9570 ! storage for high and low order fluxes
9572 REAL, DIMENSION( its-2:ite+2, kts:kte, jts-2:jte+2 ) :: fqx, fqy, fqz
9573 REAL, DIMENSION( its-2:ite+2, kts:kte, jts-2:jte+2 ) :: fqxl, fqyl, fqzl
9574 REAL, DIMENSION( its-2:ite+2, kts:kte, jts-2:jte+2 ) :: qmin, qmax
9575 REAL, DIMENSION( its-2:ite+2, kts:kte, jts-2:jte+2 ) :: scale_in, scale_out
9578 INTEGER :: horz_order, vert_order
9580 LOGICAL :: degrade_xs, degrade_ys
9581 LOGICAL :: degrade_xe, degrade_ye
9583 INTEGER :: jp1, jp0, jtmp
9585 REAL :: flux_out, ph_low, flux_in, ph_hi, scale
9586 REAL, PARAMETER :: eps=1.e-20
9589 ! definition of flux operators, 3rd, 4rth, 5th or 6th order
9591 REAL :: flux3, flux4, flux5, flux6, flux_upwind
9592 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel, cr
9594 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
9595 (7./12.)*(q_i + q_im1) - (1./12.)*(q_ip1 + q_im2)
9597 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
9598 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
9599 sign(1.,ua)*(1./12.)*((q_ip1 - q_im2)-3.*(q_i-q_im1))
9601 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
9602 (37./60.)*(q_i+q_im1) - (2./15.)*(q_ip1+q_im2) &
9603 +(1./60.)*(q_ip2+q_im3)
9605 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
9606 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
9607 -sign(1.,ua)*(1./60.)*( &
9608 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )
9610 ! flux_upwind(q_im1, q_i, cr ) = 0.
9611 flux_upwind(q_im1, q_i, cr ) = 0.5*(1.+sign(1.,cr))*q_im1 &
9612 +0.5*(1.-sign(1.,cr))*q_i
9614 LOGICAL, PARAMETER :: mono_limit = .true.
9616 ! set order for the advection schemes
9619 horz_order = config_flags%h_sca_adv_order
9620 vert_order = config_flags%v_sca_adv_order
9625 qmin(i,k,j) = field_old(i,k,j)
9626 qmax(i,k,j) = field_old(i,k,j)
9627 scale_in(i,k,j) = 1.
9628 scale_out(i,k,j) = 1.
9639 ! begin with horizontal flux divergence
9640 ! here is the choice of flux operators
9643 horizontal_order_test : IF( horz_order == 5 ) THEN
9645 ! determine boundary mods for flux operators
9646 ! We degrade the flux operators from 3rd/4rth order
9647 ! to second order one gridpoint in from the boundaries for
9648 ! all boundary conditions except periodic and symmetry - these
9649 ! conditions have boundary zone data fill for correct application
9650 ! of the higher order flux stencils
9657 IF( config_flags%periodic_x .or. &
9658 config_flags%symmetric_xs .or. &
9659 (its > ids+3) ) degrade_xs = .false.
9660 IF( config_flags%periodic_x .or. &
9661 config_flags%symmetric_xe .or. &
9662 (ite < ide-4) ) degrade_xe = .false.
9663 IF( config_flags%periodic_y .or. &
9664 config_flags%symmetric_ys .or. &
9665 (jts > jds+3) ) degrade_ys = .false.
9666 IF( config_flags%periodic_y .or. &
9667 config_flags%symmetric_ye .or. &
9668 (jte < jde-4) ) degrade_ye = .false.
9670 !--------------- y - advection first
9672 !-- y flux compute; these bounds are for periodic and sym b.c.
9676 i_end = MIN(ite,ide-1)+1
9678 j_end = MIN(jte,jde-1)+1
9682 !-- modify loop bounds if open or specified
9685 ! IF(degrade_xs) i_start = its
9686 ! IF(degrade_xe) i_end = MIN(ite,ide-1)
9687 IF(degrade_xs) i_start = MAX(its-1,ids)
9688 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
9691 ! IF(degrade_ys) then
9692 ! j_start = MAX(jts,jds+1)
9696 ! IF(degrade_ye) then
9697 ! j_end = MIN(jte,jde-2)
9702 j_start = MAX(jts-1,jds+1)
9707 j_end = MIN(jte+1,jde-2)
9711 ! compute fluxes, 5th order
9713 j_loop_y_flux_5 : DO j = j_start, j_end+1
9715 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN ! use full stencil
9718 DO i = i_start, i_end
9722 fqyl(i,k,j) = vel*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), vel)
9724 fqy( i, k, j ) = vel*flux5( &
9725 field(i,k,j-3), field(i,k,j-2), field(i,k,j-1), &
9726 field(i,k,j ), field(i,k,j+1), field(i,k,j+2), vel )
9728 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
9731 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k,j-1))
9732 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k,j-1))
9734 qmax(i,k,j-1) = amax1(qmax(i,k,j-1),field_old(i,k,j))
9735 qmin(i,k,j-1) = amin1(qmin(i,k,j-1),field_old(i,k,j))
9741 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
9744 DO i = i_start, i_end
9748 fqyl(i,k,j) = vel*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
9750 fqy(i,k, j) = 0.5*rv(i,k,j)* &
9751 (field(i,k,j)+field(i,k,j-1))
9753 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
9756 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k,j-1))
9757 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k,j-1))
9759 qmax(i,k,j-1) = amax1(qmax(i,k,j-1),field_old(i,k,j))
9760 qmin(i,k,j-1) = amin1(qmin(i,k,j-1),field_old(i,k,j))
9766 ELSE IF ( j == jds+2 ) THEN ! third of 4rth order flux 2 in from south boundary
9769 DO i = i_start, i_end
9773 fqyl(i,k,j) = vel*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
9775 fqy( i, k, j ) = vel*flux3( &
9776 field(i,k,j-2),field(i,k,j-1),field(i,k,j),field(i,k,j+1),vel )
9777 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
9780 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k,j-1))
9781 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k,j-1))
9783 qmax(i,k,j-1) = amax1(qmax(i,k,j-1),field_old(i,k,j))
9784 qmin(i,k,j-1) = amin1(qmin(i,k,j-1),field_old(i,k,j))
9790 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
9793 DO i = i_start, i_end
9797 fqyl(i,k,j) = vel*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
9799 fqy(i, k, j ) = 0.5*rv(i,k,j)* &
9800 (field(i,k,j)+field(i,k,j-1))
9801 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
9804 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k,j-1))
9805 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k,j-1))
9807 qmax(i,k,j-1) = amax1(qmax(i,k,j-1),field_old(i,k,j))
9808 qmin(i,k,j-1) = amin1(qmin(i,k,j-1),field_old(i,k,j))
9814 ELSE IF ( j == jde-2 ) THEN ! 3rd or 4rth order flux 2 in from north boundary
9817 DO i = i_start, i_end
9821 fqyl(i,k,j) = vel*flux_upwind(field_old(i,k,j-1), field_old(i,k,j ), cr)
9823 fqy( i, k, j) = vel*flux3( &
9824 field(i,k,j-2),field(i,k,j-1), &
9825 field(i,k,j),field(i,k,j+1),vel )
9826 fqy(i,k,j) = fqy(i,k,j) - fqyl(i,k,j)
9829 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k,j-1))
9830 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k,j-1))
9832 qmax(i,k,j-1) = amax1(qmax(i,k,j-1),field_old(i,k,j))
9833 qmin(i,k,j-1) = amin1(qmin(i,k,j-1),field_old(i,k,j))
9841 ENDDO j_loop_y_flux_5
9845 !-- these bounds are for periodic and sym conditions
9848 i_end = MIN(ite,ide-1)+1
9853 j_end = MIN(jte,jde-1)+1
9855 !-- modify loop bounds for open and specified b.c
9858 ! IF(degrade_ys) j_start = jts
9859 ! IF(degrade_ye) j_end = MIN(jte,jde-1)
9860 IF(degrade_ys) j_start = MAX(jts-1,jds)
9861 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
9864 ! IF(degrade_xs) then
9865 ! i_start = MAX(ids+1,its)
9866 ! i_start_f = i_start+2
9869 ! IF(degrade_xe) then
9870 ! i_end = MIN(ide-2,ite)
9875 i_start = MAX(ids+1,its-1)
9880 i_end = MIN(ide-2,ite+1)
9886 DO j = j_start, j_end
9888 ! 5th or 6th order flux
9891 DO i = i_start_f, i_end_f
9895 fqxl(i,k,j) = vel*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9897 fqx( i,k,j ) = vel*flux5( field(i-3,k,j), field(i-2,k,j), &
9898 field(i-1,k,j), field(i ,k,j), &
9899 field(i+1,k,j), field(i+2,k,j), &
9901 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9904 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i-1,k,j))
9905 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i-1,k,j))
9907 qmax(i-1,k,j) = amax1(qmax(i-1,k,j),field_old(i,k,j))
9908 qmin(i-1,k,j) = amin1(qmin(i-1,k,j),field_old(i,k,j))
9914 ! lower order fluxes close to boundaries (if not periodic or symmetric)
9916 ! WCS 20090218 degrade_xs and xe recoded
9918 IF( degrade_xs ) THEN
9920 DO i=i_start,i_start_f-1
9922 IF(i == ids+1) THEN ! second order
9926 fqxl(i,k,j) = vel*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9928 fqx(i,k,j) = 0.5*(ru(i,k,j)) &
9929 *(field(i,k,j)+field(i-1,k,j))
9931 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9934 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i-1,k,j))
9935 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i-1,k,j))
9937 qmax(i-1,k,j) = amax1(qmax(i-1,k,j),field_old(i,k,j))
9938 qmin(i-1,k,j) = amin1(qmin(i-1,k,j),field_old(i,k,j))
9943 IF(i == ids+2) THEN ! third order
9947 fqxl(i,k,j) = vel*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9948 fqx( i,k,j ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
9949 field(i ,k,j), field(i+1,k,j), &
9951 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9954 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i-1,k,j))
9955 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i-1,k,j))
9957 qmax(i-1,k,j) = amax1(qmax(i-1,k,j),field_old(i,k,j))
9958 qmin(i-1,k,j) = amin1(qmin(i-1,k,j),field_old(i,k,j))
9967 IF( degrade_xe ) THEN
9969 DO i = i_end_f+1, i_end+1
9971 IF( i == ide-1 ) THEN ! second order flux next to the boundary
9975 fqxl(i,k,j) = vel*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9976 fqx(i,k,j) = 0.5*(ru(i,k,j)) &
9977 *(field(i,k,j)+field(i-1,k,j))
9978 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
9981 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i-1,k,j))
9982 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i-1,k,j))
9984 qmax(i-1,k,j) = amax1(qmax(i-1,k,j),field_old(i,k,j))
9985 qmin(i-1,k,j) = amin1(qmin(i-1,k,j),field_old(i,k,j))
9990 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
9994 fqxl(i,k,j) = vel*flux_upwind(field_old(i-1,k,j), field_old(i,k,j ), cr)
9995 fqx( i,k,j ) = vel*flux3( field(i-2,k,j), field(i-1,k,j), &
9996 field(i ,k,j), field(i+1,k,j), &
9998 fqx(i,k,j) = fqx(i,k,j) - fqxl(i,k,j)
10001 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i-1,k,j))
10002 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i-1,k,j))
10004 qmax(i-1,k,j) = amax1(qmax(i-1,k,j),field_old(i,k,j))
10005 qmin(i-1,k,j) = amin1(qmin(i-1,k,j),field_old(i,k,j))
10012 ENDDO ! enddo for outer J loop
10016 WRITE ( wrf_err_message , * ) 'module_advect: advect_scalar_mono, h_order not known ',horz_order
10017 CALL wrf_error_fatal ( TRIM( wrf_err_message ) )
10019 ENDIF horizontal_order_test
10021 ! pick up the rest of the horizontal radiation boundary conditions.
10022 ! (these are the computations that don't require 'cb'.
10023 ! first, set to index ranges
10026 i_end = MIN(ite,ide-1)
10028 j_end = MIN(jte,jde-1)
10030 ! compute x (u) conditions for v, w, or scalar
10032 IF( (config_flags%open_xs) .and. (its == ids) ) THEN
10034 DO j = j_start, j_end
10036 ub = MIN( 0.5*(ru(its,k,j)+ru(its+1,k,j)), 0. )
10037 tendency(its,k,j) = tendency(its,k,j) &
10039 ub*( field_old(its+1,k,j) &
10040 - field_old(its ,k,j) ) + &
10041 field(its,k,j)*(ru(its+1,k,j)-ru(its,k,j)) &
10048 IF( (config_flags%open_xe) .and. (ite == ide) ) THEN
10050 DO j = j_start, j_end
10052 ub = MAX( 0.5*(ru(ite-1,k,j)+ru(ite,k,j)), 0. )
10053 tendency(i_end,k,j) = tendency(i_end,k,j) &
10055 ub*( field_old(i_end ,k,j) &
10056 - field_old(i_end-1,k,j) ) + &
10057 field(i_end,k,j)*(ru(ite,k,j)-ru(ite-1,k,j)) &
10064 IF( (config_flags%open_ys) .and. (jts == jds) ) THEN
10066 DO i = i_start, i_end
10068 vb = MIN( 0.5*(rv(i,k,jts)+rv(i,k,jts+1)), 0. )
10069 tendency(i,k,jts) = tendency(i,k,jts) &
10071 vb*( field_old(i,k,jts+1) &
10072 - field_old(i,k,jts ) ) + &
10073 field(i,k,jts)*(rv(i,k,jts+1)-rv(i,k,jts)) &
10080 IF( (config_flags%open_ye) .and. (jte == jde)) THEN
10082 DO i = i_start, i_end
10084 vb = MAX( 0.5*(rv(i,k,jte-1)+rv(i,k,jte)), 0. )
10085 tendency(i,k,j_end) = tendency(i,k,j_end) &
10087 vb*( field_old(i,k,j_end ) &
10088 - field_old(i,k,j_end-1) ) + &
10089 field(i,k,j_end)*(rv(i,k,jte)-rv(i,k,jte-1)) &
10096 !-------------------- vertical advection
10098 !-- loop bounds for periodic or sym conditions
10101 i_end = MIN(ite,ide-1)+1
10103 j_end = MIN(jte,jde-1)+1
10105 !-- loop bounds for open or specified conditions
10108 ! IF(degrade_xs) i_start = its
10109 ! IF(degrade_xe) i_end = MIN(ite,ide-1)
10110 ! IF(degrade_ys) j_start = jts
10111 ! IF(degrade_ye) j_end = MIN(jte,jde-1)
10113 IF(degrade_xs) i_start = MAX(its-1,ids)
10114 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
10115 IF(degrade_ys) j_start = MAX(jts-1,jds)
10116 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
10119 vert_order_test : IF (vert_order == 3) THEN
10121 DO j = j_start, j_end
10123 DO i = i_start, i_end
10131 DO i = i_start, i_end
10135 fqzl(i,k,j) = vel*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
10137 fqz(i,k,j) = vel*flux3( &
10138 field(i,k-2,j), field(i,k-1,j), &
10139 field(i,k ,j), field(i,k+1,j), -vel )
10140 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
10143 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k-1,j))
10144 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k-1,j))
10146 qmax(i,k-1,j) = amax1(qmax(i,k-1,j),field_old(i,k,j))
10147 qmin(i,k-1,j) = amin1(qmin(i,k-1,j),field_old(i,k,j))
10153 DO i = i_start, i_end
10158 fqzl(i,k,j) = vel*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
10159 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
10160 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
10163 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k-1,j))
10164 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k-1,j))
10166 qmax(i,k-1,j) = amax1(qmax(i,k-1,j),field_old(i,k,j))
10167 qmin(i,k-1,j) = amin1(qmin(i,k-1,j),field_old(i,k,j))
10173 fqzl(i,k,j) = vel*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
10174 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
10175 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
10178 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k-1,j))
10179 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k-1,j))
10181 qmax(i,k-1,j) = amax1(qmax(i,k-1,j),field_old(i,k,j))
10182 qmin(i,k-1,j) = amin1(qmin(i,k-1,j),field_old(i,k,j))
10188 ELSE IF (vert_order == 5) THEN
10190 DO j = j_start, j_end
10192 DO i = i_start, i_end
10200 DO i = i_start, i_end
10204 fqzl(i,k,j) = vel*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
10206 fqz(i,k,j) = vel*flux5( &
10207 field(i,k-3,j), field(i,k-2,j), field(i,k-1,j), &
10208 field(i,k ,j), field(i,k+1,j), field(i,k+2,j), -vel )
10209 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
10212 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k-1,j))
10213 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k-1,j))
10215 qmax(i,k-1,j) = amax1(qmax(i,k-1,j),field_old(i,k,j))
10216 qmin(i,k-1,j) = amin1(qmin(i,k-1,j),field_old(i,k,j))
10222 DO i = i_start, i_end
10227 fqzl(i,k,j) = vel*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
10228 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
10229 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
10232 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k-1,j))
10233 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k-1,j))
10235 qmax(i,k-1,j) = amax1(qmax(i,k-1,j),field_old(i,k,j))
10236 qmin(i,k-1,j) = amin1(qmin(i,k-1,j),field_old(i,k,j))
10242 fqzl(i,k,j) = vel*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
10243 fqz(i,k,j)= vel*flux3(field(i,k-2,j), field(i,k-1,j), &
10244 field(i,k ,j), field(i,k+1,j), -vel )
10245 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
10248 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k-1,j))
10249 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k-1,j))
10251 qmax(i,k-1,j) = amax1(qmax(i,k-1,j),field_old(i,k,j))
10252 qmin(i,k-1,j) = amin1(qmin(i,k-1,j),field_old(i,k,j))
10258 fqzl(i,k,j) = vel*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
10259 fqz(i,k,j)= vel*flux3( field(i,k-2,j), field(i,k-1,j), &
10260 field(i,k ,j), field(i,k+1,j), -vel )
10261 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
10264 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k-1,j))
10265 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k-1,j))
10267 qmax(i,k-1,j) = amax1(qmax(i,k-1,j),field_old(i,k,j))
10268 qmin(i,k-1,j) = amin1(qmin(i,k-1,j),field_old(i,k,j))
10274 fqzl(i,k,j) = vel*flux_upwind(field_old(i,k-1,j), field_old(i,k,j ), cr)
10275 fqz(i,k,j)=rom(i,k,j)*(fzm(k)*field(i,k,j)+fzp(k)*field(i,k-1,j))
10276 fqz(i,k,j) = fqz(i,k,j) - fqzl(i,k,j)
10279 qmax(i,k,j) = amax1(qmax(i,k,j),field_old(i,k-1,j))
10280 qmin(i,k,j) = amin1(qmin(i,k,j),field_old(i,k-1,j))
10282 qmax(i,k-1,j) = amax1(qmax(i,k-1,j),field_old(i,k,j))
10283 qmin(i,k-1,j) = amin1(qmin(i,k-1,j),field_old(i,k,j))
10292 WRITE (wrf_err_message,*) ' advect_scalar_mono, v_order not known ',vert_order
10293 CALL wrf_error_fatal ( wrf_err_message )
10295 ENDIF vert_order_test
10297 IF (mono_limit) THEN
10302 i_end = MIN(ite,ide-1)+1
10304 j_end = MIN(jte,jde-1)+1
10308 !-- loop bounds for open or specified conditions
10310 ! IF(degrade_xs) i_start = its
10311 ! IF(degrade_xe) i_end = MIN(ite,ide-1)
10312 ! IF(degrade_ys) j_start = jts
10313 ! IF(degrade_ye) j_end = MIN(jte,jde-1)
10315 ! IF(config_flags%specified .or. config_flags%nested) THEN
10316 ! IF (degrade_xs) i_start = MAX(its,ids+1)
10317 ! IF (degrade_xe) i_end = MIN(ite,ide-2)
10318 ! IF (degrade_ys) j_start = MAX(jts,jds+1)
10319 ! IF (degrade_ye) j_end = MIN(jte,jde-2)
10322 ! IF(config_flags%open_xs) THEN
10323 ! IF (degrade_xs) i_start = MAX(its,ids+1)
10325 ! IF(config_flags%open_xe) THEN
10326 ! IF (degrade_xe) i_end = MIN(ite,ide-2)
10328 ! IF(config_flags%open_ys) THEN
10329 ! IF (degrade_ys) j_start = MAX(jts,jds+1)
10331 ! IF(config_flags%open_ye) THEN
10332 ! IF (degrade_ye) j_end = MIN(jte,jde-2)
10335 IF(degrade_xs) i_start = MAX(its-1,ids)
10336 IF(degrade_xe) i_end = MIN(ite+1,ide-1)
10337 IF(degrade_ys) j_start = MAX(jts-1,jds)
10338 IF(degrade_ye) j_end = MIN(jte+1,jde-1)
10340 IF(config_flags%specified .or. config_flags%nested) THEN
10341 IF (degrade_xs) i_start = MAX(its-1,ids+1)
10342 IF (degrade_xe) i_end = MIN(ite+1,ide-2)
10343 IF (degrade_ys) j_start = MAX(jts-1,jds+1)
10344 IF (degrade_ye) j_end = MIN(jte+1,jde-2)
10347 IF(config_flags%open_xs) THEN
10348 IF (degrade_xs) i_start = MAX(its-1,ids+1)
10350 IF(config_flags%open_xe) THEN
10351 IF (degrade_xe) i_end = MIN(ite+1,ide-2)
10353 IF(config_flags%open_ys) THEN
10354 IF (degrade_ys) j_start = MAX(jts-1,jds+1)
10356 IF(config_flags%open_ye) THEN
10357 IF (degrade_ye) j_end = MIN(jte+1,jde-2)
10360 !-- here is the limiter...
10362 DO j=j_start, j_end
10364 DO i=i_start, i_end
10366 ! ----------------------------------------------------------------------------------------------
10368 ! We need to correct for the partial divergence created by the IEVA scheme.
10369 ! If there is no implicit vertical advection, this term == 1.0.
10370 ! Else, it rescales the qmax & qmin value to reflect the partial divergence present in both the
10371 ! low-order and high-order fluxes because the VV field is partioned.
10372 ! ----------------------------------------------------------------------------------------------
10374 ieva_corr = (c1(k)*mut(i,j)+c2(k))+dt*msfty(i,j)*rdzw(k)*(romI(i,k+1,j)-romI(i,k,j))
10376 ! ----------------------------------------------------------------------------------------------
10378 ph_upwind = ((c1(k)*mub(i,j)+c2(k))+(c1(k)*mu_old(i,j)))*field_old(i,k,j) &
10379 - dt*( msftx(i,j)*msfty(i,j)*( &
10380 rdx*(fqxl(i+1,k,j)-fqxl(i,k,j)) + &
10381 rdy*(fqyl(i,k,j+1)-fqyl(i,k,j)) ) &
10382 +msfty(i,j)*rdzw(k)*(fqzl(i,k+1,j)-fqzl(i,k,j)) )
10384 flux_in = -dt*( (msftx(i,j)*msfty(i,j))*( &
10385 rdx*( min(0.,fqx (i+1,k,j)) &
10386 -max(0.,fqx (i ,k,j)) ) &
10387 +rdy*( min(0.,fqy (i,k,j+1)) &
10388 -max(0.,fqy (i,k,j )) ) ) &
10389 +msfty(i,j)*rdzw(k)*( max(0.,fqz (i,k+1,j)) &
10390 -min(0.,fqz (i,k ,j)) ) )
10392 ph_hi = ieva_corr*qmax(i,k,j) - ph_upwind
10394 IF( flux_in .gt. ph_hi ) scale_in(i,k,j) = max(0.,ph_hi/(flux_in+eps))
10397 flux_out = dt*( (msftx(i,j)*msfty(i,j))*( &
10398 rdx*( max(0.,fqx (i+1,k,j)) &
10399 -min(0.,fqx (i ,k,j)) ) &
10400 +rdy*( max(0.,fqy (i,k,j+1)) &
10401 -min(0.,fqy (i,k,j )) ) ) &
10402 +msfty(i,j)*rdzw(k)*( min(0.,fqz (i,k+1,j)) &
10403 -max(0.,fqz (i,k ,j)) ) )
10405 ph_low = ph_upwind - ieva_corr*qmin(i,k,j)
10407 IF( flux_out .gt. ph_low ) scale_out(i,k,j) = max(0.,ph_low/(flux_out+eps))
10413 DO j=j_start, j_end
10415 DO i=i_start, i_end+1
10416 IF( fqx (i,k,j) .gt. 0.) then
10417 fqx(i,k,j) = min(scale_in(i,k,j),scale_out(i-1,k,j))*fqx(i,k,j)
10419 fqx(i,k,j) = min(scale_out(i,k,j),scale_in(i-1,k,j))*fqx(i,k,j)
10425 DO j=j_start, j_end+1
10427 DO i=i_start, i_end
10428 IF( fqy (i,k,j) .gt. 0.) then
10429 fqy(i,k,j) = min(scale_in(i,k,j),scale_out(i,k,j-1))*fqy(i,k,j)
10431 fqy(i,k,j) = min(scale_out(i,k,j),scale_in(i,k,j-1))*fqy(i,k,j)
10437 DO j=j_start, j_end
10439 DO i=i_start, i_end
10440 IF( fqz (i,k,j) .lt. 0.) then
10441 fqz(i,k,j) = min(scale_in(i,k,j),scale_out(i,k-1,j))*fqz(i,k,j)
10443 fqz(i,k,j) = min(scale_out(i,k,j),scale_in(i,k-1,j))*fqz(i,k,j)
10451 ! add in the mono-limited flux divergence
10452 ! we need to fix this for open b.c set ***********
10455 i_end = MIN(ite,ide-1)
10457 j_end = MIN(jte,jde-1)
10459 DO j = j_start, j_end
10461 DO i = i_start, i_end
10463 tendency (i,k,j) = tendency(i,k,j) &
10464 -rdzw(k)*( fqz (i,k+1,j)-fqz (i,k,j) &
10465 +fqzl(i,k+1,j)-fqzl(i,k,j))
10472 DO j = j_start, j_end
10474 DO i = i_start, i_end
10476 z_tendency (i,k,j) = 0. -rdzw(k)*( fqz (i,k+1,j)-fqz (i,k,j) &
10477 +fqzl(i,k+1,j)-fqzl(i,k,j))
10484 ! x flux divergence
10488 ! IF(degrade_xs) i_start = i_start + 1
10489 ! IF(degrade_xe) i_end = i_end - 1
10491 IF(degrade_xs) i_start = MAX(its,ids+1)
10492 IF(degrade_xe) i_end = MIN(ite,ide-2)
10494 DO j = j_start, j_end
10496 DO i = i_start, i_end
10498 ! Un-"canceled" map scale factor, ADT Eq. 48
10499 tendency (i,k,j) = tendency(i,k,j) &
10500 - msftx(i,j)*( rdx*( fqx (i+1,k,j)-fqx (i,k,j) &
10501 +fqxl(i+1,k,j)-fqxl(i,k,j)) )
10508 DO j = j_start, j_end
10510 DO i = i_start, i_end
10512 h_tendency (i,k,j) = 0. &
10513 - msftx(i,j)*( rdx*( fqx (i+1,k,j)-fqx (i,k,j) &
10514 +fqxl(i+1,k,j)-fqxl(i,k,j)) )
10521 ! y flux divergence
10524 i_end = MIN(ite,ide-1)
10527 ! IF(degrade_ys) j_start = j_start + 1
10528 ! IF(degrade_ye) j_end = j_end - 1
10530 IF(degrade_ys) j_start = MAX(jts,jds+1)
10531 IF(degrade_ye) j_end = MIN(jte,jde-2)
10533 DO j = j_start, j_end
10535 DO i = i_start, i_end
10537 ! Un-"canceled" map scale factor, ADT Eq. 48
10538 tendency (i,k,j) = tendency(i,k,j) &
10539 - msftx(i,j)*( rdy*( fqy (i,k,j+1)-fqy (i,k,j) &
10540 +fqyl(i,k,j+1)-fqyl(i,k,j)) )
10547 DO j = j_start, j_end
10549 DO i = i_start, i_end
10551 h_tendency (i,k,j) = h_tendency (i,k,j) &
10552 - msftx(i,j)*( rdy*( fqy (i,k,j+1)-fqy (i,k,j) &
10553 +fqyl(i,k,j+1)-fqyl(i,k,j)) )
10560 END SUBROUTINE advect_scalar_mono
10562 !-----------------------------------------------------------
10564 #ifdef ADVECT_KERNEL
10566 END MODULE advection_kernel
10567 !================================================================
10568 !================================================================
10570 USE advection_kernel
10572 INTEGER , PARAMETER :: MAX_SCALARS = 1
10573 TYPE(grid_config_rec_type) :: config_flags
10574 LOGICAL :: tenddec = .false.
10575 INTEGER :: ids, ide, jds, jde, kds, kde, &
10576 ims, ime, jms, jme, kms, kme, &
10577 its, ite, jts, jte, kts, kte
10578 REAL , DIMENSION( :,:,:,: ) , ALLOCATABLE :: field, &
10580 REAL , DIMENSION( :,:,: ) , ALLOCATABLE :: ru, &
10584 REAL , DIMENSION( :,: ), ALLOCATABLE :: mut, mub, mu_old
10585 REAL , DIMENSION( :,:,: ), ALLOCATABLE :: tendency
10586 REAL , DIMENSION( :,:,: ), ALLOCATABLE :: h_tendency, z_tendency
10587 REAL , DIMENSION( :,: ), ALLOCATABLE :: msfux, &
10593 REAL , DIMENSION( : ), ALLOCATABLE :: fzm, &
10596 rdzw, znw,dnw, rdnw, dn, rdn
10600 INTEGER :: time_step, im
10601 INTEGER :: i, j, k, n, loop
10603 config_flags%scalar_adv_opt = 2
10605 PRINT *,'Init dimensions'
10606 ids = 1; ide = 91; jds = 1; jde = 3; kds = 1; kde =10
10607 ims = -5; ime = 96; jms = -5; jme = 8; kms = 1; kme = 10
10608 its = 1; ite = 91; jts = 1; jte = 3; kts = 1; kte = 10
10609 PRINT *,'ALLOCATE two 4d fields'
10610 PRINT *,(ime-ims+1)*(kme-kms+1)*(jme-jms+1)*MAX_SCALARS
10611 ALLOCATE ( field(ims:ime , kms:kme , jms:jme, MAX_SCALARS ) )
10612 ALLOCATE ( field_old(ims:ime , kms:kme , jms:jme, MAX_SCALARS ) )
10613 PRINT *,'ALLOCATE three 3d fields U, V, W'
10614 PRINT *,(ime-ims+1)*(kme-kms+1)*(jme-jms+1)
10615 ALLOCATE ( ru(ims:ime , kms:kme , jms:jme ) )
10616 ALLOCATE ( rv(ims:ime , kms:kme , jms:jme ) )
10617 ALLOCATE ( rom(ims:ime , kms:kme , jms:jme ) )
10618 ALLOCATE ( romI(ims:ime , kms:kme , jms:jme ) )
10619 PRINT *,'ALLOCATE three 2d MU fields'
10620 PRINT *,(ime-ims+1)*(jme-jms+1)
10621 ALLOCATE ( mut(ims:ime , jms:jme) )
10622 ALLOCATE ( mub(ims:ime , jms:jme) )
10623 ALLOCATE ( mu_old(ims:ime , jms:jme) )
10624 PRINT *,'ALLOCATE three 3d tendency'
10625 PRINT *,(ime-ims+1)*(kme-kms+1)*(jme-jms+1)
10626 ALLOCATE ( tendency( ims:ime , kms:kme , jms:jme ) )
10627 ALLOCATE ( h_tendency( ims:ime , kms:kme , jms:jme ) )
10628 ALLOCATE ( z_tendency( ims:ime , kms:kme , jms:jme ) )
10629 PRINT *,'ALLOCATE six 2d map factors'
10630 PRINT *,(ime-ims+1)*(jme-jms+1)
10631 ALLOCATE ( msfux( ims:ime , jms:jme ) )
10632 ALLOCATE ( msfuy( ims:ime , jms:jme ) )
10633 ALLOCATE ( msfvx( ims:ime , jms:jme ) )
10634 ALLOCATE ( msfvy( ims:ime , jms:jme ) )
10635 ALLOCATE ( msftx( ims:ime , jms:jme ) )
10636 ALLOCATE ( msfty( ims:ime , jms:jme ) )
10637 PRINT *,'ALLOCATE 1d arrays'
10638 ALLOCATE ( fzm( kms:kme ) )
10639 ALLOCATE ( fzp( kms:kme ) )
10640 ALLOCATE ( rdzw( kms:kme ) )
10641 ALLOCATE ( znw( kms:kme ) )
10642 ALLOCATE ( dnw( kms:kme ) )
10643 ALLOCATE (rdnw( kms:kme ) )
10644 ALLOCATE ( dn ( kms:kme ) )
10645 ALLOCATE (rdn ( kms:kme ) )
10646 ALLOCATE ( c1 ( kms:kme ) )
10647 ALLOCATE ( c2 ( kms:kme ) )
10648 PRINT *,'CALL init'
10649 CALL init ( config_flags)
10650 CALL tophat ( field , MAX_SCALARS ,&
10651 ids, ide, jds, jde, kds, kde, &
10652 ims, ime, jms, jme, kms, kme, &
10653 its, ite, jts, jte, kts, kte )
10654 CALL tophat ( field_old , MAX_SCALARS , &
10655 ids, ide, jds, jde, kds, kde, &
10656 ims, ime, jms, jme, kms, kme, &
10657 its, ite, jts, jte, kts, kte )
10676 znw(k) = 1 - (real(k)-kts)/(real(kte)-kts)
10679 rdzw(k) = 1./(znw(k)-znw(k+1))
10682 dnw(k) = znw(k+1) - znw(k)
10683 rdnw(k) = 1./dnw(k)
10686 dn(k) = 0.5*(dnw(k)+dnw(k-1))
10688 fzp(k) = .5* dnw(k )/dn(k)
10689 fzm(k) = .5* dnw(k-1)/dn(k)
10692 c1(k) = 1. ! This is d(B)/d(eta), so assuming no hyb coord
10693 c2(k) = 0. ! This (1 - c1)*(p00 - ptop)
10701 ! Loop over advection enough times to get some meaningful timings.
10702 CALL column ( 0 , field(:,1,2,1) , its, ite )
10704 ! A representative number of times to call the advection in a time period.
10705 IF ( loop .EQ. ((loop)/200)*200 )THEN
10706 PRINT *,'LOOP over scalars',loop
10708 DO im = 1 , MAX_SCALARS
10711 CALL advect_scalar ( field(ims,kms,jms,im), &
10712 field_old(ims,kms,jms,im), &
10713 tendency(ims,kms,jms), &
10714 ru, rv, rom, c1, c2, &
10715 mut, time_step/3, config_flags,&
10716 msfux, msfuy, msfvx, msfvy, &
10720 ids, ide, jds, jde, kds, kde, &
10721 ims, ime, jms, jme, kms, kme, &
10722 its, ite, jts, jte, kts, kte )
10723 DO n = 1 , MAX_SCALARS
10724 field(:,:,:,n) = field_old(:,:,:,n) + dt * tendency(:,:,:) / 3.
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/2, 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 DO n = 1 , MAX_SCALARS
10741 field(:,:,:,n) = field_old(:,:,:,n) + dt * tendency(:,:,:) / 2.
10745 IF (config_flags%scalar_adv_opt .EQ. 0 ) THEN
10746 CALL advect_scalar ( field(ims,kms,jms,im), &
10747 field_old(ims,kms,jms,im), &
10748 tendency(ims,kms,jms), &
10749 ru, rv, rom, c1, c2, &
10750 mut, time_step, config_flags, &
10751 msfux, msfuy, msfvx, msfvy, &
10755 ids, ide, jds, jde, kds, kde, &
10756 ims, ime, jms, jme, kms, kme, &
10757 its, ite, jts, jte, kts, kte )
10758 ELSE IF (config_flags%scalar_adv_opt .EQ. 1 ) THEN
10759 CALL advect_scalar_pd ( field(ims,kms,jms,im), &
10760 field_old(ims,kms,jms,im), &
10761 tendency(ims,kms,jms), &
10762 h_tendency(ims,kms,jms), &
10763 z_tendency(ims,kms,jms), &
10764 ru, rv, rom, c1, c2, &
10765 mut, mub, mu_old, &
10766 time_step, config_flags, tenddec, &
10767 msfux, msfuy, msfvx, msfvy, &
10768 msftx, msfty, fzm, fzp, &
10769 rdx, rdy, rdzw,dt, &
10770 ids, ide, jds, jde, kds, kde, &
10771 ims, ime, jms, jme, kms, kme, &
10772 its, ite, jts, jte, kts, kte )
10773 ELSE IF (config_flags%scalar_adv_opt .EQ. 2 ) THEN
10774 CALL advect_scalar_mono ( field(ims,kms,jms,im), &
10775 field_old(ims,kms,jms,im), &
10776 tendency(ims,kms,jms), &
10777 h_tendency(ims,kms,jms), &
10778 z_tendency(ims,kms,jms), &
10779 ru, rv, rom, romI, &
10781 mut, mub, mu_old, &
10782 config_flags, tenddec, &
10783 msfux, msfuy, msfvx, msfvy, &
10784 msftx, msfty, fzm, fzp, &
10785 rdx, rdy, rdzw,dt, &
10786 ids, ide, jds, jde, kds, kde, &
10787 ims, ime, jms, jme, kms, kme, &
10788 its, ite, jts, jte, kts, kte )
10789 ELSE IF (config_flags%scalar_adv_opt .EQ. 3 ) THEN
10790 CALL advect_scalar_weno ( field(ims,kms,jms,im), &
10791 field_old(ims,kms,jms,im), &
10792 tendency(ims,kms,jms), &
10795 mut, time_step, config_flags, &
10796 msfux, msfuy, msfvx, msfvy, &
10800 ids, ide, jds, jde, kds, kde, &
10801 ims, ime, jms, jme, kms, kme, &
10802 its, ite, jts, jte, kts, kte )
10803 ELSE IF (config_flags%scalar_adv_opt .EQ. 4 ) THEN
10804 CALL advect_scalar_wenopd ( field(ims,kms,jms,im), &
10805 field_old(ims,kms,jms,im), &
10806 tendency(ims,kms,jms), &
10809 mut, mub, mu_old, &
10810 time_step, config_flags, &
10811 msfux, msfuy, msfvx, msfvy, &
10814 rdx, rdy, rdzw, dt, &
10815 ids, ide, jds, jde, kds, kde, &
10816 ims, ime, jms, jme, kms, kme, &
10817 its, ite, jts, jte, kts, kte )
10819 DO n = 1 , MAX_SCALARS
10820 field(:,:,:,n) = field_old(:,:,:,n) + dt * ( tendency(:,:,:) )
10824 field (:,k,:,:) = field (:,2,:,:)
10827 field (:,:,2,:) = field (:,:,1,:)
10828 field (:,:,3,:) = field (:,:,1,:)
10830 field (ite+0,:,:,:) = field(ids+0,:,:,:)
10831 field (ite+1,:,:,:) = field(ids+1,:,:,:)
10832 field (ite+2,:,:,:) = field(ids+2,:,:,:)
10833 field (ite+3,:,:,:) = field(ids+3,:,:,:)
10834 field (ite+4,:,:,:) = field(ids+4,:,:,:)
10835 field (ids-0,:,:,:) = field(ite-0,:,:,:)
10836 field (ids-1,:,:,:) = field(ite-1,:,:,:)
10837 field (ids-2,:,:,:) = field(ite-2,:,:,:)
10838 field (ids-3,:,:,:) = field(ite-3,:,:,:)
10839 field (ids-4,:,:,:) = field(ite-4,:,:,:)
10843 IF ( loop .EQ. (loop/200)*200 ) THEN
10844 CALL column ( loop , field(:,1,2,1) , its, ite )
10850 print *,'=============================== '
10852 print *,'Lines to input to gnuplot'
10854 print *,"set terminal x11"
10855 IF (config_flags%scalar_adv_opt .EQ. 0 ) THEN
10856 print *,'set title "Scalar Advection" font ",20"'
10857 ELSE IF (config_flags%scalar_adv_opt .EQ. 1 ) THEN
10858 print *,'set title "PD Advection" font ",20"'
10859 ELSE IF (config_flags%scalar_adv_opt .EQ. 2 ) THEN
10860 print *,'set title "Mono Advection" font ",20"'
10861 ELSE IF (config_flags%scalar_adv_opt .EQ. 3 ) THEN
10862 print *,'set title "WENO Advection" font ",20"'
10863 ELSE IF (config_flags%scalar_adv_opt .EQ. 4 ) THEN
10864 print *,'set title "WENO PD Advection" font ",20"'
10866 print *,"set yrange[-20:120]"
10867 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 "
10868 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 "
10872 #ifndef ADVECT_KERNEL
10874 !---------------------------------------------------------------------------------
10876 SUBROUTINE advect_weno_u ( u, u_old, tendency, &
10879 mut, time_step, config_flags, &
10880 msfux, msfuy, msfvx, msfvy, &
10884 ids, ide, jds, jde, kds, kde, &
10885 ims, ime, jms, jme, kms, kme, &
10886 its, ite, jts, jte, kts, kte )
10889 ! 5th-order WENO (Weighted Essentially Non-Oscillatory) scheme adapted from COMMAS.
10890 ! See Jiang and Shu, 1996, J. Comp. Phys. v. 126, 202-223;
10891 ! Shu 2003, Int. J. Comp. Fluid Dyn. v. 17 107-118; Also used by Bryan 2005, Mon. Wea. Rev.
10898 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
10900 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
10901 ims, ime, jms, jme, kms, kme, &
10902 its, ite, jts, jte, kts, kte
10904 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: u, &
10910 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut
10911 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
10913 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
10920 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
10926 REAL , INTENT(IN ) :: rdx, &
10928 INTEGER , INTENT(IN ) :: time_step
10932 INTEGER :: i, j, k, itf, jtf, ktf
10933 INTEGER :: i_start, i_end, j_start, j_end
10934 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
10935 INTEGER :: jmin, jmax, jp, jm, imin, imax, im, ip
10936 INTEGER :: jp1, jp0, jtmp
10939 real :: ue,vs,vn,wb,wt
10940 real, parameter :: f30 = 7./12., f31 = 1./12.
10941 real, parameter :: f50 = 37./60., f51 = 2./15., f52 = 1./60.
10947 real :: qim2, qim1, qi, qip1, qip2
10948 double precision :: beta0, beta1, beta2, f0, f1, f2, wi0, wi1, wi2, sumwk
10949 double precision, parameter :: gi0 = 1.d0/10.d0, gi1 = 6.d0/10.d0, gi2 = 3.d0/10.d0, eps=1.0d-18
10950 integer, parameter :: pw = 2
10953 INTEGER :: horz_order, vert_order
10955 REAL :: mrdx, mrdy, ub, vb, uw, vw, dvm, dvp
10956 REAL , DIMENSION(its:ite, kts:kte) :: vflux
10959 REAL, DIMENSION( its-1:ite+1, kts:kte ) :: fqx
10960 REAL, DIMENSION( its:ite, kts:kte, 2) :: fqy
10962 LOGICAL :: degrade_xs, degrade_ys
10963 LOGICAL :: degrade_xe, degrade_ye
10965 ! definition of flux operators, 3rd, 4th, 5th or 6th order
10967 REAL :: flux3, flux4, flux5, flux6
10968 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel
10970 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
10971 ( 7.*(q_i + q_im1) - (q_ip1 + q_im2) )/12.0
10973 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
10974 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
10975 sign(1,time_step)*sign(1.,ua)*((q_ip1 - q_im2)-3.*(q_i-q_im1))/12.0
10977 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
10978 ( 37.*(q_i+q_im1) - 8.*(q_ip1+q_im2) &
10979 +(q_ip2+q_im3) )/60.0
10981 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
10982 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
10983 -sign(1,time_step)*sign(1.,ua)*( &
10984 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )/60.0
10987 LOGICAL :: specified
10989 specified = .false.
10990 if(config_flags%specified .or. config_flags%nested) specified = .true.
10992 ! set order for vertical and horzontal flux operators
10994 horz_order = config_flags%h_mom_adv_order
10995 vert_order = config_flags%v_mom_adv_order
10999 ! begin with horizontal flux divergence
11001 ! horizontal_order_test : IF( horz_order == 6 ) THEN
11003 ! ELSE IF( horz_order == 5 ) THEN
11005 ! 5th order horizontal flux calculation
11006 ! This code is EXACTLY the same as the 6th order code
11007 ! EXCEPT the 5th order and 3rd operators are used in
11008 ! place of the 6th and 4th order operators
11010 ! determine boundary mods for flux operators
11011 ! We degrade the flux operators from 3rd/4th order
11012 ! to second order one gridpoint in from the boundaries for
11013 ! all boundary conditions except periodic and symmetry - these
11014 ! conditions have boundary zone data fill for correct application
11015 ! of the higher order flux stencils
11017 degrade_xs = .true.
11018 degrade_xe = .true.
11019 degrade_ys = .true.
11020 degrade_ye = .true.
11022 IF( config_flags%periodic_x .or. &
11023 config_flags%symmetric_xs .or. &
11024 (its > ids+3) ) degrade_xs = .false.
11025 IF( config_flags%periodic_x .or. &
11026 config_flags%symmetric_xe .or. &
11027 (ite < ide-2) ) degrade_xe = .false.
11028 IF( config_flags%periodic_y .or. &
11029 config_flags%symmetric_ys .or. &
11030 (jts > jds+3) ) degrade_ys = .false.
11031 IF( config_flags%periodic_y .or. &
11032 config_flags%symmetric_ye .or. &
11033 (jte < jde-4) ) degrade_ye = .false.
11035 !--------------- y - advection first
11039 IF ( config_flags%open_xs .or. specified ) i_start = MAX(ids+1,its)
11040 IF ( config_flags%open_xe .or. specified ) i_end = MIN(ide-1,ite)
11041 IF ( config_flags%periodic_x ) i_start = its
11042 IF ( config_flags%periodic_x ) i_end = ite
11045 j_end = MIN(jte,jde-1)
11047 ! higher order flux has a 5 or 7 point stencil, so compute
11048 ! bounds so we can switch to second order flux close to the boundary
11050 j_start_f = j_start
11053 IF(degrade_ys) then
11054 j_start = MAX(jts,jds+1)
11058 IF(degrade_ye) then
11059 j_end = MIN(jte,jde-2)
11063 IF(config_flags%polar) j_end = MIN(jte,jde-1)
11065 ! compute fluxes, 5th or 6th order
11070 j_loop_y_flux_5 : DO j = j_start, j_end+1
11072 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN ! use full stencil
11075 DO i = i_start, i_end
11076 vel = 0.5*(rv(i,k,j)+rv(i-1,k,j))
11078 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
11092 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
11093 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
11094 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
11096 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
11097 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
11098 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
11100 wi0 = gi0 / (eps + beta0)**pw
11101 wi1 = gi1 / (eps + beta1)**pw
11102 wi2 = gi2 / (eps + beta2)**pw
11104 sumwk = wi0 + wi1 + wi2
11106 fqy( i, k, jp1 ) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
11108 ! fqy( i, k, jp1 ) = vel*flux5( &
11109 ! u(i,k,j-3), u(i,k,j-2), u(i,k,j-1), &
11110 ! u(i,k,j ), u(i,k,j+1), u(i,k,j+2), vel )
11114 ! we must be close to some boundary where we need to reduce the order of the stencil
11116 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
11119 DO i = i_start, i_end
11120 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i-1,k,j)) &
11121 *(u(i,k,j)+u(i,k,j-1))
11125 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
11128 DO i = i_start, i_end
11129 vel = 0.5*(rv(i,k,j)+rv(i-1,k,j))
11130 fqy( i, k, jp1 ) = vel*flux3( &
11131 u(i,k,j-2),u(i,k,j-1), u(i,k,j),u(i,k,j+1),vel )
11135 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
11138 DO i = i_start, i_end
11139 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i-1,k,j)) &
11140 *(u(i,k,j)+u(i,k,j-1))
11144 ELSE IF ( j == jde-2 ) THEN ! 3rd order flux 2 in from north boundary
11147 DO i = i_start, i_end
11148 vel = 0.5*(rv(i,k,j)+rv(i-1,k,j))
11149 fqy( i, k, jp1 ) = vel*flux3( &
11150 u(i,k,j-2),u(i,k,j-1), &
11151 u(i,k,j),u(i,k,j+1),vel )
11157 ! y flux-divergence into tendency
11159 ! (j > j_start) will miss the u(,,jds) tendency
11160 IF ( config_flags%polar .AND. (j == jds+1) ) 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)
11167 ! This would be seen by (j > j_start) but we need to zero out the NP tendency
11168 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
11170 DO i = i_start, i_end
11171 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
11172 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
11177 IF(j > j_start) THEN
11180 DO i = i_start, i_end
11181 mrdy=msfux(i,j-1)*rdy ! ADT eqn 44, 2nd term on RHS
11182 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
11195 ENDDO j_loop_y_flux_5
11197 ! next, x - flux divergence
11203 j_end = MIN(jte,jde-1)
11205 ! higher order flux has a 5 or 7 point stencil, so compute
11206 ! bounds so we can switch to second order flux close to the boundary
11208 i_start_f = i_start
11211 IF(degrade_xs) then
11212 i_start = MAX(ids+1,its)
11216 IF(degrade_xe) then
11217 i_end = MIN(ide-1,ite)
11223 DO j = j_start, j_end
11225 ! 5th or 6th order flux
11228 DO i = i_start_f, i_end_f
11229 vel = 0.5*(ru(i,k,j)+ru(i-1,k,j))
11231 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
11245 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
11246 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
11247 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
11249 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
11250 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
11251 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
11253 wi0 = gi0 / (eps + beta0)**pw
11254 wi1 = gi1 / (eps + beta1)**pw
11255 wi2 = gi2 / (eps + beta2)**pw
11257 sumwk = wi0 + wi1 + wi2
11259 fqx(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
11261 ! fqx( i,k ) = vel*flux5( u(i-3,k,j), u(i-2,k,j), &
11262 ! u(i-1,k,j), u(i ,k,j), &
11263 ! u(i+1,k,j), u(i+2,k,j), &
11268 ! lower order fluxes close to boundaries (if not periodic or symmetric)
11269 ! specified uses upstream normal wind at boundaries
11271 IF( degrade_xs ) THEN
11273 IF( i_start == ids+1 ) THEN ! second order flux next to the boundary
11277 IF (specified .AND. u(i,k,j) .LT. 0.)ub = u(i,k,j)
11278 fqx(i, k) = 0.25*(ru(i,k,j)+ru(i-1,k,j)) &
11285 vel = 0.5*(ru(i,k,j)+ru(i-1,k,j))
11286 fqx( i, k ) = vel*flux3( u(i-2,k,j), u(i-1,k,j), &
11287 u(i ,k,j), u(i+1,k,j), &
11293 IF( degrade_xe ) THEN
11295 IF( i_end == ide-1 ) THEN ! second order flux next to the boundary
11299 IF (specified .AND. u(i-1,k,j) .GT. 0.)ub = u(i-1,k,j)
11300 fqx(i, k) = 0.25*(ru(i,k,j)+ru(i-1,k,j)) &
11307 vel = 0.5*(ru(i,k,j)+ru(i-1,k,j))
11308 fqx( i,k ) = vel*flux3( u(i-2,k,j), u(i-1,k,j), &
11309 u(i ,k,j), u(i+1,k,j), &
11315 ! x flux-divergence into tendency
11318 DO i = i_start, i_end
11319 mrdx=msfux(i,j)*rdx ! ADT eqn 44, 1st term on RHS
11320 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
11327 ! radiative lateral boundary condition in x for normal velocity (u)
11329 IF ( (config_flags%open_xs) .and. its == ids ) THEN
11332 j_end = MIN(jte,jde-1)
11334 DO j = j_start, j_end
11336 ub = MIN(ru(its,k,j)-cb*(c1(k)*mut(its,j)+c2(k)), 0.)
11337 tendency(its,k,j) = tendency(its,k,j) &
11338 - rdx*ub*(u_old(its+1,k,j) - u_old(its,k,j))
11344 IF ( (config_flags%open_xe) .and. ite == ide ) THEN
11347 j_end = MIN(jte,jde-1)
11349 DO j = j_start, j_end
11351 ub = MAX(ru(ite,k,j)+cb*(c1(k)*mut(ite-1,j)+c2(k)), 0.)
11352 tendency(ite,k,j) = tendency(ite,k,j) &
11353 - rdx*ub*(u_old(ite,k,j) - u_old(ite-1,k,j))
11359 ! pick up the rest of the horizontal radiation boundary conditions.
11360 ! (these are the computations that don't require 'cb')
11361 ! first, set to index ranges
11364 i_end = MIN(ite,ide)
11368 IF (config_flags%open_xs) THEN
11369 i_start = MAX(ids+1, its)
11372 IF (config_flags%open_xe) THEN
11373 i_end = MIN(ite,ide-1)
11377 IF( (config_flags%open_ys) .and. (jts == jds)) THEN
11379 DO i = i_start, i_end
11381 mrdy=msfux(i,jts)*rdy ! ADT eqn 44, 2nd term on RHS
11382 ip = MIN( imax, i )
11383 im = MAX( imin, i-1 )
11387 vw = 0.5*(rv(ip,k,jts)+rv(im,k,jts))
11389 dvm = rv(ip,k,jts+1)-rv(ip,k,jts)
11390 dvp = rv(im,k,jts+1)-rv(im,k,jts)
11391 tendency(i,k,jts)=tendency(i,k,jts)-mrdy*( &
11392 vb*(u_old(i,k,jts+1)-u_old(i,k,jts)) &
11393 +0.5*u(i,k,jts)*(dvm+dvp))
11399 IF( (config_flags%open_ye) .and. (jte == jde)) THEN
11401 DO i = i_start, i_end
11403 mrdy=msfux(i,jte-1)*rdy ! ADT eqn 44, 2nd term on RHS
11404 ip = MIN( imax, i )
11405 im = MAX( imin, i-1 )
11409 vw = 0.5*(rv(ip,k,jte)+rv(im,k,jte))
11411 dvm = rv(ip,k,jte)-rv(ip,k,jte-1)
11412 dvp = rv(im,k,jte)-rv(im,k,jte-1)
11413 tendency(i,k,jte-1)=tendency(i,k,jte-1)-mrdy*( &
11414 vb*(u_old(i,k,jte-1)-u_old(i,k,jte-2)) &
11415 +0.5*u(i,k,jte-1)*(dvm+dvp))
11421 !-------------------- vertical advection
11422 ! ADT eqn 44 has 3rd term on RHS = -(1/my) partial d/dz (rho u w)
11423 ! Here we have: - partial d/dz (u*rom) = - partial d/dz (u rho w / my)
11424 ! Since 'my' (map scale factor in y-direction) isn't a function of z,
11425 ! this is what we need, so leave unchanged in advect_u
11430 j_end = min(jte,jde-1)
11432 ! IF ( config_flags%open_xs ) i_start = MAX(ids+1,its)
11433 ! IF ( config_flags%open_xe ) i_end = MIN(ide-1,ite)
11435 IF ( config_flags%open_ys .or. specified ) i_start = MAX(ids+1,its)
11436 IF ( config_flags%open_ye .or. specified ) i_end = MIN(ide-1,ite)
11437 IF ( config_flags%periodic_x ) i_start = its
11438 IF ( config_flags%periodic_x ) i_end = ite
11440 DO i = i_start, i_end
11445 ! vert_order_test : IF (vert_order == 6) THEN
11447 ! ELSE IF (vert_order == 5) THEN
11449 DO j = j_start, j_end
11452 DO i = i_start, i_end
11453 vel=0.5*(rom(i-1,k,j)+rom(i,k,j))
11455 IF( -vel*sign(1,time_step) .ge. 0.0 ) THEN
11469 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
11470 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
11471 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
11473 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
11474 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
11475 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
11477 wi0 = gi0 / (eps + beta0)**pw
11478 wi1 = gi1 / (eps + beta1)**pw
11479 wi2 = gi2 / (eps + beta2)**pw
11481 sumwk = wi0 + wi1 + wi2
11483 vflux(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
11485 ! vflux(i,k) = vel*flux5( &
11486 ! u(i,k-3,j), u(i,k-2,j), u(i,k-1,j), &
11487 ! u(i,k ,j), u(i,k+1,j), u(i,k+2,j), -vel )
11491 DO i = i_start, i_end
11494 vflux(i,k)=0.5*(rom(i,k,j)+rom(i-1,k,j)) &
11495 *(fzm(k)*u(i,k,j)+fzp(k)*u(i,k-1,j))
11497 vel=0.5*(rom(i,k,j)+rom(i-1,k,j))
11498 vflux(i,k) = vel*flux3( &
11499 u(i,k-2,j), u(i,k-1,j), &
11500 u(i,k ,j), u(i,k+1,j), -vel )
11502 vel=0.5*(rom(i,k,j)+rom(i-1,k,j))
11503 vflux(i,k) = vel*flux3( &
11504 u(i,k-2,j), u(i,k-1,j), &
11505 u(i,k ,j), u(i,k+1,j), -vel )
11507 vflux(i,k)=0.5*(rom(i,k,j)+rom(i-1,k,j)) &
11508 *(fzm(k)*u(i,k,j)+fzp(k)*u(i,k-1,j))
11512 DO i = i_start, i_end
11513 tendency(i,k,j)=tendency(i,k,j)-rdzw(k)*(vflux(i,k+1)-vflux(i,k))
11519 END SUBROUTINE advect_weno_u
11521 !-------------------------------------------------------------------------------
11523 SUBROUTINE advect_weno_v ( v, v_old, tendency, &
11526 mut, time_step, config_flags, &
11527 msfux, msfuy, msfvx, msfvy, &
11531 ids, ide, jds, jde, kds, kde, &
11532 ims, ime, jms, jme, kms, kme, &
11533 its, ite, jts, jte, kts, kte )
11536 ! 5th-order WENO (Weighted Essentially Non-Oscillatory) scheme adapted from COMMAS.
11537 ! See Jiang and Shu, 1996, J. Comp. Phys. v. 126, 202-223;
11538 ! Shu 2003, Int. J. Comp. Fluid Dyn. v. 17 107-118; Also used by Bryan 2005, Mon. Wea. Rev.
11545 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
11547 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
11548 ims, ime, jms, jme, kms, kme, &
11549 its, ite, jts, jte, kts, kte
11551 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: v, &
11557 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut
11558 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
11560 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
11567 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
11573 REAL , INTENT(IN ) :: rdx, &
11575 INTEGER , INTENT(IN ) :: time_step
11580 INTEGER :: i, j, k, itf, jtf, ktf
11581 INTEGER :: i_start, i_end, j_start, j_end
11582 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
11583 INTEGER :: jmin, jmax, jp, jm, imin, imax
11586 real :: ue,vs,vn,wb,wt
11587 real, parameter :: f30 = 7./12., f31 = 1./12.
11588 real, parameter :: f50 = 37./60., f51 = 2./15., f52 = 1./60.
11594 real :: qim2, qim1, qi, qip1, qip2
11595 double precision :: beta0, beta1, beta2, f0, f1, f2, wi0, wi1, wi2, sumwk
11596 double precision, parameter :: gi0 = 1.d0/10.d0, gi1 = 6.d0/10.d0, gi2 = 3.d0/10.d0, eps=1.0d-18
11597 integer, parameter :: pw = 2
11600 REAL :: mrdx, mrdy, ub, vb, uw, vw, dup, dum
11601 REAL , DIMENSION(its:ite, kts:kte) :: vflux
11604 REAL, DIMENSION( its:ite+1, kts:kte ) :: fqx
11605 REAL, DIMENSION( its:ite, kts:kte, 2 ) :: fqy
11607 INTEGER :: horz_order
11608 INTEGER :: vert_order
11610 LOGICAL :: degrade_xs, degrade_ys
11611 LOGICAL :: degrade_xe, degrade_ye
11613 INTEGER :: jp1, jp0, jtmp
11616 ! definition of flux operators, 3rd, 4th, 5th or 6th order
11618 REAL :: flux3, flux4, flux5, flux6
11619 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel
11621 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
11622 ( 7.*(q_i + q_im1) - (q_ip1 + q_im2) )/12.0
11624 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
11625 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
11626 sign(1,time_step)*sign(1.,ua)*((q_ip1 - q_im2)-3.*(q_i-q_im1))/12.0
11628 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
11629 ( 37.*(q_i+q_im1) - 8.*(q_ip1+q_im2) &
11630 +(q_ip2+q_im3) )/60.0
11632 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
11633 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
11634 -sign(1,time_step)*sign(1.,ua)*( &
11635 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )/60.0
11639 LOGICAL :: specified
11641 specified = .false.
11642 if(config_flags%specified .or. config_flags%nested) specified = .true.
11644 ! set order for the advection schemes
11647 horz_order = config_flags%h_mom_adv_order
11648 vert_order = config_flags%v_mom_adv_order
11651 ! here is the choice of flux operators
11654 ! horizontal_order_test : IF( horz_order == 6 ) THEN
11655 ! ELSE IF( horz_order == 5 ) THEN
11657 ! 5th order horizontal flux calculation
11658 ! This code is EXACTLY the same as the 6th order code
11659 ! EXCEPT the 5th order and 3rd operators are used in
11660 ! place of the 6th and 4th order operators
11662 ! determine boundary mods for flux operators
11663 ! We degrade the flux operators from 3rd/4th order
11664 ! to second order one gridpoint in from the boundaries for
11665 ! all boundary conditions except periodic and symmetry - these
11666 ! conditions have boundary zone data fill for correct application
11667 ! of the higher order flux stencils
11669 degrade_xs = .true.
11670 degrade_xe = .true.
11671 degrade_ys = .true.
11672 degrade_ye = .true.
11674 IF( config_flags%periodic_x .or. &
11675 config_flags%symmetric_xs .or. &
11676 (its > ids+3) ) degrade_xs = .false.
11677 IF( config_flags%periodic_x .or. &
11678 config_flags%symmetric_xe .or. &
11679 (ite < ide-3) ) degrade_xe = .false.
11680 IF( config_flags%periodic_y .or. &
11681 config_flags%symmetric_ys .or. &
11682 (jts > jds+3) ) degrade_ys = .false.
11683 IF( config_flags%periodic_y .or. &
11684 config_flags%symmetric_ye .or. &
11685 (jte < jde-3) ) degrade_ye = .false.
11687 !--------------- y - advection first
11690 i_end = MIN(ite,ide-1)
11694 ! higher order flux has a 5 or 7 point stencil, so compute
11695 ! bounds so we can switch to second order flux close to the boundary
11697 j_start_f = j_start
11700 IF(degrade_ys) then
11701 j_start = MAX(jts,jds+1)
11705 IF(degrade_ye) then
11706 j_end = MIN(jte,jde-1)
11710 ! compute fluxes, 5th or 6th order
11715 j_loop_y_flux_5 : DO j = j_start, j_end+1
11717 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN
11720 DO i = i_start, i_end
11721 vel = 0.5*(rv(i,k,j)+rv(i,k,j-1))
11723 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
11737 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
11738 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
11739 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
11741 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
11742 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
11743 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
11745 wi0 = gi0 / (eps + beta0)**pw
11746 wi1 = gi1 / (eps + beta1)**pw
11747 wi2 = gi2 / (eps + beta2)**pw
11749 sumwk = wi0 + wi1 + wi2
11751 fqy( i, k, jp1 ) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
11755 ! fqy( i, k, jp1 ) = vel*flux5( &
11756 ! v(i,k,j-3), v(i,k,j-2), v(i,k,j-1), &
11757 ! v(i,k,j ), v(i,k,j+1), v(i,k,j+2), vel )
11761 ! we must be close to some boundary where we need to reduce the order of the stencil
11762 ! specified uses upstream normal wind at boundaries
11764 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
11767 DO i = i_start, i_end
11769 IF (specified .AND. v(i,k,j) .LT. 0.)vb = v(i,k,j)
11770 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i,k,j-1)) &
11775 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
11778 DO i = i_start, i_end
11779 vel = 0.5*(rv(i,k,j)+rv(i,k,j-1))
11780 fqy( i, k, jp1 ) = vel*flux3( &
11781 v(i,k,j-2),v(i,k,j-1),v(i,k,j),v(i,k,j+1),vel )
11786 ELSE IF ( j == jde ) THEN ! 2nd order flux next to north boundary
11789 DO i = i_start, i_end
11791 IF (specified .AND. v(i,k,j-1) .GT. 0.)vb = v(i,k,j-1)
11792 fqy(i, k, jp1) = 0.25*(rv(i,k,j)+rv(i,k,j-1)) &
11797 ELSE IF ( j == jde-1 ) THEN ! 3rd or 4th order flux 2 in from north boundary
11800 DO i = i_start, i_end
11801 vel = 0.5*(rv(i,k,j)+rv(i,k,j-1))
11802 fqy( i, k, jp1 ) = vel*flux3( &
11803 v(i,k,j-2),v(i,k,j-1),v(i,k,j),v(i,k,j+1),vel )
11809 ! y flux-divergence into tendency
11811 ! Comments on polar boundary conditions
11812 ! No advection over the poles means tendencies (held from jds [S. pole]
11813 ! to jde [N pole], i.e., on v grid) must be zero at poles
11814 ! [tendency(jds) and tendency(jde)=0]
11815 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
11817 DO i = i_start, i_end
11818 tendency(i,k,j-1) = 0.
11821 ! If j_end were set to jde in a special if statement apart from
11822 ! degrade_ye, then we would hit the next conditional. But since
11823 ! we want the tendency to be zero anyway, not looping to jde+1
11824 ! will produce the same effect.
11825 ELSE IF( config_flags%polar .AND. (j == jde+1) ) THEN
11827 DO i = i_start, i_end
11828 tendency(i,k,j-1) = 0.
11833 IF(j > j_start) THEN
11836 DO i = i_start, i_end
11837 mrdy=msfvy(i,j-1)*rdy ! ADT eqn 45, 2nd term on RHS
11838 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
11850 ENDDO j_loop_y_flux_5
11852 ! next, x - flux divergence
11855 i_end = MIN(ite,ide-1)
11859 ! Polar boundary conditions are like open or specified
11860 IF ( config_flags%open_ys .or. specified .or. config_flags%polar ) j_start = MAX(jds+1,jts)
11861 IF ( config_flags%open_ye .or. specified .or. config_flags%polar ) j_end = MIN(jde-1,jte)
11863 ! higher order flux has a 5 or 7 point stencil, so compute
11864 ! bounds so we can switch to second order flux close to the boundary
11866 i_start_f = i_start
11869 IF(degrade_xs) then
11870 i_start = MAX(ids+1,its)
11871 ! i_start_f = i_start+2
11872 i_start_f = MIN(i_start+2,ids+3)
11875 IF(degrade_xe) then
11876 i_end = MIN(ide-2,ite)
11882 DO j = j_start, j_end
11884 ! 5th or 6th order flux
11887 DO i = i_start_f, i_end_f
11888 vel = 0.5*(ru(i,k,j)+ru(i,k,j-1))
11890 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
11904 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
11905 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
11906 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
11908 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
11909 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
11910 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
11912 wi0 = gi0 / (eps + beta0)**pw
11913 wi1 = gi1 / (eps + beta1)**pw
11914 wi2 = gi2 / (eps + beta2)**pw
11916 sumwk = wi0 + wi1 + wi2
11918 fqx(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
11920 ! fqx( i, k ) = vel*flux5( v(i-3,k,j), v(i-2,k,j), &
11921 ! v(i-1,k,j), v(i ,k,j), &
11922 ! v(i+1,k,j), v(i+2,k,j), &
11927 ! lower order fluxes close to boundaries (if not periodic or symmetric)
11929 IF( degrade_xs ) THEN
11931 DO i=i_start,i_start_f-1
11933 IF(i == ids+1) THEN ! second order
11935 fqx(i,k) = 0.25*(ru(i,k,j)+ru(i,k,j-1)) &
11936 *(v(i,k,j)+v(i-1,k,j))
11940 IF(i == ids+2) THEN ! third order
11942 vel = 0.5*(ru(i,k,j)+ru(i,k,j-1))
11943 fqx( i,k ) = vel*flux3( v(i-2,k,j), v(i-1,k,j), &
11944 v(i ,k,j), v(i+1,k,j), &
11953 IF( degrade_xe ) THEN
11955 DO i = i_end_f+1, i_end+1
11957 IF( i == ide-1 ) THEN ! second order flux next to the boundary
11959 fqx(i,k) = 0.25*(ru(i_end+1,k,j)+ru(i_end+1,k,j-1)) &
11960 *(v(i_end+1,k,j)+v(i_end,k,j))
11964 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
11966 vel = 0.5*(ru(i,k,j)+ru(i,k,j-1))
11967 fqx( i,k ) = vel*flux3( v(i-2,k,j), v(i-1,k,j), &
11968 v(i ,k,j), v(i+1,k,j), &
11977 ! x flux-divergence into tendency
11980 DO i = i_start, i_end
11981 mrdx=msfvy(i,j)*rdx ! ADT eqn 45, 1st term on RHS
11982 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
11989 ! Comments on polar boundary condition
11990 ! Force tendency=0 at NP and SP
11991 ! We keep setting this everywhere, but it can't hurt...
11992 IF ( config_flags%polar .AND. (jts == jds) ) THEN
11995 tendency(i,k,jts)=0.
11999 IF ( config_flags%polar .AND. (jte == jde) ) THEN
12002 tendency(i,k,jte)=0.
12007 ! radiative lateral boundary condition in y for normal velocity (v)
12009 IF ( (config_flags%open_ys) .and. jts == jds ) THEN
12012 i_end = MIN(ite,ide-1)
12014 DO i = i_start, i_end
12016 vb = MIN(rv(i,k,jts)-cb*(c1(k)*mut(i,jts)+c2(k)), 0.)
12017 tendency(i,k,jts) = tendency(i,k,jts) &
12018 - rdy*vb*(v_old(i,k,jts+1) - v_old(i,k,jts))
12024 IF ( (config_flags%open_ye) .and. jte == jde ) THEN
12027 i_end = MIN(ite,ide-1)
12029 DO i = i_start, i_end
12031 vb = MAX(rv(i,k,jte)+cb*(c1(k)*mut(i,jte-1)+c2(k)), 0.)
12032 tendency(i,k,jte) = tendency(i,k,jte) &
12033 - rdy*vb*(v_old(i,k,jte) - v_old(i,k,jte-1))
12039 ! pick up the rest of the horizontal radiation boundary conditions.
12040 ! (these are the computations that don't require 'cb'.
12041 ! first, set to index ranges
12044 j_end = MIN(jte,jde)
12049 IF (config_flags%open_ys) THEN
12050 j_start = MAX(jds+1, jts)
12053 IF (config_flags%open_ye) THEN
12054 j_end = MIN(jte,jde-1)
12058 ! compute x (u) conditions for v, w, or scalar
12060 IF( (config_flags%open_xs) .and. (its == ids)) THEN
12062 DO j = j_start, j_end
12064 mrdx=msfvy(its,j)*rdx ! ADT eqn 45, 1st term on RHS
12065 jp = MIN( jmax, j )
12066 jm = MAX( jmin, j-1 )
12070 uw = 0.5*(ru(its,k,jp)+ru(its,k,jm))
12072 dup = ru(its+1,k,jp)-ru(its,k,jp)
12073 dum = ru(its+1,k,jm)-ru(its,k,jm)
12074 tendency(its,k,j)=tendency(its,k,j)-mrdx*( &
12075 ub*(v_old(its+1,k,j)-v_old(its,k,j)) &
12076 +0.5*v(its,k,j)*(dup+dum))
12082 IF( (config_flags%open_xe) .and. (ite == ide) ) THEN
12083 DO j = j_start, j_end
12085 mrdx=msfvy(ite-1,j)*rdx ! ADT eqn 45, 1st term on RHS
12086 jp = MIN( jmax, j )
12087 jm = MAX( jmin, j-1 )
12091 uw = 0.5*(ru(ite,k,jp)+ru(ite,k,jm))
12093 dup = ru(ite,k,jp)-ru(ite-1,k,jp)
12094 dum = ru(ite,k,jm)-ru(ite-1,k,jm)
12096 ! tendency(ite-1,k,j)=tendency(ite-1,k,j)-mrdx*( &
12097 ! ub*(v_old(ite-1,k,j)-v_old(ite-2,k,j)) &
12098 ! +0.5*v(ite-1,k,j)* &
12099 ! ( ru(ite,k,jp)-ru(ite-1,k,jp) &
12100 ! +ru(ite,k,jm)-ru(ite-1,k,jm)) )
12101 tendency(ite-1,k,j)=tendency(ite-1,k,j)-mrdx*( &
12102 ub*(v_old(ite-1,k,j)-v_old(ite-2,k,j)) &
12103 +0.5*v(ite-1,k,j)*(dup+dum))
12110 !-------------------- vertical advection
12111 ! ADT eqn 45 has 3rd term on RHS = -(1/mx) partial d/dz (rho v w)
12112 ! Here we have: - partial d/dz (v*rom) = - partial d/dz (v rho w / my)
12113 ! We therefore need to make a correction for advect_v
12114 ! since 'my' (map scale factor in y direction) isn't a function of z,
12115 ! we can do this using *(my/mx) (see eqn. 45 for example)
12119 i_end = MIN(ite,ide-1)
12123 DO i = i_start, i_end
12128 ! Polar boundary conditions are like open or specified
12129 ! We don't want to calculate vertical v tendencies at the N or S pole
12130 IF ( config_flags%open_ys .or. specified .or. config_flags%polar ) j_start = MAX(jds+1,jts)
12131 IF ( config_flags%open_ye .or. specified .or. config_flags%polar ) j_end = MIN(jde-1,jte)
12133 ! vert_order_test : IF (vert_order == 6) THEN
12135 ! ELSE IF (vert_order == 5) THEN
12137 DO j = j_start, j_end
12141 DO i = i_start, i_end
12142 vel=0.5*(rom(i,k,j)+rom(i,k,j-1))
12144 IF( -vel*sign(1,time_step) .ge. 0.0 ) THEN
12158 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
12159 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
12160 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
12162 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
12163 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
12164 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
12166 wi0 = gi0 / (eps + beta0)**pw
12167 wi1 = gi1 / (eps + beta1)**pw
12168 wi2 = gi2 / (eps + beta2)**pw
12170 sumwk = wi0 + wi1 + wi2
12172 vflux(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
12175 ! vflux(i,k) = vel*flux5( &
12176 ! v(i,k-3,j), v(i,k-2,j), v(i,k-1,j), &
12177 ! v(i,k ,j), v(i,k+1,j), v(i,k+2,j), -vel )
12181 DO i = i_start, i_end
12183 vflux(i,k)=0.5*(rom(i,k,j)+rom(i,k,j-1)) &
12184 *(fzm(k)*v(i,k,j)+fzp(k)*v(i,k-1,j))
12186 vel=0.5*(rom(i,k,j)+rom(i,k,j-1))
12187 vflux(i,k) = vel*flux3( &
12188 v(i,k-2,j), v(i,k-1,j), &
12189 v(i,k ,j), v(i,k+1,j), -vel )
12191 vel=0.5*(rom(i,k,j)+rom(i,k,j-1))
12192 vflux(i,k) = vel*flux3( &
12193 v(i,k-2,j), v(i,k-1,j), &
12194 v(i,k ,j), v(i,k+1,j), -vel )
12196 vflux(i,k)=0.5*(rom(i,k,j)+rom(i,k,j-1)) &
12197 *(fzm(k)*v(i,k,j)+fzp(k)*v(i,k-1,j))
12203 DO i = i_start, i_end
12204 ! We are calculating vertical fluxes on v points,
12205 ! so we must mean msf_v_x/y variables
12206 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
12213 END SUBROUTINE advect_weno_v
12216 !---------------------------------------------------------------------------------
12218 SUBROUTINE advect_weno_w ( w, w_old, tendency, &
12221 mut, time_step, config_flags, &
12222 msfux, msfuy, msfvx, msfvy, &
12226 ids, ide, jds, jde, kds, kde, &
12227 ims, ime, jms, jme, kms, kme, &
12228 its, ite, jts, jte, kts, kte )
12231 ! 5th-order WENO (Weighted Essentially Non-Oscillatory) scheme adapted from COMMAS.
12232 ! See Jiang and Shu, 1996, J. Comp. Phys. v. 126, 202-223;
12233 ! Shu 2003, Int. J. Comp. Fluid Dyn. v. 17 107-118; Also used by Bryan 2005, Mon. Wea. Rev.
12240 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
12242 INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
12243 ims, ime, jms, jme, kms, kme, &
12244 its, ite, jts, jte, kts, kte
12246 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: w, &
12252 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mut
12253 REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(INOUT) :: tendency
12255 REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfux, &
12262 REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: fzm, &
12268 REAL , INTENT(IN ) :: rdx, &
12270 INTEGER , INTENT(IN ) :: time_step
12275 INTEGER :: i, j, k, itf, jtf, ktf
12276 INTEGER :: i_start, i_end, j_start, j_end
12277 INTEGER :: i_start_f, i_end_f, j_start_f, j_end_f
12278 INTEGER :: jmin, jmax, jp, jm, imin, imax
12280 REAL :: mrdx, mrdy, ub, vb, uw, vw
12281 REAL , DIMENSION(its:ite, kts:kte) :: vflux
12284 real :: ue,vs,vn,wb,wt
12285 real, parameter :: f30 = 7./12., f31 = 1./12.
12286 real, parameter :: f50 = 37./60., f51 = 2./15., f52 = 1./60.
12292 real :: qim2, qim1, qi, qip1, qip2
12293 double precision :: beta0, beta1, beta2, f0, f1, f2, wi0, wi1, wi2, sumwk
12294 double precision, parameter :: gi0 = 1.d0/10.d0, gi1 = 6.d0/10.d0, gi2 = 3.d0/10.d0, eps=1.0d-18
12295 integer, parameter :: pw = 2
12299 INTEGER :: horz_order, vert_order
12301 REAL, DIMENSION( its:ite+1, kts:kte ) :: fqx
12302 REAL, DIMENSION( its:ite, kts:kte, 2 ) :: fqy
12304 LOGICAL :: degrade_xs, degrade_ys
12305 LOGICAL :: degrade_xe, degrade_ye
12307 INTEGER :: jp1, jp0, jtmp
12309 ! definition of flux operators, 3rd, 4th, 5th or 6th order
12311 REAL :: flux3, flux4, flux5, flux6
12312 REAL :: q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua, vel
12314 flux4(q_im2, q_im1, q_i, q_ip1, ua) = &
12315 ( 7.*(q_i + q_im1) - (q_ip1 + q_im2) )/12.0
12317 flux3(q_im2, q_im1, q_i, q_ip1, ua) = &
12318 flux4(q_im2, q_im1, q_i, q_ip1, ua) + &
12319 sign(1,time_step)*sign(1.,ua)*((q_ip1 - q_im2)-3.*(q_i-q_im1))/12.0
12321 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
12322 ( 37.*(q_i+q_im1) - 8.*(q_ip1+q_im2) &
12323 +(q_ip2+q_im3) )/60.0
12325 flux5(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) = &
12326 flux6(q_im3, q_im2, q_im1, q_i, q_ip1, q_ip2, ua) &
12327 -sign(1,time_step)*sign(1.,ua)*( &
12328 (q_ip2-q_im3)-5.*(q_ip1-q_im2)+10.*(q_i-q_im1) )/60.0
12331 LOGICAL :: specified
12333 specified = .false.
12334 if(config_flags%specified .or. config_flags%nested) specified = .true.
12336 ! set order for the advection scheme
12339 horz_order = config_flags%h_sca_adv_order
12340 vert_order = config_flags%v_sca_adv_order
12342 ! here is the choice of flux operators
12344 ! begin with horizontal flux divergence
12346 ! horizontal_order_test : IF( horz_order == 6 ) THEN
12347 ! ELSE IF (horz_order == 5 ) THEN
12349 ! determine boundary mods for flux operators
12350 ! We degrade the flux operators from 3rd/4th order
12351 ! to second order one gridpoint in from the boundaries for
12352 ! all boundary conditions except periodic and symmetry - these
12353 ! conditions have boundary zone data fill for correct application
12354 ! of the higher order flux stencils
12356 degrade_xs = .true.
12357 degrade_xe = .true.
12358 degrade_ys = .true.
12359 degrade_ye = .true.
12361 IF( config_flags%periodic_x .or. &
12362 config_flags%symmetric_xs .or. &
12363 (its > ids+3) ) degrade_xs = .false.
12364 IF( config_flags%periodic_x .or. &
12365 config_flags%symmetric_xe .or. &
12366 (ite < ide-3) ) degrade_xe = .false.
12367 IF( config_flags%periodic_y .or. &
12368 config_flags%symmetric_ys .or. &
12369 (jts > jds+3) ) degrade_ys = .false.
12370 IF( config_flags%periodic_y .or. &
12371 config_flags%symmetric_ye .or. &
12372 (jte < jde-4) ) degrade_ye = .false.
12374 !--------------- y - advection first
12377 i_end = MIN(ite,ide-1)
12379 j_end = MIN(jte,jde-1)
12381 ! higher order flux has a 5 or 7 point stencil, so compute
12382 ! bounds so we can switch to second order flux close to the boundary
12384 j_start_f = j_start
12387 IF(degrade_ys) then
12388 j_start = MAX(jts,jds+1)
12392 IF(degrade_ye) then
12393 j_end = MIN(jte,jde-2)
12397 IF(config_flags%polar) j_end = MIN(jte,jde-1)
12399 ! compute fluxes, 5th or 6th order
12404 j_loop_y_flux_5 : DO j = j_start, j_end+1
12406 IF( (j >= j_start_f ) .and. (j <= j_end_f) ) THEN
12409 DO i = i_start, i_end
12410 vel = fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)
12412 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
12426 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
12427 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
12428 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
12430 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
12431 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
12432 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
12434 wi0 = gi0 / (eps + beta0)**pw
12435 wi1 = gi1 / (eps + beta1)**pw
12436 wi2 = gi2 / (eps + beta2)**pw
12438 sumwk = wi0 + wi1 + wi2
12440 fqy( i, k, jp1 ) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
12442 ! fqy( i, k, jp1 ) = vel*flux5( &
12443 ! w(i,k,j-3), w(i,k,j-2), w(i,k,j-1), &
12444 ! w(i,k,j ), w(i,k,j+1), w(i,k,j+2), vel )
12449 DO i = i_start, i_end
12450 vel = (2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)
12452 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
12466 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
12467 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
12468 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
12470 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
12471 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
12472 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
12474 wi0 = gi0 / (eps + beta0)**pw
12475 wi1 = gi1 / (eps + beta1)**pw
12476 wi2 = gi2 / (eps + beta2)**pw
12478 sumwk = wi0 + wi1 + wi2
12480 fqy( i, k, jp1 ) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
12482 ! fqy( i, k, jp1 ) = vel*flux5( &
12483 ! w(i,k,j-3), w(i,k,j-2), w(i,k,j-1), &
12484 ! w(i,k,j ), w(i,k,j+1), w(i,k,j+2), vel )
12487 ELSE IF ( j == jds+1 ) THEN ! 2nd order flux next to south boundary
12490 DO i = i_start, i_end
12491 fqy(i, k, jp1) = 0.5*(fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j))* &
12492 (w(i,k,j)+w(i,k,j-1))
12497 DO i = i_start, i_end
12498 fqy(i, k, jp1) = 0.5*((2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j))* &
12499 (w(i,k,j)+w(i,k,j-1))
12502 ELSE IF ( j == jds+2 ) THEN ! third of 4th order flux 2 in from south boundary
12505 DO i = i_start, i_end
12506 vel = fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)
12507 fqy( i, k, jp1 ) = vel*flux3( &
12508 w(i,k,j-2),w(i,k,j-1),w(i,k,j),w(i,k,j+1),vel )
12513 DO i = i_start, i_end
12514 vel = (2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)
12515 fqy( i, k, jp1 ) = vel*flux3( &
12516 w(i,k,j-2),w(i,k,j-1),w(i,k,j),w(i,k,j+1),vel )
12519 ELSE IF ( j == jde-1 ) THEN ! 2nd order flux next to north boundary
12522 DO i = i_start, i_end
12523 fqy(i, k, jp1) = 0.5*(fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j))* &
12524 (w(i,k,j)+w(i,k,j-1))
12529 DO i = i_start, i_end
12530 fqy(i, k, jp1) = 0.5*((2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j))* &
12531 (w(i,k,j)+w(i,k,j-1))
12534 ELSE IF ( j == jde-2 ) THEN ! 3rd or 4th order flux 2 in from north boundary
12537 DO i = i_start, i_end
12538 vel = fzm(k)*rv(i,k,j)+fzp(k)*rv(i,k-1,j)
12539 fqy( i, k, jp1 ) = vel*flux3( &
12540 w(i,k,j-2),w(i,k,j-1), &
12541 w(i,k,j),w(i,k,j+1),vel )
12546 DO i = i_start, i_end
12547 vel = (2.-fzm(k-1))*rv(i,k-1,j)-fzp(k-1)*rv(i,k-2,j)
12548 fqy( i, k, jp1 ) = vel*flux3( &
12549 w(i,k,j-2),w(i,k,j-1), &
12550 w(i,k,j),w(i,k,j+1),vel )
12555 ! y flux-divergence into tendency
12557 ! Comments for polar boundary conditions
12558 ! Same process as for advect_u - tendencies run from jds to jde-1
12559 ! (latitudes are as for u grid, longitudes are displaced)
12560 ! Therefore: flow is only from one side for points next to poles
12561 IF ( config_flags%polar .AND. (j == jds+1) ) THEN
12563 DO i = i_start, i_end
12564 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
12565 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*fqy(i,k,jp1)
12568 ELSE IF( config_flags%polar .AND. (j == jde) ) THEN
12570 DO i = i_start, i_end
12571 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
12572 tendency(i,k,j-1) = tendency(i,k,j-1) + mrdy*fqy(i,k,jp0)
12577 IF(j > j_start) THEN
12580 DO i = i_start, i_end
12581 mrdy=msftx(i,j-1)*rdy ! see ADT eqn 46 dividing by my, 2nd term RHS
12582 tendency(i,k,j-1) = tendency(i,k,j-1) - mrdy*(fqy(i,k,jp1)-fqy(i,k,jp0))
12594 ENDDO j_loop_y_flux_5
12596 ! next, x - flux divergence
12599 i_end = MIN(ite,ide-1)
12602 j_end = MIN(jte,jde-1)
12604 ! higher order flux has a 5 or 7 point stencil, so compute
12605 ! bounds so we can switch to second order flux close to the boundary
12607 i_start_f = i_start
12610 IF(degrade_xs) then
12611 i_start = MAX(ids+1,its)
12612 ! i_start_f = i_start+2
12613 i_start_f = MIN(i_start+2,ids+3)
12616 IF(degrade_xe) then
12617 i_end = MIN(ide-2,ite)
12623 DO j = j_start, j_end
12625 ! 5th or 6th order flux
12628 DO i = i_start_f, i_end_f
12629 vel = fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)
12631 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
12645 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
12646 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
12647 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
12649 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
12650 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
12651 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
12653 wi0 = gi0 / (eps + beta0)**pw
12654 wi1 = gi1 / (eps + beta1)**pw
12655 wi2 = gi2 / (eps + beta2)**pw
12657 sumwk = wi0 + wi1 + wi2
12659 fqx(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
12661 ! fqx( i,k ) = vel*flux5( w(i-3,k,j), w(i-2,k,j), &
12662 ! w(i-1,k,j), w(i ,k,j), &
12663 ! w(i+1,k,j), w(i+2,k,j), &
12669 DO i = i_start_f, i_end_f
12670 vel = (2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)
12672 IF ( vel*sign(1,time_step) .ge. 0.0 ) THEN
12686 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
12687 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
12688 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
12690 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
12691 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
12692 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
12694 wi0 = gi0 / (eps + beta0)**pw
12695 wi1 = gi1 / (eps + beta1)**pw
12696 wi2 = gi2 / (eps + beta2)**pw
12698 sumwk = wi0 + wi1 + wi2
12700 fqx(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
12702 ! fqx( i,k ) = vel*flux5( w(i-3,k,j), w(i-2,k,j), &
12703 ! w(i-1,k,j), w(i ,k,j), &
12704 ! w(i+1,k,j), w(i+2,k,j), &
12708 ! lower order fluxes close to boundaries (if not periodic or symmetric)
12710 IF( degrade_xs ) THEN
12712 DO i=i_start,i_start_f-1
12714 IF(i == ids+1) THEN ! second order
12716 fqx(i,k) = 0.5*(fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)) &
12717 *(w(i,k,j)+w(i-1,k,j))
12720 fqx(i,k) = 0.5*((2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)) &
12721 *(w(i,k,j)+w(i-1,k,j))
12724 IF(i == ids+2) THEN ! third order
12726 vel = fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)
12727 fqx( i,k ) = vel*flux3( w(i-2,k,j), w(i-1,k,j), &
12728 w(i ,k,j), w(i+1,k,j), &
12732 vel = (2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)
12733 fqx( i,k ) = vel*flux3( w(i-2,k,j), w(i-1,k,j), &
12734 w(i ,k,j), w(i+1,k,j), &
12742 IF( degrade_xe ) THEN
12744 DO i = i_end_f+1, i_end+1
12746 IF( i == ide-1 ) THEN ! second order flux next to the boundary
12748 fqx(i,k) = 0.5*(fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)) &
12749 *(w(i,k,j)+w(i-1,k,j))
12752 fqx(i,k) = 0.5*((2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)) &
12753 *(w(i,k,j)+w(i-1,k,j))
12756 IF( i == ide-2 ) THEN ! third order flux one in from the boundary
12758 vel = fzm(k)*ru(i,k,j)+fzp(k)*ru(i,k-1,j)
12759 fqx( i,k ) = vel*flux3( w(i-2,k,j), w(i-1,k,j), &
12760 w(i ,k,j), w(i+1,k,j), &
12764 vel = (2.-fzm(k-1))*ru(i,k-1,j)-fzp(k-1)*ru(i,k-2,j)
12765 fqx( i,k ) = vel*flux3( w(i-2,k,j), w(i-1,k,j), &
12766 w(i ,k,j), w(i+1,k,j), &
12774 ! x flux-divergence into tendency
12777 DO i = i_start, i_end
12778 mrdx=msftx(i,j)*rdx ! see ADT eqn 46 dividing by my, 1st term RHS
12779 tendency(i,k,j) = tendency(i,k,j) - mrdx*(fqx(i+1,k)-fqx(i,k))
12786 ! pick up the the horizontal radiation boundary conditions.
12787 ! (these are the computations that don't require 'cb'.
12788 ! first, set to index ranges
12792 i_end = MIN(ite,ide-1)
12794 j_end = MIN(jte,jde-1)
12796 IF( (config_flags%open_xs) .and. (its == ids)) THEN
12798 DO j = j_start, j_end
12801 uw = 0.5*(fzm(k)*(ru(its,k ,j)+ru(its+1,k ,j)) + &
12802 fzp(k)*(ru(its,k-1,j)+ru(its+1,k-1,j)) )
12805 tendency(its,k,j) = tendency(its,k,j) &
12807 ub*(w_old(its+1,k,j) - w_old(its,k,j)) + &
12809 fzm(k)*(ru(its+1,k ,j)-ru(its,k ,j))+ &
12810 fzp(k)*(ru(its+1,k-1,j)-ru(its,k-1,j))) &
12816 DO j = j_start, j_end
12818 uw = 0.5*( (2.-fzm(k-1))*(ru(its,k-1,j)+ru(its+1,k-1,j)) &
12819 -fzp(k-1)*(ru(its,k-2,j)+ru(its+1,k-2,j)) )
12822 tendency(its,k,j) = tendency(its,k,j) &
12824 ub*(w_old(its+1,k,j) - w_old(its,k,j)) + &
12826 (2.-fzm(k-1))*(ru(its+1,k-1,j)-ru(its,k-1,j))- &
12827 fzp(k-1)*(ru(its+1,k-2,j)-ru(its,k-2,j))) &
12833 IF( (config_flags%open_xe) .and. (ite == ide)) THEN
12835 DO j = j_start, j_end
12838 uw = 0.5*(fzm(k)*(ru(ite-1,k ,j)+ru(ite,k ,j)) + &
12839 fzp(k)*(ru(ite-1,k-1,j)+ru(ite,k-1,j)) )
12842 tendency(i_end,k,j) = tendency(i_end,k,j) &
12844 ub*(w_old(i_end,k,j) - w_old(i_end-1,k,j)) + &
12846 fzm(k)*(ru(ite,k ,j)-ru(ite-1,k ,j)) + &
12847 fzp(k)*(ru(ite,k-1,j)-ru(ite-1,k-1,j))) &
12853 DO j = j_start, j_end
12855 uw = 0.5*( (2.-fzm(k-1))*(ru(ite-1,k-1,j)+ru(ite,k-1,j)) &
12856 -fzp(k-1)*(ru(ite-1,k-2,j)+ru(ite,k-2,j)) )
12859 tendency(i_end,k,j) = tendency(i_end,k,j) &
12861 ub*(w_old(i_end,k,j) - w_old(i_end-1,k,j)) + &
12863 (2.-fzm(k-1))*(ru(ite,k-1,j)-ru(ite-1,k-1,j)) - &
12864 fzp(k-1)*(ru(ite,k-2,j)-ru(ite-1,k-2,j))) &
12871 IF( (config_flags%open_ys) .and. (jts == jds)) THEN
12873 DO i = i_start, i_end
12876 vw = 0.5*( fzm(k)*(rv(i,k ,jts)+rv(i,k ,jts+1)) + &
12877 fzp(k)*(rv(i,k-1,jts)+rv(i,k-1,jts+1)) )
12880 tendency(i,k,jts) = tendency(i,k,jts) &
12882 vb*(w_old(i,k,jts+1) - w_old(i,k,jts)) + &
12884 fzm(k)*(rv(i,k ,jts+1)-rv(i,k ,jts))+ &
12885 fzp(k)*(rv(i,k-1,jts+1)-rv(i,k-1,jts))) &
12891 DO i = i_start, i_end
12892 vw = 0.5*( (2.-fzm(k-1))*(rv(i,k-1,jts)+rv(i,k-1,jts+1)) &
12893 -fzp(k-1)*(rv(i,k-2,jts)+rv(i,k-2,jts+1)) )
12896 tendency(i,k,jts) = tendency(i,k,jts) &
12898 vb*(w_old(i,k,jts+1) - w_old(i,k,jts)) + &
12900 (2.-fzm(k-1))*(rv(i,k-1,jts+1)-rv(i,k-1,jts))- &
12901 fzp(k-1)*(rv(i,k-2,jts+1)-rv(i,k-2,jts))) &
12907 IF( (config_flags%open_ye) .and. (jte == jde) ) THEN
12909 DO i = i_start, i_end
12912 vw = 0.5*( fzm(k)*(rv(i,k ,jte-1)+rv(i,k ,jte)) + &
12913 fzp(k)*(rv(i,k-1,jte-1)+rv(i,k-1,jte)) )
12916 tendency(i,k,j_end) = tendency(i,k,j_end) &
12918 vb*(w_old(i,k,j_end) - w_old(i,k,j_end-1)) + &
12920 fzm(k)*(rv(i,k ,jte)-rv(i,k ,jte-1))+ &
12921 fzp(k)*(rv(i,k-1,jte)-rv(i,k-1,jte-1))) &
12927 DO i = i_start, i_end
12929 vw = 0.5*( (2.-fzm(k-1))*(rv(i,k-1,jte-1)+rv(i,k-1,jte)) &
12930 -fzp(k-1)*(rv(i,k-2,jte-1)+rv(i,k-2,jte)) )
12933 tendency(i,k,j_end) = tendency(i,k,j_end) &
12935 vb*(w_old(i,k,j_end) - w_old(i,k,j_end-1)) + &
12937 (2.-fzm(k-1))*(rv(i,k-1,jte)-rv(i,k-1,jte-1))- &
12938 fzp(k-1)*(rv(i,k-2,jte)-rv(i,k-2,jte-1))) &
12944 !-------------------- vertical advection
12945 ! ADT eqn 46 has 3rd term on RHS (dividing through by my) = - partial d/dz (w rho w /my)
12946 ! Here we have: - partial d/dz (w*rom) = - partial d/dz (w rho w / my)
12947 ! Therefore we don't need to make a correction for advect_w
12950 i_end = MIN(ite,ide-1)
12952 j_end = MIN(jte,jde-1)
12954 DO i = i_start, i_end
12959 ! vert_order_test : IF (vert_order == 6) THEN
12961 ! ELSE IF (vert_order == 5) THEN
12963 DO j = j_start, j_end
12966 DO i = i_start, i_end
12967 vel=0.5*(rom(i,k,j)+rom(i,k-1,j))
12969 IF( -vel*sign(1,time_step) .ge. 0.0 ) THEN
12983 f0 = 1./3.*qim2 - 7./6.*qim1 + 11./6.*qi
12984 f1 = -1./6.*qim1 + 5./6.*qi + 1./3. *qip1
12985 f2 = 1./3.*qi + 5./6.*qip1 - 1./6. *qip2
12987 beta0 = 13./12.*(qim2 - 2.*qim1 + qi )**2 + 1./4.*(qim2 - 4.*qim1 + 3.*qi)**2
12988 beta1 = 13./12.*(qim1 - 2.*qi + qip1)**2 + 1./4.*(qim1 - qip1)**2
12989 beta2 = 13./12.*(qi - 2.*qip1 + qip2)**2 + 1./4.*(qip2 - 4.*qip1 + 3.*qi)**2
12991 wi0 = gi0 / (eps + beta0)**pw
12992 wi1 = gi1 / (eps + beta1)**pw
12993 wi2 = gi2 / (eps + beta2)**pw
12995 sumwk = wi0 + wi1 + wi2
12997 vflux(i,k) = vel * (wi0*f0 + wi1*f1 + wi2*f2) / sumwk
12999 ! vflux(i,k) = vel*flux5( &
13000 ! w(i,k-3,j), w(i,k-2,j), w(i,k-1,j), &
13001 ! w(i,k ,j), w(i,k+1,j), w(i,k+2,j), -vel )
13005 DO i = i_start, i_end
13008 vflux(i,k)=0.25*(rom(i,k,j)+rom(i,k-1,j))*(w(i,k,j)+w(i,k-1,j))
13011 vel=0.5*(rom(i,k,j)+rom(i,k-1,j))
13012 vflux(i,k) = vel*flux3( &
13013 w(i,k-2,j), w(i,k-1,j), &
13014 w(i,k ,j), w(i,k+1,j), -vel )
13016 vel=0.5*(rom(i,k,j)+rom(i,k-1,j))
13017 vflux(i,k) = vel*flux3( &
13018 w(i,k-2,j), w(i,k-1,j), &
13019 w(i,k ,j), w(i,k+1,j), -vel )
13022 vflux(i,k)=0.25*(rom(i,k,j)+rom(i,k-1,j))*(w(i,k,j)+w(i,k-1,j))
13027 DO i = i_start, i_end
13028 tendency(i,k,j)=tendency(i,k,j)-rdzu(k)*(vflux(i,k+1)-vflux(i,k))
13032 ! pick up flux contribution for w at the lid, wcs. 13 march 2004
13034 DO i = i_start, i_end
13035 tendency(i,k,j)=tendency(i,k,j)+2.*rdzu(k-1)*(vflux(i,k))
13041 END SUBROUTINE advect_weno_w
13044 END MODULE module_advect_em