TugJulia/julia/tug/Simulation.jl
nebmit 957f73bb83
refactor!: structural changes
Improved julia structs and removed redundant calculations

[skip ci]
2023-11-20 12:16:15 +01:00

144 lines
5.5 KiB
Julia

using Printf
include("Grid.jl")
include("Boundary.jl")
include("Core/BTCS.jl")
@enum APPROACH BTCS
@enum SOLVER EIGEN_LU_SOLVER
@enum CONSOLE_OUTPUT CONSOLE_OUTPUT_OFF CONSOLE_OUTPUT_ON CONSOLE_OUTPUT_VERBOSE
@enum CSV_OUPUT CSV_OUPUT_OFF CSV_OUPUT_ON CSV_OUPUT_VERBOSE CSV_OUPUT_XTREME
# Create the Simulation class
struct Simulation{T,approach,solver}
grid::Grid{T}
bc::Boundary{T}
approach::APPROACH
solver::SOLVER
iterations::Int
numThreads::Int
timestep::T
consoleOutput::CONSOLE_OUTPUT
csvOutput::CSV_OUPUT
function Simulation(grid::Grid{T}, bc::Boundary{T}, approach::APPROACH=BTCS,
solver::SOLVER=EIGEN_LU_SOLVER, iterations::Int=1, numThreads::Int=1, timestep::T=0.1,
consoleOutput::CONSOLE_OUTPUT=CONSOLE_OUTPUT_OFF, csvOutput::CSV_OUPUT=CSV_OUPUT_OFF) where {T}
new{T,APPROACH,SOLVER}(grid, bc, approach, solver, iterations, numThreads, timestep, consoleOutput, csvOutput)
end
end
function createCSVfile(simulation::Simulation{T,approach,solver})::IOStream where {T,approach,solver}
appendIdent = 0
approachString = (simulation.approach == BTCS) ? "BTCS" : "UNKNOWN" # Add other approaches as needed
row = simulation.grid.rows
col = simulation.grid.cols
numIterations = simulation.iterations
filename = string(approachString, "_", row, "_", col, "_", numIterations, ".csv")
while isfile(filename)
appendIdent += 1
filename = string(approachString, "_", row, "_", col, "_", numIterations, "-", appendIdent, ".csv")
end
# Write boundary conditions if required
if simulation.csvOutput == CSV_OUPUT_XTREME
open(filename, "w") do file
writeBoundarySideValues(file, simulation.bc, LEFT)
writeBoundarySideValues(file, simulation.bc, RIGHT)
if simulation.grid.dim == 2
writeBoundarySideValues(file, simulation.bc, TOP)
writeBoundarySideValues(file, simulation.bc, BOTTOM)
end
write(file, "\n\n")
end
end
file = open(filename, "a")
return file
end
function writeBoundarySideValues(file, bc::Boundary{T}, side) where {T}
values::Vector{BoundaryElement} = getBoundarySide(bc, side)
formatted_values = join(map(getValue, values), " ")
write(file, formatted_values, "\n")
end
function printConcentrationsCSV(simulation::Simulation{T,approach,solver}, file::IOStream) where {T,approach,solver}
concentrations = simulation.grid.concentrations[]
for row in eachrow(concentrations)
formatted_row = [Printf.@sprintf("%.6g", x) for x in row] # Format each element like is done in the C++ version using Eigen3
println(file, join(formatted_row, " "))
end
println(file) # Add extra newlines for separation
println(file)
end
function printConcentrations(simulation::Simulation{T,approach,solver}) where {T,approach,solver}
println(simulation.grid.concentrations[])
end
function run(simulation::Simulation{T,approach,solver}) where {T,approach,solver}
file = nothing
try
if simulation.csvOutput > CSV_OUPUT_OFF
file = createCSVfile(simulation)
end
if simulation.approach == BTCS
if simulation.solver == EIGEN_LU_SOLVER
for _ in 1:(simulation.iterations)
if simulation.consoleOutput >= CONSOLE_OUTPUT_VERBOSE
printConcentrations(simulation)
end
if simulation.csvOutput >= CSV_OUPUT_VERBOSE
printConcentrationsCSV(simulation, file)
end
BTCS_step(simulation.grid, simulation.bc, simulation.timestep, simulation.numThreads)
end
else
error("Undefined solver!")
end
else
error("Undefined approach!")
end
if simulation.consoleOutput == CONSOLE_OUTPUT_ON || simulation.consoleOutput == CONSOLE_OUTPUT_VERBOSE
printConcentrations(simulation)
end
if simulation.csvOutput == CSV_OUPUT_ON || simulation.csvOutput == CSV_OUPUT_VERBOSE || simulation.csvOutput == CSV_OUPUT_XTREME
printConcentrationsCSV(simulation, file)
end
finally
if file !== nothing
close(file)
end
end
end
function setTimestep(simulation::Simulation{T,approach,solver}, timestep::T) where {T,approach,solver}
return Simulation(simulation.grid, simulation.bc, simulation.approach, simulation.solver, simulation.iterations, simulation.numThreads, timestep, simulation.consoleOutput, simulation.csvOutput)
end
function setIterations(simulation::Simulation{T,approach,solver}, iterations::Int) where {T,approach,solver}
return Simulation(simulation.grid, simulation.bc, simulation.approach, simulation.solver, iterations, simulation.numThreads, simulation.timestep, simulation.consoleOutput, simulation.csvOutput)
end
function setOutputConsole(simulation::Simulation{T,approach,solver}, consoleOutput::CONSOLE_OUTPUT) where {T,approach,solver}
return Simulation(simulation.grid, simulation.bc, simulation.approach, simulation.solver, simulation.iterations, simulation.numThreads, simulation.timestep, consoleOutput, simulation.csvOutput)
end
function setOutputCSV(simulation::Simulation{T,approach,solver}, csvOutput::CSV_OUPUT) where {T,approach,solver}
return Simulation(simulation.grid, simulation.bc, simulation.approach, simulation.solver, simulation.iterations, simulation.numThreads, simulation.timestep, simulation.consoleOutput, csvOutput)
end