#ifdef GEOS5
#include "MAPL_Generic.h"
#endif
!-------------------------------------------------------------------------
! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
!-------------------------------------------------------------------------
!BOP
!
! !MODULE: SS_GridCompMod --- SS Grid Component Class
!
! !INTERFACE:
!
module SS_GridCompMod 1
! !USES:
#ifdef GEOS5
USE ESMF_Mod
USE MAPL_Mod
#endif
use Chem_Mod
! Chemistry Base Class
use Chem_StateMod
! Chemistry State
use Chem_SettlingMod
! Settling
use Chem_DepositionMod
! Aerosol Deposition
use Chem_ConstMod
, only: grav, von_karman, cpd ! Constants !
use Chem_UtilMod
! I/O
use Chem_MieMod
! Aerosol LU Tables, calculator
use m_inpak90
! Resource file management
use m_die
, only: die
implicit none
! !PUBLIC TYPES:
!
PRIVATE
PUBLIC SS_GridComp ! The SS object
!
! !PUBLIIC MEMBER FUNCTIONS:
!
PUBLIC SS_GridCompInitialize
PUBLIC SS_GridCompRun
PUBLIC SS_GridCompFinalize
!
! !DESCRIPTION:
!
! This module implements the (pre-ESMF) SS Grid Component.
!
! !REVISION HISTORY:
!
! 16Sep2003 da Silva First crack.
!
!EOP
!-------------------------------------------------------------------------
type SS_GridComp
character(len=255) :: name
type(Chem_Mie), pointer :: mie_tables ! aod LUTs
integer :: rhFlag
real, pointer :: radius(:) ! particle effective radius [um]
real, pointer :: rLow(:) ! lower radius of particle bin [um]
real, pointer :: rUp(:) ! upper radius of particle bin [um]
real, pointer :: rhop(:) ! dry salt particle density [kg m-3]
end type SS_GridComp
real, parameter :: OCEAN=0.0, LAND = 1.0, SEA_ICE = 2.0
CONTAINS
!-------------------------------------------------------------------------
! NASA/GSFC, Global Modeling and Assimilation Office, Code 900.3 !
!-------------------------------------------------------------------------
!BOP
!
! !IROUTINE: SS_GridCompInitialize --- Initialize SS_GridComp
!
! !INTERFACE:
!
subroutine SS_GridCompInitialize ( gcSS, w_c, impChem, expChem, & 1,88
nymd, nhms, cdt, rc )
! !USES:
implicit NONE
! !INPUT PARAMETERS:
type(Chem_Bundle), intent(inout) :: w_c ! Chemical tracer fields
integer, intent(in) :: nymd, nhms ! time
real, intent(in) :: cdt ! chemical timestep (secs)
! !OUTPUT PARAMETERS:
type(SS_GridComp), intent(inout) :: gcSS ! Grid Component
type(ESMF_State), intent(inout) :: impChem ! Import State
type(ESMF_State), intent(inout) :: expChem ! Export State
integer, intent(out) :: rc ! Error return code:
! 0 - all is well
! 1 -
! !DESCRIPTION: Initializes the SS Grid Component. It primarily sets
! the import state for each active constituent package.
!
! !REVISION HISTORY:
!
! 18Sep2003 da Silva First crack.
!
!EOP
!-------------------------------------------------------------------------
character(len=*), parameter :: myname = 'SS_GridCompInitialize'
character(len=255) :: rcfilen = 'SS_GridComp.rc'
integer :: ios, n
integer, allocatable :: ier(:)
integer :: i1, i2, im, j1, j2, jm, nbins, n1, n2, nbins_rc
real :: qmin, qmax
real :: radius, rlow, rup, rmrat, rmin, rhop, fscav
integer :: irhFlag
character(len=255) :: CARMA_Services = ' '
gcSS%name = 'SS Constituent Package'
! Initialize local variables
! --------------------------
rc = 0
i1 = w_c%grid%i1; i2 = w_c%grid%i2; im = w_c%grid%im
j1 = w_c%grid%j1; j2 = w_c%grid%j2; jm = w_c%grid%jm
nbins = w_c%reg%n_SS
n1 = w_c%reg%i_SS
n2 = w_c%reg%j_SS
call init_
()
if ( rc /= 0 ) return
! -------------------
! Parse resource file
! -------------------
! Load resource file
! ------------------
call i90_loadf
( rcfilen, ier(1) )
if ( ier(1) .ne. 0 ) then
call final_
(10)
return
end if
call i90_label
( 'number_SS_bins:', ier(1) )
nbins_rc = i90_gint ( ier(2) )
if ( any(ier(1:2) /= 0) ) then
call final_
(20)
return
end if
if ( nbins_rc /= nbins ) then
call final_
(25)
return
end if
! call final_(0)
! CARMA Services
! --------------
call i90_label
( 'CARMA_Services:', ier(1) )
if ( ier(1) /= 0 ) then
CARMA_Services = ' '
else
call i90_gtoken
( CARMA_Services, ier(1) )
if ( ier(1) /= 0 ) then
CARMA_Services = ' '
end if
end if
do n = n1, n2
w_c%qa(n)%wantServices = trim(CARMA_Services)
enddo
! Particle radius
! ---------------
call i90_label
( 'particle_radius:', ier(1) )
do n = 1, nbins
radius = i90_gfloat ( ier(n+1) )
gcSS%radius(n) = radius
w_c%qa(n1+n-1)%r = radius * 1.e-6 ! save radius in [m]
end do
if ( any(ier(1:nbins+1) /= 0) ) then
call final_
(50)
return
end if
! Particle radius (lower bound)
! ---------------
call i90_label
( 'radius_lower:', ier(1) )
do n = 1, nbins
rlow = i90_gfloat ( ier(n+1) )
gcSS%rlow(n) = rlow
w_c%qa(n1+n-1)%rlow = rlow * 1.e-6 ! save radius in [m]
end do
if ( any(ier(1:nbins+1) /= 0) ) then
call final_
(50)
return
end if
! Particle radius (upper bound)
! ---------------
call i90_label
( 'radius_upper:', ier(1) )
do n = 1, nbins
rup = i90_gfloat ( ier(n+1) )
gcSS%rup(n) = rup
w_c%qa(n1+n-1)%rup = rup * 1.e-6 ! save radius in [m]
end do
if ( any(ier(1:nbins+1) /= 0) ) then
call final_
(50)
return
end if
! -------
! Dry Particle Density
! ---------------
call i90_label
( 'SS_density:', ier(1) )
do n = 1, nbins
rhop = i90_gfloat ( ier(n+1) )
gcSS%rhop(n) = rhop
w_c%qa(n1+n-1)%rhop = rhop
end do
if ( any(ier(1:nbins+1) /= 0) ) then
call final_
(50)
return
end if
! -------
! Scavenging Efficiency
! To be used in convtran.F90, this parameter
! is the scavenging efficiency of the tracer [km -1]
! ---------------
call i90_label
( 'fscav:', ier(1) )
do n = 1, nbins
fscav = i90_gfloat ( ier(n+1) )
w_c%reg%fscav(n1+n-1) = fscav
w_c%qa(n1+n-1)%fscav = fscav
end do
if ( any(ier(1:nbins+1) /= 0) ) then
call final_
(50)
return
end if
! -------
! Particle affected by relative humidity?
! ---------------
call i90_label
( 'rhFlag:', ier(1) )
irhFlag = i90_gint ( ier(2) )
w_c%qa(n1+n-1)%irhFlag = irhFlag
gcSS%rhFlag = irhFlag
if ( any(ier(1:2) /= 0) ) then
call final_
(50)
return
end if
#ifndef GEOS5
!\/--- cut --- --- cut --- --- cut --- --- cut --- --- cut --- --- cut ---\/
! Set which fvGCM fields are needed
! ---------------------------------
call Chem_StateSetNeeded
( impChem, iFRACLAKE, .true., ier(1) )
call Chem_StateSetNeeded
( impChem, iGWETTOP, .true., ier(2) )
call Chem_StateSetNeeded
( impChem, iORO, .true., ier(3) )
call Chem_StateSetNeeded
( impChem, iU10M, .true., ier(4) )
call Chem_StateSetNeeded
( impChem, iV10M, .true., ier(5) )
call Chem_StateSetNeeded
( impChem, iLAI, .true., ier(6) )
call Chem_StateSetNeeded
( impChem, iUSTAR, .true., ier(7) )
call Chem_StateSetNeeded
( impChem, iPRECC, .true., ier(8) )
call Chem_StateSetNeeded
( impChem, iPRECL, .true., ier(9) )
call Chem_StateSetNeeded
( impChem, iDQCOND, .true., ier(10) )
call Chem_StateSetNeeded
( impChem, iT, .true., ier(11) )
call Chem_StateSetNeeded
( impChem, iAIRDENS, .true., ier(12) )
call Chem_StateSetNeeded
( impChem, iU, .true., ier(13) )
call Chem_StateSetNeeded
( impChem, iV, .true., ier(14) )
call Chem_StateSetNeeded
( impChem, iPBLH, .true., ier(15) )
call Chem_StateSetNeeded
( impChem, iSHFX, .true., ier(16) )
call Chem_StateSetNeeded
( impChem, iZ0H, .true., ier(17) )
call Chem_StateSetNeeded
( impChem, iHSURF, .true., ier(18) )
call Chem_StateSetNeeded
( impChem, iHGHTE, .true., ier(19) )
if ( any(ier(1:19) /= 0) ) then
call final_
(90)
return
endif
! Select fields to be produced in the export state
! ------------------------------------------------
n = nbins
! Emission Flux
if(n>0) call Chem_StateSetNeeded
( expChem, iSSEM001, .true., ier(1) )
if(n>1) call Chem_StateSetNeeded
( expChem, iSSEM002, .true., ier(2) )
if(n>2) call Chem_StateSetNeeded
( expChem, iSSEM003, .true., ier(3) )
if(n>3) call Chem_StateSetNeeded
( expChem, iSSEM004, .true., ier(4) )
if(n>4) call Chem_StateSetNeeded
( expChem, iSSEM005, .true., ier(5) )
if(n>5) call Chem_StateSetNeeded
( expChem, iSSEM006, .true., ier(6) )
if(n>6) call Chem_StateSetNeeded
( expChem, iSSEM007, .true., ier(7) )
if(n>7) call Chem_StateSetNeeded
( expChem, iSSEM008, .true., ier(8) )
if(n>8) ier(9) = 1 ! not enough bins - need to change mod_diag.F
if ( any(ier(1:9) /= 0) ) then
call final_
(91)
return
endif
! Sedimentation Flux
if(n>0) call Chem_StateSetNeeded
( expChem, iSSSD001, .true., ier(1) )
if(n>1) call Chem_StateSetNeeded
( expChem, iSSSD002, .true., ier(2) )
if(n>2) call Chem_StateSetNeeded
( expChem, iSSSD003, .true., ier(3) )
if(n>3) call Chem_StateSetNeeded
( expChem, iSSSD004, .true., ier(4) )
if(n>4) call Chem_StateSetNeeded
( expChem, iSSSD005, .true., ier(5) )
if(n>5) call Chem_StateSetNeeded
( expChem, iSSSD006, .true., ier(6) )
if(n>6) call Chem_StateSetNeeded
( expChem, iSSSD007, .true., ier(7) )
if(n>7) call Chem_StateSetNeeded
( expChem, iSSSD008, .true., ier(8) )
if(n>8) ier(9) = 1 ! not enough bins - need to change mod_diag.F
if ( any(ier(1:9) /= 0) ) then
call final_
(92)
return
endif
! Dry Deposition Flux
if(n>0) call Chem_StateSetNeeded
( expChem, iSSDP001, .true., ier(1) )
if(n>1) call Chem_StateSetNeeded
( expChem, iSSDP002, .true., ier(2) )
if(n>2) call Chem_StateSetNeeded
( expChem, iSSDP003, .true., ier(3) )
if(n>3) call Chem_StateSetNeeded
( expChem, iSSDP004, .true., ier(4) )
if(n>4) call Chem_StateSetNeeded
( expChem, iSSDP005, .true., ier(5) )
if(n>5) call Chem_StateSetNeeded
( expChem, iSSDP006, .true., ier(6) )
if(n>6) call Chem_StateSetNeeded
( expChem, iSSDP007, .true., ier(7) )
if(n>7) call Chem_StateSetNeeded
( expChem, iSSDP008, .true., ier(8) )
if(n>8) ier(9) = 1 ! not enough bins - need to change mod_diag.F
if ( any(ier(1:9) /= 0) ) then
call final_
(93)
return
endif
! Wet Deposition Flux
if(n>0) call Chem_StateSetNeeded
( expChem, iSSWT001, .true., ier(1) )
if(n>1) call Chem_StateSetNeeded
( expChem, iSSWT002, .true., ier(2) )
if(n>2) call Chem_StateSetNeeded
( expChem, iSSWT003, .true., ier(3) )
if(n>3) call Chem_StateSetNeeded
( expChem, iSSWT004, .true., ier(4) )
if(n>4) call Chem_StateSetNeeded
( expChem, iSSWT005, .true., ier(5) )
if(n>5) call Chem_StateSetNeeded
( expChem, iSSWT006, .true., ier(6) )
if(n>6) call Chem_StateSetNeeded
( expChem, iSSWT007, .true., ier(7) )
if(n>7) call Chem_StateSetNeeded
( expChem, iSSWT008, .true., ier(8) )
if(n>8) ier(9) = 1 ! not enough bins - need to change mod_diag.F
if ( any(ier(1:9) /= 0) ) then
call final_
(94)
return
endif
! Other diagnostics
call Chem_StateSetNeeded
( expChem, iSSSMASS, .true., ier(1) )
call Chem_StateSetNeeded
( expChem, iSSCMASS, .true., ier(2) )
call Chem_StateSetNeeded
( expChem, iSSMASS, .true., ier(3) )
call Chem_StateSetNeeded
( expChem, iSSEXTTAU, .true., ier(4) )
call Chem_StateSetNeeded
( expChem, iSSSCATAU, .true., ier(5) )
call Chem_StateSetNeeded
( expChem, iSSSM25, .true., ier(6) )
call Chem_StateSetNeeded
( expChem, iSSCM25, .true., ier(7) )
call Chem_StateSetNeeded
( expChem, iSSMASS25, .true., ier(8) )
call Chem_StateSetNeeded
( expChem, iSSEXTT25, .true., ier(9) )
call Chem_StateSetNeeded
( expChem, iSSSCAT25, .true., ier(10) )
if ( any(ier(1:10) /= 0) ) then
call final_
(70)
return
endif
!/\--- cut --- --- cut --- --- cut --- --- cut --- --- cut --- --- cut ---/\
#endif
! All done
! --------
call i90_release
()
deallocate(ier)
return
CONTAINS
subroutine init_() 36,316
integer ios, nerr
nerr = max ( 32, nbins+1 )
allocate ( gcSS%radius(nbins), gcSS%rLow(nbins), gcSS%rUp(nbins), &
gcSS%rhop(nbins), ier(nerr), stat=ios )
if ( ios /= 0 ) rc = 100
end subroutine init_
subroutine final_(ierr) 174,11
integer :: ierr
integer ios
deallocate ( gcSS%radius, gcSS%rhop, gcSS%rLow, gcSS%rUp, ier, stat=ios )
call i90_release
()
rc = ierr
end subroutine final_
end subroutine SS_GridCompInitialize
!-------------------------------------------------------------------------
! NASA/GSFC, Global Modeling and Assimilation Office, Code 900.3 !
!-------------------------------------------------------------------------
!BOP
!
! !IROUTINE: SS_GridCompRun --- The Chem Driver
!
! !INTERFACE:
!
subroutine SS_GridCompRun ( gcSS, w_c, impChem, expChem, & 1,61
nymd, nhms, cdt, rc )
! !USES:
implicit NONE
! !INPUT/OUTPUT PARAMETERS:
type(SS_GridComp), intent(inout) :: gcSS ! Grid Component
type(Chem_Bundle), intent(inout) :: w_c ! Chemical tracer fields
! !INPUT PARAMETERS:
type(ESMF_State), intent(inout) :: impChem ! Import State
integer, intent(in) :: nymd, nhms ! time
real, intent(in) :: cdt ! chemical timestep (secs)
! !OUTPUT PARAMETERS:
type(ESMF_State), intent(inout) :: expChem ! Export State
integer, intent(out) :: rc ! Error return code:
! 0 - all is well
! 1 -
! !DESCRIPTION: This routine implements the so-called SS Driver. That
! is, adds chemical tendencies to each of the constituents,
! Note: water wapor, the first constituent is not considered a chemical
! constituents.
!
! !REVISION HISTORY:
!
! 18Sep2003 da Silva First crack.
!
!EOP
!-------------------------------------------------------------------------
character(len=*), parameter :: myname = 'SS_GridCompRun'
character(len=*), parameter :: Iam = myname
integer :: ier(32), idiag
integer :: i1, i2, im, j1, j2, jm, nbins, nbeg, nend, km, n, ios, ijl, ijkl
real :: qmin, qmax
real, pointer :: SS_radius(:), SS_rhop(:)
! Input fields from fvGCM
! -----------------------
real, pointer, dimension(:,:) :: fraclake, gwettop, oro, u10m, v10m, &
xlai, ustar, precc, precl, pblh, &
shflux, z0h, hsurf
real, pointer, dimension(:,:,:) :: dqcond, tmpu, rhoa, u, v, hghte
#ifdef GEOS5
#define EXPORT expChem
#define ptrSSWT SS_wet
#define ptrSSEM SS_emis
#define ptrSSDP SS_dep
#define ptrSSSD SS_set
#define ptrSSMASS SS_mass
#define ptrSSMASS25 SS_mass25
#define ptrSSSMASS SS_sfcmass
#define ptrSSCMASS SS_colmass
#define ptrSSEXTTAU SS_exttau
#define ptrSSSCATAU SS_scatau
#define ptrSSSMASS25 SS_sfcmass25
#define ptrSSCMASS25 SS_colmass25
#define ptrSSEXTT25 SS_exttau25
#define ptrSSSCAT25 SS_scatau25
#define ptrSSAERIDX SS_aeridx
integer :: STATUS
#include "SS_GetPointer___.h"
#else
!\/--- cut --- --- cut --- --- cut --- --- cut --- --- cut --- --- cut ---\/
! Quantities to be exported
! -------------------------
type(Chem_Array), pointer :: SS_emis(:), SS_set(:), SS_dep(:), SS_wet(:), &
SS_sfcmass, SS_colmass, SS_mass, SS_exttau, &
SS_scatau, &
SS_sfcmass25, SS_colmass25, SS_mass25, SS_exttau25, &
SS_scatau25
!/\--- cut --- --- cut --- --- cut --- --- cut --- --- cut --- --- cut ---/\
#endif
! Initialize local variables
! --------------------------
rc = 0
i1 = w_c%grid%i1; i2 = w_c%grid%i2; im = w_c%grid%im
j1 = w_c%grid%j1; j2 = w_c%grid%j2; jm = w_c%grid%jm
km = w_c%grid%km
nbins = w_c%reg%n_SS
nbeg = w_c%reg%i_SS
nend = w_c%reg%j_SS
ijl = ( i2 - i1 + 1 ) * ( j2 - j1 + 1 )
ijkl = ijl * km
#ifndef GEOS5
!\/--- cut --- --- cut --- --- cut --- --- cut --- --- cut --- --- cut ---\/
! Work space for holding seasalt output
! ----------------------------------
allocate ( SS_emis(nbins), SS_set(nbins), SS_dep(nbins), SS_wet(nbins), &
SS_sfcmass, SS_colmass, SS_mass, SS_exttau, SS_scatau, &
SS_sfcmass25, SS_colmass25, SS_mass25, SS_exttau25, SS_scatau25, &
stat = ios)
if ( ios /= 0 ) then
rc = 1
return
end if
!/\--- cut --- --- cut --- --- cut --- --- cut --- --- cut --- --- cut ---/\
#endif
! Seasalt particle radius [m] and density [kg m-3]
! ---------------------------------------------
allocate( SS_radius(nbins), SS_rhop(nbins) )
SS_radius = 1.e-6*gcSS%radius
SS_rhop = gcSS%rhop
#ifdef GEOS5
! Get 2D Imports
! --------------
call MAPL_GetPointer ( impChem, fraclake, 'FRLAKE', rc=ier(1) )
call MAPL_GetPointer ( impChem, gwettop, 'WET1', rc=ier(2) )
call MAPL_GetPointer ( impChem, oro, 'LWI', rc=ier(3) )
call MAPL_GetPointer ( impChem, u10m, 'U10M', rc=ier(4) )
call MAPL_GetPointer ( impChem, v10m, 'V10M', rc=ier(5) )
call MAPL_GetPointer ( impChem, xlai, 'LAI', rc=ier(6) )
call MAPL_GetPointer ( impChem, ustar, 'USTAR', rc=ier(7) )
call MAPL_GetPointer ( impChem, precc, 'CN_PRCP', rc=ier(8) )
call MAPL_GetPointer ( impChem, precl, 'NCN_PRCP', rc=ier(9) )
call MAPL_GetPointer ( impChem, pblh, 'ZPBL', rc=ier(10) )
call MAPL_GetPointer ( impChem, shflux, 'SH', rc=ier(11) )
call MAPL_GetPointer ( impChem, z0h, 'Z0H', rc=ier(12) )
ier(13) = 0 ! see below for hsurf
! Get 3D Imports
! --------------
call MAPL_GetPointer ( impChem, dqcond, 'DQDT', rc=ier(14) )
call MAPL_GetPointer ( impChem, tmpu, 'T', rc=ier(15) )
call MAPL_GetPointer ( impChem, rhoa, 'AIRDENS', rc=ier(16) )
call MAPL_GetPointer ( impChem, u, 'U', rc=ier(17) )
call MAPL_GetPointer ( impChem, v, 'V', rc=ier(18) )
call MAPL_GetPointer ( impChem, hghte, 'ZLE', rc=ier(19) )
! Unlike GEOS-4 hghte is defined for km+1
! ---------------------------------------
hsurf => hghte(i1:i2,j1:j2,km) ! in GEOS-5 hghte is in [0,km]
#else
!\/--- cut --- --- cut --- --- cut --- --- cut --- --- cut --- --- cut ---\/
! Get input fvGCM 2D diagnostics
! ------------------------------
call Chem_StateGetArray2D
( impChem, iFRACLAKE, fraclake, ier(1) )
call Chem_StateGetArray2D
( impChem, iGWETTOP, gwettop, ier(2) )
call Chem_StateGetArray2D
( impChem, iORO, oro, ier(3) )
call Chem_StateGetArray2D
( impChem, iU10M, u10m, ier(4) )
call Chem_StateGetArray2D
( impChem, iV10M, v10m, ier(5) )
call Chem_StateGetArray2D
( impChem, iLAI, xlai, ier(6) )
call Chem_StateGetArray2D
( impChem, iUSTAR, ustar, ier(7) )
call Chem_StateGetArray2D
( impChem, iPRECC, precc, ier(8) )
call Chem_StateGetArray2D
( impChem, iPRECL, precl, ier(9) )
call Chem_StateGetArray2D
( impChem, iPBLH, pblh, ier(10) )
call Chem_StateGetArray2D
( impChem, iSHFX, shflux, ier(11) )
call Chem_StateGetArray2D
( impChem, iZ0H, z0h, ier(12) )
call Chem_StateGetArray2D
( impChem, iHSURF, hsurf, ier(13) )
! Get input fvGCM 3D diagnostics
! ------------------------------
call Chem_StateGetArray3D
( impChem, iDQCOND, dqcond, ier(14) )
call Chem_StateGetArray3D
( impChem, iT, tmpu, ier(15) )
call Chem_StateGetArray3D
( impChem, iAIRDENS, rhoa, ier(16) )
call Chem_StateGetArray3D
( impChem, iU, u, ier(17) )
call Chem_StateGetArray3D
( impChem, iV, v, ier(18) )
call Chem_StateGetArray3D
( impChem, iHGHTE, hghte, ier(19) )
!/\--- cut --- --- cut --- --- cut --- --- cut --- --- cut --- --- cut ---/\
#endif
if ( any(ier(1:19) /= 0) ) then
rc = 10
return
end if
! Make sure LAI has values over ocean
! -----------------------------------
where ( oro /= LAND ) xlai = 0.0
#ifdef DEBUG
call pmaxmin
('SS: fraclake ', fraclake, qmin, qmax, ijl,1, 1. )
call pmaxmin
('SS: gwtop ', gwettop , qmin, qmax, ijl,1, 1. )
call pmaxmin
('SS: oro ', oro , qmin, qmax, ijl,1, 1. )
call pmaxmin
('SS: u10m ', u10m , qmin, qmax, ijl,1, 1. )
call pmaxmin
('SS: v10m ', v10m , qmin, qmax, ijl,1, 1. )
call pmaxmin
('SS: xlai ', xlai , qmin, qmax, ijl,1, 1. )
call pmaxmin
('SS: ustar ', ustar , qmin, qmax, ijl,1, 1. )
call pmaxmin
('SS: precc ', precc , qmin, qmax, ijl,1, 1. )
call pmaxmin
('SS: precl ', precl , qmin, qmax, ijl,1, 1. )
call pmaxmin
('SS: pblh ', pblh , qmin, qmax, ijl,1, 1. )
call pmaxmin
('SS: shfflux ', shflux , qmin, qmax, ijl,1, 1. )
call pmaxmin
('SS: z0h ', z0h , qmin, qmax, ijl,1, 1. )
call pmaxmin
('SS: hsurf ', hsurf , qmin, qmax, ijl,1, 1. )
call pmaxmin
('SS: dqcond ', dqcond , qmin, qmax, ijkl,1, 1. )
call pmaxmin
('SS: tmpu ', tmpu , qmin, qmax, ijkl,1, 1. )
call pmaxmin
('SS: rhoa ', rhoa , qmin, qmax, ijkl,1, 1. )
call pmaxmin
('SS: u ', u , qmin, qmax, ijkl,1, 1. )
call pmaxmin
('SS: v ', v , qmin, qmax, ijkl,1, 1. )
call pmaxmin
('SS: hghte ', hghte , qmin, qmax, ijkl,1, 1. )
#endif
#ifndef GEOS5
!\/--- cut --- --- cut --- --- cut --- --- cut --- --- cut --- --- cut ---\/
! Get pointers to export state
! ----------------------------
do n = 1, nbins
idiag = iSSEM001 + n - 1
call Chem_StateGetArray2D
( expChem, idiag, SS_emis(n)%data2d, ier(n) )
end do
if ( any(ier(1:nbins) /= 0) ) then
rc = 15
return
end if
do n = 1, nbins
idiag = iSSSD001 + n - 1
call Chem_StateGetArray2D
( expChem, idiag, SS_set(n)%data2d, ier(n) )
end do
if ( any(ier(1:nbins) /= 0) ) then
rc = 15
return
end if
do n = 1, nbins
idiag = iSSDP001 + n - 1
call Chem_StateGetArray2D
( expChem, idiag, SS_dep(n)%data2d, ier(n) )
end do
if ( any(ier(1:nbins) /= 0) ) then
rc = 15
return
end if
do n = 1, nbins
idiag = iSSWT001 + n - 1
call Chem_StateGetArray2D
( expChem, idiag, SS_wet(n)%data2d, ier(n) )
end do
if ( any(ier(1:nbins) /= 0) ) then
rc = 15
return
end if
idiag = iSSSMASS
call Chem_StateGetArray2D
( expChem, idiag, SS_sfcmass%data2d, ier(1) )
if ( ier(1) /= 0 ) then
rc = 15
return
end if
idiag = iSSCMASS
call Chem_StateGetArray2D
( expChem, idiag, SS_colmass%data2d, ier(1) )
if ( ier(1) /= 0 ) then
rc = 15
return
end if
idiag = iSSMASS
call Chem_StateGetArray3D
( expChem, idiag, SS_mass%data3d, ier(1) )
if ( ier(1) /= 0 ) then
rc = 15
return
end if
idiag = iSSEXTTAU
call Chem_StateGetArray2D
( expChem, idiag, SS_exttau%data2d, ier(1) )
if ( ier(1) /= 0 ) then
rc = 15
return
end if
idiag = iSSSCATAU
call Chem_StateGetArray2D
( expChem, idiag, SS_scatau%data2d, ier(1) )
if ( ier(1) /= 0 ) then
rc = 15
return
end if
idiag = iSSSM25
call Chem_StateGetArray2D
( expChem, idiag, SS_sfcmass25%data2d, ier(1) )
if ( ier(1) /= 0 ) then
rc = 15
return
end if
idiag = iSSCM25
call Chem_StateGetArray2D
( expChem, idiag, SS_colmass25%data2d, ier(1) )
if ( ier(1) /= 0 ) then
rc = 15
return
end if
idiag = iSSMASS25
call Chem_StateGetArray3D
( expChem, idiag, SS_mass25%data3d, ier(1) )
if ( ier(1) /= 0 ) then
rc = 15
return
end if
idiag = iSSEXTT25
call Chem_StateGetArray2D
( expChem, idiag, SS_exttau25%data2d, ier(1) )
if ( ier(1) /= 0 ) then
rc = 15
return
end if
idiag = iSSSCAT25
call Chem_StateGetArray2D
( expChem, idiag, SS_scatau25%data2d, ier(1) )
if ( ier(1) /= 0 ) then
rc = 15
return
end if
!/\--- cut --- --- cut --- --- cut --- --- cut --- --- cut --- --- cut ---/\
#endif
! Seasalt Source
! -----------
call SS_Emission
( i1, i2, j1, j2, km, nbins, cdt, gcSS, w_c, &
oro, u10m, v10m, SS_emis, rc )
#ifdef DEBUG
do n = nbeg, nend
call pmaxmin
('SS: q_emi', w_c%qa(n)%data3d(i1:i2,j1:j2,1:km), &
qmin, qmax, ijl, km, 1. )
end do
#endif
! Seasalt Settling
! ----------------
! CARMA potentially provides this service. Check to see.
if( index(w_c%qa(nbeg)%wantServices,":CARMA_Sedimentation:") .eq. 0) then
call Chem_Settling
( i1, i2, j1, j2, km, nbeg, nend, nbins, gcSS%rhFlag, &
SS_radius, SS_rhop, cdt, w_c, tmpu, rhoa, hsurf, &
hghte, SS_set, rc )
endif
#ifdef DEBUG
do n = nbeg, nend
call pmaxmin
('SS: q_set', w_c%qa(n)%data3d(i1:i2,j1:j2,1:km), qmin, qmax, &
ijl, km, 1. )
end do
#endif
! Seasalt Deposition
! -----------
call Chem_Deposition
( i1, i2, j1, j2, km, nbeg, nend, nbins, cdt, w_c, &
SS_radius, SS_rhop, tmpu, rhoa, hsurf, hghte, oro, ustar, &
u10m, v10m, fraclake, gwettop, pblh, shflux, z0h, SS_dep, rc )
#ifdef DEBUG
do n = nbeg, nend
call pmaxmin
('SS: q_dry', w_c%qa(n)%data3d(i1:i2,j1:j2,1:km), qmin, qmax, &
ijl, km, 1. )
end do
#endif
! Seasalt Wet Removal
! -----------
call SS_Wet_Removal
( i1, i2, j1, j2, km, nbins, cdt, rhoa, gcSS, w_c, &
precc, precl, dqcond, tmpu, SS_wet, rc )
#ifdef DEBUG
do n = nbeg, nend
call pmaxmin
('SS: q_wet', w_c%qa(n)%data3d(i1:i2,j1:j2,1:km), qmin, qmax, &
ijl, km, 1. )
end do
#endif
! Compute the desired output diagnostics here
! Ideally this will go where chemout is called in fvgcm.F since that
! will reflect the distributions after transport, etc.
! ------------------------------------------------------------------
call SS_Compute_Diags
(i1, i2, j1, j2, km, nbins, gcSS, w_c, tmpu, rhoa, &
SS_sfcmass, SS_colmass, SS_mass, SS_exttau, SS_scatau, &
SS_sfcmass25, SS_colmass25, SS_mass25, SS_exttau25, SS_scatau25, &
rc)
! Clean up
! --------
deallocate ( SS_radius, SS_rhop, stat=ios )
#ifndef GEOS5
!\/--- cut --- --- cut --- --- cut --- --- cut --- --- cut --- --- cut ---\/
deallocate ( SS_emis, SS_set, SS_dep, SS_wet, &
SS_sfcmass, SS_colmass, SS_mass, SS_exttau, SS_scatau, &
SS_sfcmass25, SS_colmass25, SS_mass25, SS_exttau25, &
SS_scatau25, stat=ios )
!/\--- cut --- --- cut --- --- cut --- --- cut --- --- cut --- --- cut ---/\
#endif
return
CONTAINS
!##############################################################################
!-------------------------------------------------------------------------
! NASA/GSFC, Global Modeling and Assimilation Office, Code 900.3 !
!-------------------------------------------------------------------------
!BOP
!
! !IROUTINE: SS_Emission - Adds seasalt emission for one timestep
!
! !INTERFACE:
!
subroutine SS_Emission ( i1, i2, j1, j2, km, nbins, cdt, gcSS, w_c, & 1
oro, u10m, v10m, SS_emis, rc )
! !USES:
implicit NONE
! !INPUT PARAMETERS:
integer, intent(in) :: i1, i2, j1, j2, km, nbins
real, intent(in) :: cdt
type(SS_GridComp), intent(in) :: gcSS ! SS Grid Component
real, pointer, dimension(:,:) :: oro, u10m, v10m
! !OUTPUT PARAMETERS:
type(Chem_Bundle), intent(inout) :: w_c ! Chemical tracer fields
type(Chem_Array), intent(inout) :: SS_emis(nbins) ! SS emissions, kg/m2/s
integer, intent(out) :: rc ! Error return code:
! 0 - all is well
! 1 -
character(len=*), parameter :: myname = 'SS_Emission'
! !DESCRIPTION: Updates the seasalt concentration with emissions every timestep
! The approach here is to use the modified Monahan et al. (1986) source
! formulation (see Gong 2003) which does a reasonable job simulating
! sea salt number concentrations for r80 between 0.07 um and 20 um.
! Gong suggests that the parameterization is good to dry radius 0.03 um,
! so we use that as our lower radius bin limit. The function gives the
! particle flux at RH = 80% dF/dr [# m-2 s-1 um-1] as a function of particle
! radius r [um] and the 10-m wind speed [m s-1]. The dry particle number
! flux is just dF/drDry = fac*dF/dr, where fac is really a function of
! particle size converting dry radius to wet radius (RH=80%).
! Two parameterizations for the swelling are permitted. Setting rhFlag = 1 in
! the resource file specifies the Fitzgerald parameterization. For our sizes
! a value of fac = 2.00 is pretty good, so we use that (see Fitzgerald, JAM,
! 1975 for 100% soluble NaCl). Setting rhFlag = 2 is the resource file
! specifies the Gerber parameterization. See Gong et al. 1997. For our size
! range and that choice fac = 1.65 is pretty good.
!
! Convert to a mass flux by multiplying by the particle mass (note the units).
! Similar to GOCART, we have five major bins and employ a simple sub-binning
! to put the right mass into each bin (i.e., radius_i has rLow_i and rUp_i
! which define the edges of the bin and we actually calculate the emissions
! across the range with a number of sub-bins and dump all the mass into a super-bin.
! FUTURE IMPROVEMENTS: 1) Evaluate the choice of bin sizes used
!
! !REVISION HISTORY:
!
! 06Nov2003, Colarco
! Based on Ginoux
!
!EOP
!-------------------------------------------------------------------------
! !Local Variables
integer :: i, j, k, m, n, ios, ir, nr
integer :: nbeg, nend
real :: emis(i1:i2,j1:j2) ! Local bin emission
real, parameter :: pi = 3.1415
real, parameter :: rho = 1000. ! density of water [kg m-3]
real :: rLow, rUp ! bounding radii of super-bins [um]
real :: radius ! sub-bin radius at 80% RH [um]
real :: dr ! sea-salt sub-bins radius width [um]
real :: fac ! factor chosen as ratio of particle
! radius at RH=80% to dry radius
real :: w10m, src, src2
real :: rDry, aFac, bFac
real :: qmax, qmin
! Initialize local variables
! --------------------------
nbeg = w_c%reg%i_SS
nend = w_c%reg%j_SS
! Choice of swelling factor based on value of rhFlag
! 0 = no swelling
! 1 = Fitzgerald Parameterization
! 2 = Gerber Parameterization
fac = 1.
if(gcSS%rhFlag .eq. 1) fac = 2.00
if(gcSS%rhFlag .eq. 2) fac = 1.65
! Loop over the number of sea-salt super-bins
do n = 1, nbins
emis = 0.0
if( associated(SS_emis(n)%data2d) ) SS_emis(n)%data2d = 0.0
! Define the upper and lower radii of the super-bin and the number of sub-bins
! defined at 80% RH
rLow = fac * gcSS%rLow(n)
rUp = fac * gcSS%rUp(n)
nr = 10
dr = (rUp-rLow)/nr
radius = rLow + 0.5*dr
! Loop over the sub-bins and add mass
! src is the accumulated dry salt mass in each super-bin divided
! by w10m**3.41. At each sub-bin this is the product of the
! number flux into the bin (dF/dr * dr) and the mass of the dry particle.
src = 0.0
do ir = 1, nr
rDry = radius/fac
! Gong 2003
aFac = 4.7*(1.+30.*radius)**(-0.017*radius**(-1.44))
bFac = (0.433-log10(radius))/0.433
src = src &
+ 4./3.*pi*gcSS%rhop(n)*rDry**3.*1.e-18 &
*1.373*radius**(-aFac)*(1.+0.057*radius**3.45) &
*10**(1.607*exp(-bFac**2.))*dr
! Gong 1997
! aFac = 3.
! bFac = (0.380-log10(radius))/0.65
! src = src &
! + 4./3.*pi*gcSS%rhop(n)*rDry**3.*1.e-18 &
! *1.373*radius**(-aFac)*(1.+0.057*radius**1.05) &
! *10**(1.19*exp(-bFac**2.))*dr
radius = radius+dr
end do
! Loop over the horizontal grid
do j = j1, j2
do i = i1, i2
if ( oro(i,j) /= OCEAN ) cycle ! only over OCEAN gridpoints
w10m = sqrt(u10m(i,j)**2.+v10m(i,j)**2.)
emis(i,j) = src*w10m**3.41
w_c%qa(nbeg+n-1)%data3d(i,j,km) = &
w_c%qa(nbeg+n-1)%data3d(i,j,km) + emis(i,j)*cdt*grav/w_c%delp(i,j,km)
end do ! i
end do ! j
if( associated(SS_emis(n)%data2d) ) SS_emis(n)%data2d = emis
end do ! n
rc = 0
end subroutine SS_Emission
!-------------------------------------------------------------------------
! NASA/GSFC, Global Modeling and Assimilation Office, Code 900.3 !
!-------------------------------------------------------------------------
!BOP
!
! !IROUTINE: SS_Wet_Removal - Removal of seasalt by precipitation
! NOTE: For the removal term, fluxout is the sum of the in-cloud
! convective and large-scale washout and the total flux across
! the surface due to below-cloud (rainout) convective and
! large-scale precipitation reaching the surface. The fluxout
! is initialized to zero at the beginning and then at each i, j
! grid point it is added to.
!
!
! !INTERFACE:
!
subroutine SS_Wet_Removal ( i1, i2, j1, j2, km, nbins, cdt, rhoa, gcSS, w_c,& 1
precc, precl, dqcond, tmpu, fluxout, rc )
! !USES:
implicit NONE
! !INPUT PARAMETERS:
integer, intent(in) :: i1, i2, j1, j2, km, nbins
real, intent(in) :: cdt
type(SS_GridComp), intent(in) :: gcSS ! SS Grid Component
real, pointer, dimension(:,:) :: precc ! total convective precip [mm day-1]
real, pointer, dimension(:,:) :: precl ! total large-scale prec. [mm day-1]
real, pointer, dimension(:,:,:) :: dqcond ! change in q due to moist
! processes [kg kg-1 s-1]
real, pointer, dimension(:,:,:) :: tmpu ! temperature [K]
real, pointer, dimension(:,:,:) :: rhoa ! air density [kg m-3]
! !OUTPUT PARAMETERS:
type(Chem_Bundle), intent(inout) :: w_c ! Chemical tracer fields
type(Chem_Array), intent(inout) :: fluxout(nbins) ! Mass lost by wet dep
! to surface, kg/m2/s
integer, intent(out) :: rc ! Error return code:
! 0 - all is well
! 1 -
character(len=*), parameter :: myname = 'SS_Wet_Removal'
! !DESCRIPTION: Updates the dust concentration in each vertical layer
! due to wet removal
!
! !REVISION HISTORY:
!
! 17Nov2003, Colarco
! Based on Ginoux
!
!EOP
!-------------------------------------------------------------------------
! !Local Variables
integer :: i, j, k, iit, n, LH, kk, ios
integer :: nbeg, nend
real :: pdog(i1:i2,j1:j2,km) ! air mass factor dp/g [kg m-2]
real :: Td_ls, Td_cv ! ls and cv timescales [s]
real :: pls, pcv, pac ! ls, cv, tot precip [mm day-1]
real :: qls(km), qcv(km) ! ls, cv portion dqcond [kg m-3 s-1]
real :: qmx, qd, A ! temporary variables on moisture
real :: F, B, BT ! temporary variables on cloud, freq.
real, allocatable :: fd(:,:) ! flux across layers [kg m-2]
real, allocatable :: DC(:) ! scavenge change in mass mixing ratio
! Rain parameters (from where?)
real, parameter :: B0_ls = 1.0e-4
real, parameter :: F0_ls = 1.0
real, parameter :: XL_ls = 5.0e-4
real, parameter :: B0_cv = 1.5e-3
real, parameter :: F0_cv = 0.3
real, parameter :: XL_cv = 2.0e-3
rc = 0
! Initialize local variables
! --------------------------
do n = 1, nbins
if( associated(fluxout(n)%data2d) ) fluxout(n)%data2d(i1:i2,j1:j2) = 0.0
end do
nbeg = w_c%reg%i_SS
nend = w_c%reg%j_SS
! Allocate the dynamic arrays
allocate(fd(km,nbins),stat=ios)
if(ios .ne. 0) stop
allocate(dc(nbins),stat=ios)
if(ios .ne. 0) stop
! Duration of rain: ls = model timestep, cv = 1800 s (<= cdt)
Td_ls = cdt
Td_cv = 1800.
! Accumulate the 3-dimensional arrays of rhoa and pdog
pdog = w_c%delp/grav
! Loop over spatial indices
do j = j1, j2
do i = i1, i2
! Check for total precipitation amount
! Assume no precip in column if precl+precc = 0
pac = precl(i,j) + precc(i,j)
if(pac .le. 0.) goto 100
pls = precl(i,j)
pcv = precc(i,j)
! Initialize the precipitation fields
qls(:) = 0.
qcv(:) = 0.
fd(:,:) = 0.
! Find the highest model layer experiencing rainout. Assumes no
! scavenging if T < 258 K
LH = 0
do k = 1, km
if(dqcond(i,j,k) .lt. 0. .and. tmpu(i,j,k) .gt. 258.) then
LH = k
goto 15
endif
end do
15 continue
if(LH .lt. 1) goto 100
! convert dqcond from kg water/kg air/s to kg water/m3/s and reverse
! sign so that dqcond < 0. (positive precip) means qls and qcv > 0.
do k = LH, km
qls(k) = -dqcond(i,j,k)*pls/pac*rhoa(i,j,k)
#ifdef GEOS5
! Addtional convective scavenging term in GEOS5
qcv(k) = -dqcond(i,j,k)*pcv/pac*rhoa(i,j,k)
#endif
end do
! Loop over vertical to do the scavenging!
do k = LH, km
!-----------------------------------------------------------------------------
! (1) LARGE-SCALE RAINOUT:
! Tracer loss by rainout = TC0 * F * exp(-B*dt)
! where B = precipitation frequency,
! F = fraction of grid box covered by precipitating clouds.
! We assume that tracer scavenged by rain is falling down to the
! next level, where a fraction could be re-evaporated to gas phase
! if Qls is less then 0 in that level.
!-----------------------------------------------------------------------------
if (qls(k) .gt. 0.) then
F = F0_ls / (1. + F0_ls*B0_ls*XL_ls/(qls(k)*cdt/Td_ls))
B = B0_ls/F0_ls +1./(F0_ls*XL_ls/qls(k))
BT = B * Td_ls
if (BT.gt.10.) BT = 10. !< Avoid overflow >
! Adjust du level:
do n = 1, nbins
DC(n) = w_c%qa(nbeg+n-1)%data3d(i,j,k) * F * (1.-exp(-BT))
if (DC(n).lt.0.) DC(n) = 0.
w_c%qa(nbeg+n-1)%data3d(i,j,k) = w_c%qa(nbeg+n-1)%data3d(i,j,k)-DC(n)
if (w_c%qa(nbeg+n-1)%data3d(i,j,k) .lt. 1.0E-32) w_c%qa(nbeg+n-1)%data3d(i,j,k) = 1.0E-32
end do
! Flux down: unit is kg m-2
! Formulated in terms of production in the layer. In the revaporation step
! we consider possibly adding flux from above...
do n = 1, nbins
Fd(k,n) = DC(n)*pdog(i,j,k)
end do
end if ! if Qls > 0 >>>
!-----------------------------------------------------------------------------
! * (2) LARGE-SCALE WASHOUT:
! * Occurs when rain at this level is less than above.
!-----------------------------------------------------------------------------
if(k .gt. LH .and. qls(k) .ge. 0.) then
if(qls(k) .lt. qls(k-1)) then
! Find a maximum F overhead until the level where Qls<0.
Qmx = 0.
do kk = k-1,LH,-1
if (Qls(kk).gt.0.) then
Qmx = max(Qmx,Qls(kk))
else
goto 333
end if
end do
333 continue
F = F0_ls / (1. + F0_ls*B0_ls*XL_ls/(Qmx*cdt/Td_ls))
if (F.lt.0.01) F = 0.01
!-----------------------------------------------------------------------------
! The following is to convert Q(k) from kgH2O/m3/sec to mm/sec in order
! to use the Harvard formula. Convert back to mixing ratio by multiplying
! by rhoa. Multiply by pdog gives kg/m2/s of precip. Divide by density
! of water (=1000 kg/m3) gives m/s of precip and multiply by 1000 gives
! units of mm/s (omit the multiply and divide by 1000).
!-----------------------------------------------------------------------------
Qd = Qmx /rhoa(i,j,k)*pdog(i,j,k)
if (Qd.ge.50.) then
B = 0.
else
B = Qd * 0.1
end if
BT = B * cdt
if (BT.gt.10.) BT = 10.
! Adjust du level:
do n = 1, nbins
DC(n) = w_c%qa(nbeg+n-1)%data3d(i,j,k) * F * (1.-exp(-BT))
if (DC(n).lt.0.) DC(n) = 0.
w_c%qa(nbeg+n-1)%data3d(i,j,k) = w_c%qa(nbeg+n-1)%data3d(i,j,k)-DC(n)
if (w_c%qa(nbeg+n-1)%data3d(i,j,k) .lt. 1.0E-32) &
w_c%qa(nbeg+n-1)%data3d(i,j,k) = 1.0E-32
if( associated(fluxout(n)%data2d) ) then
fluxout(n)%data2d(i,j) = fluxout(n)%data2d(i,j)+DC(n)*pdog(i,j,k)/cdt
endif
end do
end if
end if ! if ls washout >>>
!-----------------------------------------------------------------------------
! (3) CONVECTIVE RAINOUT:
! Tracer loss by rainout = dd0 * F * exp(-B*dt)
! where B = precipitation frequency,
! F = fraction of grid box covered by precipitating clouds.
!-----------------------------------------------------------------------------
if (qcv(k) .gt. 0.) then
F = F0_cv / (1. + F0_cv*B0_cv*XL_cv/(Qcv(k)*cdt/Td_cv))
B = B0_cv
BT = B * Td_cv
if (BT.gt.10.) BT = 10. !< Avoid overflow >
! Adjust du level:
do n = 1, nbins
DC(n) = w_c%qa(nbeg+n-1)%data3d(i,j,k) * F * (1.-exp(-BT))
if (DC(n).lt.0.) DC(n) = 0.
w_c%qa(nbeg+n-1)%data3d(i,j,k) = w_c%qa(nbeg+n-1)%data3d(i,j,k)-DC(n)
if (w_c%qa(nbeg+n-1)%data3d(i,j,k) .lt. 1.0E-32) w_c%qa(nbeg+n-1)%data3d(i,j,k) = 1.0E-32
end do
!------ Flux down: unit is kg. Including both ls and cv.
do n = 1, nbins
Fd(k,n) = Fd(k,n) + DC(n)*pdog(i,j,k)
end do
end if ! if Qcv > 0 >>>
!-----------------------------------------------------------------------------
! (4) CONVECTIVE WASHOUT:
! Occurs when rain at this level is less than above.
!-----------------------------------------------------------------------------
if (k.gt.LH .and. Qcv(k).ge.0.) then
if (Qcv(k).lt.Qcv(k-1)) then
!----- Find a maximum F overhead until the level where Qls<0.
Qmx = 0.
do kk = k-1, LH, -1
if (Qcv(kk).gt.0.) then
Qmx = max(Qmx,Qcv(kk))
else
goto 444
end if
end do
444 continue
F = F0_cv / (1. + F0_cv*B0_cv*XL_cv/(Qmx*cdt/Td_cv))
if (F.lt.0.01) F = 0.01
!-----------------------------------------------------------------------------
! The following is to convert Q(k) from kgH2O/m3/sec to mm/sec in order
! to use the Harvard formula. Convert back to mixing ratio by multiplying
! by rhoa. Multiply by pdog gives kg/m2/s of precip. Divide by density
! of water (=1000 kg/m3) gives m/s of precip and multiply by 1000 gives
! units of mm/s (omit the multiply and divide by 1000).
!-----------------------------------------------------------------------------
Qd = Qmx / rhoa(i,j,k)*pdog(i,j,k)
if (Qd.ge.50.) then
B = 0.
else
B = Qd * 0.1
end if
BT = B * cdt
if (BT.gt.10.) BT = 10.
! Adjust du level:
do n = 1, nbins
DC(n) = w_c%qa(nbeg+n-1)%data3d(i,j,k) * F * (1.-exp(-BT))
if (DC(n).lt.0.) DC(n) = 0.
w_c%qa(nbeg+n-1)%data3d(i,j,k) = w_c%qa(nbeg+n-1)%data3d(i,j,k)-DC(n)
if (w_c%qa(nbeg+n-1)%data3d(i,j,k) .lt. 1.0E-32) &
w_c%qa(nbeg+n-1)%data3d(i,j,k) = 1.0E-32
if( associated(fluxout(n)%data2d) ) then
fluxout(n)%data2d(i,j) = fluxout(n)%data2d(i,j)+DC(n)*pdog(i,j,k)/cdt
endif
end do
end if
end if ! if cv washout >>>
!-----------------------------------------------------------------------------
! (5) RE-EVAPORATION. Assume that SO2 is re-evaporated as SO4 since it
! has been oxidized by H2O2 at the level above.
!-----------------------------------------------------------------------------
! Add in the flux from above, which will be subtracted if reevaporation occurs
if(k .gt. LH) then
do n = 1, nbins
Fd(k,n) = Fd(k,n) + Fd(k-1,n)
end do
! Is there evaporation in the currect layer?
if (-dqcond(i,j,k) .lt. 0.) then
! Fraction evaporated = H2O(k)evap / H2O(next condensation level).
if (-dqcond(i,j,k-1) .gt. 0.) then
A = abs( dqcond(i,j,k) * pdog(i,j,k) &
/ ( dqcond(i,j,k-1) * pdog(i,j,k-1)) )
if (A .gt. 1.) A = 1.
! Adjust tracer in the level
do n = 1, nbins
DC(n) = Fd(k-1,n) / pdog(i,j,k) * A
w_c%qa(nbeg+n-1)%data3d(i,j,k) = w_c%qa(nbeg+n-1)%data3d(i,j,k) + DC(n)
w_c%qa(nbeg+n-1)%data3d(i,j,k) = max(w_c%qa(nbeg+n-1)%data3d(i,j,k),1.e-32)
! Adjust the flux out of the bottom of the layer
Fd(k,n) = Fd(k,n) - DC(n)*pdog(i,j,k)
end do
endif
endif ! if -moistq < 0
endif
end do ! k
do n = 1, nbins
if( associated(fluxout(n)%data2d) ) then
fluxout(n)%data2d(i,j) = fluxout(n)%data2d(i,j)+Fd(km,n)/cdt
endif
end do
100 continue
end do ! i
end do ! j
deallocate(fd,DC,stat=ios)
end subroutine SS_Wet_Removal
!-------------------------------------------------------------------------
! NASA/GSFC, Global Modeling and Assimilation Office, Code 900.3 !
!-------------------------------------------------------------------------
!BOP
!
! !IROUTINE: SS_Compute_Diags - Calculate dust 2D diagnostics
!
! !INTERFACE:
!
subroutine SS_Compute_Diags ( i1, i2, j1, j2, km, nbins, gcSS, w_c, tmpu, rhoa, & 1,2
sfcmass, colmass, mass, exttau, scatau, &
sfcmass25, colmass25, mass25, exttau25, scatau25, &
rc )
! !USES:
implicit NONE
! !INPUT PARAMETERS:
integer, intent(in) :: i1, i2, j1, j2, km, nbins
type(SS_GridComp), intent(inout):: gcSS ! SS Grid Component
type(Chem_Bundle), intent(in) :: w_c ! Chem Bundle
real, pointer, dimension(:,:,:) :: tmpu ! temperature [K]
real, pointer, dimension(:,:,:) :: rhoa ! air density [kg m-3]
! !OUTPUT PARAMETERS:
type(Chem_Array), intent(inout) :: sfcmass ! sfc mass concentration kg/m3
type(Chem_Array), intent(inout) :: colmass ! col mass density kg/m2
type(Chem_Array), intent(inout) :: mass ! 3d mass mixing ratio kg/kg
type(Chem_Array), intent(inout) :: exttau ! ext. AOT at 550 nm
type(Chem_Array), intent(inout) :: scatau ! sct. AOT at 550 nm
type(Chem_Array), intent(inout) :: sfcmass25 ! sfc mass concentration kg/m3 (pm2.5)
type(Chem_Array), intent(inout) :: colmass25 ! col mass density kg/m2 (pm2.5)
type(Chem_Array), intent(inout) :: mass25 ! 3d mass mixing ratio kg/kg (pm2.5)
type(Chem_Array), intent(inout) :: exttau25 ! ext. AOT at 550 nm (pm2.5)
type(Chem_Array), intent(inout) :: scatau25 ! sct. AOT at 550 nm (pm2.5)
integer, intent(out) :: rc ! Error return code:
! 0 - all is well
! 1 -
! !DESCRIPTION: Calculates some simple 2d diagnostics from the SS fields
! Surface concentration (dry)
! Column mass load (dry)
! Extinction aot 550 (wet)
! Scattering aot 550 (wet)
! For the moment, this is hardwired.
!
! !REVISION HISTORY:
!
! 16APR2004, Colarco
!
!EOP
!-------------------------------------------------------------------------
! !Local Variables
character(len=*), parameter :: myname = 'SS_Compute_Diags'
integer :: i, j, k, n, nbeg, nend, ios, nch, idx
real :: tau, ssa
real :: fPM25(nbins) ! fraction of bin with particles diameter < 2.5 um
character(len=255) :: qname
! Initialize local variables
! --------------------------
nbeg = w_c%reg%i_SS
nend = w_c%reg%j_SS
nch = gcSS%mie_tables%nch
! Compute the PM2.5 bin-wise fractions
! ------------------------------------
do n = 1, nbins
if(gcSS%rup(n) < 1.25) then
fPM25(n) = 1.
else
if(gcSS%rlow(n) < 1.25) then
! Assume dm/dlnr = constant, i.e., dm/dr ~ 1/r
fPM25(n) = log(1.25/gcSS%rlow(n)) / log(gcSS%rup(n)/gcSS%rlow(n))
else
fPM25(n) = 0.
endif
endif
enddo
! Calculate the diagnostic variables if requested
! -----------------------------------------------
! Calculate the surface mass concentration
if( associated(sfcmass%data2d) ) then
sfcmass%data2d(i1:i2,j1:j2) = 0.
do n = 1, nbins
sfcmass%data2d(i1:i2,j1:j2) &
= sfcmass%data2d(i1:i2,j1:j2) &
+ w_c%qa(n+nbeg-1)%data3d(i1:i2,j1:j2,km)*rhoa(i1:i2,j1:j2,km)
end do
endif
if( associated(sfcmass25%data2d) ) then
sfcmass25%data2d(i1:i2,j1:j2) = 0.
do n = 1, nbins
sfcmass25%data2d(i1:i2,j1:j2) &
= sfcmass25%data2d(i1:i2,j1:j2) &
+ w_c%qa(n+nbeg-1)%data3d(i1:i2,j1:j2,km)*rhoa(i1:i2,j1:j2,km)*fPM25(n)
end do
endif
! Calculate the seasalt column loading
if( associated(colmass%data2d) ) then
colmass%data2d(i1:i2,j1:j2) = 0.
do n = 1, nbins
do k = 1, km
colmass%data2d(i1:i2,j1:j2) &
= colmass%data2d(i1:i2,j1:j2) &
+ w_c%qa(n+nbeg-1)%data3d(i1:i2,j1:j2,k)*w_c%delp(i1:i2,j1:j2,k)/grav
end do
end do
endif
if( associated(colmass25%data2d)) then
colmass25%data2d(i1:i2,j1:j2) = 0.
do n = 1, nbins
do k = 1, km
colmass25%data2d(i1:i2,j1:j2) &
= colmass25%data2d(i1:i2,j1:j2) &
+ w_c%qa(n+nbeg-1)%data3d(i1:i2,j1:j2,k)*w_c%delp(i1:i2,j1:j2,k)/grav*fPM25(n)
end do
end do
endif
! Calculate the total mass mixing ratio
if( associated(mass%data3d) ) then
mass%data3d(i1:i2,j1:j2,1:km) = 0.
do n = 1, nbins
mass%data3d(i1:i2,j1:j2,1:km) &
= mass%data3d(i1:i2,j1:j2,1:km) &
+ w_c%qa(n+nbeg-1)%data3d(i1:i2,j1:j2,1:km)
end do
endif
if( associated(mass25%data3d) ) then
mass25%data3d(i1:i2,j1:j2,1:km) = 0.
do n = 1, nbins
mass25%data3d(i1:i2,j1:j2,1:km) &
= mass25%data3d(i1:i2,j1:j2,1:km) &
+ w_c%qa(n+nbeg-1)%data3d(i1:i2,j1:j2,1:km)*fPM25(n)
end do
endif
! Calculate the extinction and/or scattering AOD
if( associated(exttau%data2d) .or. associated(scatau%data2d) ) then
if( associated(exttau%data2d)) exttau%data2d(i1:i2,j1:j2) = 0.
if( associated(scatau%data2d)) scatau%data2d(i1:i2,j1:j2) = 0.
if( associated(exttau25%data2d)) exttau25%data2d(i1:i2,j1:j2) = 0.
if( associated(scatau25%data2d)) scatau25%data2d(i1:i2,j1:j2) = 0.
do n = 1, nbins
! Select the name for species
qname = trim(w_c%reg%vname(w_c%reg%i_SS+n-1))
idx = Chem_MieQueryIdx(gcSS%mie_tables,qname,rc)
if(rc .ne. 0) call die
(myname, 'cannot find proper Mie table index')
! Recall -- at present need to divide RH by 100 to get to tables
do k = 1, km
do j = j1, j2
do i = i1, i2
call Chem_MieQuery
(gcSS%mie_tables, idx, 1., &
w_c%qa(nbeg+n-1)%data3d(i,j,k)*w_c%delp(i,j,k)/grav, &
w_c%rh(i,j,k)/100., tau=tau, ssa=ssa)
! Integrate in the vertical
if( associated(exttau%data2d) ) exttau%data2d(i,j) = exttau%data2d(i,j) + tau
if( associated(exttau25%data2d)) &
exttau25%data2d(i,j) = exttau25%data2d(i,j) + tau*fPM25(n)
if( associated(scatau%data2d) ) scatau%data2d(i,j) = scatau%data2d(i,j) + tau*ssa
if( associated(scatau25%data2d) ) &
scatau25%data2d(i,j) = scatau25%data2d(i,j) + tau*ssa*fPM25(n)
enddo
enddo
enddo
enddo ! nbins
endif
rc = 0
end subroutine SS_Compute_Diags
end subroutine SS_GridCompRun
!-------------------------------------------------------------------------
! NASA/GSFC, Global Modeling and Assimilation Office, Code 900.3 !
!-------------------------------------------------------------------------
!BOP
!
! !IROUTINE: SS_GridCompFinalize --- The Chem Driver
!
! !INTERFACE:
!
subroutine SS_GridCompFinalize ( gcSS, w_c, impChem, expChem, & 1
nymd, nhms, cdt, rc )
! !USES:
implicit NONE
! !INPUT/OUTPUT PARAMETERS:
type(SS_GridComp), intent(inout) :: gcSS ! Grid Component
! !INPUT PARAMETERS:
type(Chem_Bundle), intent(in) :: w_c ! Chemical tracer fields
integer, intent(in) :: nymd, nhms ! time
real, intent(in) :: cdt ! chemical timestep (secs)
! !OUTPUT PARAMETERS:
type(ESMF_State), intent(inout) :: impChem ! Import State
type(ESMF_State), intent(inout) :: expChem ! Import State
integer, intent(out) :: rc ! Error return code:
! 0 - all is well
! 1 -
! !DESCRIPTION: This routine finalizes this Grid Component.
!
! !REVISION HISTORY:
!
! 18Sep2003 da Silva First crack.
!
!EOP
!-------------------------------------------------------------------------
character(len=*), parameter :: myname = 'SS_GridCompFinalize'
rc = 0
return
end subroutine SS_GridCompFinalize
end module SS_GridCompMod