Skip to content

Commit

Permalink
Merge branch 'beharrop/atm/co2_profile_fix' (PR #3003)
Browse files Browse the repository at this point in the history
Modifications to preserve the vertical shape of CO2 tracers

Follows suggestions by Keith Lindsay for modifying the fix
to conserve non-water tracer species (#2883 ) so that the
nearly constant profile of CO2 is preserved.

[NBFB]

* beharrop/atm/co2_profile_fix:
  Modifications to preserve the vertical shape of CO2 tracers
  • Loading branch information
singhbalwinder committed Jul 29, 2019
2 parents 7746543 + 3a7a913 commit d4c4b23
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 18 deletions.
20 changes: 17 additions & 3 deletions components/cam/src/physics/cam/clubb_intr.F90
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,7 @@ subroutine clubb_tend_cam( &

use ppgrid, only: pver, pverp, pcols
use constituents, only: cnst_get_ind, cnst_type
use co2_cycle, only: co2_cycle_set_cnst_type
use camsrfexch, only: cam_in_t
use ref_pres, only: top_lev => trop_cloud_top_lev
use time_manager, only: is_first_step
Expand Down Expand Up @@ -1181,6 +1182,7 @@ subroutine clubb_tend_cam( &
type(pdf_parameter), dimension(pverp) :: pdf_params ! PDF parameters [units vary]
character(len=200) :: temp1, sub ! Strings needed for CLUBB output
logical :: l_Lscale_plume_centered, l_use_ice_latent
character(len=3), dimension(pcnst) :: cnst_type_loc ! local override option for constituents cnst_type


! --------------- !
Expand Down Expand Up @@ -1302,7 +1304,10 @@ subroutine clubb_tend_cam( &
call physics_state_copy(state,state1)

! constituents are all treated as wet mmr by clubb
call set_dry_to_wet(state1)
! don't convert co2 tracers to wet mixing ratios
cnst_type_loc(:) = cnst_type(:)
call co2_cycle_set_cnst_type(cnst_type_loc, 'wet')
call set_dry_to_wet(state1, cnst_type_loc)

if (micro_do_icesupersat) then
naai_idx = pbuf_get_index('NAAI')
Expand Down Expand Up @@ -2665,6 +2670,7 @@ subroutine clubb_surface (state, ptend, ztodt, cam_in, ustar, obklen)
use physconst, only: gravit, zvir, latvap
use ppgrid, only: pver, pcols
use constituents, only: pcnst, cnst_get_ind, cnst_type
use co2_cycle, only: co2_cycle_set_cnst_type
use camsrfexch, only: cam_in_t

implicit none
Expand Down Expand Up @@ -2708,6 +2714,8 @@ subroutine clubb_surface (state, ptend, ztodt, cam_in, ustar, obklen)

logical :: lq(pcnst)

character(len=3), dimension(pcnst) :: cnst_type_loc ! local override option for constituents cnst_type

#endif
obklen(pcols) = 0.0_r8
ustar(pcols) = 0.0_r8
Expand All @@ -2718,7 +2726,10 @@ subroutine clubb_surface (state, ptend, ztodt, cam_in, ustar, obklen)
! ----------------------- !

! Assume 'wet' mixing ratios in surface diffusion code.
call set_dry_to_wet(state)
! don't convert co2 tracers to wet mixing ratios
cnst_type_loc(:) = cnst_type(:)
call co2_cycle_set_cnst_type(cnst_type_loc, 'wet')
call set_dry_to_wet(state, cnst_type_loc)

call cnst_get_ind('Q',ixq)
if (use_sgv) then
Expand Down Expand Up @@ -2766,7 +2777,10 @@ subroutine clubb_surface (state, ptend, ztodt, cam_in, ustar, obklen)
endif
end do
! convert wet mmr back to dry before conservation check
call set_wet_to_dry(state)
! avoid converting co2 tracers again
cnst_type_loc(:) = cnst_type(:)
call co2_cycle_set_cnst_type(cnst_type_loc, 'wet')
call set_wet_to_dry(state, cnst_type_loc)

return

Expand Down
27 changes: 27 additions & 0 deletions components/cam/src/physics/cam/co2_cycle.F90
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module co2_cycle
public co2_init ! initialize (history) variables
public co2_time_interp_ocn ! time interpolate co2 flux
public co2_time_interp_fuel ! time interpolate co2 flux
public co2_cycle_set_cnst_type ! set co2 tracers mixing type for local versions of cnst_type

! Public data

Expand Down Expand Up @@ -317,5 +318,31 @@ subroutine co2_init_cnst(name, q, gcid)

end subroutine co2_init_cnst
!===============================================================================

subroutine co2_cycle_set_cnst_type(cnst_type_loc, cnst_type_val)

!-----------------------------------------------------------------------
!
! Purpose:
! Set a local copy of cnst_type to be 'wet' or 'dry'
!
!-----------------------------------------------------------------------
use constituents, only: pcnst

! Arguments
character(len=3), intent(inout) :: cnst_type_loc(pcnst) ! a local copy of cnst_type
character(len=3), intent(in) :: cnst_type_val ! set mmr type: 'wet' or 'dry'
integer :: m ! loop index
!-----------------------------------------------------------------------

if (.not. co2_flag) return

! set cnst_type_loc for each CO2 tracer
do m = 1, ncnst
cnst_type_loc(c_i(m)) = cnst_type_val
end do

end subroutine co2_cycle_set_cnst_type
!===============================================================================

end module co2_cycle
9 changes: 8 additions & 1 deletion components/cam/src/physics/cam/gw_drag.F90
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ subroutine gw_tend(state, sgh, pbuf, dt, ptend, cam_in)
!-----------------------------------------------------------------------
use physics_types, only: physics_state_copy, set_dry_to_wet
use constituents, only: cnst_type
use co2_cycle, only: co2_cycle_set_cnst_type
use physics_buffer, only: physics_buffer_desc, pbuf_get_field
use camsrfexch, only: cam_in_t
! Location-dependent cpair
Expand Down Expand Up @@ -661,13 +662,19 @@ subroutine gw_tend(state, sgh, pbuf, dt, ptend, cam_in)
real(r8) :: rdpm(state%ncol,pver)
real(r8) :: zm(state%ncol,pver)

! local override option for constituents cnst_type
character(len=3), dimension(pcnst) :: cnst_type_loc

!------------------------------------------------------------------------

! Make local copy of input state.
call physics_state_copy(state, state1)

! constituents are all treated as wet mmr
call set_dry_to_wet(state1)
! don't convert co2 tracers to wet mixing ratios
cnst_type_loc(:) = cnst_type(:)
call co2_cycle_set_cnst_type(cnst_type_loc, 'wet')
call set_dry_to_wet(state1, cnst_type_loc)

lchnk = state1%lchnk
ncol = state1%ncol
Expand Down
44 changes: 32 additions & 12 deletions components/cam/src/physics/cam/physics_types.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1433,41 +1433,61 @@ end subroutine set_state_pdry

!===============================================================================

subroutine set_wet_to_dry (state)
subroutine set_wet_to_dry (state, cnst_type_in)

use constituents, only: pcnst, cnst_type

type(physics_state), intent(inout) :: state
character(len=3), intent(in), optional :: cnst_type_in(pcnst) ! use a specified cnst_type instead
! of that in the module constituents

integer m, ncol

ncol = state%ncol

do m = 1,pcnst
if (cnst_type(m).eq.'dry') then
state%q(:ncol,:,m) = state%q(:ncol,:,m)*state%pdel(:ncol,:)/state%pdeldry(:ncol,:)
endif
end do
if ( present(cnst_type_in) ) then
do m = 1,pcnst
if (cnst_type_in(m).eq.'dry') then
state%q(:ncol,:,m) = state%q(:ncol,:,m)*state%pdel(:ncol,:)/state%pdeldry(:ncol,:)
endif
end do
else
do m = 1,pcnst
if (cnst_type(m).eq.'dry') then
state%q(:ncol,:,m) = state%q(:ncol,:,m)*state%pdel(:ncol,:)/state%pdeldry(:ncol,:)
endif
end do
endif

end subroutine set_wet_to_dry

!===============================================================================

subroutine set_dry_to_wet (state)
subroutine set_dry_to_wet (state, cnst_type_in)

use constituents, only: pcnst, cnst_type

type(physics_state), intent(inout) :: state
character(len=3), intent(in), optional :: cnst_type_in(pcnst) ! use a specified cnst_type instead
! of that in the module constituents

integer m, ncol

ncol = state%ncol

do m = 1,pcnst
if (cnst_type(m).eq.'dry') then
state%q(:ncol,:,m) = state%q(:ncol,:,m)*state%pdeldry(:ncol,:)/state%pdel(:ncol,:)
endif
end do
if ( present(cnst_type_in) ) then
do m = 1,pcnst
if (cnst_type_in(m).eq.'dry') then
state%q(:ncol,:,m) = state%q(:ncol,:,m)*state%pdeldry(:ncol,:)/state%pdel(:ncol,:)
endif
end do
else
do m = 1,pcnst
if (cnst_type(m).eq.'dry') then
state%q(:ncol,:,m) = state%q(:ncol,:,m)*state%pdeldry(:ncol,:)/state%pdel(:ncol,:)
endif
end do
endif

end subroutine set_dry_to_wet

Expand Down
13 changes: 11 additions & 2 deletions components/cam/src/physics/cam/vertical_diffusion.F90
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,7 @@ subroutine vertical_diffusion_tend( &
use wv_saturation, only : qsat
use molec_diff, only : compute_molec_diff, vd_lu_qdecomp
use constituents, only : qmincg, qmin, cnst_type
use co2_cycle, only : co2_cycle_set_cnst_type
use diffusion_solver, only : compute_vdiff, any, operator(.not.)
use physconst, only : cpairv, rairv !Needed for calculation of upward H flux
use time_manager, only : get_nstep
Expand Down Expand Up @@ -815,12 +816,17 @@ subroutine vertical_diffusion_tend( &

logical :: lq(pcnst)

character(len=3), dimension(pcnst) :: cnst_type_loc ! local override option for constituents cnst_type

! ----------------------- !
! Main Computation Begins !
! ----------------------- !

! Assume 'wet' mixing ratios in diffusion code.
call set_dry_to_wet(state)
! don't convert co2 tracers to wet mixing ratios
cnst_type_loc(:) = cnst_type(:)
call co2_cycle_set_cnst_type(cnst_type_loc, 'wet')
call set_dry_to_wet(state, cnst_type_loc)

rztodt = 1._r8 / ztodt
lchnk = state%lchnk
Expand Down Expand Up @@ -1226,7 +1232,10 @@ subroutine vertical_diffusion_tend( &
endif
end do
! convert wet mmr back to dry before conservation check
call set_wet_to_dry(state)
! avoid converting co2 tracers again
cnst_type_loc(:) = cnst_type(:)
call co2_cycle_set_cnst_type(cnst_type_loc, 'wet')
call set_wet_to_dry(state, cnst_type_loc)

slten(:ncol,:) = ( sl(:ncol,:) - sl_prePBL(:ncol,:) ) * rztodt
qtten(:ncol,:) = ( qt(:ncol,:) - qt_prePBL(:ncol,:) ) * rztodt
Expand Down

0 comments on commit d4c4b23

Please sign in to comment.