/wrfv2_fire/dyn_em/module_big_step_utilities_em.F
FORTRAN Legacy | 6155 lines | 3822 code | 1351 blank | 982 comment | 56 complexity | 28eae140e72dd9b7b229817c61222a96 MD5 | raw file
Possible License(s): AGPL-1.0
Large files files are truncated, but you can click here to view the full file
- !wrf:MODEL_LAYER:DYNAMICS
- !
- #if (RWORDSIZE == 4)
- # define VPOWX vspowx
- # define VPOW vspow
- #else
- # define VPOWX vpowx
- # define VPOW vpow
- #endif
- MODULE module_big_step_utilities_em
- USE module_model_constants
- USE module_state_description, only: p_qg, p_qs, p_qi, gdscheme, tiedtkescheme, kfetascheme, g3scheme, &
- p_qv, param_first_scalar, p_qr, p_qc
- USE module_configure, ONLY : grid_config_rec_type
- CONTAINS
- !-------------------------------------------------------------------------------
- SUBROUTINE calc_mu_uv ( config_flags, &
- mu, mub, muu, muv, &
- ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte )
- IMPLICIT NONE
-
- ! Input data
- TYPE(grid_config_rec_type ) , INTENT(IN ) :: config_flags
- INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte
- REAL, DIMENSION( ims:ime , jms:jme ) , INTENT( OUT) :: muu, muv
- REAL, DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mu, mub
- ! local stuff
- INTEGER :: i, j, itf, jtf, im, jm
- !<DESCRIPTION>
- !
- ! calc_mu_uv calculates the full column dry-air mass at the staggered
- ! horizontal velocity points (u,v) and places the results in muu and muv.
- ! This routine uses the reference state (mub) and perturbation state (mu)
- !
- !</DESCRIPTION>
- itf=ite
- jtf=MIN(jte,jde-1)
- IF ( ( its .NE. ids ) .AND. ( ite .NE. ide ) ) THEN
- DO j=jts,jtf
- DO i=its,itf
- muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j)+mub(i,j)+mub(i-1,j))
- ENDDO
- ENDDO
- ELSE IF ( ( its .EQ. ids ) .AND. ( ite .NE. ide ) ) THEN
- DO j=jts,jtf
- DO i=its+1,itf
- muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j)+mub(i,j)+mub(i-1,j))
- ENDDO
- ENDDO
- i=its
- im = its
- if(config_flags%periodic_x) im = its-1
- DO j=jts,jtf
- ! muu(i,j) = mu(i,j) +mub(i,j)
- ! fix for periodic b.c., 13 march 2004, wcs
- muu(i,j) = 0.5*(mu(i,j)+mu(im,j)+mub(i,j)+mub(im,j))
- ENDDO
- ELSE IF ( ( its .NE. ids ) .AND. ( ite .EQ. ide ) ) THEN
- DO j=jts,jtf
- DO i=its,itf-1
- muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j)+mub(i,j)+mub(i-1,j))
- ENDDO
- ENDDO
- i=ite
- im = ite-1
- if(config_flags%periodic_x) im = ite
- DO j=jts,jtf
- ! muu(i,j) = mu(i-1,j) +mub(i-1,j)
- ! fix for periodic b.c., 13 march 2004, wcs
- muu(i,j) = 0.5*(mu(i-1,j)+mu(im,j)+mub(i-1,j)+mub(im,j))
- ENDDO
- ELSE IF ( ( its .EQ. ids ) .AND. ( ite .EQ. ide ) ) THEN
- DO j=jts,jtf
- DO i=its+1,itf-1
- muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j)+mub(i,j)+mub(i-1,j))
- ENDDO
- ENDDO
- i=its
- im = its
- if(config_flags%periodic_x) im = its-1
- DO j=jts,jtf
- ! muu(i,j) = mu(i,j) +mub(i,j)
- ! fix for periodic b.c., 13 march 2004, wcs
- muu(i,j) = 0.5*(mu(i,j)+mu(im,j)+mub(i,j)+mub(im,j))
- ENDDO
- i=ite
- im = ite-1
- if(config_flags%periodic_x) im = ite
- DO j=jts,jtf
- ! muu(i,j) = mu(i-1,j) +mub(i-1,j)
- ! fix for periodic b.c., 13 march 2004, wcs
- muu(i,j) = 0.5*(mu(i-1,j)+mu(im,j)+mub(i-1,j)+mub(im,j))
- ENDDO
- END IF
- itf=MIN(ite,ide-1)
- jtf=jte
- IF ( ( jts .NE. jds ) .AND. ( jte .NE. jde ) ) THEN
- DO j=jts,jtf
- DO i=its,itf
- muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1)+mub(i,j)+mub(i,j-1))
- ENDDO
- ENDDO
- ELSE IF ( ( jts .EQ. jds ) .AND. ( jte .NE. jde ) ) THEN
- DO j=jts+1,jtf
- DO i=its,itf
- muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1)+mub(i,j)+mub(i,j-1))
- ENDDO
- ENDDO
- j=jts
- jm = jts
- if(config_flags%periodic_y) jm = jts-1
- DO i=its,itf
- ! muv(i,j) = mu(i,j) +mub(i,j)
- ! fix for periodic b.c., 13 march 2004, wcs
- muv(i,j) = 0.5*(mu(i,j)+mu(i,jm)+mub(i,j)+mub(i,jm))
- ENDDO
- ELSE IF ( ( jts .NE. jds ) .AND. ( jte .EQ. jde ) ) THEN
- DO j=jts,jtf-1
- DO i=its,itf
- muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1)+mub(i,j)+mub(i,j-1))
- ENDDO
- ENDDO
- j=jte
- jm = jte-1
- if(config_flags%periodic_y) jm = jte
- DO i=its,itf
- muv(i,j) = mu(i,j-1) +mub(i,j-1)
- ! fix for periodic b.c., 13 march 2004, wcs
- muv(i,j) = 0.5*(mu(i,j-1)+mu(i,jm)+mub(i,j-1)+mub(i,jm))
- ENDDO
- ELSE IF ( ( jts .EQ. jds ) .AND. ( jte .EQ. jde ) ) THEN
- DO j=jts+1,jtf-1
- DO i=its,itf
- muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1)+mub(i,j)+mub(i,j-1))
- ENDDO
- ENDDO
- j=jts
- jm = jts
- if(config_flags%periodic_y) jm = jts-1
- DO i=its,itf
- ! muv(i,j) = mu(i,j) +mub(i,j)
- ! fix for periodic b.c., 13 march 2004, wcs
- muv(i,j) = 0.5*(mu(i,j)+mu(i,jm)+mub(i,j)+mub(i,jm))
- ENDDO
- j=jte
- jm = jte-1
- if(config_flags%periodic_y) jm = jte
- DO i=its,itf
- ! muv(i,j) = mu(i,j-1) +mub(i,j-1)
- ! fix for periodic b.c., 13 march 2004, wcs
- muv(i,j) = 0.5*(mu(i,j-1)+mu(i,jm)+mub(i,j-1)+mub(i,jm))
- ENDDO
- END IF
- END SUBROUTINE calc_mu_uv
- !-------------------------------------------------------------------------------
- SUBROUTINE calc_mu_uv_1 ( config_flags, &
- mu, muu, muv, &
- ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte )
- IMPLICIT NONE
-
- ! Input data
- TYPE(grid_config_rec_type ) , INTENT(IN ) :: config_flags
- INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte
- REAL, DIMENSION( ims:ime , jms:jme ) , INTENT( OUT) :: muu, muv
- REAL, DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mu
- ! local stuff
- INTEGER :: i, j, itf, jtf, im, jm
- !<DESCRIPTION>
- !
- ! calc_mu_uv calculates the full column dry-air mass at the staggered
- ! horizontal velocity points (u,v) and places the results in muu and muv.
- ! This routine uses the full state (mu)
- !
- !</DESCRIPTION>
-
- itf=ite
- jtf=MIN(jte,jde-1)
- IF ( ( its .NE. ids ) .AND. ( ite .NE. ide ) ) THEN
- DO j=jts,jtf
- DO i=its,itf
- muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j))
- ENDDO
- ENDDO
- ELSE IF ( ( its .EQ. ids ) .AND. ( ite .NE. ide ) ) THEN
- DO j=jts,jtf
- DO i=its+1,itf
- muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j))
- ENDDO
- ENDDO
- i=its
- im = its
- if(config_flags%periodic_x) im = its-1
- DO j=jts,jtf
- muu(i,j) = 0.5*(mu(i,j)+mu(im,j))
- ENDDO
- ELSE IF ( ( its .NE. ids ) .AND. ( ite .EQ. ide ) ) THEN
- DO j=jts,jtf
- DO i=its,itf-1
- muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j))
- ENDDO
- ENDDO
- i=ite
- im = ite-1
- if(config_flags%periodic_x) im = ite
- DO j=jts,jtf
- muu(i,j) = 0.5*(mu(i-1,j)+mu(im,j))
- ENDDO
- ELSE IF ( ( its .EQ. ids ) .AND. ( ite .EQ. ide ) ) THEN
- DO j=jts,jtf
- DO i=its+1,itf-1
- muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j))
- ENDDO
- ENDDO
- i=its
- im = its
- if(config_flags%periodic_x) im = its-1
- DO j=jts,jtf
- muu(i,j) = 0.5*(mu(i,j)+mu(im,j))
- ENDDO
- i=ite
- im = ite-1
- if(config_flags%periodic_x) im = ite
- DO j=jts,jtf
- muu(i,j) = 0.5*(mu(i-1,j)+mu(im,j))
- ENDDO
- END IF
- itf=MIN(ite,ide-1)
- jtf=jte
- IF ( ( jts .NE. jds ) .AND. ( jte .NE. jde ) ) THEN
- DO j=jts,jtf
- DO i=its,itf
- muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1))
- ENDDO
- ENDDO
- ELSE IF ( ( jts .EQ. jds ) .AND. ( jte .NE. jde ) ) THEN
- DO j=jts+1,jtf
- DO i=its,itf
- muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1))
- ENDDO
- ENDDO
- j=jts
- jm = jts
- if(config_flags%periodic_y) jm = jts-1
- DO i=its,itf
- muv(i,j) = 0.5*(mu(i,j)+mu(i,jm))
- ENDDO
- ELSE IF ( ( jts .NE. jds ) .AND. ( jte .EQ. jde ) ) THEN
- DO j=jts,jtf-1
- DO i=its,itf
- muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1))
- ENDDO
- ENDDO
- j=jte
- jm = jte-1
- if(config_flags%periodic_y) jm = jte
- DO i=its,itf
- muv(i,j) = 0.5*(mu(i,j-1)+mu(i,jm))
- ENDDO
- ELSE IF ( ( jts .EQ. jds ) .AND. ( jte .EQ. jde ) ) THEN
- DO j=jts+1,jtf-1
- DO i=its,itf
- muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1))
- ENDDO
- ENDDO
- j=jts
- jm = jts
- if(config_flags%periodic_y) jm = jts-1
- DO i=its,itf
- muv(i,j) = 0.5*(mu(i,j)+mu(i,jm))
- ENDDO
- j=jte
- jm = jte-1
- if(config_flags%periodic_y) jm = jte
- DO i=its,itf
- muv(i,j) = 0.5*(mu(i,j-1)+mu(i,jm))
- ENDDO
- END IF
- END SUBROUTINE calc_mu_uv_1
- !-------------------------------------------------------------------------------
- ! Map scale factor comments for this routine:
- ! Locally not changed, but sent the correct map scale factors
- ! from module_em (msfuy, msfvx, msfty)
- SUBROUTINE couple_momentum ( muu, ru, u, msfu, &
- muv, rv, v, msfv, msfv_inv, &
- mut, rw, w, msft, &
- ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte )
- IMPLICIT NONE
- ! Input data
- INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte
- REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT( OUT) :: ru, rv, rw
- REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: muu, muv, mut
- REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfu, msfv, msft, msfv_inv
-
- REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: u, v, w
-
- ! Local data
-
- INTEGER :: i, j, k, itf, jtf, ktf
-
- !<DESCRIPTION>
- !
- ! couple_momentum couples the velocities to the full column mass and
- ! the map factors.
- !
- !</DESCRIPTION>
- ktf=MIN(kte,kde-1)
-
- itf=ite
- jtf=MIN(jte,jde-1)
- DO j=jts,jtf
- DO k=kts,ktf
- DO i=its,itf
- ru(i,k,j)=u(i,k,j)*muu(i,j)/msfu(i,j)
- ENDDO
- ENDDO
- ENDDO
- itf=MIN(ite,ide-1)
- jtf=jte
- DO j=jts,jtf
- DO k=kts,ktf
- DO i=its,itf
- rv(i,k,j)=v(i,k,j)*muv(i,j)*msfv_inv(i,j)
- ! rv(i,k,j)=v(i,k,j)*muv(i,j)/msfv(i,j)
- ENDDO
- ENDDO
- ENDDO
- itf=MIN(ite,ide-1)
- jtf=MIN(jte,jde-1)
- DO j=jts,jtf
- DO k=kts,kte
- DO i=its,itf
- rw(i,k,j)=w(i,k,j)*mut(i,j)/msft(i,j)
- ENDDO
- ENDDO
- ENDDO
- END SUBROUTINE couple_momentum
- !-------------------------------------------------------------------
- SUBROUTINE calc_mu_staggered ( mu, mub, muu, muv, &
- ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte )
- IMPLICIT NONE
-
- ! Input data
- INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte
- REAL, DIMENSION( ims:ime , jms:jme ) , INTENT( OUT) :: muu, muv
- REAL, DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mu, mub
- ! local stuff
- INTEGER :: i, j, itf, jtf
- !<DESCRIPTION>
- !
- ! calc_mu_staggered calculates the full dry air mass at the staggered
- ! velocity points (u,v).
- !
- !</DESCRIPTION>
-
- itf=ite
- jtf=MIN(jte,jde-1)
- IF ( ( its .NE. ids ) .AND. ( ite .NE. ide ) ) THEN
- DO j=jts,jtf
- DO i=its,itf
- muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j)+mub(i,j)+mub(i-1,j))
- ENDDO
- ENDDO
- ELSE IF ( ( its .EQ. ids ) .AND. ( ite .NE. ide ) ) THEN
- DO j=jts,jtf
- DO i=its+1,itf
- muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j)+mub(i,j)+mub(i-1,j))
- ENDDO
- ENDDO
- i=its
- DO j=jts,jtf
- muu(i,j) = mu(i,j) +mub(i,j)
- ENDDO
- ELSE IF ( ( its .NE. ids ) .AND. ( ite .EQ. ide ) ) THEN
- DO j=jts,jtf
- DO i=its,itf-1
- muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j)+mub(i,j)+mub(i-1,j))
- ENDDO
- ENDDO
- i=ite
- DO j=jts,jtf
- muu(i,j) = mu(i-1,j) +mub(i-1,j)
- ENDDO
- ELSE IF ( ( its .EQ. ids ) .AND. ( ite .EQ. ide ) ) THEN
- DO j=jts,jtf
- DO i=its+1,itf-1
- muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j)+mub(i,j)+mub(i-1,j))
- ENDDO
- ENDDO
- i=its
- DO j=jts,jtf
- muu(i,j) = mu(i,j) +mub(i,j)
- ENDDO
- i=ite
- DO j=jts,jtf
- muu(i,j) = mu(i-1,j) +mub(i-1,j)
- ENDDO
- END IF
- itf=MIN(ite,ide-1)
- jtf=jte
- IF ( ( jts .NE. jds ) .AND. ( jte .NE. jde ) ) THEN
- DO j=jts,jtf
- DO i=its,itf
- muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1)+mub(i,j)+mub(i,j-1))
- ENDDO
- ENDDO
- ELSE IF ( ( jts .EQ. jds ) .AND. ( jte .NE. jde ) ) THEN
- DO j=jts+1,jtf
- DO i=its,itf
- muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1)+mub(i,j)+mub(i,j-1))
- ENDDO
- ENDDO
- j=jts
- DO i=its,itf
- muv(i,j) = mu(i,j) +mub(i,j)
- ENDDO
- ELSE IF ( ( jts .NE. jds ) .AND. ( jte .EQ. jde ) ) THEN
- DO j=jts,jtf-1
- DO i=its,itf
- muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1)+mub(i,j)+mub(i,j-1))
- ENDDO
- ENDDO
- j=jte
- DO i=its,itf
- muv(i,j) = mu(i,j-1) +mub(i,j-1)
- ENDDO
- ELSE IF ( ( jts .EQ. jds ) .AND. ( jte .EQ. jde ) ) THEN
- DO j=jts+1,jtf-1
- DO i=its,itf
- muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1)+mub(i,j)+mub(i,j-1))
- ENDDO
- ENDDO
- j=jts
- DO i=its,itf
- muv(i,j) = mu(i,j) +mub(i,j)
- ENDDO
- j=jte
- DO i=its,itf
- muv(i,j) = mu(i,j-1) +mub(i,j-1)
- ENDDO
- END IF
- END SUBROUTINE calc_mu_staggered
- !-------------------------------------------------------------------------------
- SUBROUTINE couple ( mu, mub, rfield, field, name, &
- msf, &
- ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte )
- IMPLICIT NONE
- ! Input data
- INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte
- CHARACTER(LEN=1) , INTENT(IN ) :: name
- REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT( OUT) :: rfield
- REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mu, mub, msf
-
- REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: field
-
- ! Local data
-
- INTEGER :: i, j, k, itf, jtf, ktf
- REAL , DIMENSION(ims:ime,jms:jme) :: muu , muv
- !<DESCRIPTION>
- !
- ! subroutine couple couples the input variable with the dry-air
- ! column mass (mu).
- !
- !</DESCRIPTION>
-
- ktf=MIN(kte,kde-1)
-
- IF (name .EQ. 'u')THEN
- CALL calc_mu_staggered ( mu, mub, muu, muv, &
- ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte )
- itf=ite
- jtf=MIN(jte,jde-1)
- DO j=jts,jtf
- DO k=kts,ktf
- DO i=its,itf
- rfield(i,k,j)=field(i,k,j)*muu(i,j)/msf(i,j)
- ENDDO
- ENDDO
- ENDDO
- ELSE IF (name .EQ. 'v')THEN
- CALL calc_mu_staggered ( mu, mub, muu, muv, &
- ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte )
- itf=ite
- itf=MIN(ite,ide-1)
- jtf=jte
- DO j=jts,jtf
- DO k=kts,ktf
- DO i=its,itf
- rfield(i,k,j)=field(i,k,j)*muv(i,j)/msf(i,j)
- ENDDO
- ENDDO
- ENDDO
- ELSE IF (name .EQ. 'w')THEN
- itf=MIN(ite,ide-1)
- jtf=MIN(jte,jde-1)
- DO j=jts,jtf
- DO k=kts,kte
- DO i=its,itf
- rfield(i,k,j)=field(i,k,j)*(mu(i,j)+mub(i,j))/msf(i,j)
- ENDDO
- ENDDO
- ENDDO
- ELSE IF (name .EQ. 'h')THEN
- itf=MIN(ite,ide-1)
- jtf=MIN(jte,jde-1)
- DO j=jts,jtf
- DO k=kts,kte
- DO i=its,itf
- rfield(i,k,j)=field(i,k,j)*(mu(i,j)+mub(i,j))
- ENDDO
- ENDDO
- ENDDO
- ELSE
- itf=MIN(ite,ide-1)
- jtf=MIN(jte,jde-1)
- DO j=jts,jtf
- DO k=kts,ktf
- DO i=its,itf
- rfield(i,k,j)=field(i,k,j)*(mu(i,j)+mub(i,j))
- ENDDO
- ENDDO
- ENDDO
-
- ENDIF
- END SUBROUTINE couple
- !-------------------------------------------------------------------------------
- SUBROUTINE calc_ww_cp ( u, v, mup, mub, ww, &
- rdx, rdy, msftx, msfty, &
- msfux, msfuy, msfvx, msfvx_inv, &
- msfvy, dnw, &
- ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte )
- IMPLICIT NONE
- ! Input data
- INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte
- REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: u, v
- REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mup, mub, &
- msftx, msfty, &
- msfux, msfuy, &
- msfvx, msfvy, &
- msfvx_inv
- REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: dnw
-
- REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(OUT ) :: ww
- REAL , INTENT(IN ) :: rdx, rdy
-
- ! Local data
-
- INTEGER :: i, j, k, itf, jtf, ktf
- REAL , DIMENSION( its:ite ) :: dmdt
- REAL , DIMENSION( its:ite, kts:kte ) :: divv
- REAL , DIMENSION( its:ite+1, jts:jte+1 ) :: muu, muv
- !<DESCRIPTION>
- !
- ! calc_ww calculates omega using the velocities (u,v) and the dry-air
- ! column mass (mup+mub).
- ! The algorithm integrates the continuity equation through the column
- ! followed by a diagnosis of omega.
- !
- !</DESCRIPTION>
- !<DESCRIPTION>
- !
- ! calc_ww_cp calculates omega using the velocities (u,v) and the
- ! column mass mu.
- !
- !</DESCRIPTION>
- jtf=MIN(jte,jde-1)
- ktf=MIN(kte,kde-1)
- itf=MIN(ite,ide-1)
- ! mu coupled with the appropriate map factor
- DO j=jts,jtf
- DO i=its,min(ite+1,ide)
- ! u is always coupled with my
- muu(i,j) = 0.5*(mup(i,j)+mub(i,j)+mup(i-1,j)+mub(i-1,j))/msfuy(i,j)
- ENDDO
- ENDDO
- DO j=jts,min(jte+1,jde)
- DO i=its,itf
- ! v is always coupled with mx
- ! muv(i,j) = 0.5*(mup(i,j)+mub(i,j)+mup(i,j-1)+mub(i,j-1))/msfvx(i,j)
- muv(i,j) = 0.5*(mup(i,j)+mub(i,j)+mup(i,j-1)+mub(i,j-1))*msfvx_inv(i,j)
- ENDDO
- ENDDO
- DO j=jts,jtf
- DO i=its,ite
- dmdt(i) = 0.
- ww(i,1,j) = 0.
- ww(i,kte,j) = 0.
- ENDDO
- ! Comments on the modifications for map scale factors
- ! ADT eqn 47 / my (putting rho -> 'mu') is:
- ! (1/my) partial d mu/dt = -mx partial d/dx(mu u/my)
- ! -mx partial d/dy(mu v/mx)
- ! -partial d/dz(mu w/my)
- !
- ! Using nu instead of z the last term becomes:
- ! -partial d/dnu(mu (dnu/dt)/my)
- !
- ! Integrating with respect to nu over ALL levels, with dnu/dt=0 at top
- ! and bottom, the last term becomes = 0
- !
- ! Integral|bot->top[(1/my) partial d mu/dt]dnu =
- ! Integral|bot->top[-mx partial d/dx(mu u/my)
- ! -mx partial d/dy(mu v/mx)]dnu
- !
- ! muu='mu'[on u]/my, muv='mu'[on v]/mx
- ! (1/my) partial d mu/dt is independent of nu
- ! => LHS = Integral|bot->top[con]dnu = conservation*(-1) = -dmdt
- !
- ! => dmdt = mx*Integral|bot->top[partial d/dx(mu u/my) +
- ! partial d/dy(mu v/mx)]dnu
- ! => dmdt = sum_bot->top[divv]
- ! where
- ! divv=mx*[partial d/dx(mu u/my) + partial d/dy(mu v/mx)]*delta nu
- DO k=kts,ktf
- DO i=its,itf
- divv(i,k) = msftx(i,j)*dnw(k)*( rdx*(muu(i+1,j)*u(i+1,k,j)-muu(i,j)*u(i,k,j)) &
- +rdy*(muv(i,j+1)*v(i,k,j+1)-muv(i,j)*v(i,k,j)) )
- ! dmdt(i) = dmdt(i) + dnw(k)* ( rdx*(ru(i+1,k,j)-ru(i,k,j)) &
- ! +rdy*(rv(i,k,j+1)-rv(i,k,j)) )
- dmdt(i) = dmdt(i) + divv(i,k)
- ENDDO
- ENDDO
- ! Further map scale factor notes:
- ! Now integrate from bottom to top, level by level:
- ! mu dnu/dt/my [k+1] = mu dnu/dt/my [k] + [-(1/my) partial d mu/dt
- ! -mx partial d/dx(mu u/my)
- ! -mx partial d/dy(mu v/mx)]*dnu[k->k+1]
- ! ww [k+1] = ww [k] -(1/my) partial d mu/dt * dnu[k->k+1] - divv[k]
- ! = ww [k] -dmdt * dnw[k] - divv[k]
- DO k=2,ktf
- DO i=its,itf
- ! ww(i,k,j)=ww(i,k-1,j) &
- ! - dnw(k-1)* ( dmdt(i) &
- ! +rdx*(ru(i+1,k-1,j)-ru(i,k-1,j)) &
- ! +rdy*(rv(i,k-1,j+1)-rv(i,k-1,j)) )
- ww(i,k,j)=ww(i,k-1,j) - dnw(k-1)*dmdt(i) - divv(i,k-1)
- ENDDO
- ENDDO
- ENDDO
- END SUBROUTINE calc_ww_cp
- !-------------------------------------------------------------------------------
-
- SUBROUTINE calc_cq ( moist, cqu, cqv, cqw, n_moist, &
- ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte )
- IMPLICIT NONE
-
- ! Input data
- INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte
- INTEGER , INTENT(IN ) :: n_moist
-
- REAL, DIMENSION( ims:ime, kms:kme , jms:jme , n_moist ), INTENT(IN ) :: moist
-
- REAL, DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT( OUT) :: cqu, cqv, cqw
- ! Local stuff
- REAL :: qtot
-
- INTEGER :: i, j, k, itf, jtf, ktf, ispe
- !<DESCRIPTION>
- !
- ! calc_cq calculates moist coefficients for the momentum equations.
- !
- !</DESCRIPTION>
- itf=ite
- jtf=MIN(jte,jde-1)
- ktf=MIN(kte,kde-1)
- IF( n_moist >= PARAM_FIRST_SCALAR ) THEN
- DO j=jts,jtf
- DO k=kts,ktf
- DO i=its,itf
- qtot = 0.
- !DEC$ loop count(3)
- DO ispe=PARAM_FIRST_SCALAR,n_moist
- qtot = qtot + moist(i,k,j,ispe) + moist(i-1,k,j,ispe)
- ENDDO
- ! qtot = 0.5*( moist(i ,k,j,1)+moist(i ,k,j,2)+moist(i ,k,j,3)+ &
- ! & moist(i-1,k,j,1)+moist(i-1,k,j,2)+moist(i-1,k,j,3) )
- ! cqu(i,k,j) = 1./(1.+qtot)
- cqu(i,k,j) = 1./(1.+0.5*qtot)
- ENDDO
- ENDDO
- ENDDO
- itf=MIN(ite,ide-1)
- jtf=jte
- DO j=jts,jtf
- DO k=kts,ktf
- DO i=its,itf
- qtot = 0.
- !DEC$ loop count(3)
- DO ispe=PARAM_FIRST_SCALAR,n_moist
- qtot = qtot + moist(i,k,j,ispe) + moist(i,k,j-1,ispe)
- ENDDO
- ! qtot = 0.5*( moist(i,k,j ,1)+moist(i,k,j ,2)+moist(i,k,j ,3)+ &
- ! & moist(i,k,j-1,1)+moist(i,k,j-1,2)+moist(i,k,j-1,3) )
- ! cqv(i,k,j) = 1./(1.+qtot)
- cqv(i,k,j) = 1./(1.+0.5*qtot)
- ENDDO
- ENDDO
- ENDDO
- itf=MIN(ite,ide-1)
- jtf=MIN(jte,jde-1)
- DO j=jts,jtf
- DO k=kts+1,ktf
- DO i=its,itf
- qtot = 0.
- !DEC$ loop count(3)
- DO ispe=PARAM_FIRST_SCALAR,n_moist
- qtot = qtot + moist(i,k,j,ispe) + moist(i,k-1,j,ispe)
- ENDDO
- ! qtot = 0.5*( moist(i,k ,j,1)+moist(i,k ,j,2)+moist(i,k-1,j,3)+ &
- ! & moist(i,k-1,j,1)+moist(i,k-1,j,2)+moist(i,k ,j,3) )
- ! cqw(i,k,j) = qtot
- cqw(i,k,j) = 0.5*qtot
- ENDDO
- ENDDO
- ENDDO
- ELSE
- DO j=jts,jtf
- DO k=kts,ktf
- DO i=its,itf
- cqu(i,k,j) = 1.
- ENDDO
- ENDDO
- ENDDO
- itf=MIN(ite,ide-1)
- jtf=jte
- DO j=jts,jtf
- DO k=kts,ktf
- DO i=its,itf
- cqv(i,k,j) = 1.
- ENDDO
- ENDDO
- ENDDO
- itf=MIN(ite,ide-1)
- jtf=MIN(jte,jde-1)
- DO j=jts,jtf
- DO k=kts+1,ktf
- DO i=its,itf
- cqw(i,k,j) = 0.
- ENDDO
- ENDDO
- ENDDO
- END IF
- END SUBROUTINE calc_cq
- !----------------------------------------------------------------------
- SUBROUTINE calc_alt ( alt, al, alb, &
- ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte )
- IMPLICIT NONE
-
- ! Input data
- INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte
- REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN ) :: alb, al
- REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT( OUT) :: alt
- ! Local stuff
- INTEGER :: i, j, k, itf, jtf, ktf
- !<DESCRIPTION>
- !
- ! calc_alt computes the full inverse density
- !
- !</DESCRIPTION>
- itf=MIN(ite,ide-1)
- jtf=MIN(jte,jde-1)
- ktf=MIN(kte,kde-1)
- DO j=jts,jtf
- DO k=kts,ktf
- DO i=its,itf
- alt(i,k,j) = al(i,k,j)+alb(i,k,j)
- ENDDO
- ENDDO
- ENDDO
- END SUBROUTINE calc_alt
- !----------------------------------------------------------------------
- SUBROUTINE calc_p_rho_phi ( moist, n_moist, hypsometric_opt, &
- al, alb, mu, muts, ph, phb, p, pb, &
- t, p0, t0, ptop, znu, znw, dnw, rdnw, &
- rdn, non_hydrostatic, &
- ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte )
- IMPLICIT NONE
-
- ! Input data
- LOGICAL , INTENT(IN ) :: non_hydrostatic
- INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte
- INTEGER , INTENT(IN ) :: n_moist
- INTEGER , INTENT(IN ) :: hypsometric_opt
- REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN ) :: alb, &
- pb, &
- t
- REAL, DIMENSION( ims:ime , kms:kme , jms:jme, n_moist ), INTENT(IN ) :: moist
- REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT( OUT) :: al, p
- REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(INOUT) :: ph, phb
- REAL, DIMENSION( ims:ime , jms:jme ), INTENT(IN ) :: mu, muts
- REAL, DIMENSION( kms:kme ), INTENT(IN ) :: znu, znw, dnw, rdnw, rdn
- REAL, INTENT(IN ) :: t0, p0, ptop
- ! Local stuff
- INTEGER :: i, j, k, itf, jtf, ktf, ispe
- REAL :: qvf, qtot, qf1, qf2
- REAL, DIMENSION( its:ite) :: temp,cpovcv_v
- REAL :: pfu, phm, pfd
- !<DESCRIPTION>
- !
- ! For the nonhydrostatic option, calc_p_rho_phi calculates the
- ! diagnostic quantities pressure and (inverse) density from the
- ! prognostic variables using the equation of state.
- !
- ! For the hydrostatic option, calc_p_rho_phi calculates the
- ! diagnostic quantities (inverse) density and geopotential from the
- ! prognostic variables using the equation of state and the hydrostatic
- ! equation.
- !
- !</DESCRIPTION>
- itf=MIN(ite,ide-1)
- jtf=MIN(jte,jde-1)
- ktf=MIN(kte,kde-1)
- #ifndef INTELMKL
- cpovcv_v = cpovcv
- #endif
- IF (non_hydrostatic) THEN
- IF (hypsometric_opt == 1) THEN
- DO j=jts,jtf
- DO k=kts,ktf
- DO i=its,itf
- al(i,k,j)=-1./muts(i,j)*(alb(i,k,j)*mu(i,j) + rdnw(k)*(ph(i,k+1,j)-ph(i,k,j)))
- END DO
- END DO
- END DO
- ELSE IF (hypsometric_opt == 2) THEN
- ! The relation used to get specific volume, al, is: al = -dZ/dp,
- ! where dp = mut * d(eta). The pressure depth, dp, is replaced with
- ! p*(dp/p) ~ p*LOG((p+0.5dp)/(p-0.5dp)). Difference between dp and p*dLOG(p)
- ! is as follows: p*dLOG(p) - dp = 1/12*(dp/p)**3 + 1/90*(dp/p)**5 + ...
- ! Therefore, p*dLOG(p) is always larger than dp and the difference is
- ! in proportion to dp/p. TKW, 02/16/2010
- DO j=jts,jtf
- DO k=kts,ktf
- DO i=its,itf
- pfu = muts(i,j)*znw(k+1)+ptop
- pfd = muts(i,j)*znw(k) +ptop
- phm = muts(i,j)*znu(k) +ptop
- al(i,k,j) = (ph(i,k+1,j)-ph(i,k,j)+phb(i,k+1,j)-phb(i,k,j))/phm/LOG(pfd/pfu)-alb(i,k,j)
- END DO
- END DO
- END DO
- ELSE
- CALL wrf_error_fatal ( 'calc_p_rho_phi: hypsometric_opt should be 1 or 2' )
- END IF
- IF (n_moist >= PARAM_FIRST_SCALAR ) THEN
- DO j=jts,jtf
- DO k=kts,ktf
- DO i=its,itf
- qvf = 1.+rvovrd*moist(i,k,j,P_QV)
- temp(i)=(r_d*(t0+t(i,k,j))*qvf)/(p0*(al(i,k,j)+alb(i,k,j)))
- ENDDO
- #ifdef INTELMKL
- CALL VPOWX ( itf-its+1, temp(its), cpovcv, p(its,k,j) )
- #else
- ! use vector version from libmassv or from compat lib in frame/libmassv.F
- CALL VPOW ( p(its,k,j), temp(its), cpovcv_v(its), itf-its+1 )
- #endif
- DO i=its,itf
- p(i,k,j)= p(i,k,j)*p0-pb(i,k,j)
- ENDDO
- ENDDO
- ENDDO
- ELSE
- DO j=jts,jtf
- DO k=kts,ktf
- DO i=its,itf
- p(i,k,j)=p0*( (r_d*(t0+t(i,k,j)))/ &
- (p0*(al(i,k,j)+alb(i,k,j))) )**cpovcv &
- -pb(i,k,j)
- ENDDO
- ENDDO
- ENDDO
- END IF
- ELSE
- ! hydrostatic pressure, al, and ph1 calc; WCS, 5 sept 2001
- IF (n_moist >= PARAM_FIRST_SCALAR ) THEN
- DO j=jts,jtf
- k=ktf ! top layer
- DO i=its,itf
- qtot = 0.
- DO ispe=PARAM_FIRST_SCALAR,n_moist
- qtot = qtot + moist(i,k,j,ispe)
- ENDDO
- qf2 = 1.
- qf1 = qtot*qf2
- p(i,k,j) = - 0.5*(mu(i,j)+qf1*muts(i,j))/rdnw(k)/qf2
- qvf = 1.+rvovrd*moist(i,k,j,P_QV)
- al(i,k,j) = (r_d/p1000mb)*(t(i,k,j)+t0)*qvf* &
- (((p(i,k,j)+pb(i,k,j))/p1000mb)**cvpm) - alb(i,k,j)
- ENDDO
- DO k=ktf-1,kts,-1 ! remaining layers, integrate down
- DO i=its,itf
- qtot = 0.
- DO ispe=PARAM_FIRST_SCALAR,n_moist
- qtot = qtot + 0.5*( moist(i,k ,j,ispe) + moist(i,k+1,j,ispe) )
- ENDDO
- qf2 = 1.
- qf1 = qtot*qf2
- p(i,k,j) = p(i,k+1,j) - (mu(i,j) + qf1*muts(i,j))/qf2/rdn(k+1)
- qvf = 1.+rvovrd*moist(i,k,j,P_QV)
- al(i,k,j) = (r_d/p1000mb)*(t(i,k,j)+t0)*qvf* &
- (((p(i,k,j)+pb(i,k,j))/p1000mb)**cvpm) - alb(i,k,j)
- ENDDO
- ENDDO
- ENDDO
- ELSE
- DO j=jts,jtf
- k=ktf ! top layer
- DO i=its,itf
- qtot = 0.
- qf2 = 1.
- qf1 = qtot*qf2
- p(i,k,j) = - 0.5*(mu(i,j)+qf1*muts(i,j))/rdnw(k)/qf2
- qvf = 1.
- al(i,k,j) = (r_d/p1000mb)*(t(i,k,j)+t0)*qvf* &
- (((p(i,k,j)+pb(i,k,j))/p1000mb)**cvpm) - alb(i,k,j)
- ENDDO
- DO k=ktf-1,kts,-1 ! remaining layers, integrate down
- DO i=its,itf
- qtot = 0.
- qf2 = 1.
- qf1 = qtot*qf2
- p(i,k,j) = p(i,k+1,j) - (mu(i,j) + qf1*muts(i,j))/qf2/rdn(k+1)
- qvf = 1.
- al(i,k,j) = (r_d/p1000mb)*(t(i,k,j)+t0)*qvf* &
- (((p(i,k,j)+pb(i,k,j))/p1000mb)**cvpm) - alb(i,k,j)
- ENDDO
- ENDDO
- ENDDO
- END IF
- IF (hypsometric_opt == 1) THEN
- DO j=jts,jtf
- DO k=2,ktf+1 ! integrate hydrostatic equation for geopotential
- DO i=its,itf
- ph(i,k,j) = ph(i,k-1,j) - (dnw(k-1))*( &
- (muts(i,j))*al(i,k-1,j)+ &
- mu(i,j)*alb(i,k-1,j) )
- ENDDO
- ENDDO
- ENDDO
- ELSE
- ! Revised hypsometric eq.: dZ=-al*p*dLOG(p), where p is dry pressure
- DO j=jts,jtf
- DO i=its,itf
- ph(i,kts,j) = phb(i,kts,j)
- END DO
- DO k=kts+1,ktf+1
- DO i=its,itf
- pfu = muts(i,j)*znw(k) +ptop
- pfd = muts(i,j)*znw(k-1)+ptop
- phm = muts(i,j)*znu(k-1)+ptop
- ph(i,k,j) = ph(i,k-1,j) + (al(i,k-1,j)+alb(i,k-1,j))*phm*LOG(pfd/pfu)
- ENDDO
- ENDDO
- DO k=kts,ktf+1
- DO i=its,itf
- ph(i,k,j) = ph(i,k,j) - phb(i,k,j)
- END DO
- END DO
- END DO
- END IF
- END IF
- END SUBROUTINE calc_p_rho_phi
- !----------------------------------------------------------------------
- SUBROUTINE calc_php ( php, ph, phb, &
- ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte )
- IMPLICIT NONE
-
- ! Input data
- INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte
- REAL, DIMENSION( ims:ime, kms:kme , jms:jme ), INTENT(IN ) :: phb, ph
- REAL, DIMENSION( ims:ime, kms:kme , jms:jme ), INTENT( OUT) :: php
- ! Local stuff
- INTEGER :: i, j, k, itf, jtf, ktf
- !<DESCRIPTION>
- !
- ! calc_php calculates the full geopotential from the reference state
- ! geopotential and the perturbation geopotential (phb_ph).
- !
- !</DESCRIPTION>
- itf=MIN(ite,ide-1)
- jtf=MIN(jte,jde-1)
- ktf=MIN(kte,kde-1)
- DO j=jts,jtf
- DO k=kts,ktf
- DO i=its,itf
- php(i,k,j) = 0.5*(phb(i,k,j)+phb(i,k+1,j)+ph(i,k,j)+ph(i,k+1,j))
- ENDDO
- ENDDO
- ENDDO
- END SUBROUTINE calc_php
- !-------------------------------------------------------------------------------
- SUBROUTINE diagnose_w( ph_tend, ph_new, ph_old, w, mu, dt, &
- u, v, ht, &
- cf1, cf2, cf3, rdx, rdy, &
- msftx, msfty, &
- ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte )
- IMPLICIT NONE
- INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte
- REAL, DIMENSION( ims:ime, kms:kme , jms:jme ), INTENT(IN ) :: ph_tend, &
- ph_new, &
- ph_old, &
- u, &
- v
- REAL, DIMENSION( ims:ime, kms:kme , jms:jme ), INTENT( OUT) :: w
- REAL, DIMENSION( ims:ime, jms:jme ), INTENT(IN ) :: mu, ht, msftx, msfty
- REAL, INTENT(IN ) :: dt, cf1, cf2, cf3, rdx, rdy
- INTEGER :: i, j, k, itf, jtf
- itf=MIN(ite,ide-1)
- jtf=MIN(jte,jde-1)
- !<DESCRIPTION>
- !
- ! diagnose_w diagnoses the vertical velocity from the geopoential equation.
- ! Used with the hydrostatic option.
- !
- !</DESCRIPTION>
- DO j = jts, jtf
- ! lower b.c. on w
- ! Notes on map scale factors:
- ! Chain rule: if Z=Z(X,Y) [true at the surface] then
- ! dZ/dt = dZ/dX * dX/dt + dZ/dY * dY/dt, U=dX/dt, V=dY/dt
- ! Using capitals to denote actual values
- ! In mapped values, u=U, v=V, z=Z, 1/dX=mx/dx, 1/dY=my/dy
- ! => w = dz/dt = mx u dz/dx + my v dz/dy
- ! [where dz/dx is just the surface height change between x
- ! gridpoints, and dz/dy is the change between y gridpoints]
- ! [NB: cf1, cf2 and cf3 do vertical weighting of u or v values
- ! nearest the surface]
- ! Previously msft multiplied by rdy and rdx terms.
- ! Now msfty multiplies rdy term, and msftx multiplies msftx term
- DO i = its, itf
- w(i,1,j)= msfty(i,j)*.5*rdy*( &
- (ht(i,j+1)-ht(i,j )) &
- *(cf1*v(i,1,j+1)+cf2*v(i,2,j+1)+cf3*v(i,3,j+1)) &
- +(ht(i,j )-ht(i,j-1)) &
- *(cf1*v(i,1,j )+cf2*v(i,2,j )+cf3*v(i,3,j )) ) &
- +msftx(i,j)*.5*rdx*( &
- (ht(i+1,j)-ht(i,j )) &
- *(cf1*u(i+1,1,j)+cf2*u(i+1,2,j)+cf3*u(i+1,3,j)) &
- +(ht(i,j )-ht(i-1,j)) &
- *(cf1*u(i ,1,j)+cf2*u(i ,2,j)+cf3*u(i ,3,j)) )
- ENDDO
- ! use geopotential equation to diagnose w
- ! Further notes on map scale factors
- ! If ph_tend contains: -mx partial d/dx(mu rho u/my)
- ! -mx partial d/dy(phi mu v/mx)
- ! -partial d/dz(phi mu w/my)
- ! then phi eqn is: partial d/dt(mu phi/my) = ph_tend + mu g w/my
- ! => w = [my/(mu*g)]*[partial d/dt(mu phi/my) - ph_tend]
- DO k = 2, kte
- DO i = its, itf
- w(i,k,j) = msfty(i,j)*( (ph_new(i,k,j)-ph_old(i,k,j))/dt &
- - ph_tend(i,k,j)/mu(i,j) )/g
- ENDDO
- ENDDO
- ENDDO
- END SUBROUTINE diagnose_w
- !-------------------------------------------------------------------------------
- SUBROUTINE rhs_ph( ph_tend, u, v, ww, &
- ph, ph_old, phb, w, &
- mut, muu, muv, &
- fnm, fnp, &
- rdnw, cfn, cfn1, rdx, rdy, &
- msfux, msfuy, msfvx, &
- msfvx_inv, msfvy, &
- msftx, msfty, &
- non_hydrostatic, &
- config_flags, &
- ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte )
- IMPLICIT NONE
- TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
- INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte
- REAL, DIMENSION( ims:ime, kms:kme , jms:jme ), INTENT(IN ) :: &
- u, &
- v, &
- ww, &
- ph, &
- ph_old, &
- phb, &
- w
- REAL, DIMENSION( ims:ime, kms:kme , jms:jme ), INTENT(INOUT) :: ph_tend
- REAL, DIMENSION( ims:ime, jms:jme ), INTENT(IN ) :: muu, muv, mut, &
- msfux, msfuy, &
- msfvx, msfvy, &
- msftx, msfty, &
- msfvx_inv
- REAL, DIMENSION( kms:kme ), INTENT(IN ) :: rdnw, fnm, fnp
- REAL, INTENT(IN ) :: cfn, cfn1, rdx, rdy
- LOGICAL, INTENT(IN ) :: non_hydrostatic
- ! Local stuff
- INTEGER :: i, j, k, itf, jtf, ktf, kz, i_start, j_start
- REAL :: ur, ul, ub, vr, vl, vb
- REAL, DIMENSION(its:ite,kts:kte) :: wdwn
- INTEGER :: advective_order
- LOGICAL :: specified
- !<DESCRIPTION>
- !
- ! rhs_ph calculates the large-timestep tendency terms for the geopotential
- ! equation. These terms include the advection and "gw". The geopotential
- ! equation is cast in advective form, so we don't use the flux form advection
- ! algorithms here.
- !
- !</DESCRIPTION>
- specified = .false.
- if(config_flags%specified .or. config_flags%nested) specified = .true.
- advective_order = config_flags%h_sca_adv_order
- itf=MIN(ite,ide-1)
- jtf=MIN(jte,jde-1)
- ktf=MIN(kte,kde-1)
- ! Notes on map scale factors (WCS, 2 march 2008)
- ! phi equation is: mu/my d/dt(phi) = -(1/my) mx mu u d/dx(phi)
- ! -(1/my) my mu v d/dy(phi)
- ! - omega d/d_eta(phi)
- ! +mu g w/my
- !
- ! A little further explanation...
- ! The tendency term we are computing here is for mu/my d/dt(phi). It is advective form
- ! but it is multiplied be mu/my. It will be decoupled from (mu/my) when the implicit w-phi
- ! solution is computed in subourine advance_w. The formulation dates from the early
- ! days of the mass coordinate model when we were testing both a flux and an advective formulation
- ! for the geopotential equation and different forms of the vertical momentum equation and the
- ! vertically implicit solver.
- ! advective form for the geopotential equation
- DO j = jts, jtf
- DO k = 2, kte
- DO i = its, itf
- wdwn(i,k) = .5*(ww(i,k,j)+ww(i,k-1,j))*rdnw(k-1) &
- *(ph(i,k,j)-ph(i,k-1,j)+phb(i,k,j)-phb(i,k-1,j))
- ENDDO
- ENDDO
- ! RHS term 3 is: - omega partial d/dnu(phi)
- DO k = 2, kte-1
- DO i = its, itf
- ph_tend(i,k,j) = ph_tend(i,k,j) &
- - (fnm(k)*wdwn(i,k+1)+fnp(k)*wdwn(i,k))
- ENDDO
- ENDDO
- ENDDO
- IF (non_hydrostatic) THEN ! add in "gw" term.
- DO j = jts, jtf ! in hydrostatic mode, "gw" will be diagnosed
- ! after the timestep to give us "w"
- DO i = its, itf
- ph_tend(i,kde,j) = 0.
- ENDDO
- DO k = 2, kte
- DO i = its, itf
- ! phi equation RHS term 4
- ph_tend(i,k,j) = ph_tend(i,k,j) + mut(i,j)*g*w(i,k,j)/msfty(i,j)
- ENDDO
- ENDDO
- ENDDO
- END IF
- ! Notes on map scale factors:
- ! RHS terms 1 and 2 are: -(1/my) mx u mu partial d/dx(phi)
- ! -(1/my) my v mu partial d/dy(phi)
- IF (advective_order <= 2) THEN
- ! y (v) advection
- i_start = its
- j_start = jts
- itf=MIN(ite,ide-1)
- jtf=MIN(jte,jde-1)
- IF ( (config_flags%open_ys .or. specified) .and. jts == jds ) j_start = jts+1
- IF ( (config_flags%open_ye .or. specified) .and. jte == jde ) jtf = jtf-2
- DO j = j_start, jtf
- DO k = 2, kte-1
- DO i = i_start, itf
- ph_tend(i,k,j)=ph_tend(i,k,j) - (0.25*rdy/msfty(i,j))* &
- ( muv(i,j+1)*(v(i,k,j+1)+v(i,k-1,j+1))*msfvy(i,j+1)* &
- (phb(i,k,j+1)-phb(i,k,j )+ph(i,k,j+1)-ph(i,k,j )) &
- +muv(i,j )*(v(i,k,j )+v(i,k-1,j ))*msfvy(i,j )* &
- (phb(i,k,j )-phb(i,k,j-1)+ph(i,k,j )-ph(i,k,j-1)) )
- ENDDO
- ENDDO
- k = kte
- DO i = i_start, itf
- ph_tend(i,k,j)=ph_tend(i,k,j) - (0.5*rdy/msfty(i,j))* &
- ( muv(i,j+1)*(cfn*v(i,k-1,j+1)+cfn1*v(i,k-2,j+1))*msfvy(i,j+1)* &
- (phb(i,k,j+1)-phb(i,k,j )+ph(i,k,j+1)-ph(i,k,j )) &
- +muv(i,j )*(cfn*v(i,k-1,j )+cfn1*v(i,k-2,j ))*msfvy(i,j )* &
- (phb(i,k,j )-phb(i,k,j-1)+ph(i,k,j )-ph(i,k,j-1)) )
- ENDDO
- ENDDO
- ! x (u) advection
- i_start = its
- j_start = jts
- itf=MIN(ite,ide-1)
- jtf=MIN(jte,jde-1)
- IF ( (config_flags%open_xs .or. specified) .and. its == ids ) i_start = its+1
- IF ( (config_flags%open_xe .or. specified) .and. ite == ide ) itf = itf-2
- DO j = j_start, jtf
- DO k = 2, kte-1
- DO i = i_start, itf
- ph_tend(i,k,j)=ph_tend(i,k,j) - (0.25*rdx/msfty(i,j))* &
- ( muu(i+1,j)*(u(i+1,k,j)+u(i+1,k-1,j))*msfux(i+1,j)* &
- (phb(i+1,k,j)-phb(i ,k,j)+ph(i+1,k,j)-ph(i ,k,j)) &
- +muu(i ,j)*(u(i ,k,j)+u(i ,k-1,j))*msfux(i ,j)* &
- (phb(i ,k,j)-phb(i-1,k,j)+ph(i ,k,j)-ph(i-1,k,j)) )
- ENDDO
- ENDDO
-
- k = kte
- DO i = i_start, itf
- ph_tend(i,k,j)=ph_tend(i,k,j) - (0.5*rdx/msfty(i,j))* &
- ( muu(i+1,j)*(cfn*u(i+1,k-1,j)+cfn1*u(i+1,k-2,j))*msfux(i+1,j)* &
- (phb(i+1,k,j)-phb(i ,k,j)+ph(i+1,k,j)-ph(i ,k,j)) &
- +muu(i ,j)*(cfn*u(i ,k-1,j)+cfn1*u(i ,k-2,j))*msfux( i,j)* &
- (phb(i ,k,j)-phb(i-1,k,j)+ph(i ,k,j)-ph(i-1,k,j)) )
- ENDDO
- ENDDO
- ELSE IF (advective_order <= 4) THEN
- ! y (v) advection
- i_start = its
- j_start = jts
- itf=MIN(ite,ide-1)
- jtf=MIN(jte,jde-1)
- IF ( (config_flags%open_ys .or. specified) .and. jts == jds ) j_start = jts+2
- IF ( (config_flags%open_ye .or. specified) .and. jte == jde ) jtf = jtf-3
- DO j = j_start, jtf
- DO k = 2, kte-1
- DO i = i_start, itf
- ph_tend(i,k,j)=ph_tend(i,k,j) - (0.25*rdy/msfty(i,j))*( &
- ( muv(i,j+1)*(v(i,k,j+1)+v(i,k-1,j+1))*msfvy(i,j+1) &
- +muv(i,j )*(v(i,k,j )+v(i,k-1,j ))*msfvy(i,j ))* (1./12.)*( &
- 8.*(ph(i,k,j+1)-ph(i,k,j-1)) &
- -(ph(i,k,j+2)-ph(i,k,j-2)) &
- +8.*(phb(i,k,j+1)-phb(i,k,j-1)) &
- -(phb(i,k,j+2)-phb(i,k,j-2)) ) )
- ENDDO
- ENDDO
- k = kte
- DO i = i_start, itf
- ph_tend(i,k,j)=ph_tend(i,k,j) - (0.5*rdy/msfty(i,j))*( &
- ( muv(i,j+1)*(cfn*v(i,k-1,j+1)+cfn1*v(i,k-2,j+1))*msfvy(i,j+1) &
- +muv(i,j )*(cfn*v(i,k-1,j )+cfn1*v(i,k-2,j ))*msfvy(i,j ))* (1./12.)*( &
- 8.*(ph(i,k,j+1)-ph(i,k,j-1)) &
- -(ph(i,k,j+2)-ph(i,k,j-2)) &
- +8.*(phb(i,k,j+1)-phb(i,k,j-1)) &
- -(phb(i,k,j+2)-phb(i,k,j-2)) ) )
- ENDDO
- ENDDO
- ! pick up near boundary rows using 2nd order stencil for open and specified conditions
- IF ( (config_flags%open_ys .or. specified) .and. jts <= jds+1 ) THEN
- j = jds+1
- DO k = 2, kte-1
- DO i = i_start, itf
- ph_tend(i,k,j)=ph_tend(i,k,j) - (0.25*rdy/msfty(i,j))* &
- ( muv(i,j+1)*(v(i,k,j+1)+v(i,k-1,j+1))*msfvy(i,j+1)* &
- (phb(i,k,j+1)-phb(i,k,j )+ph(i,k,j+1)-ph(i,k,j )) &
- +muv(i,j )*(v(i,k,j )+v(i,k-1,j ))*msfvy(i,j )* &
- (phb(i,k,j )-phb(i,k,j-1)+ph(i,k,j )-ph(i,k,j-1)) )
- ENDDO
- ENDDO
- k = kte
- DO i = i_start, itf
- ph_tend(i,k,j)=ph_tend(i,k,j) - (0.5*rdy/msfty(i,j))* &
- ( muv(i,j+1)*(cfn*v(i,k-1,j+1)+cfn1*v(i,k-2,j+1))*msfvy(i,j+1)* &
- (phb(i,k,j+1)-phb(i,k,j )+ph(i,k,j+1)-ph(i,k,j )) &
- +muv(i,j )*(cfn*v(i,k-1,j )+cfn1*v(i,k-2,j ))*msfvy(i,j )* &
- (phb(i,k,j )-phb(i,k,j-1)+ph(i,k,j )-ph(i,k,j-1)) )
- ENDDO
- END IF
- IF ( (config_fla…
Large files files are truncated, but you can click here to view the full file