LCOV - code coverage report
Current view: top level - control - camsrfexch.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 250 271 92.3 %
Date: 2025-03-14 01:26:08 Functions: 5 7 71.4 %

          Line data    Source code
       1             : module camsrfexch
       2             : 
       3             :   !-----------------------------------------------------------------------
       4             :   ! Module to handle data that is exchanged between the CAM atmosphere
       5             :   ! model and the surface models (land, sea-ice, and ocean).
       6             :   !-----------------------------------------------------------------------
       7             : 
       8             :   use shr_kind_mod,    only: r8 => shr_kind_r8, r4 => shr_kind_r4
       9             :   use constituents,    only: pcnst
      10             :   use ppgrid,          only: pcols, begchunk, endchunk
      11             :   use phys_grid,       only: get_ncols_p, phys_grid_initialized
      12             :   use infnan,          only: posinf, assignment(=)
      13             :   use cam_abortutils,  only: endrun
      14             :   use cam_logfile,     only: iulog
      15             :   use srf_field_check, only: active_Sl_ram1, active_Sl_fv, active_Sl_soilw,                &
      16             :                              active_Fall_flxdst1, active_Fall_flxvoc, active_Fall_flxfire
      17             :   use cam_control_mod, only: aqua_planet, simple_phys
      18             : 
      19             :   implicit none
      20             :   private
      21             : 
      22             :   ! Public interfaces
      23             :   public atm2hub_alloc              ! Atmosphere to surface data allocation method
      24             :   public hub2atm_alloc              ! Merged hub surface to atmosphere data allocation method
      25             :   public atm2hub_deallocate
      26             :   public hub2atm_deallocate
      27             :   public cam_export
      28             : 
      29             :   ! Public data types
      30             :   public cam_out_t                  ! Data from atmosphere
      31             :   public cam_in_t                   ! Merged surface data
      32             : 
      33             :   !---------------------------------------------------------------------------
      34             :   ! This is the data that is sent from the atmosphere to the surface models
      35             :   !---------------------------------------------------------------------------
      36             : 
      37             :   type cam_out_t
      38             :      integer  :: lchnk               ! chunk index
      39             :      integer  :: ncol                ! number of columns in chunk
      40             :      real(r8) :: tbot(pcols)         ! bot level temperature
      41             :      real(r8) :: zbot(pcols)         ! bot level height above surface
      42             :      real(r8) :: topo(pcols)         ! surface topographic height (m)
      43             :      real(r8) :: ubot(pcols)         ! bot level u wind
      44             :      real(r8) :: vbot(pcols)         ! bot level v wind
      45             :      real(r8) :: qbot(pcols,pcnst)   ! bot level specific humidity
      46             :      real(r8) :: pbot(pcols)         ! bot level pressure
      47             :      real(r8) :: rho(pcols)          ! bot level density
      48             :      real(r8) :: netsw(pcols)        !
      49             :      real(r8) :: flwds(pcols)        !
      50             :      real(r8) :: precsc(pcols)       !
      51             :      real(r8) :: precsl(pcols)       !
      52             :      real(r8) :: precc(pcols)        !
      53             :      real(r8) :: precl(pcols)        !
      54             :      real(r8) :: soll(pcols)         !
      55             :      real(r8) :: sols(pcols)         !
      56             :      real(r8) :: solld(pcols)        !
      57             :      real(r8) :: solsd(pcols)        !
      58             :      real(r8) :: thbot(pcols)        !
      59             :      real(r8) :: co2prog(pcols)      ! prognostic co2
      60             :      real(r8) :: co2diag(pcols)      ! diagnostic co2
      61             :      real(r8) :: ozone(pcols)        ! surface ozone concentration (mole/mole)
      62             :      real(r8) :: lightning_flash_freq(pcols) ! cloud-to-ground lightning flash frequency (/min)
      63             :      real(r8) :: psl(pcols)
      64             :      real(r8) :: bcphiwet(pcols)     ! wet deposition of hydrophilic black carbon
      65             :      real(r8) :: bcphidry(pcols)     ! dry deposition of hydrophilic black carbon
      66             :      real(r8) :: bcphodry(pcols)     ! dry deposition of hydrophobic black carbon
      67             :      real(r8) :: ocphiwet(pcols)     ! wet deposition of hydrophilic organic carbon
      68             :      real(r8) :: ocphidry(pcols)     ! dry deposition of hydrophilic organic carbon
      69             :      real(r8) :: ocphodry(pcols)     ! dry deposition of hydrophobic organic carbon
      70             :      real(r8) :: dstwet1(pcols)      ! wet deposition of dust (bin1)
      71             :      real(r8) :: dstdry1(pcols)      ! dry deposition of dust (bin1)
      72             :      real(r8) :: dstwet2(pcols)      ! wet deposition of dust (bin2)
      73             :      real(r8) :: dstdry2(pcols)      ! dry deposition of dust (bin2)
      74             :      real(r8) :: dstwet3(pcols)      ! wet deposition of dust (bin3)
      75             :      real(r8) :: dstdry3(pcols)      ! dry deposition of dust (bin3)
      76             :      real(r8) :: dstwet4(pcols)      ! wet deposition of dust (bin4)
      77             :      real(r8) :: dstdry4(pcols)      ! dry deposition of dust (bin4)
      78             :      real(r8), pointer, dimension(:) :: nhx_nitrogen_flx ! nitrogen deposition fluxes (kgN/m2/s)
      79             :      real(r8), pointer, dimension(:) :: noy_nitrogen_flx ! nitrogen deposition fluxes (kgN/m2/s)
      80             :   end type cam_out_t
      81             : 
      82             :   !---------------------------------------------------------------------------
      83             :   ! This is the merged state of sea-ice, land and ocean surface parameterizations
      84             :   !---------------------------------------------------------------------------
      85             : 
      86             :   type cam_in_t
      87             :      integer  :: lchnk                   ! chunk index
      88             :      integer  :: ncol                    ! number of active columns
      89             :      real(r8) :: asdir(pcols)            ! albedo: shortwave, direct
      90             :      real(r8) :: asdif(pcols)            ! albedo: shortwave, diffuse
      91             :      real(r8) :: aldir(pcols)            ! albedo: longwave, direct
      92             :      real(r8) :: aldif(pcols)            ! albedo: longwave, diffuse
      93             :      real(r8) :: lwup(pcols)             ! longwave up radiative flux
      94             :      real(r8) :: lhf(pcols)              ! latent heat flux
      95             :      real(r8) :: shf(pcols)              ! sensible heat flux
      96             :      real(r8) :: wsx(pcols)              ! surface u-stress (N)
      97             :      real(r8) :: wsy(pcols)              ! surface v-stress (N)
      98             :      real(r8) :: tref(pcols)             ! ref height surface air temp
      99             :      real(r8) :: qref(pcols)             ! ref height specific humidity
     100             :      real(r8) :: u10(pcols)              ! 10m wind speed
     101             :      real(r8) :: ugustOut(pcols)         ! gustiness added
     102             :      real(r8) :: u10withGusts(pcols)     ! 10m wind speed with gusts added
     103             :      real(r8) :: ts(pcols)               ! merged surface temp
     104             :      real(r8) :: sst(pcols)              ! sea surface temp
     105             :      real(r8) :: snowhland(pcols)        ! snow depth (liquid water equivalent) over land
     106             :      real(r8) :: snowhice(pcols)         ! snow depth over ice
     107             :      real(r8) :: fco2_lnd(pcols)         ! co2 flux from lnd
     108             :      real(r8) :: fco2_ocn(pcols)         ! co2 flux from ocn
     109             :      real(r8) :: fdms(pcols)             ! dms flux
     110             :      real(r8) :: landfrac(pcols)         ! land area fraction
     111             :      real(r8) :: icefrac(pcols)          ! sea-ice areal fraction
     112             :      real(r8) :: ocnfrac(pcols)          ! ocean areal fraction
     113             :      real(r8) :: cflx(pcols,pcnst)       ! constituent flux (emissions)
     114             :      real(r8) :: ustar(pcols)            ! atm/ocn saved version of ustar
     115             :      real(r8) :: re(pcols)               ! atm/ocn saved version of re
     116             :      real(r8) :: ssq(pcols)              ! atm/ocn saved version of ssq
     117             :      real(r8), pointer, dimension(:)   :: ram1  !aerodynamical resistance (s/m) (pcols)
     118             :      real(r8), pointer, dimension(:)   :: fv    !friction velocity (m/s) (pcols)
     119             :      real(r8), pointer, dimension(:)   :: soilw !volumetric soil water (m3/m3)
     120             :      real(r8), pointer, dimension(:,:) :: depvel ! deposition velocities
     121             :      real(r8), pointer, dimension(:,:) :: dstflx ! dust fluxes
     122             :      real(r8), pointer, dimension(:,:) :: meganflx ! MEGAN fluxes
     123             :      real(r8), pointer, dimension(:,:) :: fireflx ! wild fire emissions
     124             :      real(r8), pointer, dimension(:)   :: fireztop ! wild fire emissions vert distribution top
     125             :   end type cam_in_t
     126             : 
     127             : !===============================================================================
     128             : CONTAINS
     129             : !===============================================================================
     130             : 
     131         768 :   subroutine hub2atm_alloc( cam_in )
     132             : 
     133             :     ! Allocate space for the surface to atmosphere data type. And initialize
     134             :     ! the values.
     135             : 
     136             :     use shr_drydep_mod,  only: n_drydep
     137             :     use shr_megan_mod,   only: shr_megan_mechcomps_n
     138             :     use shr_fire_emis_mod,only: shr_fire_emis_mechcomps_n
     139             : 
     140             :     ! ARGUMENTS:
     141             :     type(cam_in_t), pointer ::  cam_in(:)     ! Merged surface state
     142             : 
     143             :     ! LOCAL VARIABLES:
     144             :     integer :: c        ! chunk index
     145             :     integer :: ierror   ! Error code
     146             :     character(len=*), parameter :: sub = 'hub2atm_alloc'
     147             :     !-----------------------------------------------------------------------
     148             : 
     149         768 :     if ( .not. phys_grid_initialized() ) call endrun(sub//": phys_grid not called yet")
     150        2304 :     allocate (cam_in(begchunk:endchunk), stat=ierror)
     151         768 :     if ( ierror /= 0 )then
     152           0 :       write(iulog,*) sub//': Allocation error: ', ierror
     153           0 :       call endrun(sub//': allocation error')
     154             :     end if
     155             : 
     156        3072 :     do c = begchunk,endchunk
     157        2304 :        nullify(cam_in(c)%ram1)
     158        2304 :        nullify(cam_in(c)%fv)
     159        2304 :        nullify(cam_in(c)%soilw)
     160        2304 :        nullify(cam_in(c)%depvel)
     161        2304 :        nullify(cam_in(c)%dstflx)
     162        2304 :        nullify(cam_in(c)%meganflx)
     163        2304 :        nullify(cam_in(c)%fireflx)
     164        3072 :        nullify(cam_in(c)%fireztop)
     165             :     enddo
     166        3072 :     do c = begchunk,endchunk
     167        2304 :        if (active_Sl_ram1) then
     168        2304 :           allocate (cam_in(c)%ram1(pcols), stat=ierror)
     169        2304 :           if ( ierror /= 0 ) call endrun(sub//': allocation error ram1')
     170             :        endif
     171        2304 :        if (active_Sl_fv) then
     172        2304 :           allocate (cam_in(c)%fv(pcols), stat=ierror)
     173        2304 :           if ( ierror /= 0 ) call endrun(sub//': allocation error fv')
     174             :        endif
     175        2304 :        if (active_Sl_soilw) then
     176           0 :           allocate (cam_in(c)%soilw(pcols), stat=ierror)
     177           0 :           if ( ierror /= 0 ) call endrun(sub//': allocation error soilw')
     178             :        end if
     179        2304 :        if (active_Fall_flxdst1) then
     180             :           ! Assume 4 bins from surface model ....
     181        2304 :           allocate (cam_in(c)%dstflx(pcols,4), stat=ierror)
     182        2304 :           if ( ierror /= 0 ) call endrun(sub//': allocation error dstflx')
     183             :        endif
     184        3072 :        if (active_Fall_flxvoc .and. shr_megan_mechcomps_n>0) then
     185        6912 :           allocate (cam_in(c)%meganflx(pcols,shr_megan_mechcomps_n), stat=ierror)
     186        2304 :           if ( ierror /= 0 ) call endrun(sub//': allocation error meganflx')
     187             :        endif
     188             :     end do
     189             : 
     190         768 :     if (n_drydep>0) then
     191        3072 :        do c = begchunk,endchunk
     192        6912 :           allocate (cam_in(c)%depvel(pcols,n_drydep), stat=ierror)
     193        3072 :           if ( ierror /= 0 ) call endrun(sub//': allocation error depvel')
     194             :        end do
     195             :     endif
     196             : 
     197         768 :     if (active_Fall_flxfire .and. shr_fire_emis_mechcomps_n>0) then
     198           0 :        do c = begchunk,endchunk
     199           0 :           allocate(cam_in(c)%fireflx(pcols,shr_fire_emis_mechcomps_n), stat=ierror)
     200           0 :           if ( ierror /= 0 ) call endrun(sub//': allocation error fireflx')
     201           0 :           allocate(cam_in(c)%fireztop(pcols), stat=ierror)
     202           0 :           if ( ierror /= 0 ) call endrun(sub//': allocation error fireztop')
     203             :        enddo
     204             :     endif
     205             : 
     206        3072 :     do c = begchunk,endchunk
     207        2304 :        cam_in(c)%lchnk = c
     208        2304 :        cam_in(c)%ncol  = get_ncols_p(c)
     209       39168 :        cam_in(c)%asdir    (:) = 0._r8
     210       39168 :        cam_in(c)%asdif    (:) = 0._r8
     211       39168 :        cam_in(c)%aldir    (:) = 0._r8
     212       39168 :        cam_in(c)%aldif    (:) = 0._r8
     213       39168 :        cam_in(c)%lwup     (:) = 0._r8
     214       39168 :        cam_in(c)%lhf      (:) = 0._r8
     215       39168 :        cam_in(c)%shf      (:) = 0._r8
     216       39168 :        cam_in(c)%wsx      (:) = 0._r8
     217       39168 :        cam_in(c)%wsy      (:) = 0._r8
     218       39168 :        cam_in(c)%tref     (:) = 0._r8
     219       39168 :        cam_in(c)%qref     (:) = 0._r8
     220       39168 :        cam_in(c)%u10      (:) = 0._r8
     221       39168 :        cam_in(c)%ugustOut (:) = 0._r8
     222       39168 :        cam_in(c)%u10withGusts (:) = 0._r8
     223       39168 :        cam_in(c)%ts       (:) = 0._r8
     224       39168 :        cam_in(c)%sst      (:) = 0._r8
     225       39168 :        cam_in(c)%snowhland(:) = 0._r8
     226       39168 :        cam_in(c)%snowhice (:) = 0._r8
     227       39168 :        cam_in(c)%fco2_lnd (:) = 0._r8
     228       39168 :        cam_in(c)%fco2_ocn (:) = 0._r8
     229       39168 :        cam_in(c)%fdms     (:) = 0._r8
     230        2304 :        cam_in(c)%landfrac (:) = posinf
     231        2304 :        cam_in(c)%icefrac  (:) = posinf
     232        2304 :        cam_in(c)%ocnfrac  (:) = posinf
     233             : 
     234        2304 :        if (associated(cam_in(c)%ram1)) &
     235       39168 :             cam_in(c)%ram1  (:) = 0.1_r8
     236        2304 :        if (associated(cam_in(c)%fv)) &
     237       39168 :             cam_in(c)%fv    (:) = 0.1_r8
     238        2304 :        if (associated(cam_in(c)%soilw)) &
     239           0 :             cam_in(c)%soilw (:) = 0.0_r8
     240        2304 :        if (associated(cam_in(c)%dstflx)) &
     241      158976 :             cam_in(c)%dstflx(:,:) = 0.0_r8
     242        2304 :        if (associated(cam_in(c)%meganflx)) &
     243       80640 :             cam_in(c)%meganflx(:,:) = 0.0_r8
     244             : 
     245     3958272 :        cam_in(c)%cflx   (:,:) = 0._r8
     246       39168 :        cam_in(c)%ustar    (:) = 0._r8
     247       39168 :        cam_in(c)%re       (:) = 0._r8
     248       39168 :        cam_in(c)%ssq      (:) = 0._r8
     249        2304 :        if (n_drydep>0) then
     250      550656 :           cam_in(c)%depvel (:,:) = 0._r8
     251             :        endif
     252        3072 :        if (active_Fall_flxfire .and. shr_fire_emis_mechcomps_n>0) then
     253           0 :           cam_in(c)%fireflx(:,:) = 0._r8
     254           0 :           cam_in(c)%fireztop(:) = 0._r8
     255             :        endif
     256             :     end do
     257             : 
     258         768 :   end subroutine hub2atm_alloc
     259             : 
     260             :   !===============================================================================
     261             : 
     262         768 :   subroutine atm2hub_alloc( cam_out )
     263             : 
     264             :     ! Allocate space for the atmosphere to surface data type. And initialize
     265             :     ! the values.
     266             : 
     267             :     ! ARGUMENTS:
     268             :     type(cam_out_t), pointer :: cam_out(:)    ! Atmosphere to surface input
     269             : 
     270             :     ! LOCAL VARIABLES:
     271             :     integer :: c            ! chunk index
     272             :     integer :: ierror       ! Error code
     273             :     character(len=*), parameter :: sub = 'atm2hub_alloc'
     274             :     !-----------------------------------------------------------------------
     275             : 
     276         768 :     if (.not. phys_grid_initialized()) call endrun(sub//": phys_grid not called yet")
     277        2304 :     allocate (cam_out(begchunk:endchunk), stat=ierror)
     278         768 :     if ( ierror /= 0 )then
     279           0 :       write(iulog,*) sub//': Allocation error: ', ierror
     280           0 :       call endrun(sub//': allocation error: cam_out')
     281             :     end if
     282             : 
     283        3072 :     do c = begchunk,endchunk
     284        2304 :        cam_out(c)%lchnk       = c
     285        2304 :        cam_out(c)%ncol        = get_ncols_p(c)
     286       39168 :        cam_out(c)%tbot(:)     = 0._r8
     287       39168 :        cam_out(c)%zbot(:)     = 0._r8
     288       39168 :        cam_out(c)%topo(:)     = 0._r8
     289       39168 :        cam_out(c)%ubot(:)     = 0._r8
     290       39168 :        cam_out(c)%vbot(:)     = 0._r8
     291     3958272 :        cam_out(c)%qbot(:,:)   = 0._r8
     292       39168 :        cam_out(c)%pbot(:)     = 0._r8
     293       39168 :        cam_out(c)%rho(:)      = 0._r8
     294       39168 :        cam_out(c)%netsw(:)    = 0._r8
     295       39168 :        cam_out(c)%flwds(:)    = 0._r8
     296       39168 :        cam_out(c)%precsc(:)   = 0._r8
     297       39168 :        cam_out(c)%precsl(:)   = 0._r8
     298       39168 :        cam_out(c)%precc(:)    = 0._r8
     299       39168 :        cam_out(c)%precl(:)    = 0._r8
     300       39168 :        cam_out(c)%soll(:)     = 0._r8
     301       39168 :        cam_out(c)%sols(:)     = 0._r8
     302       39168 :        cam_out(c)%solld(:)    = 0._r8
     303       39168 :        cam_out(c)%solsd(:)    = 0._r8
     304       39168 :        cam_out(c)%thbot(:)    = 0._r8
     305       39168 :        cam_out(c)%co2prog(:)  = 0._r8
     306       39168 :        cam_out(c)%co2diag(:)  = 0._r8
     307       39168 :        cam_out(c)%ozone(:)    = 0._r8
     308       39168 :        cam_out(c)%lightning_flash_freq(:) = 0._r8
     309       39168 :        cam_out(c)%psl(:)      = 0._r8
     310       39168 :        cam_out(c)%bcphidry(:) = 0._r8
     311       39168 :        cam_out(c)%bcphodry(:) = 0._r8
     312       39168 :        cam_out(c)%bcphiwet(:) = 0._r8
     313       39168 :        cam_out(c)%ocphidry(:) = 0._r8
     314       39168 :        cam_out(c)%ocphodry(:) = 0._r8
     315       39168 :        cam_out(c)%ocphiwet(:) = 0._r8
     316       39168 :        cam_out(c)%dstdry1(:)  = 0._r8
     317       39168 :        cam_out(c)%dstwet1(:)  = 0._r8
     318       39168 :        cam_out(c)%dstdry2(:)  = 0._r8
     319       39168 :        cam_out(c)%dstwet2(:)  = 0._r8
     320       39168 :        cam_out(c)%dstdry3(:)  = 0._r8
     321       39168 :        cam_out(c)%dstwet3(:)  = 0._r8
     322       39168 :        cam_out(c)%dstdry4(:)  = 0._r8
     323       39168 :        cam_out(c)%dstwet4(:)  = 0._r8
     324             : 
     325        2304 :        nullify(cam_out(c)%nhx_nitrogen_flx)
     326        2304 :        nullify(cam_out(c)%noy_nitrogen_flx)
     327             : 
     328        3072 :        if (.not.(simple_phys .or. aqua_planet)) then
     329             : 
     330        2304 :           allocate (cam_out(c)%nhx_nitrogen_flx(pcols), stat=ierror)
     331        2304 :           if ( ierror /= 0 ) call endrun(sub//': allocation error nhx_nitrogen_flx')
     332       39168 :           cam_out(c)%nhx_nitrogen_flx(:) = 0._r8
     333             : 
     334        2304 :           allocate (cam_out(c)%noy_nitrogen_flx(pcols), stat=ierror)
     335        2304 :           if ( ierror /= 0 ) call endrun(sub//': allocation error noy_nitrogen_flx')
     336       39168 :           cam_out(c)%noy_nitrogen_flx(:) = 0._r8
     337             : 
     338             :        endif
     339             : 
     340             :     end do
     341             : 
     342         768 :   end subroutine atm2hub_alloc
     343             : 
     344             :   !===============================================================================
     345             : 
     346         768 :   subroutine atm2hub_deallocate(cam_out)
     347             : 
     348             :     type(cam_out_t), pointer :: cam_out(:)    ! Atmosphere to surface input
     349             :     !-----------------------------------------------------------------------
     350             : 
     351         768 :     if(associated(cam_out)) then
     352         768 :        deallocate(cam_out)
     353             :     end if
     354         768 :     nullify(cam_out)
     355             : 
     356         768 :   end subroutine atm2hub_deallocate
     357             : 
     358             :   !===============================================================================
     359             : 
     360         768 :   subroutine hub2atm_deallocate(cam_in)
     361             : 
     362             :     type(cam_in_t), pointer :: cam_in(:)    ! Atmosphere to surface input
     363             : 
     364             :     integer :: c
     365             :     !-----------------------------------------------------------------------
     366             : 
     367         768 :     if(associated(cam_in)) then
     368        3072 :        do c=begchunk,endchunk
     369        2304 :           if(associated(cam_in(c)%ram1)) then
     370        2304 :              deallocate(cam_in(c)%ram1)
     371        2304 :              nullify(cam_in(c)%ram1)
     372             :           end if
     373        2304 :           if(associated(cam_in(c)%fv)) then
     374        2304 :              deallocate(cam_in(c)%fv)
     375        2304 :              nullify(cam_in(c)%fv)
     376             :           end if
     377        2304 :           if(associated(cam_in(c)%soilw)) then
     378           0 :              deallocate(cam_in(c)%soilw)
     379           0 :              nullify(cam_in(c)%soilw)
     380             :           end if
     381        2304 :           if(associated(cam_in(c)%dstflx)) then
     382        2304 :              deallocate(cam_in(c)%dstflx)
     383        2304 :              nullify(cam_in(c)%dstflx)
     384             :           end if
     385        2304 :           if(associated(cam_in(c)%meganflx)) then
     386        2304 :              deallocate(cam_in(c)%meganflx)
     387        2304 :              nullify(cam_in(c)%meganflx)
     388             :           end if
     389        3072 :           if(associated(cam_in(c)%depvel)) then
     390        2304 :              deallocate(cam_in(c)%depvel)
     391        2304 :              nullify(cam_in(c)%depvel)
     392             :           end if
     393             : 
     394             :        enddo
     395             : 
     396         768 :        deallocate(cam_in)
     397             :     end if
     398         768 :     nullify(cam_in)
     399             : 
     400         768 :   end subroutine hub2atm_deallocate
     401             : 
     402             : 
     403             : !======================================================================
     404             : 
     405       24192 : subroutine cam_export(state,cam_out,pbuf)
     406             : 
     407             :    ! Transfer atmospheric fields into necessary surface data structures
     408             : 
     409             :    use physics_types,    only: physics_state
     410             :    use ppgrid,           only: pver
     411             :    use cam_history,      only: outfld
     412             :    use chem_surfvals,    only: chem_surfvals_get
     413             :    use co2_cycle,        only: co2_transport, c_i
     414             :    use physconst,        only: rair, mwdry, mwco2, gravit, mwo3
     415             :    use constituents,     only: pcnst
     416             :    use physics_buffer,   only: pbuf_get_index, pbuf_get_field, physics_buffer_desc
     417             :    use rad_constituents, only: rad_cnst_get_gas
     418             :    use cam_control_mod,  only: simple_phys
     419             : 
     420             :    implicit none
     421             : 
     422             :    ! Input arguments
     423             :    type(physics_state),  intent(in) :: state
     424             :    type (cam_out_t),     intent(inout) :: cam_out
     425             :    type(physics_buffer_desc), pointer  :: pbuf(:)
     426             : 
     427             :    ! Local variables
     428             : 
     429             :    integer :: i              ! Longitude index
     430             :    integer :: m              ! constituent index
     431             :    integer :: lchnk          ! Chunk index
     432             :    integer :: ncol
     433             :    integer :: psl_idx
     434             :    integer :: prec_dp_idx, snow_dp_idx, prec_sh_idx, snow_sh_idx
     435             :    integer :: prec_sed_idx,snow_sed_idx,prec_pcw_idx,snow_pcw_idx
     436             :    integer :: srf_ozone_idx, lightning_idx
     437             : 
     438       24192 :    real(r8), pointer :: psl(:)
     439             : 
     440       24192 :    real(r8), pointer :: prec_dp(:)                 ! total precipitation   from ZM convection
     441       24192 :    real(r8), pointer :: snow_dp(:)                 ! snow from ZM   convection
     442       24192 :    real(r8), pointer :: prec_sh(:)                 ! total precipitation   from Hack convection
     443       24192 :    real(r8), pointer :: snow_sh(:)                 ! snow from   Hack   convection
     444       24192 :    real(r8), pointer :: prec_sed(:)                ! total precipitation   from ZM convection
     445       24192 :    real(r8), pointer :: snow_sed(:)                ! snow from ZM   convection
     446       24192 :    real(r8), pointer :: prec_pcw(:)                ! total precipitation   from Hack convection
     447       24192 :    real(r8), pointer :: snow_pcw(:)                ! snow from Hack   convection
     448       24192 :    real(r8), pointer :: o3_ptr(:,:), srf_o3_ptr(:)
     449       24192 :    real(r8), pointer :: lightning_ptr(:)
     450             :    !-----------------------------------------------------------------------
     451             : 
     452       24192 :    lchnk = state%lchnk
     453       24192 :    ncol  = state%ncol
     454             : 
     455       48384 :    psl_idx = pbuf_get_index('PSL')
     456       24192 :    call pbuf_get_field(pbuf, psl_idx, psl)
     457             : 
     458       24192 :    prec_dp_idx = pbuf_get_index('PREC_DP', errcode=i)
     459       24192 :    snow_dp_idx = pbuf_get_index('SNOW_DP', errcode=i)
     460       24192 :    prec_sh_idx = pbuf_get_index('PREC_SH', errcode=i)
     461       24192 :    snow_sh_idx = pbuf_get_index('SNOW_SH', errcode=i)
     462       24192 :    prec_sed_idx = pbuf_get_index('PREC_SED', errcode=i)
     463       24192 :    snow_sed_idx = pbuf_get_index('SNOW_SED', errcode=i)
     464       24192 :    prec_pcw_idx = pbuf_get_index('PREC_PCW', errcode=i)
     465       24192 :    snow_pcw_idx = pbuf_get_index('SNOW_PCW', errcode=i)
     466       24192 :    srf_ozone_idx = pbuf_get_index('SRFOZONE', errcode=i)
     467       24192 :    lightning_idx = pbuf_get_index('LGHT_FLASH_FREQ', errcode=i)
     468             : 
     469       24192 :    if (prec_dp_idx > 0) then
     470       24192 :      call pbuf_get_field(pbuf, prec_dp_idx, prec_dp)
     471             :    end if
     472       24192 :    if (snow_dp_idx > 0) then
     473       24192 :      call pbuf_get_field(pbuf, snow_dp_idx, snow_dp)
     474             :    end if
     475       24192 :    if (prec_sh_idx > 0) then
     476       24192 :      call pbuf_get_field(pbuf, prec_sh_idx, prec_sh)
     477             :    end if
     478       24192 :    if (snow_sh_idx > 0) then
     479       24192 :      call pbuf_get_field(pbuf, snow_sh_idx, snow_sh)
     480             :    end if
     481       24192 :    if (prec_sed_idx > 0) then
     482       24192 :      call pbuf_get_field(pbuf, prec_sed_idx, prec_sed)
     483             :    end if
     484       24192 :    if (snow_sed_idx > 0) then
     485       24192 :      call pbuf_get_field(pbuf, snow_sed_idx, snow_sed)
     486             :    end if
     487       24192 :    if (prec_pcw_idx > 0) then
     488       24192 :      call pbuf_get_field(pbuf, prec_pcw_idx, prec_pcw)
     489             :    end if
     490       24192 :    if (snow_pcw_idx > 0) then
     491       24192 :      call pbuf_get_field(pbuf, snow_pcw_idx, snow_pcw)
     492             :    end if
     493             : 
     494      314496 :    do i=1,ncol
     495      290304 :       cam_out%tbot(i)  = state%t(i,pver)
     496      290304 :       cam_out%thbot(i) = state%t(i,pver) * state%exner(i,pver)
     497      290304 :       cam_out%zbot(i)  = state%zm(i,pver)
     498      290304 :       cam_out%topo(i)  = state%phis(i) / gravit
     499      290304 :       cam_out%ubot(i)  = state%u(i,pver)
     500      290304 :       cam_out%vbot(i)  = state%v(i,pver)
     501      290304 :       cam_out%pbot(i)  = state%pmid(i,pver)
     502      290304 :       cam_out%psl(i)   = psl(i)
     503      314496 :       cam_out%rho(i)   = cam_out%pbot(i)/(rair*cam_out%tbot(i))
     504             :    end do
     505     2467584 :    do m = 1, pcnst
     506    31788288 :      do i = 1, ncol
     507    31764096 :         cam_out%qbot(i,m) = state%q(i,pver,m)
     508             :      end do
     509             :    end do
     510             : 
     511      314496 :    cam_out%co2diag(:ncol) = chem_surfvals_get('CO2VMR') * 1.0e+6_r8
     512       24192 :    if (co2_transport()) then
     513           0 :       do i=1,ncol
     514           0 :          cam_out%co2prog(i) = state%q(i,pver,c_i(4)) * 1.0e+6_r8 *mwdry/mwco2
     515             :       end do
     516             :    end if
     517             : 
     518             :    ! get bottom layer ozone concentrations to export to surface models
     519       24192 :    if (srf_ozone_idx > 0) then
     520       24192 :       call pbuf_get_field(pbuf, srf_ozone_idx, srf_o3_ptr)
     521      314496 :       cam_out%ozone(:ncol) = srf_o3_ptr(:ncol)
     522           0 :    else if (.not.simple_phys) then
     523           0 :       call rad_cnst_get_gas(0, 'O3', state, pbuf, o3_ptr)
     524           0 :       cam_out%ozone(:ncol) = o3_ptr(:ncol,pver) * mwdry/mwo3 ! mole/mole
     525             :    endif
     526             : 
     527             :    ! get cloud to ground lightning flash freq (/min) to export to surface models
     528       24192 :    if (lightning_idx>0) then
     529       24192 :       call pbuf_get_field(pbuf, lightning_idx, lightning_ptr)
     530      314496 :       cam_out%lightning_flash_freq(:ncol) = lightning_ptr(:ncol)
     531             :    end if
     532             : 
     533             :    !
     534             :    ! Precipation and snow rates from shallow convection, deep convection and stratiform processes.
     535             :    ! Compute total convective and stratiform precipitation and snow rates
     536             :    !
     537      314496 :    do i=1,ncol
     538      290304 :       cam_out%precc (i) = 0._r8
     539      290304 :       cam_out%precl (i) = 0._r8
     540      290304 :       cam_out%precsc(i) = 0._r8
     541      290304 :       cam_out%precsl(i) = 0._r8
     542      290304 :       if (prec_dp_idx > 0) then
     543      290304 :         cam_out%precc (i) = cam_out%precc (i) + prec_dp(i)
     544             :       end if
     545      290304 :       if (prec_sh_idx > 0) then
     546      290304 :         cam_out%precc (i) = cam_out%precc (i) + prec_sh(i)
     547             :       end if
     548      290304 :       if (prec_sed_idx > 0) then
     549      290304 :         cam_out%precl (i) = cam_out%precl (i) + prec_sed(i)
     550             :       end if
     551      290304 :       if (prec_pcw_idx > 0) then
     552      290304 :         cam_out%precl (i) = cam_out%precl (i) + prec_pcw(i)
     553             :       end if
     554      290304 :       if (snow_dp_idx > 0) then
     555      290304 :         cam_out%precsc(i) = cam_out%precsc(i) + snow_dp(i)
     556             :       end if
     557      290304 :       if (snow_sh_idx > 0) then
     558      290304 :         cam_out%precsc(i) = cam_out%precsc(i) + snow_sh(i)
     559             :       end if
     560      290304 :       if (snow_sed_idx > 0) then
     561      290304 :         cam_out%precsl(i) = cam_out%precsl(i) + snow_sed(i)
     562             :       end if
     563      290304 :       if (snow_pcw_idx > 0) then
     564      290304 :         cam_out%precsl(i) = cam_out%precsl(i) + snow_pcw(i)
     565             :       end if
     566             : 
     567             :       ! jrm These checks should not be necessary if they exist in the parameterizations
     568      290304 :       if (cam_out%precc(i) .lt.0._r8) cam_out%precc(i)=0._r8
     569      290304 :       if (cam_out%precl(i) .lt.0._r8) cam_out%precl(i)=0._r8
     570      290304 :       if (cam_out%precsc(i).lt.0._r8) cam_out%precsc(i)=0._r8
     571      290304 :       if (cam_out%precsl(i).lt.0._r8) cam_out%precsl(i)=0._r8
     572      290304 :       if (cam_out%precsc(i).gt.cam_out%precc(i)) cam_out%precsc(i)=cam_out%precc(i)
     573      314496 :       if (cam_out%precsl(i).gt.cam_out%precl(i)) cam_out%precsl(i)=cam_out%precl(i)
     574             : 
     575             :    end do
     576             : 
     577       48384 : end subroutine cam_export
     578             : 
     579       24192 : end module camsrfexch

Generated by: LCOV version 1.14