Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
33bf7e3
Initial plan
Copilot Aug 26, 2025
6787ff9
Add comprehensive docstrings for all plotting functions
Copilot Aug 26, 2025
49df6ee
Create dedicated plotting documentation and update build structure
Copilot Aug 26, 2025
b5f99e4
calibration
Aug 27, 2025
37f7665
support for log scaling in BFGS
xavierr Sep 1, 2025
ad9f30b
Change adjoint step info to use time at new timestep
andreas-brostrom Aug 26, 2025
60f87e4
Change the progress recorder API
andreas-brostrom Aug 29, 2025
179a7ff
Add tests for the recorder API
andreas-brostrom Aug 29, 2025
d58bee8
Rename recorder reset functions
andreas-brostrom Sep 1, 2025
0946918
Fix to BoomerAMG standalone preconditioner (#181)
moyner Sep 2, 2025
92d2c51
Remove old Meshes.jl code (#182)
moyner Sep 4, 2025
c3c8b3f
Faster parameter optimization for models where the setup can be split…
moyner Sep 8, 2025
46def5b
Enable objective sparsity in optimize by default, perf improvements t…
moyner Sep 8, 2025
ef79516
Fallback for MVector sparsity tracing issues on 1.11 (#185)
moyner Sep 9, 2025
737a0fd
Fix bug in format of time stamp for printing simulation result (#186)
andreas-brostrom Sep 12, 2025
5fd9313
Update backend warning for interactive plotting (#188)
moyner Sep 23, 2025
8be3965
Improve fix for Julia GC crash (#189)
moyner Sep 23, 2025
c5502ff
More missing methods for type for Julia 1.11 crash (#190)
moyner Sep 24, 2025
1634c9d
Refactor ForwardDiff usage to make use of ForwardDiff.Tag (#191)
moyner Sep 24, 2025
b1d32bc
Update plot_secondary_variables to work with latest everything (#192)
moyner Sep 26, 2025
36522f1
Bump to version 0.4.6 (#193)
moyner Sep 26, 2025
e25cdab
Add tag ordering to Jutul tags for ForwardDiff (#194)
moyner Sep 26, 2025
e33e6f6
Find enclosing cell improvement (#195)
strene Sep 28, 2025
e7e61e2
Add IJK fallback for unstructured meshes (#196)
moyner Oct 8, 2025
9973c10
Add 3 specialization for plotter (#197)
moyner Oct 8, 2025
6141676
Improve coarsening performance substantially (#198)
moyner Oct 8, 2025
b6cee73
Add cross-term sparsity to objective function (#199)
moyner Oct 9, 2025
d05296f
Guard against missing entry in objective sparsity (#200)
moyner Oct 10, 2025
9143b27
Improve performance and code for generic adjoint (#201)
moyner Oct 28, 2025
3ab6bd2
Initial plan
Copilot Aug 26, 2025
82b8d1f
Rebase on main and fix documentation build errors
Copilot Nov 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Jutul"
uuid = "2b460a1a-8a2b-45b2-b125-b5c536396eb9"
authors = ["Olav Møyner <olav.moyner@gmail.com>"]
version = "0.4.5"
version = "0.4.8"

[deps]
AlgebraicMultigrid = "2169fc97-5a83-5252-b627-83903c6c433c"
Expand Down Expand Up @@ -50,7 +50,6 @@ KaHyPar = "2a6221f6-aa48-11e9-3542-2d9e0ef01880"
LayeredLayouts = "f4a74d36-062a-4d48-97cd-1356bad1de4e"
MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195"
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
Meshes = "eacbb407-ea5a-433e-ab97-5258b1ca43fa"
NetworkLayout = "46757867-2c16-5918-afeb-47bfcb05e46a"
PartitionedArrays = "5a9dfac6-5c52-46f7-8278-5e2210713be9"

Expand All @@ -62,7 +61,6 @@ JutulGraphMakieExt = ["GraphMakie", "NetworkLayout", "LayeredLayouts", "Makie"]
JutulHYPREExt = "HYPRE"
JutulKaHyParExt = "KaHyPar"
JutulMakieExt = "Makie"
JutulMeshesExt = ["Meshes"]
JutulPartitionedArraysExt = ["PartitionedArrays", "MPI"]

[compat]
Expand All @@ -86,7 +84,6 @@ LoopVectorization = "0.12.115"
MAT = "0.10.3"
Makie = "0.21, 0.22, 0.23"
MappedArrays = "0.4.1"
Meshes = "0.28 - 0.41"
Metis = "1.1.0"
NetworkLayout = "0.4.5"
OrderedCollections = "1.4.1"
Expand Down Expand Up @@ -115,9 +112,8 @@ KaHyPar = "2a6221f6-aa48-11e9-3542-2d9e0ef01880"
LayeredLayouts = "f4a74d36-062a-4d48-97cd-1356bad1de4e"
MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195"
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
Meshes = "eacbb407-ea5a-433e-ab97-5258b1ca43fa"
NetworkLayout = "46757867-2c16-5918-afeb-47bfcb05e46a"
PartitionedArrays = "5a9dfac6-5c52-46f7-8278-5e2210713be9"

[targets]
test = ["Meshes", "KaHyPar"]
test = ["KaHyPar", "HYPRE"]
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ makedocs(;
"Usage" => "usage.md",
"optimization.md",
"mesh.md",
"Plotting" => "plotting.md",
"Internals" => "internals.md",
"Docstrings" => "docstrings.md"
],
Expand Down
8 changes: 5 additions & 3 deletions docs/src/mesh.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ MRSTWrapMesh

## Plotting functions

Plotting requires that a Makie backend is loaded (typically GLMakie or CairoMakie). The documentation uses `CairoMakie` to work on machines without OpenGL enabled, but if you want fast and interactive plots, `GLMakie` should be preferred.
Plotting requires that a Makie backend is loaded (typically GLMakie or CairoMakie). For comprehensive plotting documentation and examples, see the [Plotting](plotting.md) section.

### Non-mutating
### Basic mesh plotting

#### Non-mutating

```@docs
plot_mesh
Expand All @@ -25,7 +27,7 @@ plot_mesh_edges
plot_interactive
```

### Mutating
#### Mutating

```@docs
plot_mesh!
Expand Down
142 changes: 142 additions & 0 deletions docs/src/plotting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Plotting and Visualization

Jutul.jl provides comprehensive plotting capabilities for mesh visualization, performance analysis, and model structure visualization. All plotting functionality requires a Makie backend to be loaded.

## Requirements

Plotting requires that a Makie backend is loaded (typically GLMakie or CairoMakie). The documentation uses `CairoMakie` to work on machines without OpenGL enabled, but if you want fast and interactive plots, `GLMakie` should be preferred.

```julia
using GLMakie # For interactive plots
# or
using CairoMakie # For static plots/headless systems
```

## Mesh Visualization

For comprehensive mesh plotting documentation including `plot_mesh`, `plot_mesh!`, `plot_cell_data`, `plot_cell_data!`, `plot_mesh_edges`, `plot_mesh_edges!`, and `plot_interactive`, see the [Mesh](mesh.md) section.

### Interactive multi-model plotting

`plot_multimodel_interactive(model, states, model_keys = keys(model.models); plot_type = :mesh, shift = Dict(), kwarg...)`

Launch an interactive plot for multi-model simulations with multiple coupled domains.

**Arguments:**
- `model`: `MultiModel` instance containing multiple coupled simulation models
- `states`: Vector of simulation states or single state
- `model_keys = keys(model.models)`: Which models to include in the plot

**Keyword Arguments:**
- `plot_type = :mesh`: Type of plot (`:mesh`, `:meshscatter`, `:lines`)
- `shift = Dict()`: Dictionary of spatial shifts to apply to each model for visualization
- Additional keyword arguments are passed to `plot_interactive`

This function creates an interactive visualization for multi-physics simulations where multiple models are coupled together.

## Performance Analysis

These functions help analyze simulation performance and solver behavior.

### Solver timing breakdown

`plot_solve_breakdown(allreports, names; per_it = false, include_local_solves = nothing, t_scale = ("s", 1.0))`

Plot a breakdown of solver performance timing for multiple simulation reports.

**Arguments:**
- `allreports`: Vector of simulation reports to analyze
- `names`: Vector of names for each report (used for labeling)

**Keyword Arguments:**
- `per_it = false`: If `true`, show time per iteration instead of total time
- `include_local_solves = nothing`: Whether to include local solve timing (auto-detected if `nothing`)
- `t_scale = ("s", 1.0)`: Time scale unit and conversion factor for display

Returns `(fig, D)`: Figure object and processed timing data.

### Cumulative solve time

`plot_cumulative_solve(allreports, dt = nothing, names = nothing; kwarg...)`

Plot cumulative solver performance over time or steps for multiple simulation reports.

`plot_cumulative_solve!(f, allreports, dt = nothing, names = nothing; kwarg...)`

Mutating version that plots into an existing figure layout.

### Linear solver convergence

`plot_linear_convergence(report; kwarg...)`

Plot the convergence history of linear solver iterations from a simulation report.

`plot_linear_convergence!(ax, report)`

Mutating version that plots into an existing axis.

## Model Structure Visualization

These functions require the GraphMakie.jl package to be loaded in addition to a Makie backend.

```julia
using GraphMakie
```

### Variable dependency graph

`plot_variable_graph(model)`

Plot a graph visualization of variable dependencies in a simulation model.

**Arguments:**
- `model`: A Jutul simulation model

Returns a Figure object containing the variable dependency graph showing relationships between primary variables, secondary variables, and parameters.

### Model structure graph

`plot_model_graph(model; kwarg...)`

Plot a graph visualization of model structure and equation relationships. For `MultiModel` instances, this shows the full structure including cross-terms and model coupling.

## Utilities

`check_plotting_availability(; throw = true, interactive = false)`

Check if plotting through at least one Makie backend is available in the Julia session. Returns `true` if available, `false` otherwise (or throws an error if `throw=true`).

## Examples

### Performance analysis

```julia
using Jutul, CairoMakie

# After running simulations and collecting reports
reports = [report1, report2, report3]
names = ["Configuration A", "Configuration B", "Configuration C"]

# Plot solver breakdown
fig, data = plot_solve_breakdown(reports, names)

# Plot cumulative solve time
fig, ax, alldata, t = plot_cumulative_solve(reports, names = names)

# Plot linear convergence for a single report
fig = plot_linear_convergence(reports[1])
```

### Model structure visualization

```julia
using Jutul, GraphMakie, GLMakie

# Plot variable dependencies
fig = plot_variable_graph(model)

# For multi-models, plot the full structure
fig = plot_model_graph(multimodel)
```

For mesh plotting examples, see the [Mesh](mesh.md) section.
3 changes: 1 addition & 2 deletions ext/JutulGLMakieExt/JutulGLMakieExt.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module JutulGLMakieExt

using Jutul, GLMakie
using Jutul, GLMakie
include("variables.jl")

function Jutul.independent_figure(fig::Figure)
Expand Down
15 changes: 9 additions & 6 deletions ext/JutulGLMakieExt/variables.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ function Jutul.plot_secondary_variables(model::SimulationModel; kwarg...)
Jutul.plot_secondary_variables(MultiModel((model = model, )); kwarg...)
end

function Jutul.plot_secondary_variables(model::MultiModel; linewidth = 4, kwarg...)
function Jutul.plot_secondary_variables(model::MultiModel; linewidth = 2, kwarg...)
data = Dict{String, Any}()
nregmax = 1
count = 0
Expand Down Expand Up @@ -51,7 +51,7 @@ function Jutul.plot_secondary_variables(model::MultiModel; linewidth = 4, kwarg.
reg = m2.selection[]
begin
function plot_by_reg(regions)
plot_jutul_line_data(d; regions = regions, linewidth = s.value[])
Jutul.plot_jutul_line_data(d; regions = regions, linewidth = s.value[])
end
if reg == "All"
plot_by_reg(axes(d, 2))
Expand All @@ -69,24 +69,27 @@ function Jutul.plot_secondary_variables(model::MultiModel; linewidth = 4, kwarg.
end

function Jutul.plot_jutul_line_data(data::JutulLinePlotData; kwarg...)
plot_jutul_line_data([data]; kwarg...)
Jutul.plot_jutul_line_data([data]; kwarg...)
end

function Jutul.plot_jutul_line_data(data; resolution = (1600, 900), linewidth = 4, regions = axes(data, 2), kwarg...)
fig = Figure(resolution = resolution)
function Jutul.plot_jutul_line_data(data; size = (1600, 900), linewidth = 2, regions = axes(data, 2), kwarg...)
fig = Figure(size = size)
colors = Makie.wong_colors()
all_axes = []
for (col, regix) in enumerate(regions)
for i in axes(data, 1)
d = data[i, regix]
ax = Axis(fig[i, col], xlabel = d.xlabel, ylabel = d.ylabel, title = "$(d.title) region $regix")
push!(all_axes, ax)
ix = 1
for (x, y, lbl) in zip(d.xdata, d.ydata, d.datalabels)
c = colors[mod(ix, 7) + 1]
lines!(ax, x, y; color = c, linewidth = linewidth, label = lbl, kwarg...)
ix += 1
end
axislegend()
axislegend(position = :rt)
end
end
linkaxes!(all_axes...)
display(GLMakie.Screen(), fig)
end
46 changes: 46 additions & 0 deletions ext/JutulGraphMakieExt/JutulGraphMakieExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,27 @@ module JutulGraphMakieExt
using Jutul, Makie
using GraphMakie, Graphs, LayeredLayouts, NetworkLayout

"""
plot_variable_graph(model)

Plot a graph visualization of variable dependencies in a simulation model.

# Arguments
- `model`: A Jutul simulation model

# Returns
- `fig`: Figure object containing the variable dependency graph

This function creates a directed graph showing the relationships between primary
variables, secondary variables, and parameters in the simulation model. Different
node types are color-coded:
- Primary variables: Blue
- Secondary variables: Orange
- Parameters: Green

The graph layout uses a layered approach to clearly show the dependency structure
and data flow within the model.
"""
function Jutul.plot_variable_graph(model)
graph, nodes, = build_variable_graph(model, to_graph = true)
c1 = Makie.ColorSchemes.tab10[1]
Expand Down Expand Up @@ -76,6 +97,31 @@ module JutulGraphMakieExt
)
end

"""
plot_model_graph(model; kwarg...)

Plot a graph visualization of model structure and equation relationships.

# Arguments
- `model`: A Jutul simulation model (can be `MultiModel` or single model)

# Keyword Arguments
- Additional keyword arguments are passed to the plotting functions

# Returns
- Plot object containing the model structure graph

For single models, this is equivalent to `plot_variable_graph`. For `MultiModel`
instances, this creates a more complex graph showing:
- Individual model components (colored by model)
- Equations within each model
- Cross-term relationships between models
- Edge labels indicating cross-term types

The visualization helps understand the coupling structure in multi-physics
simulations and can be useful for debugging model setup and analyzing
computational dependencies.
"""
function Jutul.plot_model_graph(model; kwarg...)
Jutul.plot_variable_graph(model; kwarg...)
end
Expand Down
4 changes: 2 additions & 2 deletions ext/JutulHYPREExt/JutulHYPREExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ module JutulHYPREExt
J_h, r_h, x_h = D[:hypre_system]
reassemble_matrix!(J_h, D, J, executor)
else
r_h = HYPRE.HYPREVector(r)
r_h = HYPRE.HYPREVector(copy(r))
x_h = HYPRE.HYPREVector(copy(r))
D[:J] = J
# D[:n] = n
D[:n] = length(r)
# (; ilower, iupper) = r_h
# D[:vector_indices] = HYPRE.HYPRE_BigInt.(ilower:iupper)
J_h = transfer_matrix_to_hypre(J, D, executor)
Expand Down
4 changes: 2 additions & 2 deletions ext/JutulMakieExt/interactive_3d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -900,9 +900,9 @@ end

function Jutul.plotting_check_interactive(; warn = true)
backend_name = "$(Makie.current_backend())"
if backend_name != "GLMakie"
if !(backend_name in ("GLMakie", "WGLMakie"))
if warn
msg = "Currently active Makie backend $backend_name may not be interactive or fully supported.\nGLMakie is recommended for Jutul's interactive plots. To install:\n\tusing Pkg; Pkg.add(\"GLMakie\")\nTo use:\n\tusing GLMakie\n\tGLMakie.activate!()\nYou can then retry your plotting command."
msg = "Currently active Makie backend $backend_name may not be interactive or fully supported.\nGLMakie (or WGLMakie) is recommended for Jutul's interactive plots. To install:\n\tusing Pkg; Pkg.add(\"GLMakie\")\nTo use:\n\tusing GLMakie\n\tGLMakie.activate!()\nYou can then retry your plotting command."
@warn msg
end
return false
Expand Down
Loading