Physical systems
Immiscible, compositional, geothermal and black-oil flow
High-performance porous media and reservoir simulator based on automatic differentiation

JutulDarcy.jl is a general high-performance purpose porous media simulator toolbox (CO2 sequestration, gas/H2 storage, oil/gas fields) written in Julia based on Jutul.jl, developed by the Applied Computational Science group at SINTEF Digital.
A few highlights:
Immiscible, black-oil, compositional, CO2-brine and geothermal systems
Fully differentiable through adjoint method (history matching of parameters, optimization of well controls)
High performance, with optional support for compiling MPI parallel binaries
Consistent discretizations
Industry standard input formats - or make your own model as a script
3D visualization and tools for post-processing of simulation results
Getting started is the main setup guide that includes the basics of installing Julia and creating a Julia environment for JutulDarcy.jl, written for users who may not already be familiar with Julia package management.
If you want to get started right away: Install Julia and add the following packages together with a Makie backend library to your environment of choice using Julia's package manager Pkg:
using Pkg
Pkg.add("GLMakie") # Plotting
Pkg.add("Jutul") # Base package
Pkg.add("JutulDarcy") # Reservoir simulatorTo verify that everything is working, we have a minimal example that runs an industry standard input file and produces interactive plots. Note that interactive plotting requires GLMakie, which may not work if you are running Julia over SSH:
using JutulDarcy, GLMakie
# Load the SPE9 dataset
spe9_dir = JutulDarcy.GeoEnergyIO.test_input_file_path("SPE9")
file_path = joinpath(spe9_dir, "SPE9.DATA")
case = setup_case_from_data_file(file_path)
# Simulate and plot
result = simulate_reservoir(case)
plot_reservoir(case, result, fancy = true)
We can then continue to produce interactive plots for the wells:
plot_well_results(result)
There is also support for plotting summary data:
plot_summary(result)
This can then be used to create dashboard that summarize the field behavior for specified values:
# Plot field rates and rates for two specific wells in field units
plot_summary(result, plots = ["FWPR,FOPR,FGPR", "PRODU2:WOPR,WWPR,WGPR", "PRODU4:WOPR,WWPR,WGPR"], unit_system = "Field")
Alternatively, the code has a Python package that can be installed using pip:
pip install jutuldarcyThe examples are published in the documentation. For a list of examples categorized by tags, see the Example overview page.
To get access to all the examples as code, you can generate a folder that contains the examples locally, you can run the following code to create a folder jutuldarcy_examples in your current working directory:
using JutulDarcy
generate_jutuldarcy_examples()These examples can then be run using include("jutuldarcy_examples/example_name.jl") or opened in an editor to be run line by line.
If you use JutulDarcy for a scientific publication, please cite the main paper the following way:
O. MΓΈyner, (2024). JutulDarcy.jl - a Fully Differentiable High-Performance Reservoir Simulator Based on Automatic Differentiation. Computational Geosciences (2025), Open Access: https://doi.org/10.1007/s10596-025-10366-6
@article{jutuldarcy,
title={JutulDarcy.jl - a fully differentiable high-performance reservoir simulator based on automatic differentiation},
author={M{\o}yner, Olav},
journal={Computational Geosciences},
volume={29},
number={30},
year={2025},
publisher={Springer}
}Fimbul.jl is built on top of JutulDarcy.jl and contains extensions and examples that cover advanced geothermal systems, including closed-loop and enhanced geothermal systems.
jutul-agent is an agentic interface that has specializations for JutulDarcy that allows setting up cases, visualization and interaction with other agents.
JutulDarcy.jl builds upon many of the excellent packages in the Julia ecosystem. Here are a few of them, and what they are used for:
ForwardDiff.jl implements the Dual number class used throughout the code
SparsityTracing.jl provides sparsity detection inside Jutul
Krylov.jl provides the iterative linear solvers
ILUZero.jl for ILU(0) preconditioners
HYPRE.jl for robust AMG preconditioners with MPI support
PartitionedArrays.jl for MPI assembly and linear solve
CUDA.jl for CUDA-GPU support
AMGX.jl for AMG on CUDA GPUs
TimerOutputs.jl and ProgressMeter.jl gives nice output to terminal.
Makie.jl is used for the visualization features
MultiComponentFlash.jl provides many of the compositional features
...and many more directly, and indirectly - see the Project.toml and Manifest files for a full list!