module cloudsimulator 3,4 !----------------------------------------------------------------------- !Purpose: CAM interface to ! Name: ISCCP Simulator ICARUS/SCOPS ! What: Simulate ISCCP cloud products from GCM inputs ! Version: 3.4 ! Authors: Steve Klein (sak@gfdl.noaa.gov) ! Mark Webb (Mark.Webb@MetOffice.com) ! !Author: W. Lin, Original version ! J. Rosinski, Modifications, March 2003 ! B. Eaton, Update to simulator version 3.4, March 2004 !----------------------------------------------------------------------- use shr_kind_mod, only: r8 => shr_kind_r8 use ppgrid, only: pcols, pver use cam_history, only: addfld, add_default, phys_decomp, outfld, fillvalue use icarus_scops, only: ntau, npres use perf_mod implicit none private save !Public functions/subroutines public :: & cloudsimulator_init, & cloudsimulator_run logical, public :: doisccp = .false. ! whether to do ISCCP calcs and I/O CONTAINS subroutine cloudsimulator_init 1,32 use icarus_scops, only: icarus_scops_init !------------------------------------------------------------------------------ call addfld ('FISCCP1 ','mixed ',npres*ntau,'A', & 'grid box fraction covered by each ISCCP D level cloud types',phys_decomp,& flag_xyfill=.true., flag_isccplev=.true.) call addfld ('TCLDAREA','fraction',1,'A','Total cloud area',phys_decomp,flag_xyfill=.true.) call addfld ('MEANPTOP','mb ',1,'A','Mean cloud top pressure',phys_decomp,flag_xyfill=.true.) call addfld ('MEANTAU ','unitless',1,'A','Mean optical thickness',phys_decomp,flag_xyfill=.true.) call addfld ('MEANTTOP','K ',1,'A','Mean cloud top temperature',phys_decomp,flag_xyfill=.true.) call addfld ('CLOUDY ','fraction',1,'A','Binary flag for TCLDAREA > cldmin',phys_decomp,flag_xyfill=.true.) call add_default ('FISCCP1 ', 1, ' ') call add_default ('TCLDAREA', 1, ' ') call add_default ('MEANPTOP', 1, ' ') call add_default ('MEANTAU ', 1, ' ') call add_default ('MEANTTOP', 1, ' ') call add_default ('CLOUDY ', 1, ' ') call icarus_scops_init end subroutine cloudsimulator_init subroutine cloudsimulator_run(state, ts, concld, cld, cliqwp, & 1,21 cicewp, rel, rei, emis, coszrs ) use physics_types, only: physics_state use icarus_scops, only: isccp_cloud_types type(physics_state), intent(in) :: state real(r8), intent(in) :: ts(pcols) ! skin temperature real(r8), intent(in) :: concld(pcols,pver) ! convective cloud cover real(r8), intent(in) :: cld(pcols,pver) ! cloud cover real(r8), intent(in) :: cliqwp(pcols,pver) ! in-cloud liquid water path real(r8), intent(in) :: cicewp(pcols,pver) ! in-cloud ice water path real(r8), intent(in) :: rel(pcols,pver) ! Liquid cloud particle effective radius real(r8), intent(in) :: rei(pcols,pver) ! Ice effective drop size (microns) real(r8), intent(in) :: emis(pcols,pver) ! Cloud longwave emissivity real(r8), intent(in) :: coszrs(pcols) ! cosine solar zenith angle (to tell if day or night) ! Local variables: integer, parameter :: debug = 0 ! set to non-zero value to print out inputs ! with step debug integer, parameter :: debugcol = 0 ! set to non-zero value to print out column ! decomposition with step debugcol integer, parameter :: top_height = 1 ! 1 = adjust top height using both a computed ! infrared brightness temperature and the visible ! optical depth to adjust cloud top pressure. Note ! that this calculation is most appropriate to compare ! to ISCCP data during sunlit hours. integer, parameter :: overlap = 3 ! 3=max/rand integer, parameter :: nsubcol = 50 ! # of columns each grid box is subdivided into real(r8), parameter :: emsfc_lw = 0.99_r8 ! longwave emissivity of surface at 10.5 microns ! constants for optical depth calculation from radcswmx.F90 real(r8), parameter :: abarl = 2.817e-02_r8 ! A coefficient for extinction optical depth real(r8), parameter :: bbarl = 1.305_r8 ! b coefficient for extinction optical depth real(r8), parameter :: abari = 3.448e-03_r8 ! A coefficient for extinction optical depth real(r8), parameter :: bbari = 2.431_r8 ! b coefficient for extinction optical depth real(r8), parameter :: cldmin = 1.0e-80_r8 ! note: cldmin much less than cldmin from cldnrh real(r8), parameter :: cldeps = 0.0_r8 ! integer :: lchnk ! chunk identifier integer :: ncol ! number of atmospheric columns integer :: sunlit(pcols) ! 1 for day points, 0 for night time integer :: seed1(pcols) ! seed values for random number generator integer :: seed2(pcols) ! seed values for random number generator integer :: seed3(pcols) ! seed values for random number generator integer :: seed4(pcols) ! seed values for random number generator real(r8) :: tau(pcols,pver) ! optical depth real(r8) :: fq_isccp(pcols,ntau,npres) ! the fraction of the model grid box covered by ! each of the 49 ISCCP D level cloud types real(r8) :: totalcldarea(pcols) ! the fraction of model grid box columns ! with cloud somewhere in them. This should ! equal the sum over all entries of fq_isccp real(r8) :: meanptop(pcols) ! mean cloud top pressure (mb) - linear averaging ! in cloud top pressure. real(r8) :: meanttop(pcols) ! mean cloud top temp (k) - linear averaging real(r8) :: meantaucld(pcols) ! mean optical thickness ! linear averaging in albedo performed. real(r8) :: boxtau(pcols,nsubcol) ! optical thickness in each column real(r8) :: boxptop(pcols,nsubcol) ! cloud top pressure (mb) in each column real(r8) :: fq_isccp_s1(pcols,ntau*npres)! accumulated fq_isccp integer :: i, k, it, ip, itaunpres ! indices real(r8) :: cloudy(pcols) ! cloudy flag, which may be used to derived mean values under cloudy ! conditions. The cloud flag itself is freuency of cloudy condition ! when average over an accumulation period. !------------------------------------------------------------------------------------------------ call t_startf ('cloudsimulator_run') lchnk = state%lchnk ncol = state%ncol ! compute the optical depth (code from radcswmx) do k=1,pver do i=1,ncol if(cld(i,k) >= cldmin .and. cld(i,k) >= cldeps) then tau(i,k) = (abarl + bbarl/rel(i,k)) * cliqwp(i,k) + & (abari + bbari/rei(i,k)) * cicewp(i,k) else tau(i,k) = 0.0_r8 endif end do end do sunlit = 0 do i=1,ncol if (coszrs(i) > 0._r8) sunlit(i) = 1 seed1(i) = (state%pmid(i,pver) - int(state%pmid(i,pver))) * 1000000000 seed2(i) = (state%pmid(i,pver-1) - int(state%pmid(i,pver-1))) * 1000000000 seed3(i) = (state%pmid(i,pver-2) - int(state%pmid(i,pver-2))) * 1000000000 seed4(i) = (state%pmid(i,pver-3) - int(state%pmid(i,pver-3))) * 1000000000 end do call ISCCP_CLOUD_TYPES( & debug, & debugcol, & ncol, & sunlit(:ncol), & pver, & nsubcol, & seed1(:ncol), & seed2(:ncol), & seed3(:ncol), & seed4(:ncol), & state%pmid(:ncol,:), & state%pint(:ncol,:), & state%q(:ncol,:,1), & cld(:ncol,:), & concld(:ncol,:), & tau(:ncol,:), & tau(:ncol,:), & top_height, & overlap, & ts(:ncol), & emsfc_lw, & state%t(:ncol,:), & emis(:ncol,:), & emis(:ncol,:), & fq_isccp(:ncol,:,:), & totalcldarea(:ncol), & meanptop(:ncol), & meanttop(:ncol), & meantaucld(:ncol), & boxtau(:ncol,:), & boxptop(:ncol,:) ) do i=1,ncol if (coszrs(i) > 0._r8) then if (totalcldarea(i) >= cldmin) then cloudy(i) = 1.0_r8 ! save standard ISCCP type of 7x7 clouds do ip=1,npres do it=1,ntau itaunpres = (ip-1)*ntau+it fq_isccp_s1(i,itaunpres) = fq_isccp(i,it,ip) end do end do else !cloud free in the (daytime) grid box fq_isccp_s1(i,:) = 0._r8 totalcldarea(i) = 0._r8 meanptop(i) = fillvalue meantaucld(i) = fillvalue meanttop(i) = fillvalue cloudy(i) = 0._r8 endif else ! nighttime fq_isccp_s1(i,:) = fillvalue totalcldarea(i) = fillvalue meanptop(i) = fillvalue meantaucld(i) = fillvalue meanttop(i) = fillvalue cloudy(i) = fillvalue end if end do ! ! dont need to call outfld if all points are nighttime ! if (any(coszrs(:ncol) > 0._r8)) then call outfld('FISCCP1 ',fq_isccp_s1, pcols,lchnk) call outfld('TCLDAREA',totalcldarea,pcols,lchnk) call outfld('MEANPTOP',meanptop ,pcols,lchnk) call outfld('MEANTAU ',meantaucld ,pcols,lchnk) call outfld('MEANTTOP',meanttop ,pcols,lchnk) call outfld('CLOUDY ',cloudy ,pcols,lchnk) end if call t_stopf ('cloudsimulator_run') end subroutine cloudsimulator_run !####################################################################### end module cloudsimulator