diff --git a/src/core_atmosphere/Makefile b/src/core_atmosphere/Makefile
index 966027bc77..48a1262273 100644
--- a/src/core_atmosphere/Makefile
+++ b/src/core_atmosphere/Makefile
@@ -2,12 +2,13 @@
#
# 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
@@ -15,16 +16,21 @@ ifdef PHYSICS
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
@@ -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
@@ -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 )
diff --git a/src/core_atmosphere/Registry.xml b/src/core_atmosphere/Registry.xml
index bdf47ec7b4..b66ebb3217 100644
--- a/src/core_atmosphere/Registry.xml
+++ b/src/core_atmosphere/Registry.xml
@@ -1672,7 +1672,18 @@
+ packages="mp_thompson_aers_in"/>
+
+
+
+
+
+
+
+
#endif
@@ -2023,7 +2034,18 @@
+ packages="mp_thompson_aers_in"/>
+
+
+
+
+
+
+
+
#endif
diff --git a/src/core_atmosphere/chemistry/Makefile b/src/core_atmosphere/chemistry/Makefile
new file mode 100644
index 0000000000..f5b4bde970
--- /dev/null
+++ b/src/core_atmosphere/chemistry/Makefile
@@ -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
diff --git a/src/core_atmosphere/chemistry/mpas_atmchem_control.F b/src/core_atmosphere/chemistry/mpas_atmchem_control.F
new file mode 100644
index 0000000000..2f022edaa7
--- /dev/null
+++ b/src/core_atmosphere/chemistry/mpas_atmchem_control.F
@@ -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
+!=================================================================================================================
\ No newline at end of file
diff --git a/src/core_atmosphere/chemistry/musica/Makefile b/src/core_atmosphere/chemistry/musica/Makefile
new file mode 100644
index 0000000000..4e30424426
--- /dev/null
+++ b/src/core_atmosphere/chemistry/musica/Makefile
@@ -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
\ No newline at end of file
diff --git a/src/core_atmosphere/chemistry/musica/mpas_musica.F b/src/core_atmosphere/chemistry/musica/mpas_musica.F
new file mode 100644
index 0000000000..aa755e4f7a
--- /dev/null
+++ b/src/core_atmosphere/chemistry/musica/mpas_musica.F
@@ -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
+!=================================================================================================================
+
diff --git a/src/core_atmosphere/mpas_atm_core_interface.F b/src/core_atmosphere/mpas_atm_core_interface.F
index 21c651905e..e5a8d8c352 100644
--- a/src/core_atmosphere/mpas_atm_core_interface.F
+++ b/src/core_atmosphere/mpas_atm_core_interface.F
@@ -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
@@ -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
diff --git a/src/core_init_atmosphere/Registry.xml b/src/core_init_atmosphere/Registry.xml
index 40b1c144ee..87cf1ac5c8 100644
--- a/src/core_init_atmosphere/Registry.xml
+++ b/src/core_init_atmosphere/Registry.xml
@@ -1171,6 +1171,15 @@
+
+
+
+
+
+
diff --git a/src/core_init_atmosphere/mpas_init_atm_cases.F b/src/core_init_atmosphere/mpas_init_atm_cases.F
index 5ab57e4194..d4cec87782 100644
--- a/src/core_init_atmosphere/mpas_init_atm_cases.F
+++ b/src/core_init_atmosphere/mpas_init_atm_cases.F
@@ -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)
@@ -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