#include "MAPL_Generic.h"
!-------------------------------------------------------------------------
! NASA/GSFC, Global Modeling and Assimilation Office, Code 900.3 !
!-------------------------------------------------------------------------
!BOP
!
! !MODULE: CFC_GridCompMod --- CFC Grid Component Class
!
! !INTERFACE:
!
MODULE CFC_GridCompMod 1
! !USES:
USE ESMF_Mod
USE MAPL_Mod
USE Chem_Mod
! Chemistry Base Class
USE Chem_StateMod
! Chemistry State
USE Chem_ConstMod
, ONLY: grav
USE Chem_UtilMod
! I/O
USE m_inpak90
! Resource file management
USE m_die
, ONLY: die
IMPLICIT NONE
! !PUBLIC TYPES:
!
PRIVATE
PUBLIC CFC_GridComp ! The CFC object
!
! !PUBLIC MEMBER FUNCTIONS:
!
PUBLIC CFC_GridCompInitialize
PUBLIC CFC_GridCompRun
PUBLIC CFC_GridCompFinalize
!
! !DESCRIPTION:
!
! This module implements the CFC Grid Component.
!
! !REVISION HISTORY:
!
! 16Sep2003 da Silva First crack.
! 01Aug2006 da Silva Extensions for GEOS-5.
! 1Jan2008 Nielsen CFC-12 configuration for ARCTAS.
! 8Feb2008 Nielsen Standard configuration call(s) from AeroChem.
!
!EOP
!-------------------------------------------------------------------------
TYPE CFC_GridComp
CHARACTER(LEN=255) :: name
! For CFC-12 photolysis
! ---------------------
INTEGER :: nlam
INTEGER :: nsza
INTEGER :: numo3
INTEGER :: nx
INTEGER :: nxdo
INTEGER :: nts
REAL(KIND=4), POINTER :: sdat(:,:,:,:)
REAL(KIND=4), POINTER :: xtab(:,:)
REAL(KIND=4), POINTER :: o3_tab(:,:)
REAL(KIND=4), POINTER :: sza_tab(:)
REAL, POINTER :: CFCsfcFlux(:,:) ! CFC-12 surface flux kg m^-2 s^-1
REAL, POINTER :: CFCloss(:,:,:,:) ! CFC loss due to photolysis m^-3 s^-1
END TYPE CFC_GridComp
CONTAINS
!-------------------------------------------------------------------------
! NASA/GSFC, Global Modeling and Assimilation Office, Code 900.3 !
!-------------------------------------------------------------------------
!BOP
!
! !IROUTINE: CFC_GridCompInitialize --- Initialize CFC_GridComp
!
! !INTERFACE:
!
SUBROUTINE CFC_GridCompInitialize( gcCFC, w_c, impChem, expChem, & 1,13
nymd, nhms, cdt, rc )
! !USES:
IMPLICIT NONE
! !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(CFC_GridComp), INTENT(INOUT) :: gcCFC ! 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 CFC Grid Component. It primarily sets
! the import state for each active constituent package.
!
! !REVISION HISTORY:
!
! 18Sep2003 da Silva First crack.
! 31May2005 Nielsen Mods for 7 CO bins, 5 region masks
! 04Nov2005 Bian CO tagged to 4 regions
! (global, North America, South America, and Africa)
! for CR-AVE
! 12Feb2005 Nielsen 8 regions for INTEX-B 2006
! 1Jan2008 Nielsen CFC-12 configuration for ARCTAS
!
!EOP
!-------------------------------------------------------------------------
CHARACTER(LEN=*), PARAMETER :: myname = 'CFC_GridCompInitialize'
CHARACTER(LEN=255) :: rcfilen = 'CFC_GridComp.rc'
CHARACTER(LEN=255) :: dir4files
CHARACTER(LEN=255) :: fnO2Jdat
CHARACTER(LEN=255) :: fnO3SZA
CHARACTER(LEN=255) :: fnXsectJPL
CHARACTER(LEN=255) :: eFileName
INTEGER :: ier(128)
INTEGER :: i, i1, i2, im, j1, j2, jm, km, nbins
gcCFC%name = 'CFC-12 Chemistry for ARCTAS'
rc = 0
! 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_CFC
ier(:)=0
! Initialize photolysis variables
! -------------------------------
gcCFC%nlam = 79
gcCFC%nsza = 20
gcCFC%numo3 = 12
gcCFC%nx = 35
gcCFC%nxdo = 33
gcCFC%nts = 200
! Load resource file
! ------------------
CALL I90_loadf
( TRIM(rcfilen), ier(1) )
IF ( ier(1) .NE. 0 ) THEN
rc = 10
RETURN
END IF
CALL I90_label
( 'directory:', ier(30) )
CALL I90_Gtoken
( dir4files, ier(31) )
CALL I90_label
( 'O2Jtable:', ier(32) )
CALL I90_Gtoken
( fnO2Jdat, ier(33) )
CALL I90_label
( 'O3&SZAtables:', ier(36) )
CALL I90_Gtoken
( fnO3SZA, ier(37) )
CALL I90_label
( 'JPLXsections:', ier(40) )
CALL I90_Gtoken
( fnXsectJPL, ier(41) )
CALL I90_label
( 'CFC_emission_filename:', ier(50) )
CALL I90_Gtoken
( eFileName, ier(51) )
IF( ANY( ier(1:128) /= 0 ) ) THEN
rc = 12
RETURN
END IF
ier(:)=0
! Allocate space for grid-size dependent arrays
! ---------------------------------------------
ALLOCATE(gcCFC%sdat(gcCFC%nsza,gcCFC%numo3,km,gcCFC%nlam), stat=ier( 9) )
ALLOCATE( gcCFC%xtab(gcCFC%nlam,gcCFC%nts), stat=ier(10) )
ALLOCATE( gcCFC%o3_tab(gcCFC%numo3,km), stat=ier(11) )
ALLOCATE( gcCFC%sza_tab(gcCFC%nsza), stat=ier(12) )
ALLOCATE( gcCFC%CFCsfcFlux(i1:i2,j1:j2), stat=ier(13) )
ALLOCATE( gcCFC%CFCloss(i1:i2,j1:j2,1:km,nbins), stat=ier(14) )
IF( ANY( ier(1:128) /= 0 ) ) THEN
rc = 14
RETURN
END IF
ier(:)=0
! Acquire the CFC-12 emissions
! ----------------------------
CALL Chem_UtilMPread
( TRIM(eFileName), 'CFC-12_EMISSION', 20080101, &
120000, i1, i2, 0, im, j1, j2, 0, jm, 0, &
var2d=gcCFC%CFCsfcFlux, cyclic=.true., &
grid=w_c%grid_esmf )
! Read the tables
! ---------------
CALL rdPhotFiles
(km,dir4files,fnO2Jdat,fnO3SZA,fnXsectJPL)
RETURN
CONTAINS
SUBROUTINE rdPhotFiles(km,dir,fnO2Jdat,fnO3SZA,fnXsectJPL) 1
!---------------------------------------------------------------------------
!
! Read several external files for the photolysis.
!
! Input parameters:
!
! km Grid dimensions
! dir Directory on which these files reside
! fns File names
!
! Output parameters:
!
! None.
!
! Restrictions:
!
! This runs on each processor
!
! This version requires input data at jnp latitudes.
!
!-----------------------------------------------------------------------
IMPLICIT NONE
INTEGER, INTENT(IN) :: km
CHARACTER(LEN=*), INTENT(IN) :: dir
CHARACTER(LEN=*), INTENT(IN) :: fnO2Jdat
CHARACTER(LEN=*), INTENT(IN) :: fnO3SZA
CHARACTER(LEN=*), INTENT(IN) :: fnXsectJPL
REAL(KIND=4), ALLOCATABLE :: dxtab(:,:,:)
INTEGER :: i, j, k, l, ierr, iunit, iuchem, kReverse
INTEGER :: npr_in, nlam_in, nsza_in, no3_in
REAL :: deg2Rad, pi
REAL (KIND=4) :: pr_tab(km)
REAL (KIND=4) :: rlam(gcCFC%nlam)
LOGICAL :: exists,open,found
pi = 4.00*ATAN(1.00)
deg2Rad = pi/180.00
! Find an available logical unit
! ------------------------------
found=.FALSE.
iunit=11
DO WHILE (.NOT. found .AND. iunit <= 99)
INQUIRE(UNIT=iunit,EXIST=exists,OPENED=open)
IF(exists .AND. .NOT. open) THEN
found=.TRUE.
iuchem=iunit
END IF
iunit=iunit+1
END DO
IF(.NOT. found) THEN
WRITE(*,FMT="(/,'rdPhotFiles: No available logical units.')")
STOP
ELSE
IF(MAPL_AM_I_ROOT()) THEN
WRITE(*,FMT="(' ')")
WRITE(*,FMT="(' ','rdPhotFiles: Reading from UNIT ',I3)") iuchem
END IF
END IF
! Read in sdat(nsza,numo3,levels,nlam)
! ------------------------------------
OPEN(iuchem,FILE=TRIM(dir)//'/'//TRIM(fnO2Jdat),STATUS='old', &
FORM='unformatted',ACTION='read')
READ(iuchem) gcCFC%sdat
CLOSE(iuchem)
! Read solar zenith angle and O3 references after checking sizes
! --------------------------------------------------------------
OPEN(iuchem,FILE = TRIM(dir)//'/'//TRIM(fnO3SZA),STATUS='old', &
FORM='unformatted',ACTION='read')
READ(iuchem) npr_in,nlam_in,nsza_in,no3_in
READ(iuchem) pr_tab
READ(iuchem) rlam
READ(iuchem) gcCFC%sza_tab
READ(iuchem) gcCFC%o3_tab
CLOSE(iuchem)
IF(( npr_in .NE. km) .OR. (nlam_in .NE. gcCFC%nlam) .OR. &
(nsza_in .NE. gcCFC%nsza) .OR. ( no3_in .NE. gcCFC%numo3)) THEN
PRINT *,'rdPhotFiles: Array sizes of table do not match ', &
' those expected:',npr_in,km,nlam_in,gcCFC%nlam, &
nsza_in,gcCFC%nsza,no3_in,gcCFC%numo3
STOP
END IF
! Convert sza_tab(nsza) to radians
! --------------------------------
DO i=1,gcCFC%nsza
gcCFC%sza_tab(i) = gcCFC%sza_tab(i)*deg2Rad
END DO
! Reverse sdat(nsza,numo3,levels,nlam) in the vertical to accomodate GEOS-5
! -------------------------------------------------------------------------
DO l=1,gcCFC%nlam
DO j=1,gcCFC%numo3
DO i=1,gcCFC%nsza
pr_tab(1:km) = gcCFC%sdat(i,j,1:km,l)
DO k=1,km
kReverse = km-k+1
gcCFC%sdat(i,j,k,l) = pr_tab(kReverse)
END DO
END DO
END DO
END DO
! Reverse o3_tab(numo3,km) in the vertical to accomodate GEOS-5
! -------------------------------------------------------------
DO j=1,gcCFC%numo3
pr_tab(1:km) = gcCFC%o3_tab(j,1:km)
DO k=1,km
kReverse = km-k+1
gcCFC%o3_tab(j,k) = pr_tab(kReverse)
END DO
END DO
ALLOCATE(dxtab(gcCFC%nlam,gcCFC%nts,gcCFC%nx),STAT=ierr)
! JPL cross sections
! ------------------
OPEN(iuchem,FILE=TRIM(dir)//'/'//TRIM(fnXsectJPL), &
STATUS='old',ACTION='read',FORM='unformatted')
READ(iuchem) dxtab
CLOSE(iuchem)
! Need only #25
! -------------
k=25
DO j=1,gcCFC%nts
DO i=1,gcCFC%nlam
gcCFC%xtab(i,j) = dxtab(i,j,k)
END DO
END DO
DEALLOCATE(dxtab,STAT=ierr)
IF(MAPL_AM_I_ROOT()) THEN
print *,'rdPhotFiles: Done'
print *,' '
END IF
RETURN
END SUBROUTINE rdPhotFiles
END SUBROUTINE CFC_GridCompInitialize
!-------------------------------------------------------------------------
! NASA/GSFC, Global Modeling and Assimilation Office, Code 900.3 !
!-------------------------------------------------------------------------
!BOP
!
! !IROUTINE: CFC_GridCompRun --- The CFC Driver
!
! !INTERFACE:
!
SUBROUTINE CFC_GridCompRun( gcCFC, w_c, impChem, expChem, nymd, nhms, & 1,5
cdt, rc)
! !USES:
IMPLICIT NONE
! !INPUT/OUTPUT PARAMETERS:
TYPE(CFC_GridComp), INTENT(INOUT) :: gcCFC ! 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 -
CHARACTER(LEN=*), PARAMETER :: myname = 'CFC_GridCompRun'
CHARACTER(LEN=*), PARAMETER :: Iam = myname
INTEGER :: ier(128)
INTEGER :: i1, i2, im, iXj, j1, j2, jm, km, status
INTEGER :: i, indt, j, k, m, n, nbeg, nbins, nend
REAL :: o3c, qmin, qmax, r, rg, szan
! Imports
! -------
REAL, POINTER, DIMENSION(:,:,:) :: T => null()
REAL, POINTER, DIMENSION(:,:,:) :: O3 => null()
REAL, POINTER, DIMENSION(:,:) :: tropp => null()
! Local Variables
! ---------------
REAL, PARAMETER :: badVal=2.00E+05
REAL, PARAMETER :: grav=9.80
REAL, PARAMETER :: mwtAir=28.97
REAL, PARAMETER :: mwtCFC12=120.917
REAL, PARAMETER :: Nsuba=6.022E+26
REAL, PARAMETER :: rstar=8.3143E+03
REAL, PARAMETER :: O3abv80km = 1.10E+15 !m^{-2}
REAL, ALLOCATABLE :: emit2vmr(:,:)
REAL, ALLOCATABLE :: tropPa(:,:)
REAL, ALLOCATABLE :: pPa(:,:,:)
REAL, ALLOCATABLE :: nd(:,:,:)
REAL, ALLOCATABLE :: O3Col(:,:,:)
REAL, ALLOCATABLE :: photoRate(:,:,:)
REAL, ALLOCATABLE :: s(:,:,:,:)
! Disable the ACG'd CFC_GetPointer___.h for now. [Maybe fix it soon.]
! -------------------------------------------------------------------
#define EXPORT expChem
#define ptrCFCEM CFC_emis
#define ptrCFCLS CFC_loss
#define ptrCFCCL CFC_column
!JEN#include "CFC_GetPointer___.h"
! Bin sizes
! ---------
integer, parameter :: NBIN_CFCEM = 1 ! CFC Emission
integer, parameter :: NBIN_CFCLS = 2 ! CFC Loss due to photolysis
integer, parameter :: NBIN_CFCCL = 2 ! CFC Column
! Bin-indexed Chem Arrays
! -----------------------
type(Chem_Array), target :: CFCEM(NBIN_CFCEM) ! Export: CFC Surface flux
type(Chem_Array), pointer :: ptrCFCEM(:) ! Export: CFC Surface flux
type(Chem_Array), target :: CFCLS(NBIN_CFCLS) ! Export: CFC Loss due to photolysis
type(Chem_Array), pointer :: ptrCFCLS(:) ! Export: CFC Loss due to photolysis
type(Chem_Array), target :: CFCCL(NBIN_CFCCL) ! Export: CFC Column
type(Chem_Array), pointer :: ptrCFCCL(:) ! Export: CFC Column
! Local array referencing the Import/Export states
! ------------------------------------------------
type(Chem_Array), target :: CFC12S ! Export: Stratospheric CFC-12 (CCl2F2)
type(Chem_Array), pointer :: ptrCFC12S ! Export: Stratospheric CFC-12 (CCl2F2)
type(Chem_Array), target :: CFC12T ! Export: Tropospheric CFC-12 (CCl2F2)
type(Chem_Array), pointer :: ptrCFC12T ! Export: Tropospheric CFC-12 (CCl2F2)
! Get pointers to data in state
! -----------------------------
ptrCFC12S => CFC12S ! Stratospheric CFC-12 (CCl2F2)
call MAPL_GetPointer ( EXPORT, CFC12S%data3d, 'CFC12S', RC=STATUS )
VERIFY_(STATUS)
ptrCFC12T => CFC12T ! Tropospheric CFC-12 (CCl2F2)
call MAPL_GetPointer ( EXPORT, CFC12T%data3d, 'CFC12T', RC=STATUS )
VERIFY_(STATUS)
ptrCFCEM => CFCEM ! CFC-12 Surface flux
call MAPL_GetPointer ( EXPORT, CFCEM(1)%data2d, 'CFC12EM', RC=STATUS )
VERIFY_(STATUS)
ptrCFCLS => CFCLS ! CFC-12 Loss due to photolysis
call MAPL_GetPointer ( EXPORT, CFCLS(1)%data3d, 'CFC12SLS', RC=STATUS )
VERIFY_(STATUS)
call MAPL_GetPointer ( EXPORT, CFCLS(2)%data3d, 'CFC12TLS', RC=STATUS )
VERIFY_(STATUS)
ptrCFCCL => CFCCL ! CFC-12 Column mass density
call MAPL_GetPointer ( EXPORT, CFCCL(1)%data2d, 'CFC12SCL', RC=STATUS )
VERIFY_(STATUS)
call MAPL_GetPointer ( EXPORT, CFCCL(2)%data2d, 'CFC12TCL', RC=STATUS )
VERIFY_(STATUS)
! 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
iXj = ( i2 - i1 + 1 ) * ( j2 - j1 + 1 )
nbins = w_c%reg%n_CFC
nbeg = w_c%reg%i_CFC
nend = w_c%reg%j_CFC
! Imports
! -------
call MAPL_GetPointer( impChem, T, 'T', rc=ier(1) )
call MAPL_GetPointer( impChem, O3, 'O3', rc=ier(2) )
call MAPL_GetPointer( impChem, tropp, 'TROPP', rc=ier(3) )
IF(ANY(ier(:) /= 0 )) THEN
rc = 1
RETURN
END IF
ier(:)=0
#ifdef DEBUG
CALL pmaxmin
(' T', T, qmin, qmax, iXj, km, 1. )
CALL pmaxmin
(' O3', O3, qmin, qmax, iXj, km, 1. )
CALL pmaxmin
('TROPP', tropp, qmin, qmax, iXj, 1, 1. )
#endif
! Allocate temporary workspace
! ----------------------------
ALLOCATE( emit2vmr(i1:i2,j1:j2), STAT=ier(1))
ALLOCATE( tropPa(i1:i2,j1:j2), STAT=ier(1))
ALLOCATE( pPa(i1:i2,j1:j2,km), STAT=ier(2))
ALLOCATE( nd(i1:i2,j1:j2,km), STAT=ier(3))
ALLOCATE( O3Col(i1:i2,j1:j2,km), STAT=ier(4))
ALLOCATE(photoRate(i1:i2,j1:j2,km), STAT=ier(5))
IF(ANY(ier(:) /= 0 )) THEN
rc = 10
RETURN
END IF
ier(:)=0
! Fix bad tropopause pressure values if they exist.
! -------------------------------------------------
CALL Chem_UtilTroppFixer
(i2, j2, tropp, VERBOSE=.TRUE., &
NEWTROPP=tropPa, RC=STATUS)
VERIFY_(STATUS)
! Find the pressure at mid-layer
! ------------------------------
pPa(i1:i2,j1:j2,1) = w_c%grid%ptop + 0.50*w_c%delp(i1:i2,j1:j2,1)
DO k = 2, km
pPa(i1:i2,j1:j2,k) = pPa(i1:i2,j1:j2,k-1) + 0.50* &
(w_c%delp(i1:i2,j1:j2,k-1)+w_c%delp(i1:i2,j1:j2,k))
END DO
! Number density
! --------------
nd(i1:i2,j1:j2,1:km)= nsuba*pPa(i1:i2,j1:j2,1:km)/(rstar*T(i1:i2,j1:j2,1:km))
! Compute the overlying ozone from mole fraction. Result: m^{-2}
! ---------------------------------------------------------------
r = Nsuba*0.50/(mwtAir*grav)
O3col(i1:i2,j1:j2,1) = O3abv80km + O3(i1:i2,j1:j2,1)*w_c%delp(i1:i2,j1:j2,1)*r
DO k=2,km
O3col(i1:i2,j1:j2,k) = O3col(i1:i2,j1:j2,k-1) + &
(O3(i1:i2,j1:j2,k-1) * w_c%delp(i1:i2,j1:j2,k-1) + &
O3(i1:i2,j1:j2, k) * w_c%delp(i1:i2,j1:j2, k))*r
END DO
! Enable the conversion from emission [kg CFC m^{-2} s^{-1}]
! to an incremental change in the mixing ratio [s^{-1}].
! ----------------------------------------------------------
emit2vmr(i1:i2,j1:j2) = mwtAir*grav/(mwtCFC12*w_c%delp(i1:i2,j1:j2,km))
! Increment mixing ratio in surface layer of tropospheric CFC-12
! --------------------------------------------------------------
w_c%qa(nbeg+1)%data3d(i1:i2,j1:j2,km) = w_c%qa(nbeg+1)%data3d(i1:i2,j1:j2,km)+cdt* &
gcCFC%CFCsfcFlux(i1:i2,j1:j2)*emit2vmr(i1:i2,j1:j2)
! When tropospheric CFC-12 migrates to the stratosphere, reassign it
! ------------------------------------------------------------------
DO k = 1, km
WHERE(pPa(i1:i2,j1:j2,k) < tropPa(i1:i2,j1:j2) .AND. &
w_c%qa(nbeg+1)%data3d(i1:i2,j1:j2,k) > 0.00 )
w_c%qa(nbeg)%data3d(i1:i2,j1:j2,k) = w_c%qa(nbeg)%data3d(i1:i2,j1:j2,k) + &
w_c%qa(nbeg+1)%data3d(i1:i2,j1:j2,k)
w_c%qa(nbeg+1)%data3d(i1:i2,j1:j2,k) = 0.00
END WHERE
END DO
! Convert CFC-12 to number density
! --------------------------------
DO n=nbeg,nend
w_c%qa(n)%data3d(i1:i2,j1:j2,1:km) = w_c%qa(n)%data3d(i1:i2,j1:j2,1:km)* &
nd(i1:i2,j1:j2,1:km)
END DO
ALLOCATE(s(gcCFC%nlam,i1:i2,j1:j2,1:km), STAT=ier(1))
! Photolysis: Loop over horizontal domain
! ----------------------------------------
DO j=j1,j2
DO i=i1,i2
! Solar zenith angle (radians). w_c%cosz has no negative values,
! which are required for correct interpolation in the S-dat tables.
! -----------------------------------------------------------------
IF(w_c%cosz(i,j) <= 1.00E-06) THEN
szan = ACOS(-0.50)
ELSE
szan = ACOS(w_c%cosz(i,j))
END IF
DO k=1,km
o3c = O3Col(i,j,k)*1.00E-04 !to cm^{-2}
! Interpolate radiative flux function values.
! Call getS even when sun is below the horizon.
! ---------------------------------------------
CALL getS
(k,km,szan,o3c,s(:,i,j,k))
indt = T(i,j,k)-148.5
indt = MAX(1,indt)
indt = MIN(indt,200)
! Rate constant is sum over wavelengths
! -------------------------------------
photoRate(i,j,k) = SUM(s(1:gcCFC%nlam,i,j,k)*gcCFC%xtab(1:gcCFC%nlam,indt))
END DO ! Layer
END DO ! Longitude
END DO ! Latitude
DEALLOCATE(s, STAT=ier(2))
m = 0
! Apply photolysis
! ----------------
DO n=nbeg,nend
m = m+1
w_c%qa(n)%data3d(i1:i2,j1:j2,1:km) = w_c%qa(n)%data3d(i1:i2,j1:j2,1:km) - cdt * &
w_c%qa(n)%data3d(i1:i2,j1:j2,1:km) * &
photoRate(i1:i2,j1:j2,1:km)
gcCFC%CFCloss(i1:i2,j1:j2,1:km,m) = w_c%qa(n)%data3d(i1:i2,j1:j2,1:km) * &
photoRate(i1:i2,j1:j2,1:km)
END DO
! Return CFC-12 to mole fraction
! ------------------------------
DO n=nbeg,nend
w_c%qa(n)%data3d(i1:i2,j1:j2,1:km) = w_c%qa(n)%data3d(i1:i2,j1:j2,1:km)/ &
nd(i1:i2,j1:j2,1:km)
END DO
! Fill the export states.
! CFC-12 Surface emission in kg m^{-2} s^{-1}
! -------------------------------------------
IF(ASSOCIATED(CFC_emis(1)%data2d)) &
CFC_emis(1)%data2d(i1:i2,j1:j2) = gcCFC%CFCsfcFlux(i1:i2,j1:j2)
! Loss due to photolysis: Currently m^{-3} s^(-1), and positive for loss.
! -----------------------------------------------------------------------
DO n = 1, nbins
IF(ASSOCIATED(CFC_loss(n)%data3d)) &
CFC_loss(n)%data3d(i1:i2,j1:j2,1:km) = gcCFC%CFCloss(i1:i2,j1:j2,1:km,n)
END DO
! Column burden in kg m(^-2)
! --------------------------
DO n = 1, nbins
IF(ASSOCIATED(CFC_column(n)%data2d)) THEN
CFC_column(n)%data2d(i1:i2,j1:j2) = 0.
DO k = 1, km
CFC_column(n)%data2d(i1:i2,j1:j2) &
= CFC_column(n)%data2d(i1:i2,j1:j2) &
+ w_c%qa(nbeg+n-1)%data3d(i1:i2,j1:j2,k)*mwtCFC12/mwtAir &
* w_c%delp(i1:i2,j1:j2,k)/grav
END DO
END IF
END DO
! Clean up
! --------
DEALLOCATE( emit2vmr, STAT=ier(1))
DEALLOCATE( pPa, STAT=ier(2))
DEALLOCATE( nd, STAT=ier(3))
DEALLOCATE( O3Col, STAT=ier(4))
DEALLOCATE(photoRate, STAT=ier(5))
IF(ANY(ier(:) /= 0 )) THEN
rc = 99
RETURN
END IF
ier(:)=0
RETURN
CONTAINS
SUBROUTINE getS(ik,levels,sza,o3column,s) 1
! --------------------------------------------------------------------------
! NAME:
! interp_s
! PURPOSE:
! Interpolate s values for each wavelength in table to specified O3
! col and zenith angles
! CATEGORY:
! CALLING SEQUENCE:
! Call interp_s(nlam,sza,o3column,s)
! INPUTS:
! nlam -- number of wavelength intervals used
! sza -- zenith angle
! o3column -- overhead o3 column value
! OPTIONAL INPUT PARAMETERS:
! OUTPUTS:
! s -- array of s values (nlam) for each wavelength
! at model p-level interpolated to o3column and sza values
! INTERNAL VARIABLES
! sza_tab -- values of sza corresponding to sdat table values
! o3_tab -- array of overhead O3 values at each p-level (numo3s,np_ctm)
! used to index sdat
! sdat -- input array of values of radiative source function
! (nzens,numo3,np_ctm,nlam) gridded to ctm p layers
! COMMON BLOCKS:
! SIDE EFFECTS:
! PROCEDURE:
! bi-linear interpolation, for sza>94 s=0, for o3 out of range use min/max
! RESTRICTIONS:
! REQUIRED ROUTINES:
! MODIFICATION HISTORY:
! Created 930825 - SR Kawa
! Modified 960710 for 28 levels and to handle J(O2) separately
! 1Jan2008 Nielsen CFC-12 configuration for ARCTAS.
! --------------------------------------------------------------------------
IMPLICIT NONE
INTEGER, INTENT(IN) :: ik,levels
REAL, INTENT(IN) :: sza,o3column
REAL, INTENT(OUT) :: s(gcCFC%nlam)
INTEGER :: ijj,ikk,ikkm,il,is
REAL :: omt,omu,t,u
! For each input solar zenith angle, find the first element of
! tabled sza_tab values that is greater than it. Use this
! table element and previous table element to determined
! interpolated value.
! ------------------------------------------------------------
DO is=1,gcCFC%nsza
ijj = is
if(gcCFC%sza_tab(is) > sza) EXIT
END DO
! Location is dark, set s/jo2=0
! -----------------------------
IF(sza > gcCFC%sza_tab(gcCFC%nsza)) THEN
s(1:gcCFC%nlam) = 0.
ELSE
t = (sza-gcCFC%sza_tab(ijj-1))/(gcCFC%sza_tab(ijj)-gcCFC%sza_tab(ijj-1))
omt = 1.-t
! For each input overhead o3 column find the first element
! of tabled o3_tab values that is > than it. Use this
! table element and previous table element to determine
! interpolated value
! --------------------------------------------------------
DO is=1,gcCFC%numo3
ikk = is
IF (gcCFC%o3_tab(is,ik) > o3column) EXIT
END DO
ikkm = ikk-1
IF(ikk > 1 .AND. o3column <= gcCFC%o3_tab(gcCFC%numo3,ik)) THEN
u = (o3column-gcCFC%o3_tab(ikkm,ik))/ &
(gcCFC%o3_tab(ikk,ik)-gcCFC%o3_tab(ikkm,ik))
omu = 1.-u
! Bilinear interpolation at ik for each wavelength
! ------------------------------------------------
DO il=1,gcCFC%nlam
s(il) = omt*omu*gcCFC%sdat(ijj-1,ikkm,ik,il) &
+t*omu*gcCFC%sdat(ijj,ikkm,ik,il) &
+t*u*gcCFC%sdat(ijj,ikk,ik,il) &
+omt*u*gcCFC%sdat(ijj-1,ikk,ik,il)
END DO
! Extrapolate before table
! ------------------------
ELSE IF (ikk == 1) THEN
DO il=1,gcCFC%nlam
s(il) = omt*gcCFC%sdat(ijj-1,1,ik,il)+t*gcCFC%sdat(ijj,1,ik,il)
END DO
! Extrapolate past table
! ----------------------
ELSE
DO il=1,gcCFC%nlam
s(il) = omt*gcCFC%sdat(ijj-1,gcCFC%numo3,ik,il)+ &
t*gcCFC%sdat(ijj,gcCFC%numo3,ik,il)
END DO
END IF
END IF
RETURN
END SUBROUTINE getS
END SUBROUTINE CFC_GridCompRun
!-------------------------------------------------------------------------
! NASA/GSFC, Global Modeling and Assimilation Office, Code 900.3 !
!-------------------------------------------------------------------------
!BOP
!
! !IROUTINE: CFC_GridCompFinalize
!
! !INTERFACE:
!
SUBROUTINE CFC_GridCompFinalize( gcCFC, w_c, impChem, expChem, & 1
nymd, nhms, cdt, rc )
! !USES:
IMPLICIT NONE
! !INPUT/OUTPUT PARAMETERS:
TYPE(CFC_GridComp), INTENT(INOUT) :: gcCFC ! 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 = 'CFC_GridCompFinalize'
INTEGER :: ios
rc = 0
DEALLOCATE(gcCFC%sdat, gcCFC%xtab, gcCFC%o3_tab, gcCFC%sza_tab, &
gcCFC%CFCloss, gcCFC%CFCsfcFlux, STAT=ios )
IF( ios /= 0 ) THEN
rc = 1
IF(MAPL_AM_I_ROOT()) PRINT *,myname,': DEALLOCATE return code is ',ios
END IF
RETURN
END SUBROUTINE CFC_GridCompFinalize
END MODULE CFC_GridCompMod