TugJulia/julia/tug/Simulation.jl
nebmit 7331e45eea
feat: added DynamicSimulation.jl
Added dynamic simulation for use with distributed systems and incremental simulations
Added module based exports
Added test for distributed systems

[skip ci]
2023-12-04 08:23:11 +01:00

117 lines
4.4 KiB
Julia

# Simulation.jl
# API of Simulation class, that holds all information regarding a
# specific simulation run like its timestep, number of iterations and output
# options. Simulation object also holds a predefined Grid and Boundary object.
# Translated from C++'s Simulation.hpp.
include("AbstractSimulation.jl")
include("Boundary.jl")
include("Core/BTCS.jl")
include("Core/FTCS.jl")
include("Grid.jl")
# Simulation class
struct Simulation{T} <: AbstractSimulation{T}
grid::Grid{T}
bc::Boundary{T}
approach::APPROACH
iterations::Int
timestep::T
consoleOutput::CONSOLE_OUTPUT
csvOutput::CSV_OUTPUT
# Constructor
function Simulation(grid::Grid{T}, bc::Boundary{T}, approach::APPROACH=BTCS, iterations::Int=1, timestep::T=0.1,
consoleOutput::CONSOLE_OUTPUT=CONSOLE_OUTPUT_OFF, csvOutput::CSV_OUTPUT=CSV_OUTPUT_OFF) where {T}
new{T}(grid, bc, approach, iterations, timestep, consoleOutput, csvOutput)
end
end
function adjustTimestep(grid::Grid{T}, approach::APPROACH, timestep::T, iterations::Int)::Tuple{T,Int} where {T}
if approach == FTCS
if getDim(grid) == 1
deltaSquare = getDeltaCol(grid)
maxAlpha = maximum(getAlphaX(grid))
# Courant-Friedrichs-Lewy condition
cfl = deltaSquare / (4 * maxAlpha)
elseif getDim(grid) == 2
deltaColSquare = getDeltaCol(grid) * getDeltaCol(grid)
deltaRowSquare = getDeltaRow(grid) * getDeltaRow(grid)
minDeltaSquare = min(deltaColSquare, deltaRowSquare)
maxAlpha = min(maximum(getAlphaX(grid)), maximum(getAlphaY(grid)))
cfl = minDeltaSquare / (4 * maxAlpha)
end
if timestep > cfl
innerIterations = ceil(Int, timestep / cfl)
iterations = iterations * innerIterations
timestep = timestep / innerIterations
println("Warning: Timestep is too large for FTCS approach. Adjusting timestep to ", timestep, " and iterations to ", iterations, ".")
else
timestep = timestep
end
end
return timestep, iterations
end
function run(simulation::Simulation{T}) where {T}
file = nothing
try
if simulation.csvOutput > CSV_OUTPUT_OFF
file = createCSVfile(simulation)
end
function simulationStepCallback()
if simulation.consoleOutput >= CONSOLE_OUTPUT_VERBOSE
writeConcentrationsToCLI(simulation)
end
if simulation.csvOutput >= CSV_OUTPUT_VERBOSE
writeConcentrationsToCSV(file, simulation)
end
end
if simulation.approach == BTCS
runBTCS(simulation.grid, simulation.bc, simulation.timestep, simulation.iterations, simulationStepCallback)
elseif simulation.approach == FTCS
timestep, iterations = adjustTimestep(simulation.grid, simulation.approach, simulation.timestep, simulation.iterations)
runFTCS(simulation.grid, simulation.bc, timestep, iterations, simulationStepCallback)
else
error("Undefined approach!")
end
if simulation.consoleOutput >= CONSOLE_OUTPUT_ON
writeConcentrationsToCLI(simulation)
end
if simulation.csvOutput >= CSV_OUTPUT_ON
writeConcentrationsToCSV(file, simulation)
end
finally
if file !== nothing
close(file)
end
end
end
function setIterations(simulation::Simulation{T}, iterations::Int)::Simulation{T} where {T}
return Simulation(simulation.grid, simulation.bc, simulation.approach, iterations, simulation.timestep, simulation.consoleOutput, simulation.csvOutput)
end
function setOutputConsole(simulation::Simulation{T}, consoleOutput::CONSOLE_OUTPUT)::Simulation{T} where {T}
return Simulation(simulation.grid, simulation.bc, simulation.approach, simulation.iterations, simulation.timestep, consoleOutput, simulation.csvOutput)
end
function setOutputCSV(simulation::Simulation{T}, csvOutput::CSV_OUTPUT)::Simulation{T} where {T}
return Simulation(simulation.grid, simulation.bc, simulation.approach, simulation.iterations, simulation.timestep, simulation.consoleOutput, csvOutput)
end
function setTimestep(simulation::Simulation{T}, timestep::T)::Simulation{T} where {T}
return Simulation(simulation.grid, simulation.bc, simulation.approach, simulation.iterations, timestep, simulation.consoleOutput, simulation.csvOutput)
end