!REAL:MODEL_LAYER:INITIALIZATION
! This MODULE holds the routines which are used to perform various initializations
! for the individual domains, specifically for the Eulerian, mass-based coordinate.
!-----------------------------------------------------------------------
MODULE module_initialize 6
USE module_bc
USE module_configure
USE module_domain
USE module_io_domain
USE module_model_constants
USE module_si_io_em
USE module_state_description
USE module_timing
USE module_soil_pre
#ifdef DM_PARALLEL
USE module_dm
#endif
CONTAINS
!-------------------------------------------------------------------
SUBROUTINE init_domain ( grid ) 4,21
IMPLICIT NONE
! Input space and data. No gridded meteorological data has been stored, though.
! TYPE (domain), POINTER :: grid
TYPE (domain) :: grid
! Local data.
INTEGER :: dyn_opt
INTEGER :: idum1, idum2
#ifdef DEREF_KLUDGE
INTEGER :: sm31 , em31 , sm32 , em32 , sm33 , em33
#endif
#ifdef DEREF_KLUDGE
sm31 = grid%sm31
em31 = grid%em31
sm32 = grid%sm32
em32 = grid%em32
sm33 = grid%sm33
em33 = grid%em33
#endif
CALL get_dyn_opt
( dyn_opt )
CALL set_scalar_indices_from_config
( head_grid%id , idum1, idum2 )
IF ( dyn_opt .eq. 1 &
.or. dyn_opt .eq. 2 &
.or. dyn_opt .eq. 3 &
) THEN
CALL init_domain_rk
( grid, &
!
#include <em_actual_args.inc>
!
)
ELSE
WRITE(0,*)' init_domain: unknown or unimplemented dyn_opt = ',dyn_opt
STOP 'ERROR-dyn_opt-wrong-in-namelist'
ENDIF
END SUBROUTINE init_domain
!-------------------------------------------------------------------
SUBROUTINE init_domain_rk ( grid, & 7,143
!
# include <em_dummy_args.inc>
!
)
USE module_optional_si_input
IMPLICIT NONE
! Input space and data. No gridded meteorological data has been stored, though.
! TYPE (domain), POINTER :: grid
TYPE (domain) :: grid
# include <em_dummy_decl.inc>
TYPE (grid_config_rec_type) :: config_flags
! Local domain indices and counters.
INTEGER :: num_veg_cat , num_soil_top_cat , num_soil_bot_cat
INTEGER :: &
ids, ide, jds, jde, kds, kde, &
ims, ime, jms, jme, kms, kme, &
its, ite, jts, jte, kts, kte, &
i, j, k
! Local data
INTEGER :: error
REAL :: p_surf, p_level
REAL :: cof1, cof2
REAL :: qvf , qvf1 , qvf2 , pd_surf
REAL :: p00 , t00 , a
REAL :: hold_znw
LOGICAL :: stretch_grid, dry_sounding, debug
! INTEGER , PARAMETER :: nl_max = 1000
! REAL , DIMENSION(nl_max) :: dn
integer::oops1,oops2
#define COPY_IN
#include <em_scalar_derefs.inc>
#ifdef DM_PARALLEL
# include <em_data_calls.inc>
#endif
SELECT CASE ( model_data_order )
CASE ( DATA_ORDER_ZXY )
kds = grid%sd31 ; kde = grid%ed31 ;
ids = grid%sd32 ; ide = grid%ed32 ;
jds = grid%sd33 ; jde = grid%ed33 ;
kms = grid%sm31 ; kme = grid%em31 ;
ims = grid%sm32 ; ime = grid%em32 ;
jms = grid%sm33 ; jme = grid%em33 ;
kts = grid%sp31 ; kte = grid%ep31 ; ! note that tile is entire patch
its = grid%sp32 ; ite = grid%ep32 ; ! note that tile is entire patch
jts = grid%sp33 ; jte = grid%ep33 ; ! note that tile is entire patch
CASE ( DATA_ORDER_XYZ )
ids = grid%sd31 ; ide = grid%ed31 ;
jds = grid%sd32 ; jde = grid%ed32 ;
kds = grid%sd33 ; kde = grid%ed33 ;
ims = grid%sm31 ; ime = grid%em31 ;
jms = grid%sm32 ; jme = grid%em32 ;
kms = grid%sm33 ; kme = grid%em33 ;
its = grid%sp31 ; ite = grid%ep31 ; ! note that tile is entire patch
jts = grid%sp32 ; jte = grid%ep32 ; ! note that tile is entire patch
kts = grid%sp33 ; kte = grid%ep33 ; ! note that tile is entire patch
CASE ( DATA_ORDER_XZY )
ids = grid%sd31 ; ide = grid%ed31 ;
kds = grid%sd32 ; kde = grid%ed32 ;
jds = grid%sd33 ; jde = grid%ed33 ;
ims = grid%sm31 ; ime = grid%em31 ;
kms = grid%sm32 ; kme = grid%em32 ;
jms = grid%sm33 ; jme = grid%em33 ;
its = grid%sp31 ; ite = grid%ep31 ; ! note that tile is entire patch
kts = grid%sp32 ; kte = grid%ep32 ; ! note that tile is entire patch
jts = grid%sp33 ; jte = grid%ep33 ; ! note that tile is entire patch
END SELECT
CALL model_to_grid_config_rec
( grid%id , model_config_rec , config_flags )
! Check to see if the boundary conditions are set properly in the namelist file.
! This checks for sufficiency and redundancy.
CALL boundary_condition_check
( config_flags, bdyzone, error, grid%id )
! Some sort of "this is the first time" initialization. Who knows.
step_number = 0
grid%itimestep=0
! Pull in the info in the namelist to compare it to the input data.
real_data_init_type = model_config_rec%real_data_init_type
! Take the data from the input file and store it in the variables that
! use the WRF naming and ordering conventions.
DO j = jts, MIN(jte,jde-1)
DO i = its, MIN(ite,ide-1)
IF ( snow(i,j) .GE. 10. ) then
snowc(i,j) = 1.
ELSE
snowc(i,j) = 0.0
END IF
END DO
END DO
! Set flag integers for presence of snowh and soilw fields
ifndsnowh = flag_snowh
IF (num_sw_levels_input .GE. 1) THEN
ifndsoilw = 1
ELSE
ifndsoilw = 0
END IF
! For bl_surface_physics = 1, we want to use close to a 10 cm value
! for the bottom level of the soil temps.
fix_bottom_level_for_temp : SELECT CASE ( model_config_rec%bl_surface_physics(grid%id) )
CASE (SLABSCHEME)
IF ( flag_st000010 .EQ. 1 ) THEN
DO j = jts , MIN(jde-1,jte)
DO i = its , MIN(ide-1,ite)
tmn(i,j) = st000010(i,j)
END DO
END DO
ELSE IF ( flag_soilt020 .EQ. 1 ) THEN
DO j = jts , MIN(jde-1,jte)
DO i = its , MIN(ide-1,ite)
tmn(i,j) = soilt020(i,j)
END DO
END DO
END IF
CASE (LSMSCHEME)
END SELECT fix_bottom_level_for_temp
! Generate the vegetation and soil category information from the fractional input
! data, or use the existing dominant category fields if they exist.
print *,'---> ---> forcing use of static soil and veg data, due to SI v1.3.1'
vegcat(its,jts) = 0
soilcat(its,jts) = 0
IF ( ( soilcat(its,jts) .LT. 0.5 ) .AND. ( vegcat(its,jts) .LT. 0.5 ) ) THEN
num_veg_cat = SIZE ( landusef , DIM=2 )
num_soil_top_cat = SIZE ( soilctop , DIM=2 )
num_soil_bot_cat = SIZE ( soilcbot , DIM=2 )
CALL process_percent_cat_new
( landmask , &
landusef , soilctop , soilcbot , &
isltyp , ivgtyp , &
num_veg_cat , num_soil_top_cat , num_soil_bot_cat , &
ids , ide , jds , jde , kds , kde , &
ims , ime , jms , jme , kms , kme , &
its , ite , jts , jte , kts , kte , &
model_config_rec%iswater(grid%id) )
! Make all the veg/soil parms the same so as not to confuse the developer.
DO j = jts , MIN(jde-1,jte)
DO i = its , MIN(ide-1,ite)
vegcat(i,j) = ivgtyp(i,j)
soilcat(i,j) = isltyp(i,j)
END DO
END DO
ELSE
! Do we have dominant soil and veg data from the input already?
IF ( soilcat(its,jts) .GT. 0.5 ) THEN
DO j = jts, MIN(jde-1,jte)
DO i = its, MIN(ide-1,ite)
isltyp(i,j) = NINT( soilcat(i,j) )
END DO
END DO
END IF
IF ( vegcat(its,jts) .GT. 0.5 ) THEN
DO j = jts, MIN(jde-1,jte)
DO i = its, MIN(ide-1,ite)
ivgtyp(i,j) = NINT( vegcat(i,j) )
END DO
END DO
END IF
END IF
! Land use assignment.
DO j = jts, MIN(jde-1,jte)
DO i = its, MIN(ide-1,ite)
lu_index(i,j) = ivgtyp(i,j)
IF ( lu_index(i,j) .NE. model_config_rec%iswater(grid%id) ) THEN
landmask(i,j) = 1
xland(i,j) = 1
ELSE
landmask(i,j) = 0
xland(i,j) = 2
END IF
END DO
END DO
! Adjust the various soil temperature values depending on the difference in
! in elevation between the current model's elevation and the incoming data's
! orography.
IF ( flag_toposoil .EQ. 1 ) THEN
adjust_soil : SELECT CASE ( model_config_rec%bl_surface_physics(grid%id) )
CASE ( SLABSCHEME , LSMSCHEME )
CALL adjust_soil_temp_new
( tmn , model_config_rec%bl_surface_physics(grid%id) , &
tsk , ht , toposoil , landmask , flag_toposoil , &
st000010 , st010040 , st040100 , st100200 , st010200 , &
flag_st000010 , flag_st010040 , flag_st040100 , flag_st100200 , flag_st010200 , &
soilt000 , soilt005 , soilt020 , soilt040 , soilt160 , soilt300 , &
flag_soilt000 , flag_soilt005 , flag_soilt020 , flag_soilt040 , &
flag_soilt160 , flag_soilt300 , &
ids , ide , jds , jde , kds , kde , &
ims , ime , jms , jme , kms , kme , &
its , ite , jts , jte , kts , kte )
END SELECT adjust_soil
END IF
! Fix tmn and tsk.
fix_tsk_tmn : SELECT CASE ( model_config_rec%bl_surface_physics(grid%id) )
CASE ( SLABSCHEME , LSMSCHEME )
DO j = jts, MIN(jde-1,jte)
DO i = its, MIN(ide-1,ite)
IF ( ( landmask(i,j) .LT. 0.5 ) .AND. ( flag_sst .EQ. 1 ) ) THEN
tmn(i,j) = sst(i,j)
tsk(i,j) = sst(i,j)
ELSE IF ( landmask(i,j) .LT. 0.5 ) THEN
tmn(i,j) = tsk(i,j)
END IF
END DO
END DO
END SELECT fix_tsk_tmn
! Is the TSK reasonable?
DO j = jts, MIN(jde-1,jte)
DO i = its, MIN(ide-1,ite)
IF ( tsk(i,j) .LT. 170 ) THEN
print *,'error in the TSK'
print *,'i,j=',i,j
print *,'landmask=',landmask(i,j)
print *,'tsk, sst, tmn=',tsk(i,j),sst(i,j),tmn(i,j)
stop
END IF
END DO
END DO
interpolate_soil_tmw : SELECT CASE ( model_config_rec%bl_surface_physics(grid%id) )
CASE ( SLABSCHEME , LSMSCHEME )
CALL process_soil_real
( tsk , tmn , &
landmask , sst , &
st_input , sm_input , sw_input , st_levels_input , sm_levels_input , sw_levels_input , &
zs , dzs , tslb , smois , sh2o , &
flag_sst , &
ids , ide , jds , jde , kds , kde , &
ims , ime , jms , jme , kms , kme , &
its , ite , jts , jte , kts , kte , &
model_config_rec%bl_surface_physics(grid%id) , &
model_config_rec%num_soil_layers , &
model_config_rec%real_data_init_type , &
num_st_levels_input , num_sm_levels_input , num_sw_levels_input , &
num_st_levels_alloc , num_sm_levels_alloc , num_sw_levels_alloc )
END SELECT interpolate_soil_tmw
! Let us make sure (again) that the landmask and the veg/soil categories match.
oops1=0
oops2=0
DO j = jts, MIN(jde-1,jte)
DO i = its, MIN(ide-1,ite)
IF ( ( ( landmask(i,j) .LT. 0.5 ) .AND. ( ivgtyp(i,j) .NE. config_flags%iswater .OR. isltyp(i,j) .NE. 14 ) ) .OR. &
( ( landmask(i,j) .GT. 0.5 ) .AND. ( ivgtyp(i,j) .EQ. config_flags%iswater .OR. isltyp(i,j) .EQ. 14 ) ) ) THEN
IF ( tslb(i,1,j) .GT. 1. ) THEN
oops1=oops1+1
ivgtyp(i,j) = 5
isltyp(i,j) = 8
landmask(i,j) = 1
xland(i,j) = 1
ELSE IF ( sst(i,j) .GT. 1. ) THEN
oops2=oops2+1
ivgtyp(i,j) = config_flags%iswater
isltyp(i,j) = 14
landmask(i,j) = 0
xland(i,j) = 2
ELSE
print *,'the landmask and soil/veg cats do not match'
print *,'i,j=',i,j
print *,'landmask=',landmask(i,j)
print *,'ivgtyp=',ivgtyp(i,j)
print *,'isltyp=',isltyp(i,j)
print *,'iswater=', config_flags%iswater
print *,'tslb=',tslb(i,:,j)
print *,'sst=',sst(i,j)
STOP 'mismatch_landmask_ivgtyp'
END IF
END IF
END DO
END DO
if (oops1.gt.0) then
print *,'points artificially set to land : ',oops1
endif
if(oops2.gt.0) then
print *,'points artificially set to water: ',oops2
endif
! From the full level data, we can get the half levels, reciprocals, and layer
! thicknesses. These are all defined at half level locations, so one less level.
! We allow the vertical coordinate to *accidently* come in upside down. We want
! the first full level to be the ground surface.
IF ( znw(1) .LT. znw(kde) ) THEN
DO k=1, kde/2
hold_znw = znw(k)
znw(k)=znw(kde+1-k)
znw(kde+1-k)=hold_znw
END DO
END IF
DO k=1, kde-1
dnw(k) = znw(k+1) - znw(k)
rdnw(k) = 1./dnw(k)
znu(k) = 0.5*(znw(k+1)+znw(k))
END DO
! Now the same sort of computations with the half eta levels, even ANOTHER
! level less than the one above.
DO k=2, kde-1
dn(k) = 0.5*(dnw(k)+dnw(k-1))
rdn(k) = 1./dn(k)
fnp(k) = .5* dnw(k )/dn(k)
fnm(k) = .5* dnw(k-1)/dn(k)
END DO
! Scads of vertical coefficients.
cof1 = (2.*dn(2)+dn(3))/(dn(2)+dn(3))*dnw(1)/dn(2)
cof2 = dn(2) /(dn(2)+dn(3))*dnw(1)/dn(3)
cf1 = fnp(2) + cof1
cf2 = fnm(2) - cof1 - cof2
cf3 = cof2
cfn = (.5*dnw(kde-1)+dn(kde-1))/dn(kde-1)
cfn1 = -.5*dnw(kde-1)/dn(kde-1)
! Inverse grid distances.
rdx = 1./dx
rdy = 1./dy
! Some of the many weird geopotential initializations that we'll see today: ph0 is total,
! and ph_2 is a perturbation from the base state geopotential. We set the base geopotential
! at the lowest level to terrain elevation * gravity.
DO j=jts,jte
DO i=its,ite
ph0(i,1,j) = ht(i,j) * g
ph_2(i,1,j) = 0.
END DO
END DO
! To define the base state, we call a USER MODIFIED routine to set the three
! necessary constants: p00 (sea level pressure, Pa), t00 (sea level temperature, K),
! and A (temperature difference, from 1000 mb to 300 mb, K).
CALL const_module_initialize
( p00 , t00 , a )
! Base state potential temperature and inverse density (alpha = 1/rho) from
! the half eta levels and the base-profile surface pressure. Compute 1/rho
! from equation of state. The potential temperature is a perturbation from t0.
DO j = jts, MIN(jte,jde-1)
DO i = its, MIN(ite,ide-1)
! Base state pressure is a function of eta level and terrain, only, plus
! the hand full of constants: p00 (sea level pressure, Pa), t00 (sea level
! temperature, K), and A (temperature difference, from 1000 mb to 300 mb, K).
p_surf = p00 * EXP ( -t00/a + ( (t00/a)**2 - 2.*g*ht(i,j)/a/r_d ) **0.5 )
DO k = 1, kte-1
pb(i,k,j) = znu(k)*(p_surf - p_top) + p_top
t_init(i,k,j) = (t00 + A*LOG(pb(i,k,j)/p00))*(p00/pb(i,k,j))**(r_d/cp) - t0
alb(i,k,j) = (r_d/p1000mb)*(t_init(i,k,j)+t0)*(pb(i,k,j)/p1000mb)**cvpm
END DO
! Base state mu is defined as base state surface pressure minus p_top
mub(i,j) = p_surf - p_top
! Dry surface pressure is defined as the following (this mu is from the input file
! computed from the dry pressure). Here the dry pressure is just reconstituted.
pd_surf = mu0(i,j) + p_top
! Compute the perturbation mass and the full mass from the base surface pressure
! (a function of elevation) and the dry surface pressure.
mu_2(i,j) = pd_surf-p_surf
! Integrate base geopotential, starting at terrain elevation. This assures that
! the base state is in exact hydrostatic balance with respect to the model equations.
! This field is on full levels.
phb(i,1,j) = ht(i,j) * g
DO k = 2,kte
phb(i,k,j) = phb(i,k-1,j) - dnw(k-1)*mub(i,j)*alb(i,k-1,j)
END DO
END DO
END DO
! Fill in the outer rows and columns to allow us to be sloppy.
IF ( ite .EQ. ide ) THEN
i = ide
DO j = jts, MIN(jde-1,jte)
mub(i,j) = mub(i-1,j)
mu_2(i,j) = mu_2(i-1,j)
DO k = 1, kte-1
pb(i,k,j) = pb(i-1,k,j)
t_init(i,k,j) = t_init(i-1,k,j)
alb(i,k,j) = alb(i-1,k,j)
END DO
DO k = 1, kte
phb(i,k,j) = phb(i-1,k,j)
END DO
END DO
END IF
IF ( jte .EQ. jde ) THEN
j = jde
DO i = its, ite
mub(i,j) = mub(i,j-1)
mu_2(i,j) = mu_2(i,j-1)
DO k = 1, kte-1
pb(i,k,j) = pb(i,k,j-1)
t_init(i,k,j) = t_init(i,k,j-1)
alb(i,k,j) = alb(i,k,j-1)
END DO
DO k = 1, kte
phb(i,k,j) = phb(i,k,j-1)
END DO
END DO
END IF
DO j = jts, min(jde-1,jte)
DO i = its, min(ide-1,ite)
! Assign the potential temperature (perturbation from t0) and qv on all the mass
! point locations.
DO k = 1 , kde-1
t_2(i,k,j) = t_2(i,k,j) - t0
END DO
! Integrate the hydrostatic equation (from the RHS of the bigstep vertical momentum
! equation) down from the top to get the pressure perturbation. First get the pressure
! perturbation, moisture, and inverse density (total and perturbation) at the top-most level.
k = kte-1
qvf1 = 0.5*(moist_2(i,k,j,P_QV)+moist_2(i,k,j,P_QV))
qvf2 = 1./(1.+qvf1)
qvf1 = qvf1*qvf2
p(i,k,j) = - 0.5*(mu_2(i,j)+qvf1*mub(i,j))/rdnw(k)/qvf2
qvf = 1. + rvovrd*moist_2(i,k,j,P_QV)
alt(i,k,j) = (r_d/p1000mb)*(t_2(i,k,j)+t0)*qvf*(((p(i,k,j)+pb(i,k,j))/p1000mb)**cvpm)
al(i,k,j) = alt(i,k,j) - alb(i,k,j)
! Now, integrate down the column to compute the pressure perturbation, and diagnose the two
! inverse density fields (total and perturbation).
DO k=kte-2,1,-1
qvf1 = 0.5*(moist_2(i,k,j,P_QV)+moist_2(i,k+1,j,P_QV))
qvf2 = 1./(1.+qvf1)
qvf1 = qvf1*qvf2
p(i,k,j) = p(i,k+1,j) - (mu_2(i,j) + qvf1*mub(i,j))/qvf2/rdn(k+1)
qvf = 1. + rvovrd*moist_2(i,k,j,P_QV)
alt(i,k,j) = (r_d/p1000mb)*(t_2(i,k,j)+t0)*qvf* &
(((p(i,k,j)+pb(i,k,j))/p1000mb)**cvpm)
al(i,k,j) = alt(i,k,j) - alb(i,k,j)
END DO
! This is the hydrostatic equation used in the model after the small timesteps. In
! the model, al (inverse density) is computed from the geopotential.
DO k = 2,kte
ph_2(i,k,j) = ph_2(i,k-1,j) - &
dnw(k-1) * ( (mub(i,j)+mu_2(i,j))*al(i,k-1,j) + mu_2(i,j)*alb(i,k-1,j) )
ph0(i,k,j) = ph_2(i,k,j) + phb(i,k,j)
END DO
END DO
END DO
#ifdef DM_PARALLEL
# include "HALO_EM_INIT.inc"
#endif
#define COPY_OUT
#include <em_scalar_derefs.inc>
RETURN
END SUBROUTINE init_domain_rk
!---------------------------------------------------------------------
SUBROUTINE const_module_initialize ( p00 , t00 , a ) 2
IMPLICIT NONE
REAL , PARAMETER :: sea_level_pressure_base = 100000.
REAL , PARAMETER :: sea_level_temperature_base = 290.
REAL , PARAMETER :: temp_diff_1000_to_300_mb = 50.
REAL , INTENT(OUT) :: p00 , t00 , a
p00 = sea_level_pressure_base
t00 = sea_level_temperature_base
a = temp_diff_1000_to_300_mb
END SUBROUTINE const_module_initialize
!-------------------------------------------------------------------
SUBROUTINE rebalance_driver ( grid ) 1,1
IMPLICIT NONE
TYPE (domain) :: grid
#ifdef DEREF_KLUDGE
INTEGER :: sm31 , em31 , sm32 , em32 , sm33 , em33
#endif
#ifdef DEREF_KLUDGE
sm31 = grid%sm31
em31 = grid%em31
sm32 = grid%sm32
em32 = grid%em32
sm33 = grid%sm33
em33 = grid%em33
#endif
CALL rebalance
( grid, &
!
#include <em_actual_args.inc>
!
)
END SUBROUTINE rebalance_driver
!---------------------------------------------------------------------
SUBROUTINE rebalance ( grid , & 1,1
!
#include <em_dummy_args.inc>
!
)
IMPLICIT NONE
TYPE (domain) :: grid
#include <em_dummy_decl.inc>
TYPE (grid_config_rec_type) :: config_flags
REAL :: p_surf , pd_surf, p_surf_int , pb_int , ht_hold
REAL :: qvf , qvf1 , qvf2
REAL :: p00 , t00 , a
REAL , DIMENSION(:,:,:) , ALLOCATABLE :: t_init_int
! Local domain indices and counters.
INTEGER :: num_veg_cat , num_soil_top_cat , num_soil_bot_cat
INTEGER :: &
ids, ide, jds, jde, kds, kde, &
ims, ime, jms, jme, kms, kme, &
its, ite, jts, jte, kts, kte, &
i, j, k
#define COPY_IN
#include <em_scalar_derefs.inc>
#ifdef DM_PARALLEL
# include <em_data_calls.inc>
#endif
SELECT CASE ( model_data_order )
CASE ( DATA_ORDER_ZXY )
kds = grid%sd31 ; kde = grid%ed31 ;
ids = grid%sd32 ; ide = grid%ed32 ;
jds = grid%sd33 ; jde = grid%ed33 ;
kms = grid%sm31 ; kme = grid%em31 ;
ims = grid%sm32 ; ime = grid%em32 ;
jms = grid%sm33 ; jme = grid%em33 ;
kts = grid%sp31 ; kte = grid%ep31 ; ! note that tile is entire patch
its = grid%sp32 ; ite = grid%ep32 ; ! note that tile is entire patch
jts = grid%sp33 ; jte = grid%ep33 ; ! note that tile is entire patch
CASE ( DATA_ORDER_XYZ )
ids = grid%sd31 ; ide = grid%ed31 ;
jds = grid%sd32 ; jde = grid%ed32 ;
kds = grid%sd33 ; kde = grid%ed33 ;
ims = grid%sm31 ; ime = grid%em31 ;
jms = grid%sm32 ; jme = grid%em32 ;
kms = grid%sm33 ; kme = grid%em33 ;
its = grid%sp31 ; ite = grid%ep31 ; ! note that tile is entire patch
jts = grid%sp32 ; jte = grid%ep32 ; ! note that tile is entire patch
kts = grid%sp33 ; kte = grid%ep33 ; ! note that tile is entire patch
CASE ( DATA_ORDER_XZY )
ids = grid%sd31 ; ide = grid%ed31 ;
kds = grid%sd32 ; kde = grid%ed32 ;
jds = grid%sd33 ; jde = grid%ed33 ;
ims = grid%sm31 ; ime = grid%em31 ;
kms = grid%sm32 ; kme = grid%em32 ;
jms = grid%sm33 ; jme = grid%em33 ;
its = grid%sp31 ; ite = grid%ep31 ; ! note that tile is entire patch
kts = grid%sp32 ; kte = grid%ep32 ; ! note that tile is entire patch
jts = grid%sp33 ; jte = grid%ep33 ; ! note that tile is entire patch
END SELECT
ALLOCATE ( t_init_int(ims:ime,kms:kme,jms:jme) )
! Some of the many weird geopotential initializations that we'll see today: ph0 is total,
! and ph_2 is a perturbation from the base state geopotential. We set the base geopotential
! at the lowest level to terrain elevation * gravity.
DO j=jts,jte
DO i=its,ite
ph0(i,1,j) = ht_fine(i,j) * g
ph_2(i,1,j) = 0.
END DO
END DO
! To define the base state, we call a USER MODIFIED routine to set the three
! necessary constants: p00 (sea level pressure, Pa), t00 (sea level temperature, K),
! and A (temperature difference, from 1000 mb to 300 mb, K).
CALL const_module_initialize
( p00 , t00 , a )
! Base state potential temperature and inverse density (alpha = 1/rho) from
! the half eta levels and the base-profile surface pressure. Compute 1/rho
! from equation of state. The potential temperature is a perturbation from t0.
DO j = jts, MIN(jte,jde-1)
DO i = its, MIN(ite,ide-1)
! Base state pressure is a function of eta level and terrain, only, plus
! the hand full of constants: p00 (sea level pressure, Pa), t00 (sea level
! temperature, K), and A (temperature difference, from 1000 mb to 300 mb, K).
! The fine grid terrain is ht_fine, the interpolated is ht.
p_surf = p00 * EXP ( -t00/a + ( (t00/a)**2 - 2.*g*ht_fine(i,j)/a/r_d ) **0.5 )
p_surf_int = p00 * EXP ( -t00/a + ( (t00/a)**2 - 2.*g*ht(i,j) /a/r_d ) **0.5 )
DO k = 1, kte-1
pb(i,k,j) = znu(k)*(p_surf - p_top) + p_top
pb_int = znu(k)*(p_surf_int - p_top) + p_top
t_init(i,k,j) = (t00 + A*LOG(pb(i,k,j)/p00))*(p00/pb(i,k,j))**(r_d/cp) - t0
t_init_int(i,k,j)= (t00 + A*LOG(pb_int /p00))*(p00/pb_int )**(r_d/cp) - t0
alb(i,k,j) = (r_d/p1000mb)*(t_init(i,k,j)+t0)*(pb(i,k,j)/p1000mb)**cvpm
END DO
! Base state mu is defined as base state surface pressure minus p_top
mub(i,j) = p_surf - p_top
! Dry surface pressure is defined as the following (this mu is from the input file
! computed from the dry pressure). Here the dry pressure is just reconstituted.
pd_surf = ( mub(i,j) + mu_2(i,j) ) + p_top
! Integrate base geopotential, starting at terrain elevation. This assures that
! the base state is in exact hydrostatic balance with respect to the model equations.
! This field is on full levels.
phb(i,1,j) = ht_fine(i,j) * g
DO k = 2,kte
phb(i,k,j) = phb(i,k-1,j) - dnw(k-1)*mub(i,j)*alb(i,k-1,j)
END DO
END DO
END DO
! Replace interpolated terrain with fine grid values.
DO j = jts, MIN(jte,jde-1)
DO i = its, MIN(ite,ide-1)
ht(i,j) = ht_fine(i,j)
END DO
END DO
! Perturbation fields.
DO j = jts, min(jde-1,jte)
DO i = its, min(ide-1,ite)
! The potential temperature is THETAnest = THETAinterp + ( TBARnest - TBARinterp)
DO k = 1 , kde-1
t_2(i,k,j) = t_2(i,k,j) + ( t_init(i,k,j) - t_init_int(i,k,j) )
END DO
! Integrate the hydrostatic equation (from the RHS of the bigstep vertical momentum
! equation) down from the top to get the pressure perturbation. First get the pressure
! perturbation, moisture, and inverse density (total and perturbation) at the top-most level.
k = kte-1
qvf1 = 0.5*(moist_2(i,k,j,P_QV)+moist_2(i,k,j,P_QV))
qvf2 = 1./(1.+qvf1)
qvf1 = qvf1*qvf2
p(i,k,j) = - 0.5*(mu_2(i,j)+qvf1*mub(i,j))/rdnw(k)/qvf2
qvf = 1. + rvovrd*moist_2(i,k,j,P_QV)
alt(i,k,j) = (r_d/p1000mb)*(t_2(i,k,j)+t0)*qvf*(((p(i,k,j)+pb(i,k,j))/p1000mb)**cvpm)
al(i,k,j) = alt(i,k,j) - alb(i,k,j)
! Now, integrate down the column to compute the pressure perturbation, and diagnose the two
! inverse density fields (total and perturbation).
DO k=kte-2,1,-1
qvf1 = 0.5*(moist_2(i,k,j,P_QV)+moist_2(i,k+1,j,P_QV))
qvf2 = 1./(1.+qvf1)
qvf1 = qvf1*qvf2
p(i,k,j) = p(i,k+1,j) - (mu_2(i,j) + qvf1*mub(i,j))/qvf2/rdn(k+1)
qvf = 1. + rvovrd*moist_2(i,k,j,P_QV)
alt(i,k,j) = (r_d/p1000mb)*(t_2(i,k,j)+t0)*qvf* &
(((p(i,k,j)+pb(i,k,j))/p1000mb)**cvpm)
al(i,k,j) = alt(i,k,j) - alb(i,k,j)
END DO
! This is the hydrostatic equation used in the model after the small timesteps. In
! the model, al (inverse density) is computed from the geopotential.
DO k = 2,kte
ph_2(i,k,j) = ph_2(i,k-1,j) - &
dnw(k-1) * ( (mub(i,j)+mu_2(i,j))*al(i,k-1,j) + mu_2(i,j)*alb(i,k-1,j) )
ph0(i,k,j) = ph_2(i,k,j) + phb(i,k,j)
END DO
END DO
END DO
DEALLOCATE ( t_init_int )
END SUBROUTINE rebalance
!---------------------------------------------------------------------
SUBROUTINE init_module_initialize,8
END SUBROUTINE init_module_initialize
!---------------------------------------------------------------------
END MODULE module_initialize