#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