From 2da87acef717770132a3f766a23276103a1638b9 Mon Sep 17 00:00:00 2001 From: Kyle Shores Date: Thu, 23 Jul 2026 17:09:08 -0500 Subject: [PATCH] Carry v0 species diffusion coefficient onto phase species In v0 configs the diffusion coefficient is defined on the species, but MICM reads it from the phase species (e.g. for surface reactions). When the v0 parser placed all species into the gas phase it copied only the name, dropping the diffusion coefficient. This caused MICM to throw "Diffusion coefficient for species '' is not defined" for any v0 species used in a surface reaction. Forward the species-level diffusion coefficient onto each gas-phase PhaseSpecies and extend the v0 species test to cover it. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/v0/parser.cpp | 4 ++++ test/unit/v0/test_species_config.cpp | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/v0/parser.cpp b/src/v0/parser.cpp index 1786c82b..df52c941 100644 --- a/src/v0/parser.cpp +++ b/src/v0/parser.cpp @@ -176,6 +176,10 @@ namespace mechanism_configuration::v0 { types::PhaseSpecies phase_species; phase_species.name = species.name; + // Carry the species-level diffusion coefficient onto the phase species so it survives + // into MICM, which reads the coefficient from the phase species (e.g. for surface + // reactions) rather than from the species definition. + phase_species.diffusion_coefficient = species.diffusion_coefficient; gas_phase.species.push_back(phase_species); } mechanism.phases.push_back(gas_phase); diff --git a/test/unit/v0/test_species_config.cpp b/test/unit/v0/test_species_config.cpp index 04e936bf..7a07b450 100644 --- a/test/unit/v0/test_species_config.cpp +++ b/test/unit/v0/test_species_config.cpp @@ -62,5 +62,25 @@ TEST(SpeciesConfig, ValidSpeciesConfig) EXPECT_FALSE(species_vector[3].diffusion_coefficient.has_value()); EXPECT_FALSE(species_vector[3].absolute_tolerance.has_value()); } + + // In v0 all species are placed in the gas phase. The species-level diffusion + // coefficient must be carried onto the phase species, since MICM reads the + // coefficient from the phase species (e.g. for surface reactions). + ASSERT_EQ(mechanism.phases.size(), 1); + auto& gas_phase = mechanism.phases[0]; + EXPECT_EQ(gas_phase.name, "gas"); + ASSERT_EQ(gas_phase.species.size(), 4); + + EXPECT_EQ(gas_phase.species[0].name, "foo"); + EXPECT_EQ(gas_phase.species[0].diffusion_coefficient, 2.3e-4); + + EXPECT_EQ(gas_phase.species[1].name, "bar"); + EXPECT_EQ(gas_phase.species[1].diffusion_coefficient, 0.4e-5); + + EXPECT_EQ(gas_phase.species[2].name, "baz"); + EXPECT_FALSE(gas_phase.species[2].diffusion_coefficient.has_value()); + + EXPECT_EQ(gas_phase.species[3].name, "quz"); + EXPECT_FALSE(gas_phase.species[3].diffusion_coefficient.has_value()); } }