Skip to content

Add a Julia Interface for Cantera (Cantera.jl)#2149

Open
Fastaxx wants to merge 24 commits into
Cantera:mainfrom
Fastaxx:interface-julia
Open

Add a Julia Interface for Cantera (Cantera.jl)#2149
Fastaxx wants to merge 24 commits into
Cantera:mainfrom
Fastaxx:interface-julia

Conversation

@Fastaxx

@Fastaxx Fastaxx commented Jul 3, 2026

Copy link
Copy Markdown

Changes proposed in this pull request

  • Add a new Julia interface (Cantera.jl) under interfaces/julia, linking directly against the native libcantera through generated CLib bindings (no Python dependency).
  • Extend sourcegen with CLib recipes covering kinetics derivatives, _ddX getters, ReactorNet state, standard-state species properties, and heat production/release rates, and use them to generate the low-level Julia bindings (src/generated/*.jl).
  • Wrap the generated bindings in a public API (Solution, ReactorNet, Reactor, Domain/Sim1D, Multiphase, Func1, connectors, reaction-diagnostics, etc.), including thermodynamic, kinetic, transport, mixture, and 1-D flame functionality.
  • Add a test suite (test/runtests.jl and per-module tests) with reference values, examples (examples/*.jl), and API documentation (docs/, README.md).
  • Add a CI workflow that builds libcantera from source and runs the Julia test suite.

If applicable, fill in the issue number this pull request is fixing

Cantera/enhancements#81

If applicable, provide an example illustrating new features this pull request is introducing

using Cantera
gas = Solution("gri30.yaml")
set_TPX!(gas, 1000.0, one_atm, "H2:2, O2:1, N2:4")
net = ReactorNet(IdealGasReactor(gas))
advance!(net, 1e-3)
temperature(gas)          # ignited temperature [K]

AI Statement (required)

Limited use of generative AI.
Standard or boilerplate code snippets were generated with AI and manually reviewed;
all design, logic, and implementation decisions were made by the contributor.
Examples: IDE code-completions or brief LLM queries for common patterns.

For additional information on Cantera's AI policy, see
https://github.com/Cantera/cantera/blob/main/CONTRIBUTING.md#restrictions-on-generative-ai-usage

Checklist

  • The pull request includes a clear description of this code change
  • Commit messages have short titles and reference relevant issues
  • Build passes (scons build & scons test) and unit tests address code coverage
  • Style & formatting of contributed code follows contributing guidelines
  • AI Statement is included
  • The pull request is ready for review

Comment thread .github/workflows/julia-interface.yml Fixed
Comment thread .github/workflows/julia-interface.yml Fixed
Comment thread .github/workflows/julia-interface.yml Fixed

@speth speth left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for contributing this, @Fastaxx. Overall, I think this looks really interesting, and I'm looking forward to seeing where this goes. A few general comments in addition to my in-line comments:

  • I'm a little torn on the low-level binding generator -- rather than having generate_bindings work off the generated CLib headers, I feel like it would be a little cleaner to have at least this layer of the interface directly generated by sourcegen, with Julia as a new submodule there alongside clib and dotnet. On the other hand, this works, so we can go with it for now and if it breaks later, maybe that will be the impetus for a rewrite.

  • While this is a pretty comprehensive start, it would be useful to know what future plans you have for this, if any. For example, what the path is to getting documentation that we can integrate with the other API docs, and the path toward packaging this without users having to build Cantera from source (how does Julia handle packages with dependencies on compiled libraries?) If you want to post about this in the Cantera/enhancements#81 thread, that would be very helpful.

  • All the new source files (excluding the generated ones and the examples) should contain the license/copyright preamble:

# This file is part of Cantera. See License.txt in the top-level directory or
# at https://cantera.org/license.txt for license and copyright information.
  • I think you may be understating the degree to which this was implemented by an LLM. There's no inherent problem with contributing AI-generated code, but it does help the review process to understand where this came from. Can you please update the "AI Statement" to provide a little more detail about how you created this?

  • Please add yourself to AUTHORS.md

Comment thread .github/workflows/julia-interface.yml Outdated
Comment thread interfaces/sourcegen/src/sourcegen/headers/ctkin.yaml Outdated
Comment thread interfaces/sourcegen/src/sourcegen/headers/ctkin.yaml Outdated
Comment thread interfaces/julia/src/generated/libct.jl Outdated
Comment thread interfaces/julia/src/thermo.jl Outdated
Comment thread interfaces/julia/test/test_gaps.jl Outdated
Comment thread interfaces/julia/test/test_gaps.jl Outdated
Comment thread interfaces/julia/test/test_rdiag.jl Outdated
Comment thread interfaces/julia/.gitignore Outdated
Comment on lines +4 to +5
version = "0.1.0"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess while this is very much a pre-release feature, we can leave this as an 0.x version, it should be updated to match the Cantera version once this matures.

@Fastaxx

Fastaxx commented Jul 11, 2026

Copy link
Copy Markdown
Author

Hello @speth,
Thank you very much for your detailed and constructive feedback. I started using Julia three years ago for my PhD thesis. This Cantera connector allows me to access and integrate data from the Cantera project into my research.

I have incorporated a large number of changes following your comments.

However, I have some questions regarding best practice concerning the following points.

  • bindings : I used the low-level approach with generate-bindings for my experiment. However, it seems to me that we could use Yggdrasil to generate and distribute the low-level bindings via a pre-compiled Cantera_jll package, as i try in another project.

  • Documentation within the project. Is it better to use the Doxygen template from the repository, or to host the documentation via the Julia Documenter package with deployment to gh-pages?

  • Regarding the AI statement, i would say a Medium Use of AI, particularly the generation of bindings, with which I am not yet familiar. Also the automatic generation of documentation. I did, however, want to structure the interface myself, as well as write the tests and carry out functional verification.

@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.15%. Comparing base (39cfc14) to head (af3cff4).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2149   +/-   ##
=======================================
  Coverage   78.15%   78.15%           
=======================================
  Files         453      453           
  Lines       55433    55433           
  Branches     9117     9117           
=======================================
  Hits        43324    43324           
  Misses       9060     9060           
  Partials     3049     3049           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@speth

speth commented Jul 12, 2026

Copy link
Copy Markdown
Member
  • Documentation within the project. Is it better to use the Doxygen template from the repository, or to host the documentation via the Julia Documenter package with deployment to gh-pages?

I think the docs should be integrated and hosted with the rest of the Cantera documentation. There are two approaches to doing this. One, which we use with the Matlab toolbox, is to have Sphinx be the documentation generator for the Julia code. That depends on there being a (good) Sphinx plugin for Julia, and I don't know if that exists or not. The other, which is what we do with C++, is to let the language-specific documentation generator (Doxygen for C++ or Documenter for Julia) generate its own pages, doing what we can to configure the output for a similar style, and then merge the resulting outputs. In the case of Doxygen, we get some interlinking capability due to the doxysphinx extension, but you can also just use relative HTML links if the paths are predictable. Again, I'm not sure what's available here.

Take a look at doc/SConscript to see how the doc build process is driven. If we have scons build the Julia docs along with the Sphinx and Doxygen ones as part of the docs workflow in main.yml, then updated ones will automatically be deployed and accessible at https://cantera.org/dev/reference after each PR is merged.

Fastaxx added 21 commits July 13, 2026 21:45
…rNet state

Exposes analytic kinetic derivatives (getFwd/Rev/Net RatesOfProgress and
Creation/Destruction/NetProduction _dd{T,P,C}), densified composition Jacobians
(_ddX), and ReactorNet neq/getState/componentName through the generated CLib.
Header-parsing generator emitting ccall wrappers from cantera_clib/*.h, the
generated bindings, runtime library/data discovery (LibCantera), and the error
and marshalling helpers.
Layered suite validated against Python Cantera reference values (gri30 + h2o2),
plus basic/reactor/flame/reactor-network examples.
Build the Julia interface docs with Documenter and merge the output into
build/doc/html/julia so they deploy with the rest of the Cantera docs, via
a new julia_docs scons option and 'julia' target. Wire the docs CI job to
build them.
Co-authored-by: Ray Speth <yarmond@gmail.com>
@Fastaxx

Fastaxx commented Jul 13, 2026

Copy link
Copy Markdown
Author

Thank you for the suggestions. I’ve taken your comments on board. I’ve also added the documentation. Is that all right with you, overall?

@Fastaxx
Fastaxx requested a review from speth July 13, 2026 19:50
Fastaxx added 2 commits July 17, 2026 14:08
The ThermoPhase/Kinetics/Transport views borrow handles owned by a
Solution and hold a reference to it so that the Solution cannot be
finalized while a view is still reachable. That reference was stored in
an `Any` field, leaving the structs abstractly typed; make it a type
parameter instead.

Add a test covering the lifetime guarantee. Each view is built from its
own Solution, since views sharing one Solution keep each other's owner
alive and would mask a regression in any single accessor.
The low-level bindings were generated by a bespoke Julia script that
parsed the `cantera_clib/*.h` headers with regular expressions. Those
headers are themselves scaffolded by sourcegen from the YAML
specifications, so the script reverse-engineered structured data back
out of generated C and had to be run by hand before the package could
be loaded.

Add a Julia sourcegen plugin that reads the same specifications used for
the CLib and the .NET interface, and an SConscript that runs it as part
of the build. `scons build` now emits src/generated/, so `using Cantera`
works from a checkout with no separate generator step, and a new ct*.yaml
no longer needs a matching entry in a hand-maintained list.

The scaffolded ccall wrappers are unchanged: all 455 wrappers across the
14 headers are identical to those emitted by the script it replaces.
@Fastaxx

Fastaxx commented Jul 17, 2026

Copy link
Copy Markdown
Author

I pushed two new commits.

  • sourcegen for the low-level bindings. Went with your first instinct : generate_bindings.jl is gone, replaced by a julia submodule under interfaces/sourcegen/src/sourcegen/ alongside clib and csharp, scaffolding from the same ct*.yaml specs. An interfaces/julia/SConscript runs it during the build, so scons build emits src/generated/ and using Cantera works with no generator step. One less step in CI too. The regex parser for the CLib headers is gone with it, and the output is unchanged: all 455 wrappers across the 14 headers are identical to what the script emitted, tests pass.

  • About the handles.jl question. Yes, the views now hold a reference to the owning Solution. Added a test; each view is built from its own Solution, since views sharing an owner keep each other alive and would mask a regression in any
    single accessor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants