Getting Started
August 21, 2026 ยท View on GitHub
Model Independent Chemical Module. MICM can be used to configure and solve atmospheric chemistry systems.
Note MICM 3.x.x is part of a refactor and may include breaking changes across minor revision numbers and partially implemented features
Getting Started
Installing MICM locally
To build and install MICM locally, you must have CMake installed on your machine.
Open a terminal window, navigate to a folder where you would like the MICM files to exist, and run the following commands:
git clone https://github.com/NCAR/micm.git
cd micm
mkdir build
cd build
ccmake ..
sudo make install -j 8
To run the tests:
make test
If you would later like to uninstall MICM, you can run
sudo make uninstall from the build/ directory.
Options
There are multiple options for running micm. You can use our
solvers on CPUs, cuda-based solvers to solve chemistry on GPUs,
or Kokkos-based solvers for performance portability across CPUs and GPUs
(-DMICM_ENABLE_KOKKOS=ON; see the
Kokkos guide).
Please read our docs
to learn how to enable these options.
Third-party components fetched at build time (Kokkos, GoogleTest) are listed in NOTICE along with their licenses.
Running a MICM Docker container
You must have Docker Desktop installed and running. With Docker Desktop running, open a terminal window. To build the latest MICM release, run the following command to start the MICM container:
docker run -it ghcr.io/ncar/micm:release bash
To build the latest pre-release version of MICM, instead run:
git clone https://github.com/NCAR/micm.git
cd micm
docker build -t micm -f docker/Dockerfile .
docker run -it micm bash
Inside the container, you can run the MICM tests from the /build/ folder:
cd /build/
make test
Using the MICM API
The following example solves the fictitious chemical system:
foo --k1--> 0.8 bar + 0.2 baz
foo + bar --k2--> baz
The k1 and k2 rate constants are for Arrhenius reactions. See the MICM documentation for details on the types of reactions available in MICM and how to configure them.
To solve this system save the following code in a file named foo_chem.cpp:
#include <micm/process/chemical_reaction_builder.hpp>
#include <micm/process/rate_constant/arrhenius_rate_constant.hpp>
#include <micm/solver/rosenbrock.hpp>
#include <micm/solver/solver_builder.hpp>
#include <iomanip>
#include <iostream>
using namespace micm;
int main(const int argc, const char *argv[])
{
auto foo = Species{ "Foo" };
auto bar = Species{ "Bar" };
auto baz = Species{ "Baz" };
Phase gas_phase{ "gas", std::vector<PhaseSpecies>{ foo, bar, baz } };
System chemical_system{ gas_phase };
Process r1 = ChemicalReactionBuilder()
.SetReactants({ foo })
.SetProducts({ StoichSpecies(bar, 0.8), StoichSpecies(baz, 0.2) })
.SetRateConstant(ArrheniusRateConstantParameters{ .A_ = 1.0e-3 })
.SetPhase(gas_phase)
.Build();
Process r2 = ChemicalReactionBuilder()
.SetReactants({ foo, bar })
.SetProducts({ StoichSpecies(baz, 1) })
.SetRateConstant(ArrheniusRateConstantParameters{ .A_ = 1.0e-5, .C_ = 110.0 })
.SetPhase(gas_phase)
.Build();
std::vector<Process> reactions{ r1, r2 };
auto solver = micm::CpuSolverBuilder<micm::RosenbrockSolverParameters>(micm::RosenbrockSolverParameters::ThreeStageRosenbrockParameters())
.SetSystem(chemical_system)
.SetReactions(reactions)
.Build();
State state = solver.GetState();
state.conditions_[0].temperature_ = 287.45; // K
state.conditions_[0].pressure_ = 101319.9; // Pa
state.conditions_[0].CalculateIdealAirDensity();
state[foo] = 20.0; // mol m-3
state.PrintHeader();
for (int i = 0; i < 10; ++i)
{
solver.UpdateStateParameters(state);
auto result = solver.Solve(500.0, state);
state.PrintState(i * 500);
}
return 0;
}
To build and run the example using GNU (assuming the default install location):
g++ -o foo_chem foo_chem.cpp -I/usr/local/micm-3.13.0/include -std=c++20
./foo_chem
Output:
time, Foo, Bar, Baz
0, 1.18e+01, 5.90e+00, 1.91e+00
500, 6.79e+00, 9.05e+00, 3.32e+00
1000, 3.83e+00, 1.07e+01, 4.21e+00
1500, 2.14e+00, 1.17e+01, 4.74e+00
2000, 1.19e+00, 1.22e+01, 5.04e+00
2500, 6.58e-01, 1.24e+01, 5.21e+00
3000, 3.64e-01, 1.26e+01, 5.31e+00
3500, 2.01e-01, 1.27e+01, 5.36e+00
4000, 1.11e-01, 1.27e+01, 5.39e+00
4500, 6.13e-02, 1.28e+01, 5.41e+00
Performance
Every push to main records the benchmark and publishes the history as a chart.
Instruction counts come from callgrind and are deterministic, so they show a
hot-path change even when the wall-clock time is noisy.
Two mechanisms run. Chapman has 7 reactions and shows per-call overhead. TS1 has 547 reactions and shows how the solver scales with mechanism size.
| chart | mechanism | backend | grid cells | steps | machine |
|---|---|---|---|---|---|
| Instruction counts | Chapman | CPU | 2000 | 5 | ubuntu-latest |
| Wall-clock timing | Chapman | CPU | 10000 | 30 | ubuntu-latest |
| Instruction counts | TS1 | CPU | 2000 | 5 | ubuntu-latest |
| Wall-clock timing | TS1 | CPU | 10000 | 30 | ubuntu-latest |
| Wall-clock timing | Chapman and TS1 | CUDA | 10000 | 30 | CIRRUS a10 GPU runner |
| Wall-clock timing | Chapman and TS1 | Kokkos | 10000 | 30 | CIRRUS a10 GPU runner |
Every step advances the solver by 30 s. The callgrind charts use a smaller
grid and fewer steps, because valgrind runs far slower than a native run. The
vector128 ordering pads its last group, so it solves 2048 cells rather than
2000, and 10112 rather than 10000.
Each pull request also gets a commit comment that compares its Chapman numbers
against the latest main values. See docs/performance.md
to run the benchmark yourself.
Citation
MICM is part of the MUSICA project and can be cited by reference to the MUSICA vision paper. The BibTeX entry below can be used to generate a citation for this.
@Article { acom.software.musica-vision,
author = "Gabriele G. Pfister and Sebastian D. Eastham and Avelino F. Arellano and Bernard Aumont and Kelley C. Barsanti and Mary C. Barth and Andrew Conley and Nicholas A. Davis and Louisa K. Emmons and Jerome D. Fast and Arlene M. Fiore and Benjamin Gaubert and Steve Goldhaber and Claire Granier and Georg A. Grell and Marc Guevara and Daven K. Henze and Alma Hodzic and Xiaohong Liu and Daniel R. Marsh and John J. Orlando and John M. C. Plane and Lorenzo M. Polvani and Karen H. Rosenlof and Allison L. Steiner and Daniel J. Jacob and Guy P. Brasseur",
title = "The Multi-Scale Infrastructure for Chemistry and Aerosols (MUSICA)",
journal = "Bulletin of the American Meteorological Society",
year = "2020",
publisher = "American Meteorological Society",
address = "Boston MA, USA",
volume = "101",
number = "10",
doi = "10.1175/BAMS-D-19-0331.1",
pages= "E1743 - E1760",
url = "https://journals.ametsoc.org/view/journals/bams/101/10/bamsD190331.xml"
}
Community and contributions
We welcome contributions and feedback from anyone, everything from updating the content or appearance of the documentation to new and cutting edge science.
-
- Anyone interested in scientific collaboration which would add new software functionality should read the MUSICA software development plan.
-
- Before submiitting a PR, please thouroughly read this to you understand our expectations. We reserve the right to reject any PR not meeting our guidelines.
Documentation
Please see the MICM documentation for detailed installation and usage instructions.
License
Copyright (C) 2018-2026 University Corporation for Atmospheric Research