2 !WRF:MODEL_LAYER:DYNAMICS
5 ! SMALL_STEP code for the geometric height coordinate model
7 !---------------------------------------------------------------------------
9 MODULE module_small_step_em
12 USE module_model_constants
16 SUBROUTINE small_step_prep( u_1, u_2, v_1, v_2, w_1, w_2, &
17 t_1, t_2, ph_1, ph_2, &
19 muu, muus, muv, muvs, &
23 u_save, v_save, w_save, &
24 t_save, ph_save, mu_save, &
27 msfux, msfuy, msfvx, &
29 msfvy, msftx, msfty, &
32 ids,ide, jds,jde, kds,kde, &
33 ims,ime, jms,jme, kms,kme, &
34 its,ite, jts,jte, kts,kte )
36 IMPLICIT NONE ! religion first
38 ! declarations for the stuff coming in
40 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
41 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
42 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
44 INTEGER, INTENT(IN ) :: rk_step
46 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(INOUT) :: u_1, &
52 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT( OUT) :: u_save, &
58 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(INOUT) :: u_2, &
64 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT( OUT) :: c2a, &
67 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(IN ) :: pb, &
72 REAL, DIMENSION(ims:ime, jms:jme) , INTENT(INOUT) :: mu_1,mu_2
74 REAL, DIMENSION(ims:ime, jms:jme) , INTENT(IN ) :: mub, &
86 REAL, DIMENSION(ims:ime, jms:jme) , INTENT( OUT) :: muus, &
91 REAL, DIMENSION(ims:ime, jms:jme) , INTENT( OUT) :: mu_save
93 REAL, INTENT(IN) :: rdx,rdy
95 REAL, DIMENSION( kms:kme ),INTENT(IN ) :: c1h, c2h, c1f, c2f, &
101 INTEGER :: i_start, i_end, j_start, j_end, k_start, k_end
102 INTEGER :: i_endu, j_endv
107 ! small_step_prep prepares the prognostic variables for the small timestep.
108 ! This includes switching time-levels in the arrays and computing coupled
109 ! perturbation variables for the small timestep
110 ! (i.e. mu*u" = mu(t)*u(t)-mu(*)*u(*); mu*u" is advanced during the small
116 i_end = min(ite,ide-1)
118 j_end = min(jte,jde-1)
120 k_end = min(kte,kde-1)
125 ! if this is the first RK step, reset *_1 to *_2
126 ! (we are replacing the t-dt fields with the time t fields)
128 IF ((rk_step == 1) ) THEN
133 ww_save(i,kde,j) = 0.
135 MUDF(i,j) = 0. ! initialize external mode div damp to zero
142 u_1(i,k,j) = u_2(i,k,j)
150 v_1(i,k,j) = v_2(i,k,j)
158 t_1(i,k,j) = t_2(i,k,j)
164 DO k=k_start, min(kde,kte)
166 w_1(i,k,j) = w_2(i,k,j)
167 ph_1(i,k,j) = ph_2(i,k,j)
174 MUTS(i,j)=MUB(i,j)+MU_2(i,j)
189 MU_SAVE(i,j)=MU_2(i,j)
198 MUTS(i,j)=MUB(i,j)+MU_1(i,j)
201 MUUS(i,j)=0.5*(MUB(i,j)+MU_1(i,j)+MUB(i-1,j)+MU_1(i-1,j))
207 MUVS(i,j)=0.5*(MUB(i,j)+MU_1(i,j)+MUB(i,j-1)+MU_1(i,j-1))
213 MU_SAVE(i,j)=MU_2(i,j)
214 MU_2(i,j)=MU_1(i,j)-MU_2(i,j)
221 ! set up the small timestep variables
225 ww_save(i,kde,j) = 0.
233 c2a(i,k,j) = cpovcv*(pb(i,k,j)+p(i,k,j))/alt(i,k,j)
241 u_save(i,k,j) = u_2(i,k,j)
243 u_2(i,k,j) = ((c1h(k)*muus(i,j)+c2h(k))*u_1(i,k,j)-(c1h(k)*muu(i,j)+c2h(k))*u_2(i,k,j))/msfuy(i,j)
251 v_save(i,k,j) = v_2(i,k,j)
253 ! v_2(i,k,j) = ((c1h(k)*muvs(i,j)+c2h(k))*v_1(i,k,j)-(c1h(k)*muv(i,j)+c2h(k))*v_2(i,k,j))/msfvx(i,j)
254 v_2(i,k,j) = ((c1h(k)*muvs(i,j)+c2h(k))*v_1(i,k,j)-(c1h(k)*muv(i,j)+c2h(k))*v_2(i,k,j))*msfvx_inv(i,j)
262 t_save(i,k,j) = t_2(i,k,j)
263 t_2(i,k,j) = (c1h(k)*muts(i,j)+c2h(k))*t_1(i,k,j)-(c1h(k)*mut(i,j)+c2h(k))*t_2(i,k,j)
269 ! DO k=k_start, min(kde,kte)
272 w_save(i,k,j) = w_2(i,k,j)
274 w_2(i,k,j) = ((c1f(k)*muts(i,j)+c2f(k))* w_1(i,k,j)-(c1f(k)*mut(i,j)+c2f(k))* w_2(i,k,j))/msfty(i,j)
275 ph_save(i,k,j) = ph_2(i,k,j)
276 ph_2(i,k,j) = ph_1(i,k,j)-ph_2(i,k,j)
282 ! DO k=k_start, min(kde,kte)
285 ww_save(i,k,j) = ww(i,k,j)
290 END SUBROUTINE small_step_prep
292 !-------------------------------------------------------------------------
295 SUBROUTINE small_step_finish( u_2, u_1, v_2, v_1, w_2, w_1, &
296 t_2, t_1, ph_2, ph_1, ww, ww1, &
298 mut, muts, muu, muus, muv, muvs, &
299 c1h, c2h, c1f, c2f, &
300 c3h, c4h, c3f, c4f, &
301 u_save, v_save, w_save, &
302 t_save, ph_save, mu_save, &
303 msfux, msfuy, msfvx, msfvy, &
306 number_of_small_timesteps,dts, &
308 ids,ide, jds,jde, kds,kde, &
309 ims,ime, jms,jme, kms,kme, &
310 its,ite, jts,jte, kts,kte )
313 IMPLICIT NONE ! religion first
317 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
318 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
319 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
320 INTEGER, INTENT(IN ) :: number_of_small_timesteps
321 INTEGER, INTENT(IN ) :: rk_step, rk_order
322 REAL, INTENT(IN ) :: dts
324 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(IN ) :: u_1, &
331 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(INOUT) :: u_2, &
338 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(IN ) :: u_save, &
345 REAL, DIMENSION(ims:ime, jms:jme), INTENT(INOUT) :: muus, muvs
346 REAL, DIMENSION(ims:ime, jms:jme), INTENT(INOUT) :: mu_2, mu_1
347 REAL, DIMENSION(ims:ime, jms:jme), INTENT(INOUT) :: mut, muts, &
349 REAL, DIMENSION(ims:ime, jms:jme), INTENT(IN ) :: msfux, msfuy, &
353 REAL, DIMENSION( kms:kme ),INTENT(IN ) :: c1h, c2h, c1f, c2f, &
360 INTEGER :: i_start, i_end, j_start, j_end, i_endu, j_endv
364 ! small_step_finish reconstructs the full uncoupled prognostic variables
365 ! from the coupled perturbation variables used in the small timesteps.
370 i_end = min(ite,ide-1)
372 j_end = min(jte,jde-1)
377 ! addition of time level t back into variables
379 DO j = j_start, j_endv
381 DO i = i_start, i_end
383 v_2(i,k,j) = (msfvx(i,j)*v_2(i,k,j) + v_save(i,k,j)*(c1h(k)*muv(i,j)+c2h(k)))/(c1h(k)*muvs(i,j)+c2h(k))
388 DO j = j_start, j_end
390 DO i = i_start, i_endu
392 u_2(i,k,j) = (msfuy(i,j)*u_2(i,k,j) + u_save(i,k,j)*(c1h(k)*muu(i,j)+c2h(k)))/(c1h(k)*muus(i,j)+c2h(k))
397 DO j = j_start, j_end
399 DO i = i_start, i_end
401 w_2(i,k,j) = (msfty(i,j)*w_2(i,k,j) + w_save(i,k,j)*(c1f(k)*mut(i,j)+c2f(k)))/(c1f(k)*muts(i,j)+c2f(k))
402 ph_2(i,k,j) = ph_2(i,k,j) + ph_save(i,k,j)
403 ww(i,k,j) = ww(i,k,j) + ww1(i,k,j)
408 IF ( rk_step < rk_order ) THEN
409 DO j = j_start, j_end
411 DO i = i_start, i_end
412 t_2(i,k,j) = (t_2(i,k,j) + t_save(i,k,j)*(c1h(k)*mut(i,j)+c2h(k)))/(c1h(k)*muts(i,j)+c2h(k))
418 DO j = j_start, j_end
420 DO i = i_start, i_end
421 t_2(i,k,j) = (t_2(i,k,j) - dts*number_of_small_timesteps*(c1h(k)*mut(i,j)+c2h(k))*h_diabatic(i,k,j) &
422 + t_save(i,k,j)*(c1h(k)*mut(i,j)+c2h(k)))/(c1h(k)*muts(i,j)+c2h(k))
428 DO j = j_start, j_end
429 DO i = i_start, i_end
430 mu_2(i,j) = mu_2(i,j) + mu_save(i,j)
434 END SUBROUTINE small_step_finish
436 !-----------------------------------------------------------------------
438 SUBROUTINE calc_p_rho( al, p, ph, &
439 alt, t_2, t_1, c2a, pm1, &
441 c1h, c2h, c1f, c2f, &
442 c3h, c4h, c3f, c4f, &
445 non_hydrostatic, step, &
446 ids, ide, jds, jde, kds, kde, &
447 ims, ime, jms, jme, kms, kme, &
448 its,ite, jts,jte, kts,kte )
450 IMPLICIT NONE ! religion first
452 ! declarations for the stuff coming in
454 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
455 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
456 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
458 INTEGER, INTENT(IN ) :: step
460 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT( OUT) :: al, &
463 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(IN ) :: alt, &
468 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(INOUT) :: ph, pm1
470 REAL, DIMENSION(ims:ime, jms:jme) , INTENT(IN ) :: mu, &
473 REAL, DIMENSION(kms:kme) , INTENT(IN ) :: dnw, &
477 REAL, INTENT(IN ) :: t0, smdiv
479 REAL, DIMENSION( kms:kme ),INTENT(IN ) :: c1h, c2h, c1f, c2f, &
482 LOGICAL, INTENT(IN ) :: non_hydrostatic
487 INTEGER :: i_start, i_end, j_start, j_end, k_start, k_end
492 ! For the nonhydrostatic option,
493 ! calc_p_rho computes the perturbation inverse density and
494 ! perturbation pressure from the hydrostatic relation and the
495 ! linearized equation of state, respectively.
497 ! For the hydrostatic option,
498 ! calc_p_rho computes the perturbation pressure, perturbation density,
499 ! and perturbation geopotential
500 ! from the vertical coordinate definition, linearized equation of state
501 ! and the hydrostatic relation, respectively.
503 ! forward weighting of the pressure (divergence damping) is also
509 i_end = min(ite,ide-1)
511 j_end = min(jte,jde-1)
513 k_end = min(kte,kde-1)
515 IF (non_hydrostatic) THEN
520 ! al computation is all dry, so ok with moisture
522 al(i,k,j)=-1./(c1h(k)*Mut(i,j)+c2h(k))*(alt(i,k,j)*(c1h(k)*mu(i,j)) &
523 +rdnw(k)*(ph(i,k+1,j)-ph(i,k,j)))
525 ! this is temporally linearized p, no moisture correction needed
527 p(i,k,j)=c2a(i,k,j)*(alt(i,k,j)*(t_2(i,k,j)-(c1h(k)*mu(i,j))*t_1(i,k,j)) &
528 /((c1h(k)*Mut(i,j)+c2h(k))*(t0+t_1(i,k,j)))-al (i,k,j))
534 ELSE ! hydrostatic calculation
539 p(i,k,j)=MU(i,j)*c3h(k)
540 al(i,k,j)=alt(i,k,j)*(t_2(i,k,j)-(c1h(k)*mu(i,j))*t_1(i,k,j)) &
541 /((c1h(k)*Mut(i,j)+c2h(k))*(t0+t_1(i,k,j)))-p(i,k,j)/c2a(i,k,j)
542 ph(i,k+1,j)=ph(i,k,j)-dnw(k)*((c1h(k)*Mut(i,j)+c2h(k))*al (i,k,j) &
543 +(c1h(k)*mu(i,j))*alt(i,k,j))
548 ! divergence damping setup
549 IF (step == 0) then ! we're initializing small timesteps
557 ELSE ! we're in the small timesteps
558 DO j=j_start, j_end ! and adding div damping component
562 p(i,k,j) = p(i,k,j) + smdiv*(p(i,k,j)-pm1(i,k,j))
568 END SUBROUTINE calc_p_rho
569 !----------------------------------------------------------------------
570 SUBROUTINE calc_coef_w( a,alpha,gamma, &
572 c1h, c2h, c1f, c2f, &
573 c3h, c4h, c3f, c4f, &
576 dts, g, epssm, top_lid, &
577 ids,ide, jds,jde, kds,kde, & ! domain dims
578 ims,ime, jms,jme, kms,kme, & ! memory dims
579 its,ite, jts,jte, kts,kte ) ! tile dims
581 IMPLICIT NONE ! religion first
582 ! passed in through the call
583 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
584 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
585 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
586 LOGICAL, INTENT(IN ) :: top_lid
587 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(IN ) :: c2a, &
589 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(INOUT) :: alpha, &
592 REAL, DIMENSION(ims:ime, jms:jme), INTENT(IN ) :: mut
593 REAL, DIMENSION(kms:kme), INTENT(IN ) :: rdn, &
595 REAL, INTENT(IN ) :: epssm, &
598 REAL, DIMENSION( kms:kme ),INTENT(IN ) :: c1h, c2h, c1f, c2f, &
601 REAL, DIMENSION(ims:ime) :: cof
603 REAL :: muthmutf_kk, muthmutf_km1k, muthmutf_kkp1
604 INTEGER :: i, j, k, kk, i_start, i_end, j_start, j_end, k_start, k_end
605 INTEGER :: ij, ijp, ijm, lid_flag
608 ! calc_coef_w calculates the coefficients needed for the
609 ! implicit solution of the vertical momentum and geopotential equations.
610 ! This requires solution of a tri-diagonal equation.
614 i_end = min(ite,ide-1)
616 j_end = min(jte,jde-1)
620 IF(top_lid)lid_flag=0
621 outer_j_loop: DO j = j_start, j_end
623 DO i = i_start, i_end
624 cof(i) = (.5*dts*g*(1.+epssm))**2
626 a(i,kde,j) =-2.*cof(i)*rdnw(kde-1)**2*c2a(i,kde-1,j)*lid_flag/((c1h(k)*MUT(i,j)+c2h(k))*(c1f(k)*MUT(i,j)+c2f(k)))
632 a(i,kk,j) = -cqw(i,kk,j)*cof(i)*rdn(kk)* rdnw(kk-1)*c2a(i,kk-1,j)/((c1h(k)*MUT(i,j)+c2h(k))*(c1f(k)*MUT(i,j)+c2f(k)))
637 b = 1.+cqw(i,k,j)*cof(i)*rdn(k)*(rdnw(k )*c2a(i,k, j)/((c1h(k)*MUT(i,j)+c2h(k))*(c1f(k)*MUT(i,j)+c2f(k))) &
638 +rdnw(k-1)*c2a(i,k-1,j)/((c1h(k-1)*MUT(i,j)+c2h(k-1))*(c1f(k)*MUT(i,j)+c2f(k))) )
639 c = -cqw(i,k,j)*cof(i)*rdn(k)*rdnw(k )*c2a(i,k,j )/((c1h(k)*MUT(i,j)+c2h(k))*(c1f(k+1)*MUT(i,j)+c2f(k+1)))
640 alpha(i,k,j) = 1./(b-a(i,k,j)*gamma(i,k-1,j))
641 gamma(i,k,j) = c*alpha(i,k,j)
646 b = 1.+2.*cof(i)*rdnw(kde-1)**2*c2a(i,kde-1,j)/((c1h(k-1)*MUT(i,j)+c2h(k-1))*(c1f(k)*MUT(i,j)+c2f(k)))
648 alpha(i,kde,j) = 1./(b-a(i,kde,j)*gamma(i,kde-1,j))
649 gamma(i,kde,j) = c*alpha(i,kde,j)
652 END SUBROUTINE calc_coef_w
653 !----------------------------------------------------------------------
654 SUBROUTINE advance_uv ( u, ru_tend, v, rv_tend, &
656 ph, php, alt, al, mu, &
657 muu, cqu, muv, cqv, mudf, &
658 c1h, c2h, c1f, c2f, &
659 c3h, c4h, c3f, c4f, &
660 msfux, msfuy, msfvx, &
663 cf1, cf2, cf3, fnm, fnp, &
665 rdnw, config_flags, spec_zone, &
666 non_hydrostatic, top_lid, &
667 ids, ide, jds, jde, kds, kde, &
668 ims, ime, jms, jme, kms, kme, &
669 its, ite, jts, jte, kts, kte )
670 IMPLICIT NONE ! religion first
672 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
673 LOGICAL, INTENT(IN ) :: non_hydrostatic, top_lid
674 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
675 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
676 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
677 INTEGER, INTENT(IN ) :: spec_zone
678 REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
682 REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
694 REAL, DIMENSION( ims:ime , jms:jme ), INTENT(IN ) :: muu, &
698 REAL, DIMENSION( kms:kme ), INTENT(IN ) :: fnm, &
701 REAL, DIMENSION( ims:ime , jms:jme ), INTENT(IN ) :: msfux, &
706 REAL, INTENT(IN ) :: rdx, &
713 REAL, DIMENSION( kms:kme ),INTENT(IN ) :: c1h, c2h, c1f, c2f, &
716 ! Local 3d array from the stack (note tile size)
717 REAL, DIMENSION (its:ite, kts:kte) :: dpn, dpxy
718 REAL, DIMENSION (its:ite) :: mudf_xy
720 INTEGER :: i,j,k, i_start, i_end, j_start, j_end, k_start, k_end
721 INTEGER :: i_endu, j_endv, k_endw
722 INTEGER :: i_start_up, i_end_up, j_start_up, j_end_up
723 INTEGER :: i_start_vp, i_end_vp, j_start_vp, j_end_vp
724 INTEGER :: i_start_u_tend, i_end_u_tend, j_start_v_tend, j_end_v_tend
727 ! advance_uv advances the explicit perturbation horizontal momentum
728 ! equations (u,v) by adding in the large-timestep tendency along with
729 ! the small timestep pressure gradient tendency.
732 ! now, the real work.
733 ! set the loop bounds taking into account boundary conditions.
734 IF( config_flags%nested .or. config_flags%specified ) THEN
735 i_start = max( its,ids+spec_zone )
736 i_end = min( ite,ide-spec_zone-1 )
737 j_start = max( jts,jds+spec_zone )
738 j_end = min( jte,jde-spec_zone-1 )
740 k_end = min( kte, kde-1 )
741 i_endu = min( ite,ide-spec_zone )
742 j_endv = min( jte,jde-spec_zone )
744 IF( config_flags%periodic_x) THEN
746 i_end = min(ite,ide-1)
751 i_end = min(ite,ide-1)
753 j_end = min(jte,jde-1)
768 IF ( (config_flags%open_xs .or. &
769 config_flags%symmetric_xs ) &
770 .and. (its == ids) ) &
771 i_start_up = i_start_up + 1
772 IF ( (config_flags%open_xe .or. &
773 config_flags%symmetric_xe ) &
774 .and. (ite == ide) ) &
775 i_end_up = i_end_up - 1
776 IF ( (config_flags%open_ys .or. &
777 config_flags%symmetric_ys .or. &
778 config_flags%polar ) &
779 .and. (jts == jds) ) &
780 j_start_vp = j_start_vp + 1
781 IF ( (config_flags%open_ye .or. &
782 config_flags%symmetric_ye .or. &
783 config_flags%polar ) &
784 .and. (jte == jde) ) &
785 j_end_vp = j_end_vp - 1
786 i_start_u_tend = i_start
787 i_end_u_tend = i_endu
788 j_start_v_tend = j_start
789 j_end_v_tend = j_endv
790 IF ( config_flags%symmetric_xs .and. (its == ids) ) &
791 i_start_u_tend = i_start_u_tend+1
792 IF ( config_flags%symmetric_xe .and. (ite == ide) ) &
793 i_end_u_tend = i_end_u_tend-1
794 IF ( config_flags%symmetric_ys .and. (jts == jds) ) &
795 j_start_v_tend = j_start_v_tend+1
796 IF ( config_flags%symmetric_ye .and. (jte == jde) ) &
797 j_end_v_tend = j_end_v_tend-1
800 ! start real calculations.
802 u_outer_j_loop: DO j = j_start, j_end
803 DO k = k_start, k_end
804 DO i = i_start_u_tend, i_end_u_tend
805 u(i,k,j) = u(i,k,j) + dts*ru_tend(i,k,j)
808 DO i = i_start_up, i_end_up
809 MUDF_XY(i)= -emdiv*dx*(MUDF(i,j)-MUDF(i-1,j))/msfuy(i,j)
811 DO k = k_start, k_end
812 DO i = i_start_up, i_end_up
813 ! Comments on map scale factors:
814 ! x pressure gradient: ADT eqn 44, penultimate term on RHS
815 ! = -(mx/my)*(mu/rho)*partial dp/dx
816 ! [i.e., first rho->mu; 2nd still rho; alpha=1/rho]
817 ! Klemp et al. splits into 2 terms:
818 ! mu alpha partial dp/dx + partial dp/dnu * partial dphi/dx
820 ! mu alpha partial dp'/dx + nu mu alpha' partial dmubar/dx +
821 ! + mu partial dphi/dx + partial dphi'/dx * (partial dp'/dnu - mu')
824 ! ph, alt, p, al, pb not coupled
825 ! since we want tendency to fit ADT eqn 44 (coupled) we need to
826 ! multiply by (mx/my):
828 dpxy(i,k)= (msfux(i,j)/msfuy(i,j))*.5*rdx*(c1h(k)*muu(i,j)+c2h(k))*( &
829 ((ph (i,k+1,j)-ph (i-1,k+1,j))+(ph (i,k,j)-ph (i-1,k,j))) &
830 +(alt(i,k ,j)+alt(i-1,k ,j))*(p (i,k,j)-p (i-1,k,j)) &
831 +(al (i,k ,j)+al (i-1,k ,j))*(pb (i,k,j)-pb (i-1,k,j)) )
834 IF (non_hydrostatic) THEN
835 DO i = i_start_up, i_end_up
836 dpn(i,1) = .5*( cf1*(p(i,1,j)+p(i-1,1,j)) &
837 +cf2*(p(i,2,j)+p(i-1,2,j)) &
838 +cf3*(p(i,3,j)+p(i-1,3,j)) )
842 DO i = i_start_up, i_end_up
843 dpn(i,kde) =.5*( cf1*(p(i-1,kde-1,j)+p(i,kde-1,j)) &
844 +cf2*(p(i-1,kde-2,j)+p(i,kde-2,j)) &
845 +cf3*(p(i-1,kde-3,j)+p(i,kde-3,j)) )
848 DO k = k_start+1, k_end
849 DO i = i_start_up, i_end_up
850 dpn(i,k) = .5*( fnm(k)*(p(i,k ,j)+p(i-1,k ,j)) &
851 +fnp(k)*(p(i,k-1,j)+p(i-1,k-1,j)) )
854 ! Comments on map scale factors:
856 ! php, dpn, mu not coupled
857 ! since we want tendency to fit ADT eqn 44 (coupled) we need to
858 ! multiply by (mx/my):
859 DO k = k_start, k_end
860 DO i = i_start_up, i_end_up
861 dpxy(i,k)=dpxy(i,k) + (msfux(i,j)/msfuy(i,j))*rdx*(php(i,k,j)-php(i-1,k,j))* &
862 (rdnw(k)*(dpn(i,k+1)-dpn(i,k))-.5*((c1h(k)*mu(i-1,j))+(c1h(k)*mu(i,j))))
866 DO k = k_start, k_end
867 DO i = i_start_up, i_end_up
868 u(i,k,j)=u(i,k,j)-dts*cqu(i,k,j)*dpxy(i,k)+(c1h(k)*mudf_xy(i))
873 v_outer_j_loop: DO j = j_start_v_tend, j_end_v_tend
874 DO k = k_start, k_end
875 DO i = i_start, i_end
876 v(i,k,j) = v(i,k,j) + dts*rv_tend(i,k,j)
879 DO i = i_start, i_end
880 MUDF_XY(i)= -emdiv*dy*(MUDF(i,j)-MUDF(i,j-1))*msfvx_inv(i,j)
882 IF ( ( j >= j_start_vp) &
883 .and.( j <= j_end_vp ) ) THEN
884 DO k = k_start, k_end
885 DO i = i_start, i_end
886 ! Comments on map scale factors:
887 ! y pressure gradient: ADT eqn 45, penultimate term on RHS
888 ! = -(my/mx)*(mu/rho)*partial dp/dy
889 ! [i.e., first rho->mu; 2nd still rho; alpha=1/rho]
890 ! Klemp et al. splits into 2 terms:
891 ! mu alpha partial dp/dy + partial dp/dnu * partial dphi/dy
893 ! mu alpha partial dp'/dy + nu mu alpha' partial dmubar/dy +
894 ! + mu partial dphi/dy + partial dphi'/dy * (partial dp'/dnu - mu')
897 ! ph, alt, p, al, pb not coupled
898 ! since we want tendency to fit ADT eqn 45 (coupled) we need to
899 ! multiply by (my/mx):
900 ! mudf_xy is NOT a map scale factor coupling
901 ! it is some sort of divergence damping
902 dpxy(i,k)= (msfvy(i,j)/msfvx(i,j))*.5*rdy*(c1h(k)*muv(i,j)+c2h(k))*( &
903 ((ph(i,k+1,j)-ph(i,k+1,j-1))+(ph (i,k,j)-ph (i,k,j-1))) &
904 +(alt(i,k ,j)+alt(i,k ,j-1))*(p (i,k,j)-p (i,k,j-1)) &
905 +(al (i,k ,j)+al (i,k ,j-1))*(pb (i,k,j)-pb (i,k,j-1)) )
908 IF (non_hydrostatic) THEN
909 DO i = i_start, i_end
910 dpn(i,1) = .5*( cf1*(p(i,1,j)+p(i,1,j-1)) &
911 +cf2*(p(i,2,j)+p(i,2,j-1)) &
912 +cf3*(p(i,3,j)+p(i,3,j-1)) )
916 DO i = i_start, i_end
917 dpn(i,kde) =.5*( cf1*(p(i,kde-1,j-1)+p(i,kde-1,j)) &
918 +cf2*(p(i,kde-2,j-1)+p(i,kde-2,j)) &
919 +cf3*(p(i,kde-3,j-1)+p(i,kde-3,j)) )
922 DO k = k_start+1, k_end
923 DO i = i_start, i_end
924 dpn(i,k) = .5*( fnm(k)*(p(i,k ,j)+p(i,k ,j-1)) &
925 +fnp(k)*(p(i,k-1,j)+p(i,k-1,j-1)) )
928 ! Comments on map scale factors:
930 ! php, dpn, mu not coupled
931 ! since we want tendency to fit ADT eqn 45 (coupled) we need to
932 ! multiply by (my/mx):
933 DO k = k_start, k_end
934 DO i = i_start, i_end
935 dpxy(i,k)=dpxy(i,k) + (msfvy(i,j)/msfvx(i,j))*rdy*(php(i,k,j)-php(i,k,j-1))* &
936 (rdnw(k)*(dpn(i,k+1)-dpn(i,k))-.5*((c1h(k)*mu(i,j-1))+(c1h(k)*mu(i,j))))
940 DO k = k_start, k_end
941 DO i = i_start, i_end
942 v(i,k,j)=v(i,k,j)-dts*cqv(i,k,j)*dpxy(i,k)+(c1h(k)*mudf_xy(i))
947 ! The check for j_start_vp and j_end_vp makes sure that the edges in v
948 ! are not updated. Let's add a polar boundary condition check here for
949 ! safety to ensure that v at the poles never gets to be non-zero in the
951 IF (config_flags%polar) THEN
953 DO k = k_start, k_end
954 DO i = i_start, i_end
960 DO k = k_start, k_end
961 DO i = i_start, i_end
967 END SUBROUTINE advance_uv
968 !---------------------------------------------------------------------
969 SUBROUTINE advance_mu_t( ww, ww_1, u, u_1, v, v_1, &
970 mu, mut, muave, muts, muu, muv, mudf,&
971 c1h, c2h, c1f, c2f, &
972 c3h, c4h, c3f, c4f, &
973 uam, vam, wwam, t, t_1, &
974 t_ave, ft, mu_tend, &
975 rdx, rdy, dts, epssm, &
976 dnw, fnm, fnp, rdnw, &
977 msfux, msfuy, msfvx, msfvx_inv, &
978 msfvy, msftx, msfty, &
979 step, config_flags, &
980 ids, ide, jds, jde, kds, kde, &
981 ims, ime, jms, jme, kms, kme, &
982 its, ite, jts, jte, kts, kte )
983 IMPLICIT NONE ! religion first
985 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
986 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
987 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
988 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
989 INTEGER, INTENT(IN ) :: step
990 REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
998 REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
1008 REAL, DIMENSION( ims:ime , jms:jme ), INTENT(IN ) :: muu, &
1019 REAL, DIMENSION( ims:ime , jms:jme ), INTENT( OUT) :: muave, &
1022 REAL, DIMENSION( ims:ime , jms:jme ), INTENT(INOUT) :: mu
1023 REAL, DIMENSION( kms:kme ), INTENT(IN ) :: fnm, &
1027 REAL, INTENT(IN ) :: rdx, &
1031 REAL, DIMENSION( kms:kme ),INTENT(IN ) :: c1h, c2h, c1f, c2f, &
1033 ! Local arrays from the stack (note tile size)
1034 REAL, DIMENSION (its:ite, kts:kte) :: wdtn, dvdxi
1035 REAL, DIMENSION (its:ite) :: dmdt
1036 INTEGER :: i, j, k, kk, i_start, i_end, j_start, j_end, k_start, k_end
1037 INTEGER :: i_endu, j_endv
1041 ! advance_mu_t advances the explicit perturbation theta equation and the mass
1042 ! conservation equation. In addition, the small timestep omega is updated,
1043 ! and some quantities needed in other places are squirrelled away.
1046 ! now, the real work.
1047 ! set the loop bounds taking into account boundary conditions.
1049 i_end = min(ite,ide-1)
1051 j_end = min(jte,jde-1)
1054 IF ( .NOT. config_flags%periodic_x )THEN
1055 IF ( config_flags%specified .or. config_flags%nested ) then
1056 i_start = max(its,ids+1)
1057 i_end = min(ite,ide-2)
1060 IF ( config_flags%specified .or. config_flags%nested ) then
1061 j_start = max(jts,jds+1)
1062 j_end = min(jte,jde-2)
1066 ! CALCULATION OF WW (dETA/dt)
1067 DO j = j_start, j_end
1071 ! NOTE: mu is not coupled with the map scale factor.
1072 ! ww (omega) IS coupled with the map scale factor.
1073 ! Being coupled with the map scale factor means
1074 ! multiplication by (1/msft) in this case.
1075 ! Comments on map scale factors
1077 ! partial drho/dt = -mx*my[partial d/dx(rho u/my) + partial d/dy(rho v/mx)]
1078 ! -partial d/dz(rho w)
1079 ! with rho -> mu, dividing by my, and with partial d/dnu(rho nu/my [=ww])
1080 ! as the final term (because we're looking for d_nu_/dt)
1082 ! begin by integrating with respect to nu from bottom to top
1083 ! BCs are ww=0 at both
1084 ! final term gives 0
1085 ! first term gives Integral([1/my]partial d mu/dt) over total column = dm/dt
1086 ! RHS remaining is Integral(-mx[partial d/dx(mu u/my) +
1087 ! partial d/dy(mu v/mx)]) over column
1088 ! lines below find RHS terms at each level then set dmdt = sum over all levels
1090 ! [don't divide the below by msfty until find ww, since dmdt is used in
1094 dvdxi(i,k) = msftx(i,j)*msfty(i,j)*( &
1095 rdy*( (v(i,k,j+1)+(c1h(k)*muv(i,j+1)+c2h(k))*v_1(i,k,j+1)*msfvx_inv(i,j+1)) &
1096 -(v(i,k,j )+(c1h(k)*muv(i,j )+c2h(k))*v_1(i,k,j )*msfvx_inv(i,j )) ) &
1097 +rdx*( (u(i+1,k,j)+(c1h(k)*muu(i+1,j)+c2h(k))*u_1(i+1,k,j)/msfuy(i+1,j)) &
1098 -(u(i,k,j )+(c1h(k)*muu(i ,j)+c2h(k))*u_1(i,k,j )/msfuy(i ,j)) ))
1099 DMDT(i) = DMDT(i) + dnw(k)*dvdxi(i,k)
1103 MUAVE(i,j) = MU(i,j)
1104 MU(i,j) = MU(i,j)+dts*(DMDT(i)+MU_TEND(i,j))
1105 MUDF(i,j) = (DMDT(i)+MU_TEND(i,j)) ! save tendency for div damp filter
1106 MUTS(i,j) = MUT(i,j)+MU(i,j)
1107 MUAVE(i,j) =.5*((1.+epssm)*MU(i,j)+(1.-epssm)*MUAVE(i,j))
1112 ww(i,kk,j)=ww(i,kk-1,j)-dnw(kk-1)*((c1h(k)*dmdt(i))+dvdxi(i,kk-1)+(c1h(k)*mu_tend(i,j)))/msfty(i,j)
1115 ! NOTE: ww_1 (large timestep ww) is already coupled with the
1119 ww(i,k,j)=ww(i,k,j)-ww_1(i,k,j)
1123 ! CALCULATION OF THETA
1124 ! NOTE: theta'' is not coupled with the map-scale factor,
1125 ! while the theta'' tendency is coupled (i.e., mult by 1/msft)
1126 ! Comments on map scale factors
1127 ! BUT NOTE THAT both are mass coupled
1128 ! in flux form equations (Klemp et al.) Theta = mu*theta
1130 ! scalar eqn: partial d/dt(rho q/my) = -mx[partial d/dx(q rho u/my) +
1131 ! partial d/dy(q rho v/mx)]
1132 ! - partial d/dz(q rho w/my)
1133 ! with rho -> mu, and with partial d/dnu(q rho nu/my) as the final term
1135 ! adding previous tendency contribution which was map scale factor coupled
1136 ! (had been divided by msfty)
1137 ! need to uncouple before updating uncoupled Theta (by adding)
1141 t_ave(i,k,j) = t(i,k,j)
1142 t (i,k,j) = t(i,k,j) + msfty(i,j)*dts*ft(i,k,j)
1153 ! for scalar eqn RHS term 3
1154 wdtn(i,k)= ww(i,k,j)*(fnm(k)*t_1(i,k ,j)+fnp(k)*t_1(i,k-1,j))
1157 ! scalar eqn, RHS terms 1, 2 and 3
1158 ! multiply by msfty to uncouple result for Theta from map scale factor
1161 ! multiplication by msfty uncouples result for Theta
1162 t(i,k,j) = t(i,k,j) - dts*msfty(i,j)*( &
1163 ! multiplication by mx needed for RHS terms 1 & 2
1166 ( v(i,k,j+1)*(t_1(i,k,j+1)+t_1(i,k, j )) &
1167 -v(i,k,j )*(t_1(i,k, j )+t_1(i,k,j-1)) ) &
1169 ( u(i+1,k,j)*(t_1(i+1,k,j)+t_1(i ,k,j)) &
1170 -u(i ,k,j)*(t_1(i ,k,j)+t_1(i-1,k,j)) ) ) &
1171 + rdnw(k)*( wdtn(i,k+1)-wdtn(i,k) ) )
1175 END SUBROUTINE advance_mu_t
1177 !------------------------------------------------------------
1178 SUBROUTINE advance_w( w, rw_tend, ww, w_save, u, v, &
1179 mu1, mut, muave, muts, &
1180 c1h, c2h, c1f, c2f, &
1181 c3h, c4h, c3f, c4f, &
1183 ph, ph_1, phb, ph_tend, &
1184 ht, c2a, cqw, alt, alb, &
1186 rdx, rdy, dts, t0, epssm, &
1187 dnw, fnm, fnp, rdnw, rdn, &
1188 cf1, cf2, cf3, msftx, msfty,&
1189 config_flags, top_lid, &
1190 ids,ide, jds,jde, kds,kde, & ! domain dims
1191 ims,ime, jms,jme, kms,kme, & ! memory dims
1192 its,ite, jts,jte, kts,kte ) ! tile dims
1193 ! We have used msfty for msft_inv but have not thought through w equation
1194 ! pieces properly yet, so we will have to hope that it is okay
1195 ! We think we have found a slight error in surface w calculation
1196 IMPLICIT NONE ! religion first
1199 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
1200 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
1201 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
1202 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
1203 LOGICAL, INTENT(IN ) :: top_lid
1204 REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), &
1209 REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
1228 REAL, DIMENSION( ims:ime , jms:jme ), &
1237 REAL, DIMENSION( kms:kme ), INTENT(IN ) :: fnp, &
1242 REAL, INTENT(IN ) :: rdx, &
1250 REAL, DIMENSION( kms:kme ),INTENT(IN ) :: c1h, c2h, c1f, c2f, &
1252 ! Stack based 3d data, tile size.
1253 REAL, DIMENSION( its:ite ) :: mut_inv, msft_inv
1254 REAL, DIMENSION( its:ite, kts:kte ) :: rhs, wdwn
1255 INTEGER :: i,j,k, i_start, i_end, j_start, j_end, k_start, k_end
1256 REAL, DIMENSION (kts:kte) :: dampwt
1257 real :: htop,hbot,hdepth,hk
1259 REAL :: muthk, muthkm1
1262 ! advance_w advances the implicit w and geopotential equations.
1266 ! Currently set for periodic boundary conditions
1268 i_end = min(ite,ide-1)
1270 j_end = min(jte,jde-1)
1273 IF ( .NOT. config_flags%periodic_x )THEN
1274 IF ( config_flags%specified .or. config_flags%nested ) then
1275 i_start = max(its,ids+1)
1276 i_end = min(ite,ide-2)
1279 IF ( config_flags%specified .or. config_flags%nested ) then
1280 j_start = max(jts,jds+1)
1281 j_end = min(jte,jde-2)
1284 dampmag = dts*config_flags%dampcoef
1285 hdepth=config_flags%zdamp
1286 ! calculation of phi and w equations
1287 ! Comments on map scale factors:
1289 ! partial d/dt(rho phi/my) = -mx partial d/dx(phi rho u/my)
1290 ! -mx partial d/dy(phi rho v/mx)
1291 ! - partial d/dz(phi rho w/my) + rho g w/my
1292 ! as with scalar equation, use uncoupled value (here phi) to find the
1293 ! coupled tendency (rho phi/my)
1294 ! here as usual rho -> ~'mu'
1296 ! w eqn [divided by my] is:
1297 ! partial d/dt(rho w/my) = -mx partial d/dx(w rho u/my)
1298 ! -mx partial d/dy(v rho v/mx)
1299 ! - partial d/dz(w rho w/my)
1300 ! +rho[(u*u+v*v)/a + 2 u omega cos(lat) -
1301 ! (1/rho) partial dp/dz - g + Fz]/my
1302 ! here as usual rho -> ~'mu'
1304 ! 'u,v,w' sent here must be coupled variables (= rho w/my etc.) by their usage
1308 j_loop_w: DO j = j_start, j_end
1310 msft_inv(i) = 1./msfty(i,j)
1314 t_2ave(i,k,j)=.5*((1.+epssm)*t_2(i,k,j) &
1315 +(1.-epssm)*t_2ave(i,k,j))
1316 t_2ave(i,k,j)=(t_2ave(i,k,j) + (c1h(k)*Muave(i,j))*t0) &
1317 /((c1h(k)*Muts(i,j)+c2h(k))*(t0+t_1(i,k,j)))
1318 rhs(i,k+1) = dts*(ph_tend(i,k+1,j) + .5*g*(1.-epssm)*w(i,k+1,j))
1321 ! building up RHS of phi equation
1322 ! ph_tend contains terms 1 and 2; now adding 3 and 4 in stages:
1323 ! here rhs = delta t [ph_tend + ~g*w/2 - ~ww * partial d phi/dz]
1324 IF (config_flags%phi_adv_z == 2) THEN
1325 ! First get staggered partial d/dnu(phi) and then multiply with omega
1326 ! to avoid double staggering of omega
1330 wdwn(i,k+1)=rdnw(k)*(ph_1(i,k+1,j)-ph_1(i,k,j)+phb(i,k+1,j)-phb(i,k,j))
1336 rhs(i,k) = rhs(i,k)-dts*ww(i,k,j)*( fnm(k)*wdwn(i,k+1) &
1337 +fnp(k)*wdwn(i,k ) )
1341 ! First destagger omega and multiply with partial d/dnu(phi), then stagger the product
1345 wdwn(i,k+1)=.5*(ww(i,k+1,j)+ww(i,k,j))*rdnw(k) &
1346 *(ph_1(i,k+1,j)-ph_1(i,k,j)+phb(i,k+1,j)-phb(i,k,j))
1352 rhs(i,k) = rhs(i,k)-dts*( fnm(k)*wdwn(i,k+1) &
1353 +fnp(k)*wdwn(i,k ) )
1357 ! NOTE: phi'' is not coupled with the map-scale factor (1/m),
1358 ! but it's tendency is, so must multiply by msft here
1359 ! Comments on map scale factors:
1360 ! building up RHS of phi equation
1361 ! ph_tend contains terms 1 and 2; now adding 3 and 4 in stages:
1362 ! here rhs = ph_previous + (msft/mu)*[rhs_previous - ~ww * delta t *
1364 ! = ph_previous + (msft*delta t/mu)*[ph_tend + ~g*w/2 - ~ww *
1368 rhs(i,k) = ph(i,k,j) + msfty(i,j)*rhs(i,k)/(c1f(k)*mut(i,j)+c2f(k))
1369 if(top_lid .and. k.eq.k_end+1)rhs(i,k)=0.
1372 ! lower boundary condition on w
1373 ! Comments on map scale factors:
1374 ! Chain rule: if Z=Z(X,Y) [true at the surface] then
1375 ! dZ/dt = dZ/dX * dX/dt + dZ/dY * dY/dt, U=dX/dt, V=dY/dt
1376 ! using capitals to denote actual values
1377 ! In mapped values, u=U, v=V, z=Z, 1/dX=mx/dx, 1/dY=my/dy
1378 ! w = dz/dt = mx u dz/dx + my v dz/dy
1379 ! [where dz/dx is just the surface height change between x
1380 ! gridpoints, and dz/dy is the change between y gridpoints]
1381 ! [cf1, cf2 and cf3 do vertical weighting of u or v values nearest
1385 msfty(i,j)*.5*rdy*( &
1386 (ht(i,j+1)-ht(i,j )) &
1387 *(cf1*v(i,1,j+1)+cf2*v(i,2,j+1)+cf3*v(i,3,j+1)) &
1388 +(ht(i,j )-ht(i,j-1)) &
1389 *(cf1*v(i,1,j )+cf2*v(i,2,j )+cf3*v(i,3,j )) ) &
1390 +msftx(i,j)*.5*rdx*( &
1391 (ht(i+1,j)-ht(i,j )) &
1392 *(cf1*u(i+1,1,j)+cf2*u(i+1,2,j)+cf3*u(i+1,3,j)) &
1393 +(ht(i,j )-ht(i-1,j)) &
1394 *(cf1*u(i ,1,j)+cf2*u(i ,2,j)+cf3*u(i ,3,j)) )
1397 ! Jammed 3 doubly nested loops over k/i into 1 for slight improvement
1398 ! in efficiency. No change in results (bit-for-bit). JM 20040514
1399 ! (left a blank line where the other two k/i-loops were)
1401 ! above surface, begin by adding delta t * previous (coupled) w tendency
1405 w(i,k,j)=w(i,k,j)+dts*rw_tend(i,k,j) &
1406 + msft_inv(i)*cqw(i,k,j)*( &
1408 (c2a(i,k ,j)*rdnw(k )/(c1h(k)*MUT(i,j)+c2h(k)) &
1409 *((1.+epssm)*(rhs(i,k+1 )-rhs(i,k )) &
1410 +(1.-epssm)*(ph(i,k+1,j)-ph(i,k ,j))) &
1411 -c2a(i,k-1,j)*rdnw(k-1)/(c1h(k-1)*MUT(i,j)+c2h(k-1)) &
1412 *((1.+epssm)*(rhs(i,k )-rhs(i,k-1 )) &
1413 +(1.-epssm)*(ph(i,k ,j)-ph(i,k-1,j))))) &
1414 +dts*g*msft_inv(i)*(rdn(k)* &
1415 (c2a(i,k ,j)*alt(i,k ,j)*t_2ave(i,k ,j) &
1416 -c2a(i,k-1,j)*alt(i,k-1,j)*t_2ave(i,k-1,j)) &
1417 - (c1f(k)*muave(i,j)))
1422 w(i,k,j)=w(i,k,j)+dts*rw_tend(i,k,j) &
1424 -.5*dts*g/(c1h(k-1)*MUT(i,j)+c2h(k-1))*rdnw(k-1)**2*2.*c2a(i,k-1,j) &
1425 *((1.+epssm)*(rhs(i,k )-rhs(i,k-1 )) &
1426 +(1.-epssm)*(ph(i,k,j)-ph(i,k-1,j))) &
1427 -dts*g*(2.*rdnw(k-1)* &
1428 c2a(i,k-1,j)*alt(i,k-1,j)*t_2ave(i,k-1,j) &
1429 + (c1f(k)*muave(i,j))) )
1430 if(top_lid)w(i,k,j) = 0.
1435 w(i,k,j)=(w(i,k,j)-a(i,k,j)*w(i,k-1,j))*alpha(i,k,j)
1441 w (i,k,j)=w (i,k,j)-gamma(i,k,j)*w(i,k+1,j)
1445 IF (config_flags%damp_opt .eq. 3) THEN
1448 htop=(ph_1(i,k_end+1,j)+phb(i,k_end+1,j))/g
1449 hk=(ph_1(i,k,j)+phb(i,k,j))/g
1452 if(hk .ge. hbot)then
1453 dampwt(k) = dampmag*sin(0.5*pi*(hk-hbot)/hdepth)*sin(0.5*pi*(hk-hbot)/hdepth)
1455 w(i,k,j) = (w(i,k,j) - dampwt(k)*(c1f(k)*mut(i,j)+c2f(k))*w_save(i,k,j))/(1.+dampwt(k))
1462 ph(i,k,j) = rhs(i,k)+msfty(i,j)*.5*dts*g*(1.+epssm) &
1463 *w(i,k,j)/(c1f(k)*muts(i,j)+c2f(k))
1469 END SUBROUTINE advance_w
1471 !---------------------------------------------------------------------
1473 SUBROUTINE sumflux ( ru, rv, ww, &
1474 u_lin, v_lin, ww_lin, &
1476 c1h, c2h, c1f, c2f, &
1477 c3h, c4h, c3f, c4f, &
1478 ru_m, rv_m, ww_m, epssm, &
1479 msfux, msfuy, msfvx, msfvx_inv, msfvy, &
1480 iteration , number_of_small_timesteps, &
1481 ids,ide, jds,jde, kds,kde, &
1482 ims,ime, jms,jme, kms,kme, &
1483 its,ite, jts,jte, kts,kte )
1486 IMPLICIT NONE ! religion first
1488 ! declarations for the stuff coming in
1490 INTEGER, INTENT(IN ) :: number_of_small_timesteps
1491 INTEGER, INTENT(IN ) :: iteration
1492 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
1493 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
1494 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
1496 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(IN ) :: ru, &
1504 REAL, DIMENSION(ims:ime, kms:kme, jms:jme) , INTENT(INOUT) :: ru_m, &
1507 REAL, DIMENSION(ims:ime, jms:jme) , INTENT(IN ) :: muu, muv, &
1509 msfvx, msfvy, msfvx_inv
1511 REAL, DIMENSION( kms:kme ),INTENT(IN ) :: c1h, c2h, c1f, c2f, &
1514 INTEGER :: mini, minj, mink
1517 REAL, INTENT(IN ) :: epssm
1523 ! update the small-timestep time-averaged mass fluxes; these
1524 ! are needed for consistent mass-conserving scalar advection.
1528 IF (iteration == 1 )THEN
1540 mini = min(ide-1,ite)
1541 minj = min(jde-1,jte)
1542 mink = min(kde-1,kte)
1548 ru_m(i,k,j) = ru_m(i,k,j) + ru(i,k,j)
1549 rv_m(i,k,j) = rv_m(i,k,j) + rv(i,k,j)
1550 ww_m(i,k,j) = ww_m(i,k,j) + ww(i,k,j)
1555 IF (ite .GT. mini) THEN
1559 ru_m(i,k,j) = ru_m(i,k,j) + ru(i,k,j)
1564 IF (jte .GT. minj) THEN
1568 rv_m(i,k,j) = rv_m(i,k,j) + rv(i,k,j)
1573 IF ( kte .GT. mink) THEN
1577 ww_m(i,k,j) = ww_m(i,k,j) + ww(i,k,j)
1583 IF (iteration == number_of_small_timesteps) THEN
1588 ru_m(i,k,j) = ru_m(i,k,j) / number_of_small_timesteps &
1589 + (c1h(k)*muu(i,j)+c2h(k))*u_lin(i,k,j)/msfuy(i,j)
1590 rv_m(i,k,j) = rv_m(i,k,j) / number_of_small_timesteps &
1591 + (c1h(k)*muv(i,j)+c2h(k))*v_lin(i,k,j)*msfvx_inv(i,j)
1592 ww_m(i,k,j) = ww_m(i,k,j) / number_of_small_timesteps &
1599 IF (ite .GT. mini) THEN
1603 ru_m(i,k,j) = ru_m(i,k,j) / number_of_small_timesteps &
1604 + (c1h(k)*muu(i,j)+c2h(k))*u_lin(i,k,j)/msfuy(i,j)
1609 IF (jte .GT. minj) THEN
1613 rv_m(i,k,j) = rv_m(i,k,j) / number_of_small_timesteps &
1614 + (c1h(k)*muv(i,j)+c2h(k))*v_lin(i,k,j)*msfvx_inv(i,j)
1619 IF ( kte .GT. mink) THEN
1623 ww_m(i,k,j) = ww_m(i,k,j) / number_of_small_timesteps &
1633 END SUBROUTINE sumflux
1635 !---------------------------------------------------------------------
1637 SUBROUTINE init_module_small_step
1638 END SUBROUTINE init_module_small_step
1640 #if ( WRFPLUS == 1 )
1641 !----------------------------------------------------------------------
1642 SUBROUTINE advance_all (u, ru_tend, v, rv_tend, &
1643 w, rw_tend, t, t_tend, &
1644 mu, mu_tend, ph, ph_tend, &
1646 msfuy, msfvx, msfty, &
1648 config_flags, spec_zone, &
1649 ids, ide, jds, jde, kds, kde, &
1650 ims, ime, jms, jme, kms, kme, &
1651 ips, ipe, jps, jpe, kps, kpe, &
1652 its, ite, jts, jte, kts, kte )
1654 IMPLICIT NONE ! religion first
1656 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
1658 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
1659 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
1660 INTEGER, INTENT(IN ) :: ips,ipe, jps,jpe, kps,kpe
1661 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
1662 INTEGER, INTENT(IN ) :: spec_zone
1664 REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
1672 REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
1680 REAL, DIMENSION( ims:ime , jms:jme ), INTENT(INOUT) :: mu
1681 REAL, DIMENSION( ims:ime , jms:jme ), INTENT(IN ) :: mu_tend
1683 REAL, DIMENSION( ims:ime , jms:jme ), INTENT(IN ) :: muu, &
1687 REAL, DIMENSION( ims:ime , jms:jme ), INTENT(IN ) :: msfuy, &
1691 REAL, INTENT(IN ) :: dts
1694 INTEGER :: i,j,k, i_start, i_end, j_start, j_end, k_start, k_end
1695 INTEGER :: i_endu, j_endv, k_endw
1697 INTEGER :: i_start_u_tend, i_end_u_tend, j_start_v_tend, j_end_v_tend
1701 ! advance_all advances the explicit perturbation horizontal momentum
1702 ! equations (u,v) by adding in the large-timestep tendency along with
1703 ! the small timestep pressure gradient tendency.
1707 ! now, the real work.
1708 ! set the loop bounds taking into account boundary conditions.
1710 IF( config_flags%nested .or. config_flags%specified ) THEN
1711 i_start = max( its,ids+spec_zone )
1712 i_end = min( ite,ide-spec_zone-1 )
1713 j_start = max( jts,jds+spec_zone )
1714 j_end = min( jte,jde-spec_zone-1 )
1716 k_end = min( kte, kde-1 )
1718 i_endu = min( ite,ide-spec_zone )
1719 j_endv = min( jte,jde-spec_zone )
1722 IF( config_flags%periodic_x) THEN
1724 i_end = min(ite,ide-1)
1729 i_end = min(ite,ide-1)
1731 j_end = min(jte,jde-1)
1740 i_start_u_tend = i_start
1741 i_end_u_tend = i_endu
1742 j_start_v_tend = j_start
1743 j_end_v_tend = j_endv
1745 IF ( config_flags%symmetric_xs .and. (its == ids) ) &
1746 i_start_u_tend = i_start_u_tend+1
1747 IF ( config_flags%symmetric_xe .and. (ite == ide) ) &
1748 i_end_u_tend = i_end_u_tend-1
1749 IF ( config_flags%symmetric_ys .and. (jts == jds) ) &
1750 j_start_v_tend = j_start_v_tend+1
1751 IF ( config_flags%symmetric_ye .and. (jte == jde) ) &
1752 j_end_v_tend = j_end_v_tend-1
1754 u_outer_j_loop: DO j = j_start, j_end
1755 DO k = k_start, k_end
1756 DO i = i_start_u_tend, i_end_u_tend
1757 u(i,k,j) = u(i,k,j) + dts*ru_tend(i,k,j)*msfuy(i,j)/muu(i,j)
1760 ENDDO u_outer_j_loop
1762 v_outer_j_loop: DO j = j_start_v_tend, j_end_v_tend
1763 DO k = k_start, k_end
1764 DO i = i_start, i_end
1765 v(i,k,j) = v(i,k,j) + dts*rv_tend(i,k,j)*msfvx(i,j)/muv(i,j)
1768 ENDDO v_outer_j_loop
1771 i_end = min(ite,ide-1)
1773 j_end = min(jte,jde-1)
1776 IF ( .NOT. config_flags%periodic_x )THEN
1777 IF ( config_flags%specified .or. config_flags%nested ) then
1778 i_start = max(its,ids+1)
1779 i_end = min(ite,ide-2)
1782 IF ( config_flags%specified .or. config_flags%nested ) then
1783 j_start = max(jts,jds+1)
1784 j_end = min(jte,jde-2)
1787 DO j = j_start, j_end
1789 mu(i,j) = mu(i,j)+dts*mu_tend(i,j)
1796 t(i,k,j) = t(i,k,j) + msfty(i,j)*dts*t_tend(i,k,j)/mut(i,j)
1802 i_end = min(ite,ide-1)
1804 j_end = min(jte,jde-1)
1807 IF ( .NOT. config_flags%periodic_x )THEN
1808 IF ( config_flags%specified .or. config_flags%nested ) then
1809 i_start = max(its,ids+1)
1810 i_end = min(ite,ide-2)
1813 IF ( config_flags%specified .or. config_flags%nested ) then
1814 j_start = max(jts,jds+1)
1815 j_end = min(jte,jde-2)
1818 IF ( config_flags%non_hydrostatic ) THEN
1819 j_loop_w: DO j = j_start, j_end
1822 w(i,k,j)=w(i,k,j)+dts*rw_tend(i,k,j)*msfty(i,j)/mut(i,j)
1823 ph(i,k,j) = ph(i,k,j)+dts*ph_tend(i,k,j)*msfty(i,j)/mut(i,j)
1829 END SUBROUTINE advance_all
1831 !----------------------------------------------------------------------
1833 SUBROUTINE save_ph_mu ( ph_1, ph_2, ph_save, &
1834 mu_1, mu_2, mu_save, &
1836 ids,ide, jds,jde, kds,kde, &
1837 ims,ime, jms,jme, kms,kme, &
1838 its,ite, jts,jte, kts,kte )
1840 IMPLICIT NONE ! religion first
1842 ! declarations for the stuff coming in
1844 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
1845 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
1846 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
1848 INTEGER, INTENT(IN ) :: rk_step
1850 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(INOUT) :: ph_1
1851 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT( OUT) :: ph_save
1852 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(INOUT) :: ph_2
1853 REAL, DIMENSION(ims:ime, jms:jme), INTENT(INOUT) :: mu_1,mu_2
1854 REAL, DIMENSION(ims:ime, jms:jme), INTENT( OUT) :: mu_save
1859 INTEGER :: i_start, i_end, j_start, j_end, k_start, k_end
1863 i_end = min(ite,ide-1)
1865 j_end = min(jte,jde-1)
1867 k_end = min(kte,kde-1)
1869 ! if this is the first RK step, reset *_1 to *_2
1870 ! (we are replacing the t-dt fields with the time t fields)
1872 IF ((rk_step == 1) ) THEN
1875 DO k=k_start, min(kde,kte)
1877 ph_1(i,k,j) = ph_2(i,k,j)
1890 ! set up the small timestep variables
1893 ! DO k=k_start, min(kde,kte)
1896 ph_save(i,k,j) = ph_2(i,k,j)
1897 ph_2(i,k,j) = ph_1(i,k,j)-ph_2(i,k,j)
1904 mu_save(i,j)=mu_2(i,j)
1905 mu_2(i,j)=mu_1(i,j)-mu_2(i,j)
1909 END SUBROUTINE save_ph_mu
1911 !----------------------------------------------------------------------
1913 SUBROUTINE restore_ph_mu ( ph_2, ph_save, &
1915 ids,ide, jds,jde, kds,kde, &
1916 ims,ime, jms,jme, kms,kme, &
1917 its,ite, jts,jte, kts,kte )
1919 IMPLICIT NONE ! religion first
1921 ! declarations for the stuff coming in
1923 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
1924 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
1925 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
1927 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(IN ) :: ph_save
1928 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(INOUT) :: ph_2
1929 REAL, DIMENSION(ims:ime, jms:jme), INTENT(INOUT) :: mu_2
1930 REAL, DIMENSION(ims:ime, jms:jme), INTENT(IN ) :: mu_save
1935 INTEGER :: i_start, i_end, j_start, j_end
1939 i_end = min(ite,ide-1)
1941 j_end = min(jte,jde-1)
1943 DO j = j_start, j_end
1945 DO i = i_start, i_end
1946 ph_2(i,k,j) = ph_2(i,k,j) + ph_save(i,k,j)
1951 DO j = j_start, j_end
1952 DO i = i_start, i_end
1953 mu_2(i,j) = mu_2(i,j) + mu_save(i,j)
1957 END SUBROUTINE restore_ph_mu
1958 !----------------------------------------------------------------------
1961 END MODULE module_small_step_em