Skip to content

Add a chemistry package structure #1338

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 11 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions src/core_atmosphere/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,35 @@

#
# To build a dycore-only MPAS-Atmosphere model, comment-out or delete
# the definition of PHYSICS, below
# the definition of PHYSICS and CHEMISTRY, below
#
# If MPAS_CAM_DYCORE is found in CPPFLAGS, PHYSICS will become undefined automatically
# If MPAS_CAM_DYCORE is found in CPPFLAGS, PHYSICS and CHEMISTRY will become undefined automatically
#
ifeq ($(findstring MPAS_CAM_DYCORE,$(CPPFLAGS)),)
PHYSICS = -DDO_PHYSICS
CHEMISTRY = -DDO_CHEMISTRY
endif

ifdef PHYSICS
PHYSCORE = physcore
PHYS_OBJS = libphys/*.o
endif

ifdef CHEMISTRY
CHEMCORE = chemcore
CHEM_OBJS = libchem/*.o
endif

OBJS = mpas_atm_core.o \
mpas_atm_core_interface.o \
mpas_atm_dimensions.o \
mpas_atm_threading.o \
mpas_atm_halos.o

all: $(PHYSCORE) dycore diagcore atmcore utilities
all: $(PHYSCORE) $(CHEMCORE) dycore diagcore atmcore utilities

core_reg:
$(CPP) $(CPPFLAGS) $(CPPINCLUDES) $(PHYSICS) Registry.xml > Registry_processed.xml
$(CPP) $(CPPFLAGS) $(CPPINCLUDES) $(PHYSICS) $(CHEMISTRY) Registry.xml > Registry_processed.xml

core_input_gen:
if [ ! -e default_inputs ]; then mkdir default_inputs; fi
Expand All @@ -47,17 +53,21 @@ physcore: mpas_atm_dimensions.o
( cd ../..; ln -sf ./src/core_atmosphere/physics/physics_wrf/files/*DATA* .)
( cd ../..; ln -sf ./src/core_atmosphere/physics/physics_noahmp/parameters/*TBL .)

dycore: mpas_atm_dimensions.o $(PHYSCORE)
( cd dynamics; $(MAKE) all PHYSICS="$(PHYSICS)" )
chemcore: mpas_atm_dimensions.o
( cd chemistry; $(MAKE) all )
( mkdir libchem; cd libchem; ar -x ../chemistry/libchem.a )

dycore: mpas_atm_dimensions.o $(PHYSCORE) $(CHEMCORE)
( cd dynamics; $(MAKE) all PHYSICS="$(PHYSICS)"; $(MAKE) all CHEMISTRY="$(CHEMISTRY)" )

diagcore: $(PHYSCORE) dycore
( cd diagnostics; $(MAKE) all PHYSICS="$(PHYSICS)" )
diagcore: $(PHYSCORE) $(CHEMCORE) dycore
( cd diagnostics; $(MAKE) all PHYSICS="$(PHYSICS)"; $(MAKE) all CHEMISTRY="$(CHEMISTRY)" )

utilities: $(PHYSCORE)
( cd utils; $(MAKE) all PHYSICS="$(PHYSICS)" )
utilities: $(PHYSCORE) $(CHEMCORE)
( cd utils; $(MAKE) all PHYSICS="$(PHYSICS)"; $(MAKE) all CHEMISTRY="$(CHEMISTRY)" )

atmcore: $(PHYSCORE) dycore diagcore $(OBJS)
ar -ru libdycore.a $(OBJS) dynamics/*.o $(PHYS_OBJS) diagnostics/*.o
atmcore: $(PHYSCORE) $(CHEMCORE) dycore diagcore $(OBJS)
ar -ru libdycore.a $(OBJS) dynamics/*.o $(PHYS_OBJS) $(CHEM_OBJS) diagnostics/*.o

mpas_atm_core_interface.o: mpas_atm_core.o

Expand All @@ -67,6 +77,7 @@ mpas_atm_dimensions.o:

clean:
( cd physics; $(MAKE) clean )
( cd chemistry; $(MAKE) clean )
( cd dynamics; $(MAKE) clean )
( cd diagnostics; $(MAKE) clean )
( cd utils; $(MAKE) clean )
Expand Down
26 changes: 24 additions & 2 deletions src/core_atmosphere/Registry.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1672,7 +1672,18 @@

<var name="nwfa" array_group="number" units="nb kg^{-1}"
description="Water-friendly aerosol number concentration"
packages="mp_thompson_aers_in"/>
packages="mp_thompson_aers_in"/>

<!-- rkumar_chem_start -->
<var name="o3" array_group="chem" units="ppmv"
description="ozone mixing ratio"/>

<var name="no" array_group="chem" units="ppmv"
description="NO mixing ratio"/>

<var name="no2" array_group="chem" units="ppmv"
description="NO2 mixing ratio"/>
<!-- rkumar_chem_end -->
</var_array>
#endif

Expand Down Expand Up @@ -2023,7 +2034,18 @@

<var name="tend_nwfa" name_in_code="nwfa" array_group="number" units="nb m^{-3} s^{-1}"
description="Tendency of water-friendly aerosol number concentration multiplied by dry air density divided by d(zeta)/dz"
packages="mp_thompson_aers_in"/>
packages="mp_thompson_aers_in"/>

<!-- rkumar_chem_start -->
<var name="tend_o3" name_in_code="o3" array_group="chem" units="ppmv s^{-1}"
description="Tendency of o3 mixing ratios"/>

<var name="tend_no" name_in_code="no" array_group="chem" units="ppmv s^{-1}"
description="Tendency of no mixing ratios"/>

<var name="tend_no2" name_in_code="no2" array_group="chem" units="ppmv s^{-1}"
description="Tendency of no2 mixing ratios"/>
<!-- rkumar_chem_end -->
</var_array>
#endif
</var_struct>
Expand Down
41 changes: 41 additions & 0 deletions src/core_atmosphere/chemistry/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
.SUFFIXES: .F .o

ifeq ($(CORE),atmosphere)
COREDEF = -Dmpas
endif

all:
./../tools/manage_externals/checkout_externals --externals ./../Externals.cfg
$(MAKE) core_mpas_musica core_chemistry

dummy:
echo "****** compiling chemistry ******"

OBJS = \
mpas_atmchem_control.o

core_mpas_musica:
(cd musica; $(MAKE) all COREDEF="$(COREDEF)")

core_chemistry: core_mpas_musica
($(MAKE) chem_interface COREDEF="$(COREDEF)")
ar -ru libchem.a $(OBJS)
($(MAKE) -C ./musica mpas_musica_lib)

chem_interface: $(OBJS)

clean:
$(RM) *.o *.mod *.f90 libchem.a
( cd musica; $(MAKE) clean )
@# Certain systems with intel compilers generate *.i files
@# This removes them during the clean process
$(RM) *.i

.F.o:
$(RM) $@ $*.mod
ifeq "$(GEN_F90)" "true"
$(CPP) $(CPPFLAGS) $(COREDEF) $(HYDROSTATIC) $(CPPINCLUDES) $< > $*.f90
$(FC) $(FFLAGS) -c $*.f90 $(FCINCLUDES) -I./musica -I.. -I../../../framework -I../../../external/esmf_time_f90
else
$(FC) $(CPPFLAGS) $(COREDEF) $(HYDROSTATIC) $(FFLAGS) -c $*.F $(CPPINCLUDES) $(FCINCLUDES) -I./musica -I.. -I../../../framework -I../../../external/esmf_time_f90
endif
37 changes: 37 additions & 0 deletions src/core_atmosphere/chemistry/mpas_atmchem_control.F
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
! Copyright (c) 2025, Los Alamos National Security, LLC (LANS)
! and the University Corporation for Atmospheric Research (UCAR).
!
! Unless noted otherwise source code is licensed under the BSD license.
! Additional copyright and license information can be found in the LICENSE file
! distributed with this code, or at http://mpas-dev.github.com/license.html
!
!=================================================================================================================
module mpas_atmchem_control


implicit none
private
public:: chemistry_setup_packages

!MPAS chemistry package configuration routines.
!ACOM Software Engineering Team 2025
!
! subroutines in mpas_atmchem_init:
! ---------------------------------
! chemistry_setup_packages : identifies available chemistry packages

contains


!=================================================================================================================
subroutine chemistry_setup_packages()
!=================================================================================================================
use mpas_musica, only : log_musica_support

call log_musica_support()

end subroutine chemistry_setup_packages

!=================================================================================================================
end module mpas_atmchem_control
!=================================================================================================================
30 changes: 30 additions & 0 deletions src/core_atmosphere/chemistry/musica/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.SUFFIXES: .F .o

.PHONY: mpas_musica mpas_musica_lib

all: dummy mpas_musica

dummy:
echo "****** compiling mpas_musica ******"

OBJS = \
mpas_musica.o

mpas_musica: $(OBJS)

mpas_musica_lib:
ar -ru ./../libchem.a $(OBJS)

clean:
$(RM) *.f90 *.o *.mod
@# Certain systems with intel compilers generate *.i files
@# This removes them during the clean process
$(RM) *.i

.F.o:
ifeq "$(GEN_F90)" "true"
$(CPP) $(CPPFLAGS) $(COREDEF) $(CPPINCLUDES) $< > $*.f90
$(FC) $(FFLAGS) -c $*.f90 $(FCINCLUDES) -I.. -I../../../framework -I../../../external/esmf_time_f90
else
$(FC) $(CPPFLAGS) $(COREDEF) $(FFLAGS) -c $*.F $(CPPINCLUDES) $(FCINCLUDES) -I.. -I../../../framework -I../../../external/esmf_time_f90
endif
49 changes: 49 additions & 0 deletions src/core_atmosphere/chemistry/musica/mpas_musica.F
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
! Copyright (c) 2025 University Corporation for Atmospheric Research
!
! Unless noted otherwise, this software is licensed under the BSD license.
! Additional copyright and license information can be found in the LICENSE file
! distributed with this code, or at http://mpas-dev.github.com/license.html
!
!=================================================================================================================
module mpas_musica
#ifdef MPAS_USE_MUSICA
use musica_micm, only : get_micm_version
use musica_util, only : string_t
#endif
use mpas_log, only: mpas_log_write

implicit none
private
public:: log_musica_support

!The MUSICA library must also be compiled and linked to the MPAS executable, This is
!typically done by first installing the MUSICA and then including the `MUSICA=true` option
!when building the MPAS atmosphere model.
!
!CURRENTLY UNDER DEVELOPMENT
!
!ACOM Software Engineering Team 2025


contains


!=================================================================================================================
subroutine log_musica_support()
!=================================================================================================================
#ifdef MPAS_USE_MUSICA

!local variables
type(string_t) :: version_string

version_string = get_micm_version()
call mpas_log_write("MUSICA support is available. MICM version: "//version_string%value_)
#else
call mpas_log_write("MUSICA support not available.")
#endif
end subroutine log_musica_support

!=================================================================================================================
end module mpas_musica
!=================================================================================================================

8 changes: 8 additions & 0 deletions src/core_atmosphere/mpas_atm_core_interface.F
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ function atm_setup_packages(configs, streamInfo, packages, iocontext) result(ier
use mpas_atmphys_packages
#endif

#ifdef DO_CHEMISTRY
use mpas_atmchem_control, only : chemistry_setup_packages
#endif

implicit none

type (mpas_pool_type), intent(inout) :: configs
Expand Down Expand Up @@ -259,6 +263,10 @@ function atm_setup_packages(configs, streamInfo, packages, iocontext) result(ier

#endif

#ifdef DO_CHEMISTRY
call chemistry_setup_packages()
#endif

end function atm_setup_packages


Expand Down
9 changes: 9 additions & 0 deletions src/core_init_atmosphere/Registry.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1171,6 +1171,15 @@
<var name="nwfa" array_group="number" units="nb kg^{-1}"
description="Gocart water-friendly aerosol number concentration"
packages="mp_thompson_aers_in"/>

<var name="o3" array_group="chem" units="ppmv"
description="ozone mixing ratio"/>

<var name="no" array_group="chem" units="ppmv"
description="no mixing ratio"/>

<var name="no2" array_group="chem" units="ppmv"
description="no2 mixing ratio"/>
</var_array>

<!-- Climatology for ocean mixed-layer depth -->
Expand Down
39 changes: 38 additions & 1 deletion src/core_init_atmosphere/mpas_init_atm_cases.F
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,11 @@ subroutine init_atm_setup_case(domain, stream_manager)

call init_atm_case_gfs(block_ptr, mesh, nCells, nEdges, nVertLevels, fg, state, &
diag, diag_physics, block_ptr % dimensions, block_ptr % configs)


#ifdef DO_CHEMISTRY
call init_chem(mesh, state)
#endif

if (config_met_interp) then
call init_atm_thompson_aerosols(block_ptr, mesh, block_ptr % configs, diag, state)
call physics_initialize_real(mesh, fg, domain % dminfo, block_ptr % dimensions, block_ptr % configs)
Expand Down Expand Up @@ -7522,5 +7526,38 @@ function read_text_array(dminfo, filename, xarray) result(ierr)

end function read_text_array

subroutine init_chem(mesh, state)

implicit none

type (mpas_pool_type), intent(in) :: mesh
type (mpas_pool_type), intent(inout) :: state

integer, pointer :: index_o3
integer, pointer :: index_no
integer, pointer :: index_no2
integer, pointer :: nCells
integer, pointer :: nVertLevels

integer :: k, iCell

real (kind=RKIND), dimension(:,:,:), pointer :: scalars

call mpas_log_write('====== Handling Chemistry initialization ======')

call mpas_pool_get_dimension(mesh, 'nCells', nCells)
call mpas_pool_get_dimension(mesh, 'nVertLevels', nVertLevels)

call mpas_pool_get_dimension(state, 'index_o3', index_o3)
call mpas_pool_get_dimension(state, 'index_no', index_no)
call mpas_pool_get_dimension(state, 'index_no2', index_no2)

call mpas_pool_get_array(state, 'scalars', scalars)

scalars(index_o3,:,:) = 0.1
scalars(index_no,:,:) = 0.01
scalars(index_no2,:,:) = 0.03

end subroutine init_chem

end module init_atm_cases