Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
912b2b9
remove activate_multithread and setting BLAS threads to 1
mberto79 Oct 1, 2025
7e8326d
Move `AbstractEnergyModel` type to `0_type_definition` so that it can…
Oct 2, 2025
0ef2a8b
`multiphase sources` framework was added and includes `Lee Model`, `S…
Oct 2, 2025
7a6b9b5
comment on `abstractDrag`
Oct 2, 2025
247fc07
add multiphase solver logistics
Oct 2, 2025
de3a36f
Models for multiphase solver that include support for `Const Density`…
Oct 2, 2025
bd6149c
Added: `Multiphase Solver` Core Code
Oct 2, 2025
2bc5dcd
Merge commit '00cea8be55fd57e6db00d5d1d05ebcda46510ea6' into local-main
Oct 23, 2025
9068dae
`Fixed` multiphase solver logistics (AbstractMultiphase type added)
Oct 23, 2025
6730ec4
`Added` appropriate `save_output` dispatch for multiphase solver
Oct 23, 2025
20180e5
`Added` grad! via `Green Gauss` without the need for B.C.s
Oct 23, 2025
724054d
Merge remote-tracking branch 'upstream/HM/fix-xcal_foreach-in-GPU' in…
Dec 13, 2025
0803325
Functionality test for the new `multiphase` solver.
Dec 14, 2025
4612e25
nothing
Dec 14, 2025
219aa53
- Updates `gravity` constructor to include relevant fields to enable …
Dec 14, 2025
f45f6cc
- Added `p_rgh` formulation.
Dec 14, 2025
51b6032
Updated functionality test
Dec 14, 2025
ae86228
changelog update
Dec 14, 2025
1768d61
Merge remote-tracking branch 'upstream/main' into AA/multiphase-solve…
Dec 17, 2025
a3a5ce8
review changes (humberto)
mberto79 Dec 17, 2025
ff318c1
- T field extraction was changed followed by changes in `Isothermal` …
Dec 18, 2025
cd8884b
- Changed `Isothermal` energy model to let user optionally define `Co…
Dec 18, 2025
bb71d08
- Temperature field handling withing the `multiphase` solver was rede…
Dec 18, 2025
8ff5ef3
Ready to be merged
Dec 18, 2025
5ce62d9
bring negative sign for pressure equation to prevent DILU failure
mberto79 Feb 1, 2026
16ecc79
change sign in mass correction
mberto79 Feb 1, 2026
3262049
update examples
mberto79 Feb 1, 2026
33acc70
update examples
mberto79 Feb 1, 2026
d7d25e7
add draft of new correction to all solvers
mberto79 Feb 1, 2026
eb0a762
Merge branch 'main' into HM/improved-mass-flux-periodic
mberto79 Feb 2, 2026
dd93a31
Merge remote-tracking branch 'upstream/HM/improved-mass-flux-periodic…
Feb 18, 2026
111e7bf
Change `dt` -> `dt[1]`
Feb 18, 2026
62d5aaa
Add struct and constructor for adaptive time stepping (optionally pas…
Feb 18, 2026
b53ad80
Add test case
Feb 18, 2026
6823232
Update change log
Feb 18, 2026
9ff06ab
test case inside runtests
Feb 18, 2026
5db4e3f
Added optional adaptive time-stepping function `update_dt!` via multi…
Feb 18, 2026
ffc44d6
Cleaned files from this PR
Feb 18, 2026
92fc5a6
Fixed: dt -> dt[1]
Feb 18, 2026
b92a3a0
Remove multiphase dispatch
Feb 18, 2026
3680109
Clean a test
Feb 18, 2026
acc1982
Fix error from previous file cleansing
Feb 18, 2026
8f5d5bb
fix compilation bug
Feb 18, 2026
c3a3cdf
final update
Feb 18, 2026
2861778
final fix...
Feb 18, 2026
0924f1e
Merge branch 'AA/adaptive-time-stepping' into AA/adaptive-dt
Feb 24, 2026
3b786e8
merge
Feb 24, 2026
ed27b1a
Updated "no BCs" grad! dispatch
Feb 26, 2026
ba0cd55
`Configuration` was adapted to ensure GPU compatibility for adaptive …
Feb 26, 2026
4cd1972
`Runtime` docstring was updated to include adaptive dt description.
Feb 26, 2026
7be237e
Solvers were updated to ensure GPU compatibility with adaptive time-s…
Feb 26, 2026
65a7c80
`update_dt!` was moved to generic functions file so that it can be ac…
Feb 26, 2026
1ceb0ca
Bug fix
Feb 26, 2026
ecd05fe
Bug fix
Feb 26, 2026
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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Version [v0.5.3] - 2026-02-19

### Added
* No new functionality added
* Added optional adaptive time stepping based on Courant number control (`AdaptiveTimeStepping`) [#98](@ref)


### Fixed
Expand Down
3 changes: 2 additions & 1 deletion examples/2D_flatplate_fixedT_KOmega.jl
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ solvers = (
solver = Gmres(), # Bicgstab(), Gmres()
preconditioner = Jacobi(),
convergence = 1e-7,
relax = 0.3,
# relax = 0.3,
relax = 0.2,
atol = 1e-2
),
h = SolverSetup(
Expand Down
5 changes: 5 additions & 0 deletions src/Calculate/Calculate_0_gradient.jl
Original file line number Diff line number Diff line change
Expand Up @@ -255,4 +255,9 @@ function grad!(grad::Grad{Midpoint,F,R,I,M}, phif, phi, BCs, time, config) where
correct_interpolation!(grad, phif, phi, config)
green_gauss!(grad, phif, config)
end
end

# This is a gradient method that does not take BCs as arguments (implicitly assuming the the gradient at boundaries is 0)
function grad!(grad::Grad{Gauss,F,R,I,M}, phif, phi, time, config) where {F,R<:VectorField,I,M}
green_gauss!(grad, phif, config)
end
4 changes: 2 additions & 2 deletions src/Discretise/Discretise_1_schemes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ end
@inline scheme_source!(
term::Operator{F,P,I,Time{Euler}}, cell, cID, cIndex, prev, runtime) where {F,P,I} = begin
volume = cell.volume
vol_rdt = volume/runtime.dt
vol_rdt = volume/runtime.dt[1]

# Increment sparse and b arrays
ac = vol_rdt
Expand All @@ -48,7 +48,7 @@ end
@inline scheme_source!(
term::Operator{F,P,I,Time{CrankNicolson}}, cell, cID, cIndex, prev, runtime) where {F,P,I} = begin
volume = cell.volume
vol_rdt = volume/runtime.dt
vol_rdt = volume/runtime.dt[1]

# Increment sparse and b arrays
ac = vol_rdt
Expand Down
3 changes: 2 additions & 1 deletion src/ModelPhysics/0_type_definition.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export Momentum
export AbstractTimeModel
export Transient, Steady


"""
struct Physics{T,F,SO,M,Tu,E,D,BI}
time::T
Expand Down Expand Up @@ -159,4 +160,4 @@ end
mutable struct ModelState{T1}
residuals::T1
converged::Bool
end
end
1 change: 0 additions & 1 deletion src/ModelPhysics/Energy/Energy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ include("energy_types.jl")

# Energy models
include("Sensible_Enthalpy.jl")
# include("Laplace_Energy.jl")
include("Conduction.jl")

# Property Models
Expand Down
2 changes: 1 addition & 1 deletion src/ModelPhysics/Energy/Sensible_Enthalpy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ function energy!(
# Kbounded = ScalarField(mesh)
Pr = model.fluid.Pr

dt = runtime.dt
dt = runtime.dt[1]

# Pre-allocate auxiliary variables
TF = _get_float(mesh)
Expand Down
1 change: 1 addition & 0 deletions src/ModelPhysics/ModelPhysics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ include("Turbulence/Turbulence.jl")
include("FluidProperties/FluidProperties.jl")



end # end module
13 changes: 13 additions & 0 deletions src/ModelPhysics/Turbulence/RANS_laminar.jl
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,19 @@ function save_output(model::Physics{T,F,SO,M,Tu,E,D,BI}, outputWriter, iteration
write_results(iteration, time, model.domain, outputWriter, config.boundaries, args...)
end

# function save_output(model::Physics{T,F,SO,M,Tu,E,D,BI}, outputWriter, iteration, time, config
# ) where {T,F<:Multiphase,SO,M,Tu<:Laminar,E<:Nothing,D,BI}

# args = (
# ("U", model.momentum.U),
# ("p", model.momentum.p),
# ("alpha", model.fluid.alpha),
# ("rho", model.fluid.rho),
# # ("p_rgh", model.fluid.p_rgh)
# )
# write_results(iteration, time, model.domain, outputWriter, config.boundaries, args...)
# end

function save_output(model::Physics{T,F,SO,M,Tu,E,D,BI}, outputWriter, iteration, time, config
) where {T,F,SO,M,Tu<:Laminar,E<:Nothing,D,BI}
args = (
Expand Down
21 changes: 17 additions & 4 deletions src/Simulate/Simulate_0_types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ export Configuration
export Hardware

"""
@kwdef struct Configuration{SC,SL,RT,HW,PP}
struct Configuration{SC,SL,RT,HW,PP}
schemes::SC
solvers::SL
runtime::RT
hardware::HW
postprocess::PP = nothing
postprocess::PP
end

The `Configuration` type is passed to all flow solvers and provides all the relevant information to run a simulation.
Expand All @@ -29,16 +29,29 @@ config = Configuration(
solvers=solvers, schemes=schemes, runtime=runtime, hardware=hardware, boundaries=BCs)
```
"""
@kwdef struct Configuration{SC,SL,RT,HW,BC,PP}
struct Configuration{SC,SL,RT,HW,BC,PP}
schemes::SC
solvers::SL
runtime::RT
hardware::HW
boundaries::BC
postprocess::PP = nothing
postprocess::PP
end
Adapt.@adapt_structure Configuration

Configuration(; schemes, solvers, runtime, hardware, boundaries, postprocess=nothing) = begin
Configuration(
schemes,
solvers,
adapt(hardware.backend, runtime),
hardware,
boundaries,
postprocess
)
end




"""
hardware = Hardware(backend, workgroup)
Expand Down
60 changes: 54 additions & 6 deletions src/Solve/Solve_1_api.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export explicit_relaxation!, implicit_relaxation!, implicit_relaxation_diagdom!,
export solve_system!
export solve_equation!
export residual!
export AdaptiveTimeStepping

struct SolverSetup{
F<:AbstractFloat,
Expand Down Expand Up @@ -81,27 +82,68 @@ SolverSetup(;
float_type(atol),
float_type(rtol))

struct Runtime{I<:Integer,F<:AbstractFloat}
struct AdaptiveTimeStepping{F<:AbstractFloat}
maxCo::F
minShrink::F
maxGrow::F
end
Adapt.@adapt_structure AdaptiveTimeStepping

"""
AdaptiveTimeStepping(;
# keyword arguments

maxCo=0.75,
minShrink=0.1,
maxGrow=1.2
)

Constructs an `AdaptiveTimeStepping` object used to control automatic time-step adjustment
based on the Courant number.

This struct is passed optionally to `Runtime` and enables adaptive time stepping in transient
simulations. If not provided, a fixed time step is used.

# Input arguments

- `maxCo::AbstractFloat`: target maximum Courant number. The time step will be adjusted
such that the computed Courant number approaches this value.
- `minShrink::AbstractFloat`: lower bound on the multiplicative factor applied to the
current time step. Prevents excessively large reductions in a single update.
- `maxGrow::AbstractFloat`: upper bound on the multiplicative factor applied to the
current time step. Prevents excessive time-step growth.
"""
AdaptiveTimeStepping(;
maxCo=0.75,
minShrink=0.1,
maxGrow=1.2
) = AdaptiveTimeStepping(float(maxCo), float(minShrink), float(maxGrow))

struct Runtime{I<:Integer,F<:AbstractFloat, V<:AbstractVector{F}, A<:Union{Nothing, AdaptiveTimeStepping}}
iterations::I
dt::F
dt::V
write_interval::I
adaptive::A
end
Adapt.@adapt_structure Runtime

"""
Runtime(;
# keyword arguments

iterations::I,
write_interval::I,
time_step::N
time_step::N,
adaptive::A
) where {I<:Integer,N<:Number} = begin

# returned Runtime struct
Runtime{I<:Integer,F<:AbstractFloat}
(
iterations=iterations,
dt=time_step,
write_interval=write_interval
write_interval=write_interval,
adaptive=adaptive
)
end

Expand All @@ -112,15 +154,21 @@ This is a convenience function to set the top-level runtime information. The inp
- `iterations::Integer`: specifies the number of iterations in a simulation run.
- `write_interval::Integer`: defines how often simulation results are written to file (on the current working directory). The interval is currently based on number of iterations. Set to `-1` to run without writing results to file.
- `time_step::AbstractFloat`: the time step to use in the simulation. Notice that for steady solvers this is simply a counter and it is recommended to simply use `1`.
- `adaptive::Union{Nothing, AdaptiveTimeStepping}`: optionally enables adaptive time stepping. Pass an `AdaptiveTimeStepping` object to automatically adjust `dt` based on the Courant number during transient simulations. Defaults to `nothing`, meaning a fixed time step is used.

# Example

```julia
runtime = Runtime(iterations=2000, time_step=1, write_interval=2000)
```
"""
Runtime(; iterations::I, write_interval::I, time_step::N) where {I<:Integer,N<:Number} = begin
Runtime(iterations, float(time_step), write_interval)
Runtime(; iterations::I,
write_interval::I,
time_step::N,
adaptive=nothing) where {I<:Integer,N<:Number} = begin

val = float(time_step)
Runtime(iterations, [val], write_interval, adaptive)
end

# Set schemes function definition with default set variables
Expand Down
15 changes: 13 additions & 2 deletions src/Solvers/Solvers_0_functions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ end
@kernel function _max_courant_number!(cellsCourant, U, runtime, mesh::Mesh3)
i = @index(Global)
@uniform cells = mesh.cells
dt = runtime.dt
dt = runtime.dt[1]
umag = norm(U[i])
volume = cells[i].volume
dx = volume^0.333333
Expand All @@ -277,9 +277,20 @@ end
@kernel function _max_courant_number!(cellsCourant, U, runtime, mesh::Mesh2)
i = @index(Global)
@uniform cells = mesh.cells
dt = runtime.dt
dt = runtime.dt[1]
umag = norm(U[i])
volume = cells[i].volume
dx = volume^0.5
cellsCourant[i] = umag * dt / dx
end


update_dt!(runtime::Runtime{<:Any,<:Any,<:Any,Nothing}, courant) = nothing

function update_dt!(runtime::Runtime{<:Any,<:Any,<:Any,<:AdaptiveTimeStepping}, courant)
(; maxCo, maxGrow, minShrink) = runtime.adaptive

courant_factor = maxCo / (courant + eps())
new_dt_factor = clamp(courant_factor, minShrink, maxGrow)
runtime.dt .= runtime.dt .* new_dt_factor
end
5 changes: 4 additions & 1 deletion src/Solvers/Solvers_1_CSIMPLE.jl
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,11 @@ function CSIMPLE(
(; iterations, write_interval,dt) = runtime
(; backend) = hardware

dt_cpu = zeros(_get_float(mesh), 1)
copyto!(dt_cpu, config.runtime.dt)

# rho = get_flux(U_eqn, 1)
postprocess = convert_time_to_iterations(postprocess,model,dt,iterations)
postprocess = convert_time_to_iterations(postprocess,model,dt_cpu[1],iterations)
mdotf = get_flux(U_eqn, 2)
mueff = get_flux(U_eqn, 3)
mueffgradUt = get_source(U_eqn, 2)
Expand Down
6 changes: 4 additions & 2 deletions src/Solvers/Solvers_1_LAPLACE.jl
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,10 @@ function LAPLACE(
(; iterations, write_interval, dt) = runtime
(; backend) = hardware

dt_cpu = zeros(_get_float(mesh), 1)
copyto!(dt_cpu, config.runtime.dt)

postprocess = convert_time_to_iterations(postprocess,model,dt,iterations)
postprocess = convert_time_to_iterations(postprocess,model,dt_cpu[1],iterations)
@info "Starting LAPLACE loops..."
progress = Progress(iterations; dt=1.0, showspeed=true)

Expand Down Expand Up @@ -154,7 +156,7 @@ function LAPLACE(

ProgressMeter.next!(
progress, showvalues = [
(:time, iteration*runtime.dt),
(:time, iteration*dt_cpu[1]),
(:T_residual, R_T[iteration])
]
)
Expand Down
6 changes: 4 additions & 2 deletions src/Solvers/Solvers_1_SIMPLE.jl
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,11 @@ function SIMPLE(
(; solvers, schemes, runtime, hardware, boundaries, postprocess) = config
(; iterations, write_interval,dt) = runtime
(; backend) = hardware

dt_cpu = zeros(_get_float(mesh), 1)
copyto!(dt_cpu, config.runtime.dt)

postprocess = convert_time_to_iterations(postprocess,model,dt,iterations)
postprocess = convert_time_to_iterations(postprocess,model,dt_cpu[1],iterations)
mdotf = get_flux(U_eqn, 2)
nueff = get_flux(U_eqn, 3)
rDf = get_flux(p_eqn, 1)
Expand Down Expand Up @@ -150,7 +153,6 @@ function SIMPLE(
grad!(∇p, pf, p, boundaries.p, time, config)
limit_gradient!(schemes.p.limiter, ∇p, p, config)


update_nueff!(nueff, nu, model.turbulence, config)

@info "Starting SIMPLE loops..."
Expand Down
Loading