Skip to content

Commit

Permalink
initial mods to pass ozone concetrations to surf models
Browse files Browse the repository at this point in the history
        modified:   bld/build-namelist
        modified:   cime_config/buildnml
        modified:   src/control/camsrfexch.F90
        modified:   src/cpl/nuopc/atm_import_export.F90
  • Loading branch information
fvitt committed Jul 17, 2021
1 parent 8f93d2a commit 0e18de3
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 30 deletions.
12 changes: 10 additions & 2 deletions bld/build-namelist
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ GetOptions(
"uc|use_case=s" => \$opts{'use_case'},
"v|verbose" => \$opts{'verbose'},
"version" => \$opts{'version'},
"cmeps" => \$opts{'cmeps'},
) or usage();

# Give usage message.
Expand Down Expand Up @@ -3843,8 +3844,15 @@ foreach my $name (@nl_groups) { $nl_group{$name} = ''; }

# Dry deposition, MEGAN VOC emis and ozone namelists
@comp_groups = qw(drydep_inparm megan_emis_nl fire_emis_nl carma_inparm ndep_inparm ozone_coupling_nl);
# FIXME The following add_default call needs to be moved and the right logic needs to be put in place
add_default($nl, 'atm_ozone_frequency', 'val'=>'monthly_interpolated');

# nature of ozone data passed to surface models -- only if cmeps (nuopc) coupling is used
if ($opts{'cmeps'}) {
if ($rad_prog_ozone) {
add_default($nl, 'atm_ozone_frequency', 'val'=>'instantaneous');
} else {
add_default($nl, 'atm_ozone_frequency', 'val'=>'monthly_interpolated');
}
}
$outfile = "$opts{'dir'}/drv_flds_in";
$nl->write($outfile, 'groups'=>\@comp_groups);
if ($print>=1) {
Expand Down
4 changes: 4 additions & 0 deletions cime_config/buildnml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def buildnml(case, caseroot, compname):
RUN_REFCASE = case.get_value("RUN_REFCASE")
RUN_REFDATE = case.get_value("RUN_REFDATE")
RUN_REFTOD = case.get_value("RUN_REFTOD")
COMP_INTERFACE = case.get_value("COMP_INTERFACE")

testsrc = os.path.join(srcroot, "components", "cam")
if os.path.exists(testsrc):
Expand Down Expand Up @@ -168,6 +169,9 @@ def buildnml(case, caseroot, compname):
buildnl_opts += ["-namelist",
'" &atmexp ' + CAM_NAMELIST_OPTS + '/" ']

if COMP_INTERFACE == 'nuopc':
buildnl_opts.append("-cmeps")

cmd = os.path.join(srcroot, "bld", "build-namelist")
cmd += " " + " ".join(buildnl_opts)

Expand Down
65 changes: 37 additions & 28 deletions src/control/camsrfexch.F90
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ module camsrfexch
! This is the data that is sent from the atmosphere to the surface models
!---------------------------------------------------------------------------

type cam_out_t
type cam_out_t
integer :: lchnk ! chunk index
integer :: ncol ! number of columns in chunk
real(r8) :: tbot(pcols) ! bot level temperature
Expand All @@ -46,20 +46,21 @@ module camsrfexch
real(r8) :: vbot(pcols) ! bot level v wind
real(r8) :: qbot(pcols,pcnst) ! bot level specific humidity
real(r8) :: pbot(pcols) ! bot level pressure
real(r8) :: rho(pcols) ! bot level density
real(r8) :: netsw(pcols) !
real(r8) :: flwds(pcols) !
real(r8) :: rho(pcols) ! bot level density
real(r8) :: netsw(pcols) !
real(r8) :: flwds(pcols) !
real(r8) :: precsc(pcols) !
real(r8) :: precsl(pcols) !
real(r8) :: precc(pcols) !
real(r8) :: precl(pcols) !
real(r8) :: soll(pcols) !
real(r8) :: sols(pcols) !
real(r8) :: precc(pcols) !
real(r8) :: precl(pcols) !
real(r8) :: soll(pcols) !
real(r8) :: sols(pcols) !
real(r8) :: solld(pcols) !
real(r8) :: solsd(pcols) !
real(r8) :: thbot(pcols) !
real(r8) :: thbot(pcols) !
real(r8) :: co2prog(pcols) ! prognostic co2
real(r8) :: co2diag(pcols) ! diagnostic co2
real(r8) :: ozone(pcols) ! surface ozone concentration (ppbv)
real(r8) :: psl(pcols)
real(r8) :: bcphiwet(pcols) ! wet deposition of hydrophilic black carbon
real(r8) :: bcphidry(pcols) ! dry deposition of hydrophilic black carbon
Expand All @@ -77,13 +78,13 @@ module camsrfexch
real(r8) :: dstdry4(pcols) ! dry deposition of dust (bin4)
real(r8), pointer, dimension(:) :: nhx_nitrogen_flx ! nitrogen deposition fluxes (kgN/m2/s)
real(r8), pointer, dimension(:) :: noy_nitrogen_flx ! nitrogen deposition fluxes (kgN/m2/s)
end type cam_out_t
end type cam_out_t

!---------------------------------------------------------------------------
! This is the merged state of sea-ice, land and ocean surface parameterizations
!---------------------------------------------------------------------------

type cam_in_t
type cam_in_t
integer :: lchnk ! chunk index
integer :: ncol ! number of active columns
real(r8) :: asdir(pcols) ! albedo: shortwave, direct
Expand All @@ -96,11 +97,11 @@ module camsrfexch
real(r8) :: wsx(pcols) ! surface u-stress (N)
real(r8) :: wsy(pcols) ! surface v-stress (N)
real(r8) :: tref(pcols) ! ref height surface air temp
real(r8) :: qref(pcols) ! ref height specific humidity
real(r8) :: qref(pcols) ! ref height specific humidity
real(r8) :: u10(pcols) ! 10m wind speed
real(r8) :: ts(pcols) ! merged surface temp
real(r8) :: ts(pcols) ! merged surface temp
real(r8) :: sst(pcols) ! sea surface temp
real(r8) :: snowhland(pcols) ! snow depth (liquid water equivalent) over land
real(r8) :: snowhland(pcols) ! snow depth (liquid water equivalent) over land
real(r8) :: snowhice(pcols) ! snow depth over ice
real(r8) :: fco2_lnd(pcols) ! co2 flux from lnd
real(r8) :: fco2_ocn(pcols) ! co2 flux from ocn
Expand All @@ -120,7 +121,7 @@ module camsrfexch
real(r8), pointer, dimension(:,:) :: meganflx ! MEGAN fluxes
real(r8), pointer, dimension(:,:) :: fireflx ! wild fire emissions
real(r8), pointer, dimension(:) :: fireztop ! wild fire emissions vert distribution top
end type cam_in_t
end type cam_in_t

!===============================================================================
CONTAINS
Expand All @@ -142,7 +143,7 @@ subroutine hub2atm_alloc( cam_in )
integer :: c ! chunk index
integer :: ierror ! Error code
character(len=*), parameter :: sub = 'hub2atm_alloc'
!-----------------------------------------------------------------------
!-----------------------------------------------------------------------

if ( .not. phys_grid_initialized() ) call endrun(sub//": phys_grid not called yet")
allocate (cam_in(begchunk:endchunk), stat=ierror)
Expand All @@ -160,8 +161,8 @@ subroutine hub2atm_alloc( cam_in )
nullify(cam_in(c)%meganflx)
nullify(cam_in(c)%fireflx)
nullify(cam_in(c)%fireztop)
enddo
do c = begchunk,endchunk
enddo
do c = begchunk,endchunk
if (active_Sl_ram1) then
allocate (cam_in(c)%ram1(pcols), stat=ierror)
if ( ierror /= 0 ) call endrun(sub//': allocation error ram1')
Expand All @@ -186,14 +187,14 @@ subroutine hub2atm_alloc( cam_in )
end do

if (lnd_drydep .and. n_drydep>0) then
do c = begchunk,endchunk
do c = begchunk,endchunk
allocate (cam_in(c)%depvel(pcols,n_drydep), stat=ierror)
if ( ierror /= 0 ) call endrun(sub//': allocation error depvel')
end do
endif

if (active_Fall_flxfire .and. shr_fire_emis_mechcomps_n>0) then
do c = begchunk,endchunk
do c = begchunk,endchunk
allocate(cam_in(c)%fireflx(pcols,shr_fire_emis_mechcomps_n), stat=ierror)
if ( ierror /= 0 ) call endrun(sub//': allocation error fireflx')
allocate(cam_in(c)%fireztop(pcols), stat=ierror)
Expand Down Expand Up @@ -267,7 +268,7 @@ subroutine atm2hub_alloc( cam_out )
integer :: c ! chunk index
integer :: ierror ! Error code
character(len=*), parameter :: sub = 'atm2hub_alloc'
!-----------------------------------------------------------------------
!-----------------------------------------------------------------------

if (.not. phys_grid_initialized()) call endrun(sub//": phys_grid not called yet")
allocate (cam_out(begchunk:endchunk), stat=ierror)
Expand Down Expand Up @@ -300,6 +301,7 @@ subroutine atm2hub_alloc( cam_out )
cam_out(c)%thbot(:) = 0._r8
cam_out(c)%co2prog(:) = 0._r8
cam_out(c)%co2diag(:) = 0._r8
cam_out(c)%ozone(:) = 0._r8
cam_out(c)%psl(:) = 0._r8
cam_out(c)%bcphidry(:) = 0._r8
cam_out(c)%bcphodry(:) = 0._r8
Expand Down Expand Up @@ -338,7 +340,7 @@ end subroutine atm2hub_alloc
subroutine atm2hub_deallocate(cam_out)

type(cam_out_t), pointer :: cam_out(:) ! Atmosphere to surface input
!-----------------------------------------------------------------------
!-----------------------------------------------------------------------

if(associated(cam_out)) then
deallocate(cam_out)
Expand All @@ -354,7 +356,7 @@ subroutine hub2atm_deallocate(cam_in)
type(cam_in_t), pointer :: cam_in(:) ! Atmosphere to surface input

integer :: c
!-----------------------------------------------------------------------
!-----------------------------------------------------------------------

if(associated(cam_in)) then
do c=begchunk,endchunk
Expand Down Expand Up @@ -382,7 +384,7 @@ subroutine hub2atm_deallocate(cam_in)
deallocate(cam_in(c)%depvel)
nullify(cam_in(c)%depvel)
end if

enddo

deallocate(cam_in)
Expand All @@ -403,14 +405,15 @@ subroutine cam_export(state,cam_out,pbuf)
use cam_history, only: outfld
use chem_surfvals, only: chem_surfvals_get
use co2_cycle, only: co2_transport, c_i
use physconst, only: rair, mwdry, mwco2, gravit
use physconst, only: rair, mwdry, mwco2, gravit, mwo3
use constituents, only: pcnst
use physics_buffer, only: pbuf_get_index, pbuf_get_field, physics_buffer_desc
use rad_constituents, only: rad_cnst_get_gas

implicit none

! Input arguments
type(physics_state), intent(in) :: state
type(physics_state), intent(in) :: state
type (cam_out_t), intent(inout) :: cam_out
type(physics_buffer_desc), pointer :: pbuf(:)

Expand All @@ -434,6 +437,7 @@ subroutine cam_export(state,cam_out,pbuf)
real(r8), pointer :: snow_sed(:) ! snow from ZM convection
real(r8), pointer :: prec_pcw(:) ! total precipitation from Hack convection
real(r8), pointer :: snow_pcw(:) ! snow from Hack convection
real(r8), pointer :: o3_ptr(:,:)
!-----------------------------------------------------------------------

lchnk = state%lchnk
Expand Down Expand Up @@ -489,16 +493,21 @@ subroutine cam_export(state,cam_out,pbuf)
end do
do m = 1, pcnst
do i = 1, ncol
cam_out%qbot(i,m) = state%q(i,pver,m)
cam_out%qbot(i,m) = state%q(i,pver,m)
end do
end do

cam_out%co2diag(:ncol) = chem_surfvals_get('CO2VMR') * 1.0e+6_r8
cam_out%co2diag(:ncol) = chem_surfvals_get('CO2VMR') * 1.0e+6_r8
if (co2_transport()) then
do i=1,ncol
cam_out%co2prog(i) = state%q(i,pver,c_i(4)) * 1.0e+6_r8 *mwdry/mwco2
end do
end if

! get bottom layer ozone concentrations to export to surface models
call rad_cnst_get_gas(0, 'O3', state, pbuf, o3_ptr)
cam_out%ozone(:ncol) = o3_ptr(:ncol,pver) * 1.0e+9_r8 * mwdry/mwo3 ! ppbv

!
! Precipation and snow rates from shallow convection, deep convection and stratiform processes.
! Compute total convective and stratiform precipitation and snow rates
Expand Down
14 changes: 14 additions & 0 deletions src/cpl/nuopc/atm_import_export.F90
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ subroutine advertise_fields(gcomp, flds_scalar_name, rc)
call fldlist_add(fldsFrAtm_num, fldsFrAtm, 'Sa_pbot' )
call fldlist_add(fldsFrAtm_num, fldsFrAtm, 'Sa_dens' )
call fldlist_add(fldsFrAtm_num, fldsFrAtm, 'Sa_pslv' )
call fldlist_add(fldsFrAtm_num, fldsFrAtm, 'Sa_o3' )
call fldlist_add(fldsFrAtm_num, fldsFrAtm, 'Faxa_rainc' )
call fldlist_add(fldsFrAtm_num, fldsFrAtm, 'Faxa_rainl' )
call fldlist_add(fldsFrAtm_num, fldsFrAtm, 'Faxa_snowc' )
Expand Down Expand Up @@ -869,6 +870,7 @@ subroutine export_fields( gcomp, cam_out, rc)
real(r8), pointer :: fldptr_shum(:) , fldptr_dens(:)
real(r8), pointer :: fldptr_ptem(:) , fldptr_pslv(:)
real(r8), pointer :: fldptr_co2prog(:) , fldptr_co2diag(:)
real(r8), pointer :: fldptr_ozone(:)
character(len=*), parameter :: subname='(atm_import_export:export_fields)'
!---------------------------------------------------------------------------

Expand Down Expand Up @@ -986,6 +988,18 @@ subroutine export_fields( gcomp, cam_out, rc)
end do
end do

call state_getfldptr(exportState, 'Sa_o3', fldptr=fldptr_ozone, exists=exists, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (exists) then
g = 1
do c = begchunk,endchunk
do i = 1,get_ncols_p(c)
fldptr_ozone(g) = cam_out(c)%ozone(i) ! atm ozone
g = g + 1
end do
end do
end if

call state_getfldptr(exportState, 'Sa_co2prog', fldptr=fldptr_co2prog, exists=exists, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (exists) then
Expand Down

0 comments on commit 0e18de3

Please sign in to comment.