-
Notifications
You must be signed in to change notification settings - Fork 10
Add Julia/C++ bindings for MUSICA #794
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
Open
sjsprecious
wants to merge
12
commits into
julia-binary-distribution
Choose a base branch
from
add_julia_cxx_bindings
base: julia-binary-distribution
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
eea503f
add julia and c++ binding code
sjsprecious 144d596
update code changes suggested by claude
sjsprecious 8065c8e
more coe changes suggested by claude
sjsprecious 96e27bc
last code change suggested by claude
sjsprecious 23d7668
try to fix broken julia tests
sjsprecious 323eb1c
add -fPIC flag
sjsprecious 82a7325
fix cxxwrap_julia_stl link error
sjsprecious 96cb919
set MUSICA_JULIA_LIB env var
sjsprecious fd09811
set MUSICA_JULIA_LIB env var
sjsprecious 8fa9290
fix julia docker build
sjsprecious 3241cbf
fix musica_julia_lib path
sjsprecious d4da8ff
address copilot comments
sjsprecious File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,19 +1,79 @@ | ||
| # Copyright (C) 2023-2026 University Corporation for Atmospheric Research | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| module Musica | ||
|
|
||
| using CxxWrap | ||
| using Musica_jll | ||
|
|
||
| function __init__() | ||
| # Allow overriding the JLL library for raw CMake development builds | ||
| lib = get(ENV, "MUSICA_JULIA_LIB", nothing) | ||
| if lib !== nothing && isfile(lib) | ||
| @wrapmodule(() -> lib) | ||
| # Determine library path at compile time (must be top-level for @wrapmodule) | ||
| const _lib_path = let | ||
| env_lib = get(ENV, "MUSICA_JULIA_LIB", nothing) | ||
| if env_lib !== nothing && isfile(env_lib) | ||
| env_lib | ||
| else | ||
| @wrapmodule(() -> Musica_jll.libmusica_julia) | ||
| try | ||
| @eval using Musica_jll | ||
| Musica_jll.libmusica_julia | ||
| catch | ||
| error("MUSICA_JULIA_LIB environment variable must be set to the path of libmusica_julia.so " * | ||
| "(or install Musica_jll)") | ||
| end | ||
| end | ||
| end | ||
|
|
||
| # @wrapmodule must be at module top level so types are defined during precompilation | ||
| @wrapmodule(() -> _lib_path) | ||
|
|
||
| function __init__() | ||
| @initcxx | ||
| end | ||
|
|
||
| # Type aliases for CxxWrap pointer types (used in MICM and State structs) | ||
| const MICMPtr = CxxWrap.CxxWrapCore.CxxPtr{CppMICM} | ||
| const StatePtr = CxxWrap.CxxWrapCore.CxxPtr{CppState} | ||
|
|
||
| # Include MICM submodule files (order matters for dependencies) | ||
| include("micm/constants.jl") | ||
| include("micm/solver.jl") | ||
| include("micm/solver_result.jl") | ||
| include("micm/conditions.jl") | ||
| include("micm/solver_parameters.jl") | ||
| include("micm/utils.jl") | ||
| include("micm/state.jl") | ||
| include("micm/micm.jl") | ||
|
|
||
| # Version | ||
| export get_version | ||
|
|
||
| end | ||
| # Constants | ||
| export AVOGADRO, BOLTZMANN, GAS_CONSTANT | ||
|
|
||
| # Solver types | ||
| export SolverType | ||
| export Rosenbrock, RosenbrockStandardOrder, BackwardEuler, BackwardEulerStandardOrder, CudaRosenbrock | ||
|
|
||
| # Solver results | ||
| export SolverState, SolverStats, SolverResult | ||
| export NotYetCalled, Running, Converged, ConvergenceExceededMaxSteps | ||
| export StepSizeTooSmall, RepeatedlySingularMatrix, NaNDetected, InfDetected | ||
| export AcceptingUnconvergedIntegration | ||
|
|
||
| # Conditions | ||
| export Conditions | ||
|
|
||
| # Solver parameters | ||
| export RosenbrockSolverParameters, BackwardEulerSolverParameters | ||
|
|
||
| # MICM and State types | ||
| export MICM, State | ||
|
|
||
| # Functions | ||
| export create_state, solve! | ||
| export set_concentrations!, get_concentrations | ||
| export set_conditions!, get_conditions | ||
| export set_user_defined_rate_parameters!, get_user_defined_rate_parameters | ||
| export get_species_ordering, get_user_defined_rate_parameters_ordering | ||
| export set_solver_parameters!, get_solver_parameters | ||
| export solver_type | ||
|
|
||
| end # module Musica | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # Copyright (C) 2023-2026 University Corporation for Atmospheric Research | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| """ | ||
| Conditions | ||
|
|
||
| Environmental conditions for a grid cell. | ||
|
|
||
| If `air_density` is not provided and both `temperature` and `pressure` are given, | ||
| air density is calculated from the Ideal Gas Law. | ||
|
|
||
| # Fields | ||
| - `temperature::Float64`: Temperature in Kelvin | ||
| - `pressure::Float64`: Pressure in Pascals | ||
| - `air_density::Float64`: Air density in mol m⁻³ | ||
| """ | ||
| mutable struct Conditions | ||
| temperature::Float64 | ||
| pressure::Float64 | ||
| air_density::Float64 | ||
| end | ||
|
|
||
| function Conditions(; temperature::Real=0.0, pressure::Real=0.0, air_density::Union{Real, Nothing}=nothing) | ||
| if air_density === nothing | ||
| if temperature > 0.0 && pressure > 0.0 | ||
| air_density = pressure / (GAS_CONSTANT * temperature) | ||
| else | ||
| air_density = 0.0 | ||
| end | ||
| end | ||
| return Conditions(Float64(temperature), Float64(pressure), Float64(air_density)) | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| # Copyright (C) 2023-2026 University Corporation for Atmospheric Research | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| const AVOGADRO = 6.02214076e23 # mol^-1 | ||
| const BOLTZMANN = 1.380649e-23 # J K^-1 | ||
| const GAS_CONSTANT = AVOGADRO * BOLTZMANN # J K^-1 mol^-1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| # Copyright (C) 2023-2026 University Corporation for Atmospheric Research | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| """ | ||
| MICM | ||
|
|
||
| Wrapper around the C++ MICM chemical kinetics solver. | ||
|
|
||
| # Constructor | ||
|
|
||
| MICM(; config_path, solver_type=RosenbrockStandardOrder, solver_parameters=nothing) | ||
|
|
||
| - `config_path::String`: Path to configuration file or directory | ||
| - `solver_type::SolverType`: Type of solver to use | ||
| - `solver_parameters`: Optional `RosenbrockSolverParameters` or `BackwardEulerSolverParameters` | ||
| """ | ||
| mutable struct MICM | ||
| _ptr::MICMPtr | ||
| _solver_type::SolverType | ||
| _vector_size::Int | ||
|
|
||
| function MICM(; | ||
| config_path::String, | ||
| solver_type::SolverType=RosenbrockStandardOrder, | ||
| solver_parameters::Union{RosenbrockSolverParameters, BackwardEulerSolverParameters, Nothing}=nothing, | ||
| ) | ||
| vs = Int(cpp_get_vector_size(Int(solver_type))) | ||
| vs > 0 || error("Invalid vector size: $vs") | ||
|
|
||
| ptr = cpp_create_solver(config_path, Int(solver_type)) | ||
|
|
||
| obj = new(ptr, solver_type, vs) | ||
| finalizer(obj) do m | ||
| cpp_delete_solver(m._ptr) | ||
| end | ||
|
|
||
| if solver_parameters !== nothing | ||
| set_solver_parameters!(obj, solver_parameters) | ||
| end | ||
| return obj | ||
| end | ||
| end | ||
|
|
||
| """ | ||
| solver_type(micm::MICM) -> SolverType | ||
|
|
||
| Get the type of solver used. | ||
| """ | ||
| solver_type(micm::MICM) = micm._solver_type | ||
|
|
||
| """ | ||
| create_state(micm::MICM; number_of_grid_cells=1) -> State | ||
|
|
||
| Create a new state object for this solver. | ||
| """ | ||
| function create_state(micm::MICM; number_of_grid_cells::Int=1) | ||
| return State(micm._ptr, number_of_grid_cells, micm._vector_size, micm) | ||
| end | ||
|
|
||
| """ | ||
| solve!(micm::MICM, state::State, time_step::Real) -> SolverResult | ||
|
|
||
| Solve the chemical system for the given state and time step (in seconds). | ||
| """ | ||
| function solve!(micm::MICM, state::State, time_step::Real) | ||
| cpp_result = cpp_micm_solve(micm._ptr, state._ptr, Float64(time_step)) | ||
| return SolverResult(cpp_result) | ||
| end | ||
|
|
||
| """ | ||
| set_solver_parameters!(micm::MICM, params::RosenbrockSolverParameters) | ||
| set_solver_parameters!(micm::MICM, params::BackwardEulerSolverParameters) | ||
|
|
||
| Set solver-specific parameters. Parameter type must match the solver type. | ||
| """ | ||
| function set_solver_parameters!(micm::MICM, params::RosenbrockSolverParameters) | ||
| cpp_params = to_cpp_rosenbrock(params) | ||
| cpp_set_rosenbrock_params(micm._ptr, cpp_params) | ||
| end | ||
|
|
||
| function set_solver_parameters!(micm::MICM, params::BackwardEulerSolverParameters) | ||
| cpp_params = to_cpp_backward_euler(params) | ||
| cpp_set_backward_euler_params(micm._ptr, cpp_params) | ||
| end | ||
|
|
||
| """ | ||
| get_solver_parameters(micm::MICM) | ||
|
|
||
| Get the current solver parameters. Returns `RosenbrockSolverParameters` or | ||
| `BackwardEulerSolverParameters` depending on the solver type. | ||
| """ | ||
| function get_solver_parameters(micm::MICM) | ||
| st = micm._solver_type | ||
| if st == Rosenbrock || st == RosenbrockStandardOrder || st == CudaRosenbrock | ||
| return from_cpp_rosenbrock(cpp_get_rosenbrock_params(micm._ptr)) | ||
| elseif st == BackwardEuler || st == BackwardEulerStandardOrder | ||
| return from_cpp_backward_euler(cpp_get_backward_euler_params(micm._ptr)) | ||
| else | ||
| error("Unknown solver type: $st") | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # Copyright (C) 2023-2026 University Corporation for Atmospheric Research | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| """ | ||
| SolverType | ||
|
|
||
| Enum representing the type of MICM solver to use. | ||
|
|
||
| Values match the C++ `musica::MICMSolver` enum. | ||
| """ | ||
| @enum SolverType begin | ||
| Rosenbrock = 1 | ||
| RosenbrockStandardOrder = 2 | ||
| BackwardEuler = 3 | ||
| BackwardEulerStandardOrder = 4 | ||
| CudaRosenbrock = 5 | ||
| end |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.