style: applied linting recommendations
This commit is contained in:
parent
1e57d8b5b5
commit
39eacff904
@ -32,7 +32,13 @@ Enum representing the level of CSV file output for the simulation.
|
||||
|
||||
abstract type AbstractSimulation{T} end
|
||||
|
||||
function adjustTimestep(grid::Grid{T}, approach::APPROACH, timestep::T, iterations::Int, verbose::Bool)::Tuple{T,Int} where {T}
|
||||
function adjustTimestep(
|
||||
grid::Grid{T},
|
||||
approach::APPROACH,
|
||||
timestep::T,
|
||||
iterations::Int,
|
||||
verbose::Bool,
|
||||
)::Tuple{T,Int} where {T}
|
||||
if approach == FTCS
|
||||
if getDim(grid) == 1
|
||||
deltaSquare = getDeltaCol(grid)
|
||||
@ -55,7 +61,13 @@ function adjustTimestep(grid::Grid{T}, approach::APPROACH, timestep::T, iteratio
|
||||
iterations = iterations * innerIterations
|
||||
timestep = timestep / innerIterations
|
||||
if verbose
|
||||
println("Warning: Timestep is too large for FTCS approach. Adjusting timestep to ", timestep, " and iterations to ", iterations, ".")
|
||||
println(
|
||||
"Warning: Timestep is too large for FTCS approach. Adjusting timestep to ",
|
||||
timestep,
|
||||
" and iterations to ",
|
||||
iterations,
|
||||
".",
|
||||
)
|
||||
end
|
||||
else
|
||||
timestep = timestep
|
||||
@ -64,7 +76,10 @@ function adjustTimestep(grid::Grid{T}, approach::APPROACH, timestep::T, iteratio
|
||||
return timestep, iterations
|
||||
end
|
||||
|
||||
function createCSVfile(simulation::AbstractSimulation{T}, grid::Union{Grid{T},Nothing}=nothing) where {T}
|
||||
function createCSVfile(
|
||||
simulation::AbstractSimulation{T},
|
||||
grid::Union{Grid{T},Nothing} = nothing,
|
||||
) where {T}
|
||||
grid = grid === nothing ? simulation.grid : grid
|
||||
approachString = string(simulation.approach)
|
||||
rows = getRows(grid)
|
||||
@ -76,7 +91,18 @@ function createCSVfile(simulation::AbstractSimulation{T}, grid::Union{Grid{T},No
|
||||
appendIdent = 0
|
||||
while isfile(filename)
|
||||
appendIdent += 1
|
||||
filename = string(approachString, "_", rows, "_", cols, "_", numIterations, "-", appendIdent, ".csv")
|
||||
filename = string(
|
||||
approachString,
|
||||
"_",
|
||||
rows,
|
||||
"_",
|
||||
cols,
|
||||
"_",
|
||||
numIterations,
|
||||
"-",
|
||||
appendIdent,
|
||||
".csv",
|
||||
)
|
||||
end
|
||||
|
||||
# Write boundary conditions if required
|
||||
@ -103,12 +129,19 @@ function writeBoundarySideValuesToCSV(file::IOStream, bc::Boundary{T}, side) whe
|
||||
write(file, formatted_values, "\n")
|
||||
end
|
||||
|
||||
function writeConcentrationsToCLI(simulation::AbstractSimulation{T}, grid::Union{Grid{T},Nothing}=nothing) where {T}
|
||||
function writeConcentrationsToCLI(
|
||||
simulation::AbstractSimulation{T},
|
||||
grid::Union{Grid{T},Nothing} = nothing,
|
||||
) where {T}
|
||||
grid = grid === nothing ? simulation.grid : grid
|
||||
println(getConcentrations(grid))
|
||||
end
|
||||
|
||||
function writeConcentrationsToCSV(file::IOStream, simulation::AbstractSimulation{T}, grid::Union{Grid{T},Nothing}=nothing) where {T}
|
||||
function writeConcentrationsToCSV(
|
||||
file::IOStream,
|
||||
simulation::AbstractSimulation{T},
|
||||
grid::Union{Grid{T},Nothing} = nothing,
|
||||
) where {T}
|
||||
grid = grid === nothing ? simulation.grid : grid
|
||||
concentrations = getConcentrations(grid)
|
||||
|
||||
|
||||
@ -128,10 +128,10 @@ struct Boundary{T}
|
||||
boundaries[Int(LEFT)] = [BoundaryElement{T}()]
|
||||
boundaries[Int(RIGHT)] = [BoundaryElement{T}()]
|
||||
elseif dim == 2
|
||||
boundaries[Int(LEFT)] = [BoundaryElement{T}() for _ in 1:rows]
|
||||
boundaries[Int(RIGHT)] = [BoundaryElement{T}() for _ in 1:rows]
|
||||
boundaries[Int(TOP)] = [BoundaryElement{T}() for _ in 1:cols]
|
||||
boundaries[Int(BOTTOM)] = [BoundaryElement{T}() for _ in 1:cols]
|
||||
boundaries[Int(LEFT)] = [BoundaryElement{T}() for _ = 1:rows]
|
||||
boundaries[Int(RIGHT)] = [BoundaryElement{T}() for _ = 1:rows]
|
||||
boundaries[Int(TOP)] = [BoundaryElement{T}() for _ = 1:cols]
|
||||
boundaries[Int(BOTTOM)] = [BoundaryElement{T}() for _ = 1:cols]
|
||||
else
|
||||
throw(ArgumentError("Only 1- and 2-dimensional grids are defined!"))
|
||||
end
|
||||
@ -153,9 +153,17 @@ Retrieves the type of the boundary element at the specified side and index.
|
||||
# Returns
|
||||
The type of the boundary element (`TYPE`).
|
||||
"""
|
||||
function getBoundaryElementType(boundary::Boundary{T}, side::SIDE, index::Int)::TYPE where {T}
|
||||
function getBoundaryElementType(
|
||||
boundary::Boundary{T},
|
||||
side::SIDE,
|
||||
index::Int,
|
||||
)::TYPE where {T}
|
||||
if boundary.dim == 1 && (side == BOTTOM || side == TOP)
|
||||
throw(ArgumentError("For the one-dimensional case, only the left and right borders exist."))
|
||||
throw(
|
||||
ArgumentError(
|
||||
"For the one-dimensional case, only the left and right borders exist.",
|
||||
),
|
||||
)
|
||||
end
|
||||
if index < 1 || index > (side in (LEFT, RIGHT) ? boundary.rows : boundary.cols)
|
||||
throw(ArgumentError("Index out of bounds!"))
|
||||
@ -180,7 +188,11 @@ The value of the boundary element.
|
||||
"""
|
||||
function getBoundaryElementValue(boundary::Boundary{T}, side::SIDE, index::Int)::T where {T}
|
||||
if boundary.dim == 1 && (side == BOTTOM || side == TOP)
|
||||
throw(ArgumentError("For the one-dimensional case, only the left and right borders exist."))
|
||||
throw(
|
||||
ArgumentError(
|
||||
"For the one-dimensional case, only the left and right borders exist.",
|
||||
),
|
||||
)
|
||||
end
|
||||
if index < 1 || index > (side in (LEFT, RIGHT) ? boundary.rows : boundary.cols)
|
||||
throw(ArgumentError("Index out of bounds!"))
|
||||
@ -201,9 +213,16 @@ Retrieves the boundary elements at the specified side.
|
||||
# Returns
|
||||
The boundary elements at the specified side.
|
||||
"""
|
||||
function getBoundarySide(boundary::Boundary{T}, side::SIDE)::Vector{BoundaryElement{T}} where {T}
|
||||
function getBoundarySide(
|
||||
boundary::Boundary{T},
|
||||
side::SIDE,
|
||||
)::Vector{BoundaryElement{T}} where {T}
|
||||
if boundary.dim == 1 && (side == BOTTOM || side == TOP)
|
||||
throw(ArgumentError("For the one-dimensional case, only the left and right borders exist."))
|
||||
throw(
|
||||
ArgumentError(
|
||||
"For the one-dimensional case, only the left and right borders exist.",
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
boundary.boundaries[Int(side)]
|
||||
@ -221,15 +240,22 @@ Sets the boundary elements at the specified side to CLOSED.
|
||||
# Returns
|
||||
The boundary elements at the specified side.
|
||||
"""
|
||||
function setBoundarySideClosed!(boundary::Boundary{T}, side::SIDE)::Vector{BoundaryElement{T}} where {T}
|
||||
function setBoundarySideClosed!(
|
||||
boundary::Boundary{T},
|
||||
side::SIDE,
|
||||
)::Vector{BoundaryElement{T}} where {T}
|
||||
if boundary.dim == 1 && (side == BOTTOM || side == TOP)
|
||||
throw(ArgumentError("For the one-dimensional case, only the left and right borders exist."))
|
||||
throw(
|
||||
ArgumentError(
|
||||
"For the one-dimensional case, only the left and right borders exist.",
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
is_vertical = side in (LEFT, RIGHT)
|
||||
n = is_vertical ? boundary.rows : boundary.cols
|
||||
|
||||
boundary.boundaries[Int(side)] = [BoundaryElement{T}() for _ in 1:n]
|
||||
boundary.boundaries[Int(side)] = [BoundaryElement{T}() for _ = 1:n]
|
||||
end
|
||||
|
||||
"""
|
||||
@ -245,13 +271,21 @@ Sets the boundary elements at the specified side to CONSTANT with the specified
|
||||
# Returns
|
||||
The boundary elements at the specified side.
|
||||
"""
|
||||
function setBoundarySideConstant!(boundary::Boundary{T}, side::SIDE, value::T)::Vector{BoundaryElement{T}} where {T}
|
||||
function setBoundarySideConstant!(
|
||||
boundary::Boundary{T},
|
||||
side::SIDE,
|
||||
value::T,
|
||||
)::Vector{BoundaryElement{T}} where {T}
|
||||
if boundary.dim == 1 && (side == BOTTOM || side == TOP)
|
||||
throw(ArgumentError("For the one-dimensional case, only the left and right borders exist."))
|
||||
throw(
|
||||
ArgumentError(
|
||||
"For the one-dimensional case, only the left and right borders exist.",
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
is_vertical = side in (LEFT, RIGHT)
|
||||
n = is_vertical ? boundary.rows : boundary.cols
|
||||
|
||||
boundary.boundaries[Int(side)] = [BoundaryElement{T}(value) for _ in 1:n]
|
||||
boundary.boundaries[Int(side)] = [BoundaryElement{T}(value) for _ = 1:n]
|
||||
end
|
||||
|
||||
@ -8,7 +8,12 @@ using Base.Threads
|
||||
using LinearAlgebra
|
||||
using SparseArrays
|
||||
|
||||
function calcBoundaryCoeff(alpha_center::T, alpha_side::T, sx::T, bcType::TYPE)::Tuple{T,T} where {T}
|
||||
function calcBoundaryCoeff(
|
||||
alpha_center::T,
|
||||
alpha_side::T,
|
||||
sx::T,
|
||||
bcType::TYPE,
|
||||
)::Tuple{T,T} where {T}
|
||||
alpha = calcAlphaIntercell(alpha_center, alpha_side)
|
||||
sideCoeff = -sx * alpha
|
||||
|
||||
@ -23,12 +28,31 @@ function calcBoundaryCoeff(alpha_center::T, alpha_side::T, sx::T, bcType::TYPE):
|
||||
return (centerCoeff, sideCoeff)
|
||||
end
|
||||
|
||||
function createCoeffMatrix(alpha::Matrix{T}, alpha_left::Vector{T}, alpha_right::Vector{T}, bcLeft::Vector{BoundaryElement{T}}, bcRight::Vector{BoundaryElement{T}}, numCols::Int, rowIndex::Int, sx::T)::Tridiagonal{T} where {T}
|
||||
function createCoeffMatrix(
|
||||
alpha::Matrix{T},
|
||||
alpha_left::Vector{T},
|
||||
alpha_right::Vector{T},
|
||||
bcLeft::Vector{BoundaryElement{T}},
|
||||
bcRight::Vector{BoundaryElement{T}},
|
||||
numCols::Int,
|
||||
rowIndex::Int,
|
||||
sx::T,
|
||||
)::Tridiagonal{T} where {T}
|
||||
# Determine left side boundary coefficients based on boundary condition
|
||||
centerCoeffTop, rightCoeffTop = calcBoundaryCoeff(alpha[rowIndex, 1], alpha[rowIndex, 2], sx, getType(bcLeft[rowIndex]))
|
||||
centerCoeffTop, rightCoeffTop = calcBoundaryCoeff(
|
||||
alpha[rowIndex, 1],
|
||||
alpha[rowIndex, 2],
|
||||
sx,
|
||||
getType(bcLeft[rowIndex]),
|
||||
)
|
||||
|
||||
# Determine right side boundary coefficients based on boundary condition
|
||||
centerCoeffBottom, leftCoeffBottom = calcBoundaryCoeff(alpha[rowIndex, numCols], alpha[rowIndex, numCols-1], sx, getType(bcRight[rowIndex]))
|
||||
centerCoeffBottom, leftCoeffBottom = calcBoundaryCoeff(
|
||||
alpha[rowIndex, numCols],
|
||||
alpha[rowIndex, numCols-1],
|
||||
sx,
|
||||
getType(bcRight[rowIndex]),
|
||||
)
|
||||
|
||||
dl = [-sx .* alpha_left; leftCoeffBottom]
|
||||
d = [centerCoeffTop; 1 .+ sx .* (alpha_right + alpha_left); centerCoeffBottom]
|
||||
@ -37,26 +61,55 @@ function createCoeffMatrix(alpha::Matrix{T}, alpha_left::Vector{T}, alpha_right:
|
||||
end
|
||||
|
||||
|
||||
function calcExplicitConcentrationsBoundaryClosed(conc_center::T, alpha_center::T, alpha_neighbor::T, sy::T)::T where {T}
|
||||
function calcExplicitConcentrationsBoundaryClosed(
|
||||
conc_center::T,
|
||||
alpha_center::T,
|
||||
alpha_neighbor::T,
|
||||
sy::T,
|
||||
)::T where {T}
|
||||
alpha = calcAlphaIntercell(alpha_center, alpha_neighbor)
|
||||
return (sy * alpha + (1 - sy * alpha)) * conc_center
|
||||
end
|
||||
|
||||
function calcExplicitConcentrationsBoundaryConstant(conc_center::T, conc_bc::T, alpha_center::T, alpha_neighbor::T, sy::T)::T where {T}
|
||||
function calcExplicitConcentrationsBoundaryConstant(
|
||||
conc_center::T,
|
||||
conc_bc::T,
|
||||
alpha_center::T,
|
||||
alpha_neighbor::T,
|
||||
sy::T,
|
||||
)::T where {T}
|
||||
alpha_center_neighbor = calcAlphaIntercell(alpha_center, alpha_neighbor)
|
||||
alpha_center_center = alpha_center == alpha_neighbor ? alpha_center_neighbor : calcAlphaIntercell(alpha_center, alpha_center)
|
||||
alpha_center_center =
|
||||
alpha_center == alpha_neighbor ? alpha_center_neighbor :
|
||||
calcAlphaIntercell(alpha_center, alpha_center)
|
||||
|
||||
return sy * alpha_center_neighbor * conc_center +
|
||||
(1 - sy * (alpha_center_center + 2 * alpha_center)) * conc_center +
|
||||
sy * alpha_center * conc_bc
|
||||
end
|
||||
|
||||
function calcExplicitConcentrationsBoundaryClosed(conc_center::Vector{T}, alpha::Vector{T}, sy::T)::T where {T}
|
||||
function calcExplicitConcentrationsBoundaryClosed(
|
||||
conc_center::Vector{T},
|
||||
alpha::Vector{T},
|
||||
sy::T,
|
||||
)::T where {T}
|
||||
return (sy .* alpha .+ (1 .- sy .* alpha)) .* conc_center
|
||||
end
|
||||
|
||||
# creates a solution vector for next time step from the current state of concentrations
|
||||
function writeSolutionVector!(sv::Vector{T}, concentrations::Matrix{T}, alphaX::Matrix{T}, alphaY::Matrix{T}, bcLeft::Vector{BoundaryElement{T}}, bcRight::Vector{BoundaryElement{T}}, bcTop::Vector{BoundaryElement{T}}, bcBottom::Vector{BoundaryElement{T}}, rowIndex::Int, sx::T, sy::T) where {T}
|
||||
function writeSolutionVector!(
|
||||
sv::Vector{T},
|
||||
concentrations::Matrix{T},
|
||||
alphaX::Matrix{T},
|
||||
alphaY::Matrix{T},
|
||||
bcLeft::Vector{BoundaryElement{T}},
|
||||
bcRight::Vector{BoundaryElement{T}},
|
||||
bcTop::Vector{BoundaryElement{T}},
|
||||
bcBottom::Vector{BoundaryElement{T}},
|
||||
rowIndex::Int,
|
||||
sx::T,
|
||||
sy::T,
|
||||
) where {T}
|
||||
numRows = size(concentrations, 1)
|
||||
length = size(sv, 1)
|
||||
|
||||
@ -64,9 +117,20 @@ function writeSolutionVector!(sv::Vector{T}, concentrations::Matrix{T}, alphaX::
|
||||
if rowIndex == 1
|
||||
@inbounds for i = 1:length
|
||||
if getType(bcTop[i]) == CONSTANT
|
||||
sv[i] = calcExplicitConcentrationsBoundaryConstant(concentrations[rowIndex, i], getValue(bcTop[i]), alphaY[rowIndex, i], alphaY[rowIndex+1, i], sy)
|
||||
sv[i] = calcExplicitConcentrationsBoundaryConstant(
|
||||
concentrations[rowIndex, i],
|
||||
getValue(bcTop[i]),
|
||||
alphaY[rowIndex, i],
|
||||
alphaY[rowIndex+1, i],
|
||||
sy,
|
||||
)
|
||||
elseif getType(bcTop[i]) == CLOSED
|
||||
sv[i] = calcExplicitConcentrationsBoundaryClosed(concentrations[rowIndex, i], alphaY[rowIndex, i], alphaY[rowIndex+1, i], sy)
|
||||
sv[i] = calcExplicitConcentrationsBoundaryClosed(
|
||||
concentrations[rowIndex, i],
|
||||
alphaY[rowIndex, i],
|
||||
alphaY[rowIndex+1, i],
|
||||
sy,
|
||||
)
|
||||
else
|
||||
error("Undefined Boundary Condition Type somewhere on Left or Top!")
|
||||
end
|
||||
@ -76,11 +140,16 @@ function writeSolutionVector!(sv::Vector{T}, concentrations::Matrix{T}, alphaX::
|
||||
# Inner rows
|
||||
if rowIndex > 1 && rowIndex < numRows
|
||||
@inbounds for i = 1:length
|
||||
alpha_here_below = calcAlphaIntercell(alphaY[rowIndex, i], alphaY[rowIndex+1, i])
|
||||
alpha_here_above = alphaY[rowIndex+1, i] == alphaY[rowIndex-1, i] ? alpha_here_below : calcAlphaIntercell(alphaY[rowIndex-1, i], alphaY[rowIndex, i]) # calcAlphaIntercell is symmetric, so we can use it for both directions
|
||||
sv[i] = sy * alpha_here_below * concentrations[rowIndex+1, i] +
|
||||
(1 - sy * (alpha_here_below + alpha_here_above)) * concentrations[rowIndex, i] +
|
||||
sy * alpha_here_above * concentrations[rowIndex-1, i]
|
||||
alpha_here_below =
|
||||
calcAlphaIntercell(alphaY[rowIndex, i], alphaY[rowIndex+1, i])
|
||||
alpha_here_above =
|
||||
alphaY[rowIndex+1, i] == alphaY[rowIndex-1, i] ? alpha_here_below :
|
||||
calcAlphaIntercell(alphaY[rowIndex-1, i], alphaY[rowIndex, i]) # calcAlphaIntercell is symmetric, so we can use it for both directions
|
||||
sv[i] =
|
||||
sy * alpha_here_below * concentrations[rowIndex+1, i] +
|
||||
(1 - sy * (alpha_here_below + alpha_here_above)) *
|
||||
concentrations[rowIndex, i] +
|
||||
sy * alpha_here_above * concentrations[rowIndex-1, i]
|
||||
end
|
||||
end
|
||||
|
||||
@ -88,9 +157,20 @@ function writeSolutionVector!(sv::Vector{T}, concentrations::Matrix{T}, alphaX::
|
||||
if rowIndex == numRows
|
||||
@inbounds for i = 1:length
|
||||
if getType(bcBottom[i]) == CONSTANT
|
||||
sv[i] = calcExplicitConcentrationsBoundaryConstant(concentrations[rowIndex, i], getValue(bcBottom[i]), alphaY[rowIndex, i], alphaY[rowIndex-1, i], sy)
|
||||
sv[i] = calcExplicitConcentrationsBoundaryConstant(
|
||||
concentrations[rowIndex, i],
|
||||
getValue(bcBottom[i]),
|
||||
alphaY[rowIndex, i],
|
||||
alphaY[rowIndex-1, i],
|
||||
sy,
|
||||
)
|
||||
elseif getType(bcBottom[i]) == CLOSED
|
||||
sv[i] = calcExplicitConcentrationsBoundaryClosed(concentrations[rowIndex, i], alphaY[rowIndex, i], alphaY[rowIndex-1, i], sy)
|
||||
sv[i] = calcExplicitConcentrationsBoundaryClosed(
|
||||
concentrations[rowIndex, i],
|
||||
alphaY[rowIndex, i],
|
||||
alphaY[rowIndex-1, i],
|
||||
sy,
|
||||
)
|
||||
else
|
||||
error("Undefined Boundary Condition Type somewhere on Right or Bottom!")
|
||||
end
|
||||
@ -108,7 +188,13 @@ function writeSolutionVector!(sv::Vector{T}, concentrations::Matrix{T}, alphaX::
|
||||
end
|
||||
end
|
||||
|
||||
function BTCS_1D(grid::Grid{T}, bc::Boundary{T}, alpha_left::Matrix{T}, alpha_right::Matrix{T}, timestep::T) where {T}
|
||||
function BTCS_1D(
|
||||
grid::Grid{T},
|
||||
bc::Boundary{T},
|
||||
alpha_left::Matrix{T},
|
||||
alpha_right::Matrix{T},
|
||||
timestep::T,
|
||||
) where {T}
|
||||
sx = timestep / (getDeltaCol(grid) * getDeltaCol(grid))
|
||||
|
||||
alpha = getAlphaX(grid)
|
||||
@ -118,7 +204,16 @@ function BTCS_1D(grid::Grid{T}, bc::Boundary{T}, alpha_left::Matrix{T}, alpha_ri
|
||||
|
||||
concentrations::Matrix{T} = getConcentrations(grid)
|
||||
|
||||
A::Tridiagonal{T} = createCoeffMatrix(alpha, alpha_left[1, :], alpha_right[1, :], bcLeft, bcRight, length, 1, sx)
|
||||
A::Tridiagonal{T} = createCoeffMatrix(
|
||||
alpha,
|
||||
alpha_left[1, :],
|
||||
alpha_right[1, :],
|
||||
bcLeft,
|
||||
bcRight,
|
||||
length,
|
||||
1,
|
||||
sx,
|
||||
)
|
||||
b = concentrations[1, :]
|
||||
|
||||
if getType(bcLeft[1]) == CONSTANT
|
||||
@ -131,7 +226,15 @@ function BTCS_1D(grid::Grid{T}, bc::Boundary{T}, alpha_left::Matrix{T}, alpha_ri
|
||||
concentrations[1, :] = A \ b
|
||||
end
|
||||
|
||||
function BTCS_2D(grid::Grid{T}, bc::Boundary{T}, alphaX_left::Matrix{T}, alphaX_right::Matrix{T}, alphaY_t_left::Matrix{T}, alphaY_t_right::Matrix{T}, timestep::T) where {T}
|
||||
function BTCS_2D(
|
||||
grid::Grid{T},
|
||||
bc::Boundary{T},
|
||||
alphaX_left::Matrix{T},
|
||||
alphaX_right::Matrix{T},
|
||||
alphaY_t_left::Matrix{T},
|
||||
alphaY_t_right::Matrix{T},
|
||||
timestep::T,
|
||||
) where {T}
|
||||
rows = getRows(grid)
|
||||
cols = getCols(grid)
|
||||
sx = timestep / (2 * getDeltaCol(grid) * getDeltaCol(grid))
|
||||
@ -152,11 +255,32 @@ function BTCS_2D(grid::Grid{T}, bc::Boundary{T}, alphaX_left::Matrix{T}, alphaX_
|
||||
bcTop = getBoundarySide(bc, TOP)
|
||||
bcBottom = getBoundarySide(bc, BOTTOM)
|
||||
|
||||
localBs = [zeros(T, cols) for _ in 1:Threads.nthreads()]
|
||||
localBs = [zeros(T, cols) for _ = 1:Threads.nthreads()]
|
||||
Threads.@threads for i = 1:rows
|
||||
localB = localBs[Threads.threadid()]
|
||||
A::Tridiagonal{T} = createCoeffMatrix(alphaX, alphaX_left[i, :], alphaX_right[i, :], bcLeft, bcRight, cols, i, sx)
|
||||
writeSolutionVector!(localB, concentrations, alphaX, alphaY, bcLeft, bcRight, bcTop, bcBottom, i, sx, sy)
|
||||
A::Tridiagonal{T} = createCoeffMatrix(
|
||||
alphaX,
|
||||
alphaX_left[i, :],
|
||||
alphaX_right[i, :],
|
||||
bcLeft,
|
||||
bcRight,
|
||||
cols,
|
||||
i,
|
||||
sx,
|
||||
)
|
||||
writeSolutionVector!(
|
||||
localB,
|
||||
concentrations,
|
||||
alphaX,
|
||||
alphaY,
|
||||
bcLeft,
|
||||
bcRight,
|
||||
bcTop,
|
||||
bcBottom,
|
||||
i,
|
||||
sx,
|
||||
sy,
|
||||
)
|
||||
|
||||
concentrations_intermediate[i, :] = A \ localB
|
||||
end
|
||||
@ -165,11 +289,32 @@ function BTCS_2D(grid::Grid{T}, bc::Boundary{T}, alphaX_left::Matrix{T}, alphaX_
|
||||
concentrations_t = fetch(concentrations_t_task)
|
||||
|
||||
# Swap alphas, boundary conditions and sx/sy for column-wise calculation
|
||||
localBs = [zeros(T, rows) for _ in 1:Threads.nthreads()]
|
||||
localBs = [zeros(T, rows) for _ = 1:Threads.nthreads()]
|
||||
Threads.@threads for i = 1:cols
|
||||
localB = localBs[Threads.threadid()]
|
||||
A::Tridiagonal{T} = createCoeffMatrix(alphaY_t, alphaY_t_left[i, :], alphaY_t_right[i, :], bcTop, bcBottom, rows, i, sy)
|
||||
writeSolutionVector!(localB, concentrations_intermediate, alphaY_t, alphaX_t, bcTop, bcBottom, bcLeft, bcRight, i, sy, sx)
|
||||
A::Tridiagonal{T} = createCoeffMatrix(
|
||||
alphaY_t,
|
||||
alphaY_t_left[i, :],
|
||||
alphaY_t_right[i, :],
|
||||
bcTop,
|
||||
bcBottom,
|
||||
rows,
|
||||
i,
|
||||
sy,
|
||||
)
|
||||
writeSolutionVector!(
|
||||
localB,
|
||||
concentrations_intermediate,
|
||||
alphaY_t,
|
||||
alphaX_t,
|
||||
bcTop,
|
||||
bcBottom,
|
||||
bcLeft,
|
||||
bcRight,
|
||||
i,
|
||||
sy,
|
||||
sx,
|
||||
)
|
||||
|
||||
concentrations_t[i, :] = A \ localB
|
||||
end
|
||||
@ -179,18 +324,28 @@ function BTCS_2D(grid::Grid{T}, bc::Boundary{T}, alphaX_left::Matrix{T}, alphaX_
|
||||
setConcentrations!(grid, concentrations)
|
||||
end
|
||||
|
||||
function runBTCS(grid::Grid{T}, bc::Boundary{T}, timestep::T, iterations::Int, stepCallback::Function) where {T}
|
||||
function runBTCS(
|
||||
grid::Grid{T},
|
||||
bc::Boundary{T},
|
||||
timestep::T,
|
||||
iterations::Int,
|
||||
stepCallback::Function,
|
||||
) where {T}
|
||||
if getDim(grid) == 1
|
||||
length = getCols(grid)
|
||||
alpha = getAlphaX(grid)
|
||||
|
||||
alpha_left_task = Threads.@spawn calcAlphaIntercell(alpha[:, 1:(length-2)], alpha[:, 2:(length-1)])
|
||||
alpha_right_task = Threads.@spawn calcAlphaIntercell(alpha[:, 2:(length-1)], alpha[:, 3:length])
|
||||
alpha_left_task = Threads.@spawn calcAlphaIntercell(
|
||||
alpha[:, 1:(length-2)],
|
||||
alpha[:, 2:(length-1)],
|
||||
)
|
||||
alpha_right_task =
|
||||
Threads.@spawn calcAlphaIntercell(alpha[:, 2:(length-1)], alpha[:, 3:length])
|
||||
|
||||
alpha_left = fetch(alpha_left_task)
|
||||
alpha_right = fetch(alpha_right_task)
|
||||
|
||||
for _ in 1:(iterations)
|
||||
for _ = 1:(iterations)
|
||||
BTCS_1D(grid, bc, alpha_left, alpha_right, timestep)
|
||||
|
||||
stepCallback()
|
||||
@ -201,18 +356,32 @@ function runBTCS(grid::Grid{T}, bc::Boundary{T}, timestep::T, iterations::Int, s
|
||||
alphaX = getAlphaX(grid)
|
||||
alphaY_t = getAlphaY_t(grid)
|
||||
|
||||
alphaX_left_task = Threads.@spawn calcAlphaIntercell(alphaX[:, 1:(cols-2)], alphaX[:, 2:(cols-1)])
|
||||
alphaX_right_task = Threads.@spawn calcAlphaIntercell(alphaX[:, 2:(cols-1)], alphaX[:, 3:cols])
|
||||
alphaY_t_left_task = Threads.@spawn calcAlphaIntercell(alphaY_t[:, 1:(rows-2)], alphaY_t[:, 2:(rows-1)])
|
||||
alphaY_t_right_task = Threads.@spawn calcAlphaIntercell(alphaY_t[:, 2:(rows-1)], alphaY_t[:, 3:rows])
|
||||
alphaX_left_task =
|
||||
Threads.@spawn calcAlphaIntercell(alphaX[:, 1:(cols-2)], alphaX[:, 2:(cols-1)])
|
||||
alphaX_right_task =
|
||||
Threads.@spawn calcAlphaIntercell(alphaX[:, 2:(cols-1)], alphaX[:, 3:cols])
|
||||
alphaY_t_left_task = Threads.@spawn calcAlphaIntercell(
|
||||
alphaY_t[:, 1:(rows-2)],
|
||||
alphaY_t[:, 2:(rows-1)],
|
||||
)
|
||||
alphaY_t_right_task =
|
||||
Threads.@spawn calcAlphaIntercell(alphaY_t[:, 2:(rows-1)], alphaY_t[:, 3:rows])
|
||||
|
||||
alphaX_left = fetch(alphaX_left_task)
|
||||
alphaX_right = fetch(alphaX_right_task)
|
||||
alphaY_t_left = fetch(alphaY_t_left_task)
|
||||
alphaY_t_right = fetch(alphaY_t_right_task)
|
||||
|
||||
for _ in 1:(iterations)
|
||||
BTCS_2D(grid, bc, alphaX_left, alphaX_right, alphaY_t_left, alphaY_t_right, timestep)
|
||||
for _ = 1:(iterations)
|
||||
BTCS_2D(
|
||||
grid,
|
||||
bc,
|
||||
alphaX_left,
|
||||
alphaX_right,
|
||||
alphaY_t_left,
|
||||
alphaY_t_right,
|
||||
timestep,
|
||||
)
|
||||
|
||||
stepCallback()
|
||||
end
|
||||
|
||||
@ -7,8 +7,14 @@ using Base.Threads
|
||||
using LinearAlgebra
|
||||
using SparseArrays
|
||||
|
||||
function calcHorizontalChange(alphaX_next::T, alphaX_prev::T, alphaX_current::T,
|
||||
concentration_next::T, concentration_prev::T, concentration_current::T) where {T}
|
||||
function calcHorizontalChange(
|
||||
alphaX_next::T,
|
||||
alphaX_prev::T,
|
||||
alphaX_current::T,
|
||||
concentration_next::T,
|
||||
concentration_prev::T,
|
||||
concentration_current::T,
|
||||
) where {T}
|
||||
|
||||
intercellAlpha_next = calcAlphaIntercell(alphaX_next, alphaX_current)
|
||||
intercellAlpha_prev = calcAlphaIntercell(alphaX_prev, alphaX_current)
|
||||
@ -18,8 +24,14 @@ function calcHorizontalChange(alphaX_next::T, alphaX_prev::T, alphaX_current::T,
|
||||
intercellAlpha_prev * concentration_prev
|
||||
end
|
||||
|
||||
function calcHorizontalChangeLeftBoundary(boundaryType::TYPE, alphaX_next::T, alphaX_current::T,
|
||||
concentration_next::T, concentration_current::T, boundaryValue::T) where {T}
|
||||
function calcHorizontalChangeLeftBoundary(
|
||||
boundaryType::TYPE,
|
||||
alphaX_next::T,
|
||||
alphaX_current::T,
|
||||
concentration_next::T,
|
||||
concentration_current::T,
|
||||
boundaryValue::T,
|
||||
) where {T}
|
||||
intercellAlpha = calcAlphaIntercell(alphaX_next, alphaX_current)
|
||||
|
||||
if boundaryType == CONSTANT
|
||||
@ -33,8 +45,14 @@ function calcHorizontalChangeLeftBoundary(boundaryType::TYPE, alphaX_next::T, al
|
||||
end
|
||||
end
|
||||
|
||||
function calcHorizontalChangeRightBoundary(boundaryType::TYPE, alphaX_prev::T, alphaX_current::T,
|
||||
concentration_prev::T, concentration_current::T, boundaryValue::T) where {T}
|
||||
function calcHorizontalChangeRightBoundary(
|
||||
boundaryType::TYPE,
|
||||
alphaX_prev::T,
|
||||
alphaX_current::T,
|
||||
concentration_prev::T,
|
||||
concentration_current::T,
|
||||
boundaryValue::T,
|
||||
) where {T}
|
||||
intercellAlpha = calcAlphaIntercell(alphaX_prev, alphaX_current)
|
||||
|
||||
if boundaryType == CONSTANT
|
||||
@ -48,8 +66,14 @@ function calcHorizontalChangeRightBoundary(boundaryType::TYPE, alphaX_prev::T, a
|
||||
end
|
||||
end
|
||||
|
||||
function calcVerticalChange(alphaY_above::T, alphaY_below::T, alphaY_current::T,
|
||||
concentration_above::T, concentration_below::T, concentration_current::T) where {T}
|
||||
function calcVerticalChange(
|
||||
alphaY_above::T,
|
||||
alphaY_below::T,
|
||||
alphaY_current::T,
|
||||
concentration_above::T,
|
||||
concentration_below::T,
|
||||
concentration_current::T,
|
||||
) where {T}
|
||||
intercellAlpha_above = calcAlphaIntercell(alphaY_above, alphaY_current)
|
||||
intercellAlpha_below = calcAlphaIntercell(alphaY_below, alphaY_current)
|
||||
|
||||
@ -58,8 +82,14 @@ function calcVerticalChange(alphaY_above::T, alphaY_below::T, alphaY_current::T,
|
||||
intercellAlpha_below * concentration_below
|
||||
end
|
||||
|
||||
function calcVerticalChangeTopBoundary(boundaryType::TYPE, alphaY_above::T, alphaY_current::T,
|
||||
concentration_above::T, concentration_current::T, boundaryValue::T) where {T}
|
||||
function calcVerticalChangeTopBoundary(
|
||||
boundaryType::TYPE,
|
||||
alphaY_above::T,
|
||||
alphaY_current::T,
|
||||
concentration_above::T,
|
||||
concentration_current::T,
|
||||
boundaryValue::T,
|
||||
) where {T}
|
||||
intercellAlpha = calcAlphaIntercell(alphaY_above, alphaY_current)
|
||||
|
||||
if boundaryType == CONSTANT
|
||||
@ -74,8 +104,14 @@ function calcVerticalChangeTopBoundary(boundaryType::TYPE, alphaY_above::T, alph
|
||||
end
|
||||
|
||||
|
||||
function calcVerticalChangeBottomBoundary(boundaryType::TYPE, alphaY_current::T, alphaY_below::T,
|
||||
concentration_current::T, concentration_below::T, boundaryValue::T) where {T}
|
||||
function calcVerticalChangeBottomBoundary(
|
||||
boundaryType::TYPE,
|
||||
alphaY_current::T,
|
||||
alphaY_below::T,
|
||||
concentration_current::T,
|
||||
concentration_below::T,
|
||||
boundaryValue::T,
|
||||
) where {T}
|
||||
intercellAlpha = calcAlphaIntercell(alphaY_current, alphaY_below)
|
||||
|
||||
if boundaryType == CONSTANT
|
||||
@ -101,21 +137,42 @@ function FTCS_1D(grid::Grid{T}, bc::Boundary{T}, timestep::T) where {T}
|
||||
|
||||
# inner cells
|
||||
for col = 2:colMax-1
|
||||
concentrations_t1[row, col] += sx * calcHorizontalChange(alphaX[row, col+1], alphaX[row, col-1], alphaX[row, col],
|
||||
concentrations[row, col+1], concentrations[row, col-1], concentrations[row, col])
|
||||
concentrations_t1[row, col] +=
|
||||
sx * calcHorizontalChange(
|
||||
alphaX[row, col+1],
|
||||
alphaX[row, col-1],
|
||||
alphaX[row, col],
|
||||
concentrations[row, col+1],
|
||||
concentrations[row, col-1],
|
||||
concentrations[row, col],
|
||||
)
|
||||
end
|
||||
|
||||
# left boundary
|
||||
leftBoundaryType = getBoundaryElementType(bc, LEFT, row)
|
||||
leftBoundaryValue = getBoundaryElementValue(bc, LEFT, row)
|
||||
concentrations_t1[row, 1] += sx * calcHorizontalChangeLeftBoundary(leftBoundaryType, alphaX[row, 2], alphaX[row, 1],
|
||||
concentrations[row, 2], concentrations[row, 1], leftBoundaryValue)
|
||||
concentrations_t1[row, 1] +=
|
||||
sx * calcHorizontalChangeLeftBoundary(
|
||||
leftBoundaryType,
|
||||
alphaX[row, 2],
|
||||
alphaX[row, 1],
|
||||
concentrations[row, 2],
|
||||
concentrations[row, 1],
|
||||
leftBoundaryValue,
|
||||
)
|
||||
|
||||
# right boundary
|
||||
rightBoundaryType = getBoundaryElementType(bc, RIGHT, row)
|
||||
rightBoundaryValue = getBoundaryElementValue(bc, RIGHT, row)
|
||||
concentrations_t1[row, colMax] += sx * calcHorizontalChangeRightBoundary(rightBoundaryType, alphaX[row, colMax-1], alphaX[row, colMax],
|
||||
concentrations[row, colMax-1], concentrations[row, colMax], rightBoundaryValue)
|
||||
concentrations_t1[row, colMax] +=
|
||||
sx * calcHorizontalChangeRightBoundary(
|
||||
rightBoundaryType,
|
||||
alphaX[row, colMax-1],
|
||||
alphaX[row, colMax],
|
||||
concentrations[row, colMax-1],
|
||||
concentrations[row, colMax],
|
||||
rightBoundaryValue,
|
||||
)
|
||||
|
||||
setConcentrations!(grid, concentrations_t1)
|
||||
end
|
||||
@ -139,78 +196,201 @@ function FTCS_2D(grid::Grid{T}, bc::Boundary{T}, timestep::T) where {T}
|
||||
|
||||
Threads.@threads for row = 2:rowMax-1
|
||||
for col = 2:colMax-1
|
||||
concentrations_t1[row, col] += sy * calcVerticalChange(alphaY[row+1, col], alphaY[row-1, col], alphaY[row, col],
|
||||
concentrations[row+1, col], concentrations[row-1, col], concentrations[row, col]) +
|
||||
sx * calcHorizontalChange(alphaX[row, col+1], alphaX[row, col-1], alphaX[row, col],
|
||||
concentrations[row, col+1], concentrations[row, col-1], concentrations[row, col])
|
||||
concentrations_t1[row, col] +=
|
||||
sy * calcVerticalChange(
|
||||
alphaY[row+1, col],
|
||||
alphaY[row-1, col],
|
||||
alphaY[row, col],
|
||||
concentrations[row+1, col],
|
||||
concentrations[row-1, col],
|
||||
concentrations[row, col],
|
||||
) +
|
||||
sx * calcHorizontalChange(
|
||||
alphaX[row, col+1],
|
||||
alphaX[row, col-1],
|
||||
alphaX[row, col],
|
||||
concentrations[row, col+1],
|
||||
concentrations[row, col-1],
|
||||
concentrations[row, col],
|
||||
)
|
||||
end
|
||||
|
||||
# Boundary conditions for each row
|
||||
# Left boundary without corners
|
||||
leftBoundaryValue = getBoundaryElementValue(bc, LEFT, row)
|
||||
concentrations_t1[row, 1] += sx * calcHorizontalChangeLeftBoundary(leftBoundaryType, alphaX[row, 2], alphaX[row, 1],
|
||||
concentrations[row, 2], concentrations[row, 1], leftBoundaryValue) +
|
||||
sy * calcVerticalChange(alphaY[row+1, 1], alphaY[row-1, 1], alphaY[row, 1],
|
||||
concentrations[row+1, 1], concentrations[row-1, 1], concentrations[row, 1])
|
||||
concentrations_t1[row, 1] +=
|
||||
sx * calcHorizontalChangeLeftBoundary(
|
||||
leftBoundaryType,
|
||||
alphaX[row, 2],
|
||||
alphaX[row, 1],
|
||||
concentrations[row, 2],
|
||||
concentrations[row, 1],
|
||||
leftBoundaryValue,
|
||||
) +
|
||||
sy * calcVerticalChange(
|
||||
alphaY[row+1, 1],
|
||||
alphaY[row-1, 1],
|
||||
alphaY[row, 1],
|
||||
concentrations[row+1, 1],
|
||||
concentrations[row-1, 1],
|
||||
concentrations[row, 1],
|
||||
)
|
||||
|
||||
# Right boundary without corners
|
||||
rightBoundaryValue = getBoundaryElementValue(bc, RIGHT, row)
|
||||
concentrations_t1[row, colMax] += sx * calcHorizontalChangeRightBoundary(rightBoundaryType, alphaX[row, colMax-1], alphaX[row, colMax],
|
||||
concentrations[row, colMax-1], concentrations[row, colMax], rightBoundaryValue) +
|
||||
sy * calcVerticalChange(alphaY[row+1, colMax], alphaY[row-1, colMax], alphaY[row, colMax],
|
||||
concentrations[row+1, colMax], concentrations[row-1, colMax], concentrations[row, colMax])
|
||||
concentrations_t1[row, colMax] +=
|
||||
sx * calcHorizontalChangeRightBoundary(
|
||||
rightBoundaryType,
|
||||
alphaX[row, colMax-1],
|
||||
alphaX[row, colMax],
|
||||
concentrations[row, colMax-1],
|
||||
concentrations[row, colMax],
|
||||
rightBoundaryValue,
|
||||
) +
|
||||
sy * calcVerticalChange(
|
||||
alphaY[row+1, colMax],
|
||||
alphaY[row-1, colMax],
|
||||
alphaY[row, colMax],
|
||||
concentrations[row+1, colMax],
|
||||
concentrations[row-1, colMax],
|
||||
concentrations[row, colMax],
|
||||
)
|
||||
end
|
||||
|
||||
# Handle top/bottom boundaries
|
||||
Threads.@threads for col = 2:colMax-1
|
||||
# Top boundary
|
||||
topBoundaryValue = getBoundaryElementValue(bc, TOP, col)
|
||||
concentrations_t1[1, col] += sy * calcVerticalChangeTopBoundary(topBoundaryType, alphaY[2, col], alphaY[1, col],
|
||||
concentrations[2, col], concentrations[1, col], topBoundaryValue) +
|
||||
sx * calcHorizontalChange(alphaX[1, col+1], alphaX[1, col-1], alphaX[1, col],
|
||||
concentrations[1, col+1], concentrations[1, col-1], concentrations[1, col])
|
||||
concentrations_t1[1, col] +=
|
||||
sy * calcVerticalChangeTopBoundary(
|
||||
topBoundaryType,
|
||||
alphaY[2, col],
|
||||
alphaY[1, col],
|
||||
concentrations[2, col],
|
||||
concentrations[1, col],
|
||||
topBoundaryValue,
|
||||
) +
|
||||
sx * calcHorizontalChange(
|
||||
alphaX[1, col+1],
|
||||
alphaX[1, col-1],
|
||||
alphaX[1, col],
|
||||
concentrations[1, col+1],
|
||||
concentrations[1, col-1],
|
||||
concentrations[1, col],
|
||||
)
|
||||
|
||||
# Bottom boundary
|
||||
bottomBoundaryValue = getBoundaryElementValue(bc, BOTTOM, col)
|
||||
concentrations_t1[rowMax, col] += sy * calcVerticalChangeBottomBoundary(bottomBoundaryType, alphaY[rowMax, col], alphaY[rowMax-1, col],
|
||||
concentrations[rowMax, col], concentrations[rowMax-1, col], bottomBoundaryValue) +
|
||||
sx * calcHorizontalChange(alphaX[rowMax, col+1], alphaX[rowMax, col-1], alphaX[rowMax, col],
|
||||
concentrations[rowMax, col+1], concentrations[rowMax, col-1], concentrations[rowMax, col])
|
||||
concentrations_t1[rowMax, col] +=
|
||||
sy * calcVerticalChangeBottomBoundary(
|
||||
bottomBoundaryType,
|
||||
alphaY[rowMax, col],
|
||||
alphaY[rowMax-1, col],
|
||||
concentrations[rowMax, col],
|
||||
concentrations[rowMax-1, col],
|
||||
bottomBoundaryValue,
|
||||
) +
|
||||
sx * calcHorizontalChange(
|
||||
alphaX[rowMax, col+1],
|
||||
alphaX[rowMax, col-1],
|
||||
alphaX[rowMax, col],
|
||||
concentrations[rowMax, col+1],
|
||||
concentrations[rowMax, col-1],
|
||||
concentrations[rowMax, col],
|
||||
)
|
||||
end
|
||||
|
||||
# Handle corners
|
||||
# Top left corner
|
||||
topBoundaryValue = getBoundaryElementValue(bc, TOP, 1)
|
||||
concentrations_t1[1, 1] += sx * calcHorizontalChange(alphaX[1, 2], alphaX[1, 1], alphaX[1, 1],
|
||||
concentrations[1, 2], concentrations[1, 1], concentrations[1, 1]) +
|
||||
sy * calcVerticalChangeTopBoundary(topBoundaryType, alphaY[2, 1], alphaY[1, 1],
|
||||
concentrations[2, 1], concentrations[1, 1], topBoundaryValue)
|
||||
concentrations_t1[1, 1] +=
|
||||
sx * calcHorizontalChange(
|
||||
alphaX[1, 2],
|
||||
alphaX[1, 1],
|
||||
alphaX[1, 1],
|
||||
concentrations[1, 2],
|
||||
concentrations[1, 1],
|
||||
concentrations[1, 1],
|
||||
) +
|
||||
sy * calcVerticalChangeTopBoundary(
|
||||
topBoundaryType,
|
||||
alphaY[2, 1],
|
||||
alphaY[1, 1],
|
||||
concentrations[2, 1],
|
||||
concentrations[1, 1],
|
||||
topBoundaryValue,
|
||||
)
|
||||
|
||||
# Top right corner
|
||||
topBoundaryValue = getBoundaryElementValue(bc, TOP, colMax)
|
||||
concentrations_t1[1, colMax] += sx * calcHorizontalChange(alphaX[1, colMax-1], alphaX[1, colMax], alphaX[1, colMax],
|
||||
concentrations[1, colMax-1], concentrations[1, colMax], concentrations[1, colMax]) +
|
||||
sy * calcVerticalChangeTopBoundary(topBoundaryType, alphaY[2, colMax], alphaY[1, colMax],
|
||||
concentrations[2, colMax], concentrations[1, colMax], topBoundaryValue)
|
||||
concentrations_t1[1, colMax] +=
|
||||
sx * calcHorizontalChange(
|
||||
alphaX[1, colMax-1],
|
||||
alphaX[1, colMax],
|
||||
alphaX[1, colMax],
|
||||
concentrations[1, colMax-1],
|
||||
concentrations[1, colMax],
|
||||
concentrations[1, colMax],
|
||||
) +
|
||||
sy * calcVerticalChangeTopBoundary(
|
||||
topBoundaryType,
|
||||
alphaY[2, colMax],
|
||||
alphaY[1, colMax],
|
||||
concentrations[2, colMax],
|
||||
concentrations[1, colMax],
|
||||
topBoundaryValue,
|
||||
)
|
||||
|
||||
# Bottom left corner
|
||||
bottomBoundaryValue = getBoundaryElementValue(bc, BOTTOM, 1)
|
||||
concentrations_t1[rowMax, 1] += sx * calcHorizontalChange(alphaX[rowMax, 2], alphaX[rowMax, 1], alphaX[rowMax, 1],
|
||||
concentrations[rowMax, 2], concentrations[rowMax, 1], concentrations[rowMax, 1]) +
|
||||
sy * calcVerticalChangeBottomBoundary(bottomBoundaryType, alphaY[rowMax, 1], alphaY[rowMax-1, 1],
|
||||
concentrations[rowMax, 1], concentrations[rowMax-1, 1], bottomBoundaryValue)
|
||||
concentrations_t1[rowMax, 1] +=
|
||||
sx * calcHorizontalChange(
|
||||
alphaX[rowMax, 2],
|
||||
alphaX[rowMax, 1],
|
||||
alphaX[rowMax, 1],
|
||||
concentrations[rowMax, 2],
|
||||
concentrations[rowMax, 1],
|
||||
concentrations[rowMax, 1],
|
||||
) +
|
||||
sy * calcVerticalChangeBottomBoundary(
|
||||
bottomBoundaryType,
|
||||
alphaY[rowMax, 1],
|
||||
alphaY[rowMax-1, 1],
|
||||
concentrations[rowMax, 1],
|
||||
concentrations[rowMax-1, 1],
|
||||
bottomBoundaryValue,
|
||||
)
|
||||
|
||||
# Bottom right corner
|
||||
bottomBoundaryValue = getBoundaryElementValue(bc, BOTTOM, colMax)
|
||||
concentrations_t1[rowMax, colMax] += sx * calcHorizontalChange(alphaX[rowMax, colMax-1], alphaX[rowMax, colMax], alphaX[rowMax, colMax],
|
||||
concentrations[rowMax, colMax-1], concentrations[rowMax, colMax], concentrations[rowMax, colMax]) +
|
||||
sy * calcVerticalChangeBottomBoundary(bottomBoundaryType, alphaY[rowMax, colMax], alphaY[rowMax-1, colMax],
|
||||
concentrations[rowMax, colMax], concentrations[rowMax-1, colMax], bottomBoundaryValue)
|
||||
concentrations_t1[rowMax, colMax] +=
|
||||
sx * calcHorizontalChange(
|
||||
alphaX[rowMax, colMax-1],
|
||||
alphaX[rowMax, colMax],
|
||||
alphaX[rowMax, colMax],
|
||||
concentrations[rowMax, colMax-1],
|
||||
concentrations[rowMax, colMax],
|
||||
concentrations[rowMax, colMax],
|
||||
) +
|
||||
sy * calcVerticalChangeBottomBoundary(
|
||||
bottomBoundaryType,
|
||||
alphaY[rowMax, colMax],
|
||||
alphaY[rowMax-1, colMax],
|
||||
concentrations[rowMax, colMax],
|
||||
concentrations[rowMax-1, colMax],
|
||||
bottomBoundaryValue,
|
||||
)
|
||||
|
||||
setConcentrations!(grid, concentrations_t1)
|
||||
end
|
||||
|
||||
function runFTCS(grid::Grid{T}, bc::Boundary{T}, timestep::T, iterations::Int, stepCallback::Function) where {T}
|
||||
function runFTCS(
|
||||
grid::Grid{T},
|
||||
bc::Boundary{T},
|
||||
timestep::T,
|
||||
iterations::Int,
|
||||
stepCallback::Function,
|
||||
) where {T}
|
||||
if getDim(grid) == 1
|
||||
for _ = 1:iterations
|
||||
FTCS_1D(grid, bc, timestep)
|
||||
|
||||
@ -26,7 +26,12 @@ struct DynamicSimulation{T} <: AbstractSimulation{T}
|
||||
iterations::Int
|
||||
timestep::T
|
||||
|
||||
function DynamicSimulation(grid::Grid{T}, bc::Boundary{T}, approach::APPROACH, timestep::T)::DynamicSimulation{T} where {T}
|
||||
function DynamicSimulation(
|
||||
grid::Grid{T},
|
||||
bc::Boundary{T},
|
||||
approach::APPROACH,
|
||||
timestep::T,
|
||||
)::DynamicSimulation{T} where {T}
|
||||
timestep, iterations = adjustTimestep(grid, approach, timestep, 1, false)
|
||||
new{T}(grid, Vector{Grid{T}}(), bc, approach, iterations, timestep)
|
||||
end
|
||||
@ -76,7 +81,10 @@ Prints the concentrations of a specific grid state to the console.
|
||||
# Returns
|
||||
Nothing, but outputs the grid's concentration matrix to the console.
|
||||
"""
|
||||
function printConcentrations(simulation::DynamicSimulation{T}, gridIndex::Int)::Nothing where {T}
|
||||
function printConcentrations(
|
||||
simulation::DynamicSimulation{T},
|
||||
gridIndex::Int,
|
||||
)::Nothing where {T}
|
||||
writeConcentrationsToCLI(simulation, simulation.grids[gridIndex])
|
||||
end
|
||||
|
||||
@ -92,17 +100,35 @@ Writes the concentrations of a specific grid state to a CSV file.
|
||||
# Returns
|
||||
Nothing, but writes the grid's concentration matrix to a CSV file.
|
||||
"""
|
||||
function printConcentrationsCSV(simulation::DynamicSimulation{T}, gridIndex::Int)::Nothing where {T}
|
||||
function printConcentrationsCSV(
|
||||
simulation::DynamicSimulation{T},
|
||||
gridIndex::Int,
|
||||
)::Nothing where {T}
|
||||
file = createCSVfile(simulation, simulation.grids[gridIndex])
|
||||
writeConcentrationsToCSV(file, simulation, simulation.grids[gridIndex])
|
||||
close(file)
|
||||
end
|
||||
|
||||
function runSimulationForGrid(simulation::DynamicSimulation{T}, grid::Grid{T})::Nothing where {T}
|
||||
function runSimulationForGrid(
|
||||
simulation::DynamicSimulation{T},
|
||||
grid::Grid{T},
|
||||
)::Nothing where {T}
|
||||
if simulation.approach == BTCS
|
||||
runBTCS(grid, simulation.bc, simulation.timestep, simulation.iterations, () -> nothing)
|
||||
runBTCS(
|
||||
grid,
|
||||
simulation.bc,
|
||||
simulation.timestep,
|
||||
simulation.iterations,
|
||||
() -> nothing,
|
||||
)
|
||||
elseif simulation.approach == FTCS
|
||||
runFTCS(grid, simulation.bc, simulation.timestep, simulation.iterations, () -> nothing)
|
||||
runFTCS(
|
||||
grid,
|
||||
simulation.bc,
|
||||
simulation.timestep,
|
||||
simulation.iterations,
|
||||
() -> nothing,
|
||||
)
|
||||
else
|
||||
error("Undefined approach!")
|
||||
end
|
||||
@ -120,7 +146,10 @@ Retrieves the concentrations of a specific grid state.
|
||||
# Returns
|
||||
The concentration matrix of the specified grid.
|
||||
"""
|
||||
function getConcentrations(simulation::DynamicSimulation{T}, gridIndex::Int)::Matrix{T} where {T}
|
||||
function getConcentrations(
|
||||
simulation::DynamicSimulation{T},
|
||||
gridIndex::Int,
|
||||
)::Matrix{T} where {T}
|
||||
getConcentrations(simulation.grids[gridIndex])
|
||||
end
|
||||
|
||||
@ -137,7 +166,11 @@ Sets the concentrations of a specific grid state.
|
||||
# Returns
|
||||
Nothing, but updates the concentration matrix of the specified grid.
|
||||
"""
|
||||
function setConcentrations!(simulation::DynamicSimulation{T}, gridIndex::Int, concentrations::Matrix{T})::Nothing where {T}
|
||||
function setConcentrations!(
|
||||
simulation::DynamicSimulation{T},
|
||||
gridIndex::Int,
|
||||
concentrations::Matrix{T},
|
||||
)::Nothing where {T}
|
||||
setConcentrations!(simulation.grids[gridIndex], concentrations)
|
||||
end
|
||||
|
||||
@ -154,7 +187,11 @@ Sets the alphaX matrix of a specific grid state.
|
||||
# Returns
|
||||
Nothing, but updates the alphaX matrix of the specified grid.
|
||||
"""
|
||||
function setAlphaX!(simulation::DynamicSimulation{T}, gridIndex::Int, alphaX::Matrix{T})::Nothing where {T}
|
||||
function setAlphaX!(
|
||||
simulation::DynamicSimulation{T},
|
||||
gridIndex::Int,
|
||||
alphaX::Matrix{T},
|
||||
)::Nothing where {T}
|
||||
setAlphaX!(simulation.grids[gridIndex], alphaX)
|
||||
end
|
||||
|
||||
@ -171,6 +208,10 @@ Sets the alphaY matrix of a specific grid state.
|
||||
# Returns
|
||||
Nothing, but updates the alphaY matrix of the specified grid.
|
||||
"""
|
||||
function setAlphaY!(simulation::DynamicSimulation{T}, gridIndex::Int, alphaY::Matrix{T})::Nothing where {T}
|
||||
function setAlphaY!(
|
||||
simulation::DynamicSimulation{T},
|
||||
gridIndex::Int,
|
||||
alphaY::Matrix{T},
|
||||
)::Nothing where {T}
|
||||
setAlphaY!(simulation.grids[gridIndex], alphaY)
|
||||
end
|
||||
|
||||
@ -46,30 +46,99 @@ struct Grid{T}
|
||||
throw(ArgumentError("Given grid length too small. Must be greater than 3."))
|
||||
end
|
||||
if size(alphaX, 1) != 1 || size(alphaX, 2) != length
|
||||
throw(ArgumentError("Given matrix of alpha coefficients mismatch with Grid dimensions!"))
|
||||
throw(
|
||||
ArgumentError(
|
||||
"Given matrix of alpha coefficients mismatch with Grid dimensions!",
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
alphaX_t = alphaX'
|
||||
|
||||
new{T}(length, 1, 1, T(length), 0, T(1), 0, Ref(fill(T(0), 1, length)), alphaX, nothing, alphaX_t, nothing)
|
||||
new{T}(
|
||||
length,
|
||||
1,
|
||||
1,
|
||||
T(length),
|
||||
0,
|
||||
T(1),
|
||||
0,
|
||||
Ref(fill(T(0), 1, length)),
|
||||
alphaX,
|
||||
nothing,
|
||||
alphaX_t,
|
||||
nothing,
|
||||
)
|
||||
end
|
||||
|
||||
function Grid{T}(rows::Int, cols::Int, alphaX::Matrix{T}, alphaY::Matrix{T})::Grid{T} where {T}
|
||||
function Grid{T}(
|
||||
rows::Int,
|
||||
cols::Int,
|
||||
alphaX::Matrix{T},
|
||||
alphaY::Matrix{T},
|
||||
)::Grid{T} where {T}
|
||||
if rows <= 3 || cols <= 3
|
||||
throw(ArgumentError("Given grid dimensions too small. Must each be greater than 3."))
|
||||
throw(
|
||||
ArgumentError(
|
||||
"Given grid dimensions too small. Must each be greater than 3.",
|
||||
),
|
||||
)
|
||||
end
|
||||
if size(alphaX) != (rows, cols) || size(alphaY) != (rows, cols)
|
||||
throw(ArgumentError("Given matrices of alpha coefficients mismatch with Grid dimensions!"))
|
||||
throw(
|
||||
ArgumentError(
|
||||
"Given matrices of alpha coefficients mismatch with Grid dimensions!",
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
alphaX_t = alphaX'
|
||||
alphaY_t = alphaY'
|
||||
|
||||
new{T}(cols, rows, 2, T(cols), T(rows), T(1), T(1), Ref(fill(T(0), rows, cols)), alphaX, alphaY, alphaX_t, alphaY_t)
|
||||
new{T}(
|
||||
cols,
|
||||
rows,
|
||||
2,
|
||||
T(cols),
|
||||
T(rows),
|
||||
T(1),
|
||||
T(1),
|
||||
Ref(fill(T(0), rows, cols)),
|
||||
alphaX,
|
||||
alphaY,
|
||||
alphaX_t,
|
||||
alphaY_t,
|
||||
)
|
||||
end
|
||||
|
||||
function Grid{T}(rows::Int, cols::Int, dim::Int, domainCol::T, domainRow::T, deltaCol::T, deltaRow::T, concentrations::Ref{Matrix{T}}, alphaX::Ref{Matrix{T}}, alphaY::Union{Ref{Matrix{T}},Nothing}, alphaX_t::Union{Ref{Matrix{T}},Nothing}, alphaY_t::Union{Ref{Matrix{T}},Nothing})::Grid{T} where {T}
|
||||
new{T}(cols, rows, dim, domainCol, domainRow, deltaCol, deltaRow, concentrations, alphaX, alphaY, alphaX_t, alphaY_t)
|
||||
function Grid{T}(
|
||||
rows::Int,
|
||||
cols::Int,
|
||||
dim::Int,
|
||||
domainCol::T,
|
||||
domainRow::T,
|
||||
deltaCol::T,
|
||||
deltaRow::T,
|
||||
concentrations::Ref{Matrix{T}},
|
||||
alphaX::Ref{Matrix{T}},
|
||||
alphaY::Union{Ref{Matrix{T}},Nothing},
|
||||
alphaX_t::Union{Ref{Matrix{T}},Nothing},
|
||||
alphaY_t::Union{Ref{Matrix{T}},Nothing},
|
||||
)::Grid{T} where {T}
|
||||
new{T}(
|
||||
cols,
|
||||
rows,
|
||||
dim,
|
||||
domainCol,
|
||||
domainRow,
|
||||
deltaCol,
|
||||
deltaRow,
|
||||
concentrations,
|
||||
alphaX,
|
||||
alphaY,
|
||||
alphaX_t,
|
||||
alphaY_t,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@ -87,9 +156,35 @@ A new `Grid{T}` object that is a deep copy of the input grid.
|
||||
"""
|
||||
function clone(grid::Grid{T})::Grid{T} where {T}
|
||||
if grid.dim == 1
|
||||
return Grid{T}(1, grid.cols, grid.dim, grid.domainCol, grid.domainRow, grid.deltaCol, grid.deltaRow, Ref(copy(grid.concentrations[])), Ref(copy(grid.alphaX[])), nothing, Ref(copy(grid.alphaX_t[])), nothing)
|
||||
return Grid{T}(
|
||||
1,
|
||||
grid.cols,
|
||||
grid.dim,
|
||||
grid.domainCol,
|
||||
grid.domainRow,
|
||||
grid.deltaCol,
|
||||
grid.deltaRow,
|
||||
Ref(copy(grid.concentrations[])),
|
||||
Ref(copy(grid.alphaX[])),
|
||||
nothing,
|
||||
Ref(copy(grid.alphaX_t[])),
|
||||
nothing,
|
||||
)
|
||||
end
|
||||
Grid{T}(grid.rows, grid.cols, grid.dim, grid.domainCol, grid.domainRow, grid.deltaCol, grid.deltaRow, Ref(copy(grid.concentrations[])), Ref(copy(grid.alphaX[])), Ref(copy(grid.alphaY[])), Ref(copy(grid.alphaX_t[])), Ref(copy(grid.alphaY_t[])))
|
||||
Grid{T}(
|
||||
grid.rows,
|
||||
grid.cols,
|
||||
grid.dim,
|
||||
grid.domainCol,
|
||||
grid.domainRow,
|
||||
grid.deltaCol,
|
||||
grid.deltaRow,
|
||||
Ref(copy(grid.concentrations[])),
|
||||
Ref(copy(grid.alphaX[])),
|
||||
Ref(copy(grid.alphaY[])),
|
||||
Ref(copy(grid.alphaX_t[])),
|
||||
Ref(copy(grid.alphaY_t[])),
|
||||
)
|
||||
end
|
||||
|
||||
"""
|
||||
@ -267,7 +362,11 @@ Nothing, but modifies the alphaX matrix of the grid.
|
||||
"""
|
||||
function setAlphaX!(grid::Grid{T}, new_alphaX::Matrix{T})::Nothing where {T}
|
||||
if size(new_alphaX) != size(grid.alphaX[])
|
||||
throw(ArgumentError("Given matrix of alpha coefficients mismatch with Grid dimensions!"))
|
||||
throw(
|
||||
ArgumentError(
|
||||
"Given matrix of alpha coefficients mismatch with Grid dimensions!",
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
grid.alphaX[] = new_alphaX
|
||||
@ -293,7 +392,11 @@ function setAlphaY!(grid::Grid{T}, new_alphaY::Matrix{T})::Nothing where {T}
|
||||
error("Grid is 1D, so there is no alphaY matrix!")
|
||||
end
|
||||
if size(new_alphaY) != size(grid.alphaY[])
|
||||
throw(ArgumentError("Given matrix of alpha coefficients mismatch with Grid dimensions!"))
|
||||
throw(
|
||||
ArgumentError(
|
||||
"Given matrix of alpha coefficients mismatch with Grid dimensions!",
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
grid.alphaY[] = new_alphaY
|
||||
@ -316,7 +419,9 @@ Nothing, but modifies the concentration matrix of the grid.
|
||||
"""
|
||||
function setConcentrations!(grid::Grid{T}, new_concentrations::Matrix{T})::Nothing where {T}
|
||||
if size(new_concentrations) != size(grid.concentrations[])
|
||||
throw(ArgumentError("Given matrix of concentrations mismatch with Grid dimensions!"))
|
||||
throw(
|
||||
ArgumentError("Given matrix of concentrations mismatch with Grid dimensions!"),
|
||||
)
|
||||
end
|
||||
|
||||
grid.concentrations[] = new_concentrations
|
||||
|
||||
@ -34,8 +34,15 @@ struct Simulation{T} <: AbstractSimulation{T}
|
||||
consoleOutput::CONSOLE_OUTPUT
|
||||
csvOutput::CSV_OUTPUT
|
||||
|
||||
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)::Simulation{T} where {T}
|
||||
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,
|
||||
)::Simulation{T} where {T}
|
||||
new{T}(grid, bc, approach, iterations, timestep, consoleOutput, csvOutput)
|
||||
end
|
||||
end
|
||||
@ -69,10 +76,28 @@ function run(simulation::Simulation{T})::Nothing where {T}
|
||||
end
|
||||
|
||||
if simulation.approach == BTCS
|
||||
runBTCS(simulation.grid, simulation.bc, simulation.timestep, simulation.iterations, simulationStepCallback)
|
||||
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, simulation.consoleOutput >= CONSOLE_OUTPUT_VERBOSE)
|
||||
runFTCS(simulation.grid, simulation.bc, timestep, iterations, simulationStepCallback)
|
||||
timestep, iterations = adjustTimestep(
|
||||
simulation.grid,
|
||||
simulation.approach,
|
||||
simulation.timestep,
|
||||
simulation.iterations,
|
||||
simulation.consoleOutput >= CONSOLE_OUTPUT_VERBOSE,
|
||||
)
|
||||
runFTCS(
|
||||
simulation.grid,
|
||||
simulation.bc,
|
||||
timestep,
|
||||
iterations,
|
||||
simulationStepCallback,
|
||||
)
|
||||
else
|
||||
error("Undefined approach!")
|
||||
end
|
||||
@ -104,7 +129,15 @@ Sets the number of iterations for the given simulation.
|
||||
A new `Simulation` object with updated iterations.
|
||||
"""
|
||||
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)
|
||||
return Simulation(
|
||||
simulation.grid,
|
||||
simulation.bc,
|
||||
simulation.approach,
|
||||
iterations,
|
||||
simulation.timestep,
|
||||
simulation.consoleOutput,
|
||||
simulation.csvOutput,
|
||||
)
|
||||
end
|
||||
|
||||
"""
|
||||
@ -119,8 +152,19 @@ Sets the console output level for the simulation.
|
||||
# Returns
|
||||
A new `Simulation` object with updated console output setting.
|
||||
"""
|
||||
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)
|
||||
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
|
||||
|
||||
"""
|
||||
@ -135,8 +179,19 @@ Sets the CSV output level for the simulation.
|
||||
# Returns
|
||||
A new `Simulation` object with updated CSV output setting.
|
||||
"""
|
||||
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)
|
||||
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
|
||||
|
||||
"""
|
||||
@ -152,5 +207,13 @@ Sets the timestep for the simulation.
|
||||
A new `Simulation` object with updated timestep.
|
||||
"""
|
||||
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)
|
||||
return Simulation(
|
||||
simulation.grid,
|
||||
simulation.bc,
|
||||
simulation.approach,
|
||||
simulation.iterations,
|
||||
timestep,
|
||||
simulation.consoleOutput,
|
||||
simulation.csvOutput,
|
||||
)
|
||||
end
|
||||
|
||||
@ -3,16 +3,47 @@ module TUG
|
||||
include("Grid.jl")
|
||||
|
||||
export Grid
|
||||
export clone, getAlphaX, getAlphaY, getAlphaX_t, getAlphaY_t, getConcentrations, setConcentrations!, setAlphaX!, setAlphaY!, getDomainCol, getDomainRow, getDeltaCol, getDeltaRow, getDim
|
||||
export clone,
|
||||
getAlphaX,
|
||||
getAlphaY,
|
||||
getAlphaX_t,
|
||||
getAlphaY_t,
|
||||
getConcentrations,
|
||||
setConcentrations!,
|
||||
setAlphaX!,
|
||||
setAlphaY!,
|
||||
getDomainCol,
|
||||
getDomainRow,
|
||||
getDeltaCol,
|
||||
getDeltaRow,
|
||||
getDim
|
||||
|
||||
include("Boundary.jl")
|
||||
|
||||
export Boundary, BoundaryElement, TYPE, SIDE, BC_TYPE_CLOSED, BC_TYPE_CONSTANT, LEFT, RIGHT, TOP, BOTTOM
|
||||
export getType, getValue, setBoundarySideClosed!, setBoundarySideConstant!, getBoundarySide, getBoundaryElementType, getBoundaryElementValue
|
||||
export Boundary,
|
||||
BoundaryElement, TYPE, SIDE, BC_TYPE_CLOSED, BC_TYPE_CONSTANT, LEFT, RIGHT, TOP, BOTTOM
|
||||
export getType,
|
||||
getValue,
|
||||
setBoundarySideClosed!,
|
||||
setBoundarySideConstant!,
|
||||
getBoundarySide,
|
||||
getBoundaryElementType,
|
||||
getBoundaryElementValue
|
||||
|
||||
include("AbstractSimulation.jl")
|
||||
|
||||
export APPROACH, CONSOLE_OUTPUT, CSV_OUTPUT, BTCS, FTCS, CONSOLE_OUTPUT_OFF, CONSOLE_OUTPUT_ON, CONSOLE_OUTPUT_VERBOSE, CSV_OUTPUT_OFF, CSV_OUTPUT_ON, CSV_OUTPUT_VERBOSE, CSV_OUTPUT_XTREME
|
||||
export APPROACH,
|
||||
CONSOLE_OUTPUT,
|
||||
CSV_OUTPUT,
|
||||
BTCS,
|
||||
FTCS,
|
||||
CONSOLE_OUTPUT_OFF,
|
||||
CONSOLE_OUTPUT_ON,
|
||||
CONSOLE_OUTPUT_VERBOSE,
|
||||
CSV_OUTPUT_OFF,
|
||||
CSV_OUTPUT_ON,
|
||||
CSV_OUTPUT_VERBOSE,
|
||||
CSV_OUTPUT_XTREME
|
||||
|
||||
include("Simulation.jl")
|
||||
|
||||
@ -22,7 +53,14 @@ export run, setTimestep, setIterations, setOutputConsole, setOutputCSV
|
||||
include("DynamicSimulation.jl")
|
||||
|
||||
export DynamicSimulation
|
||||
export createGrid, next, printConcentrations, printConcentrationsCSV, getConcentrations, setConcentrations!, setAlphaX!, setAlphaY!
|
||||
export createGrid,
|
||||
next,
|
||||
printConcentrations,
|
||||
printConcentrationsCSV,
|
||||
getConcentrations,
|
||||
setConcentrations!,
|
||||
setAlphaX!,
|
||||
setAlphaY!
|
||||
|
||||
include("Core/Utils.jl")
|
||||
include("Core/BTCS.jl")
|
||||
|
||||
@ -33,11 +33,16 @@
|
||||
boundary = TUG.Boundary(grid)
|
||||
simulation = TUG.DynamicSimulation(grid, boundary, BTCS, 0.01)
|
||||
TUG.createGrid(simulation)
|
||||
for _ in 1:20
|
||||
for _ = 1:20
|
||||
TUG.next(simulation)
|
||||
end
|
||||
expected_concentrations = [1.281106278320615 3.5643693033301567 14.309048836698485 3.5643693033301598 1.281106278320616]
|
||||
@test isapprox(TUG.getConcentrations(simulation, 1), expected_concentrations, atol=1e-6)
|
||||
expected_concentrations =
|
||||
[1.281106278320615 3.5643693033301567 14.309048836698485 3.5643693033301598 1.281106278320616]
|
||||
@test isapprox(
|
||||
TUG.getConcentrations(simulation, 1),
|
||||
expected_concentrations,
|
||||
atol = 1e-6,
|
||||
)
|
||||
|
||||
grid = TUG.Grid{Float64}(5, ones(1, 5))
|
||||
TUG.setConcentrations!(grid, [1.0 1.0 20.0 1.0 1.0])
|
||||
@ -45,34 +50,77 @@
|
||||
TUG.setBoundarySideConstant!(boundary, LEFT, 5.0)
|
||||
simulation = TUG.DynamicSimulation(grid, boundary, BTCS, 0.01)
|
||||
TUG.createGrid(simulation)
|
||||
for _ in 1:20
|
||||
for _ = 1:20
|
||||
TUG.next(simulation)
|
||||
end
|
||||
expected_concentrations = [2.4416160635284823 3.6810808789967466 14.317333805802393 3.5648326408458035 1.2811288426376255]
|
||||
@test isapprox(TUG.getConcentrations(simulation, 1), expected_concentrations, atol=1e-6)
|
||||
expected_concentrations =
|
||||
[2.4416160635284823 3.6810808789967466 14.317333805802393 3.5648326408458035 1.2811288426376255]
|
||||
@test isapprox(
|
||||
TUG.getConcentrations(simulation, 1),
|
||||
expected_concentrations,
|
||||
atol = 1e-6,
|
||||
)
|
||||
end
|
||||
@testset "2D-Run" begin
|
||||
grid = TUG.Grid{Float64}(5, 5, ones(5, 5), ones(5, 5))
|
||||
TUG.setConcentrations!(grid, [1.0 1.0 20.0 1.0 1.0; 1.0 1.0 20.0 1.0 1.0; 1.0 1.0 20.0 1.0 1.0; 1.0 1.0 20.0 1.0 1.0; 1.0 1.0 20.0 1.0 1.0])
|
||||
TUG.setConcentrations!(
|
||||
grid,
|
||||
[
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
],
|
||||
)
|
||||
boundary = TUG.Boundary(grid)
|
||||
simulation = TUG.DynamicSimulation(grid, boundary, BTCS, 0.01)
|
||||
TUG.createGrid(simulation)
|
||||
for _ in 1:20
|
||||
for _ = 1:20
|
||||
TUG.next(simulation)
|
||||
end
|
||||
expected_concentrations = [1.141904802011076 3.591390417498421 14.249599956958917 3.5913904174984217 1.1419048020110782; 1.1419048020110738 3.5913904174984173 14.2495999569589 3.5913904174984177 1.1419048020110767; 1.1419048020110725 3.591390417498413 14.249599956958875 3.5913904174984137 1.1419048020110751; 1.1419048020110738 3.5913904174984164 14.249599956958901 3.5913904174984173 1.141904802011077; 1.1419048020110774 3.5913904174984297 14.24959995695894 3.5913904174984297 1.1419048020110796]
|
||||
@test isapprox(TUG.getConcentrations(simulation, 1), expected_concentrations, atol=1e-6)
|
||||
expected_concentrations = [
|
||||
1.141904802011076 3.591390417498421 14.249599956958917 3.5913904174984217 1.1419048020110782
|
||||
1.1419048020110738 3.5913904174984173 14.2495999569589 3.5913904174984177 1.1419048020110767
|
||||
1.1419048020110725 3.591390417498413 14.249599956958875 3.5913904174984137 1.1419048020110751
|
||||
1.1419048020110738 3.5913904174984164 14.249599956958901 3.5913904174984173 1.141904802011077
|
||||
1.1419048020110774 3.5913904174984297 14.24959995695894 3.5913904174984297 1.1419048020110796
|
||||
]
|
||||
@test isapprox(
|
||||
TUG.getConcentrations(simulation, 1),
|
||||
expected_concentrations,
|
||||
atol = 1e-6,
|
||||
)
|
||||
|
||||
grid = TUG.Grid{Float64}(5, 5, ones(5, 5), ones(5, 5))
|
||||
TUG.setConcentrations!(grid, [1.0 1.0 20.0 1.0 1.0; 1.0 1.0 20.0 1.0 1.0; 1.0 1.0 20.0 1.0 1.0; 1.0 1.0 20.0 1.0 1.0; 1.0 1.0 20.0 1.0 1.0])
|
||||
TUG.setConcentrations!(
|
||||
grid,
|
||||
[
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
],
|
||||
)
|
||||
boundary = TUG.Boundary(grid)
|
||||
TUG.setBoundarySideConstant!(boundary, LEFT, 5.0)
|
||||
simulation = TUG.DynamicSimulation(grid, boundary, BTCS, 0.01)
|
||||
TUG.createGrid(simulation)
|
||||
for _ in 1:20
|
||||
for _ = 1:20
|
||||
TUG.next(simulation)
|
||||
end
|
||||
expected_concentrations = [1.9866377371338924 3.67421468453773 14.255058363518529 3.5916629034159486 1.1419105589005596; 1.98663773713389 3.674214684537723 14.255058363518497 3.5916629034159406 1.1419105589005576; 1.9866377371338884 3.6742146845377186 14.255058363518481 3.591662903415937 1.1419105589005565; 1.9866377371338895 3.674214684537725 14.255058363518502 3.5916629034159424 1.1419105589005574; 1.9866377371338952 3.6742146845377377 14.255058363518547 3.591662903415955 1.141910558900562]
|
||||
@test isapprox(TUG.getConcentrations(simulation, 1), expected_concentrations, atol=1e-6)
|
||||
expected_concentrations = [
|
||||
1.9866377371338924 3.67421468453773 14.255058363518529 3.5916629034159486 1.1419105589005596
|
||||
1.98663773713389 3.674214684537723 14.255058363518497 3.5916629034159406 1.1419105589005576
|
||||
1.9866377371338884 3.6742146845377186 14.255058363518481 3.591662903415937 1.1419105589005565
|
||||
1.9866377371338895 3.674214684537725 14.255058363518502 3.5916629034159424 1.1419105589005574
|
||||
1.9866377371338952 3.6742146845377377 14.255058363518547 3.591662903415955 1.141910558900562
|
||||
]
|
||||
@test isapprox(
|
||||
TUG.getConcentrations(simulation, 1),
|
||||
expected_concentrations,
|
||||
atol = 1e-6,
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -13,7 +13,8 @@
|
||||
|
||||
grid = TUG.Grid{Float64}(5, ones(1, 5))
|
||||
boundary = TUG.Boundary(grid)
|
||||
simulation = TUG.Simulation(grid, boundary, FTCS, 2, 0.2, CONSOLE_OUTPUT_ON, CSV_OUTPUT_ON)
|
||||
simulation =
|
||||
TUG.Simulation(grid, boundary, FTCS, 2, 0.2, CONSOLE_OUTPUT_ON, CSV_OUTPUT_ON)
|
||||
@test simulation.grid == grid
|
||||
@test simulation.bc == boundary
|
||||
@test simulation.approach == FTCS
|
||||
@ -28,8 +29,9 @@
|
||||
boundary = TUG.Boundary(grid)
|
||||
simulation = TUG.Simulation(grid, boundary, BTCS, 20, 0.01)
|
||||
TUG.run(simulation)
|
||||
expected_concentrations = [1.281106278320615 3.5643693033301567 14.309048836698485 3.5643693033301598 1.281106278320616]
|
||||
@test isapprox(TUG.getConcentrations(grid), expected_concentrations, atol=1e-6)
|
||||
expected_concentrations =
|
||||
[1.281106278320615 3.5643693033301567 14.309048836698485 3.5643693033301598 1.281106278320616]
|
||||
@test isapprox(TUG.getConcentrations(grid), expected_concentrations, atol = 1e-6)
|
||||
|
||||
grid = TUG.Grid{Float64}(5, ones(1, 5))
|
||||
TUG.setConcentrations!(grid, [1.0 1.0 20.0 1.0 1.0])
|
||||
@ -37,25 +39,56 @@
|
||||
TUG.setBoundarySideConstant!(boundary, LEFT, 5.0)
|
||||
simulation = TUG.Simulation(grid, boundary, BTCS, 20, 0.01)
|
||||
TUG.run(simulation)
|
||||
expected_concentrations = [2.4416160635284823 3.6810808789967466 14.317333805802393 3.5648326408458035 1.2811288426376255]
|
||||
@test isapprox(TUG.getConcentrations(grid), expected_concentrations, atol=1e-6)
|
||||
expected_concentrations =
|
||||
[2.4416160635284823 3.6810808789967466 14.317333805802393 3.5648326408458035 1.2811288426376255]
|
||||
@test isapprox(TUG.getConcentrations(grid), expected_concentrations, atol = 1e-6)
|
||||
end
|
||||
@testset "2D-Run" begin
|
||||
grid = TUG.Grid{Float64}(5, 5, ones(5, 5), ones(5, 5))
|
||||
TUG.setConcentrations!(grid, [1.0 1.0 20.0 1.0 1.0; 1.0 1.0 20.0 1.0 1.0; 1.0 1.0 20.0 1.0 1.0; 1.0 1.0 20.0 1.0 1.0; 1.0 1.0 20.0 1.0 1.0])
|
||||
TUG.setConcentrations!(
|
||||
grid,
|
||||
[
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
],
|
||||
)
|
||||
boundary = TUG.Boundary(grid)
|
||||
simulation = TUG.Simulation(grid, boundary, BTCS, 20, 0.01)
|
||||
TUG.run(simulation)
|
||||
expected_concentrations = [1.141904802011076 3.591390417498421 14.249599956958917 3.5913904174984217 1.1419048020110782; 1.1419048020110738 3.5913904174984173 14.2495999569589 3.5913904174984177 1.1419048020110767; 1.1419048020110725 3.591390417498413 14.249599956958875 3.5913904174984137 1.1419048020110751; 1.1419048020110738 3.5913904174984164 14.249599956958901 3.5913904174984173 1.141904802011077; 1.1419048020110774 3.5913904174984297 14.24959995695894 3.5913904174984297 1.1419048020110796]
|
||||
@test isapprox(TUG.getConcentrations(grid), expected_concentrations, atol=1e-6)
|
||||
expected_concentrations = [
|
||||
1.141904802011076 3.591390417498421 14.249599956958917 3.5913904174984217 1.1419048020110782
|
||||
1.1419048020110738 3.5913904174984173 14.2495999569589 3.5913904174984177 1.1419048020110767
|
||||
1.1419048020110725 3.591390417498413 14.249599956958875 3.5913904174984137 1.1419048020110751
|
||||
1.1419048020110738 3.5913904174984164 14.249599956958901 3.5913904174984173 1.141904802011077
|
||||
1.1419048020110774 3.5913904174984297 14.24959995695894 3.5913904174984297 1.1419048020110796
|
||||
]
|
||||
@test isapprox(TUG.getConcentrations(grid), expected_concentrations, atol = 1e-6)
|
||||
|
||||
grid = TUG.Grid{Float64}(5, 5, ones(5, 5), ones(5, 5))
|
||||
TUG.setConcentrations!(grid, [1.0 1.0 20.0 1.0 1.0; 1.0 1.0 20.0 1.0 1.0; 1.0 1.0 20.0 1.0 1.0; 1.0 1.0 20.0 1.0 1.0; 1.0 1.0 20.0 1.0 1.0])
|
||||
TUG.setConcentrations!(
|
||||
grid,
|
||||
[
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
1.0 1.0 20.0 1.0 1.0
|
||||
],
|
||||
)
|
||||
boundary = TUG.Boundary(grid)
|
||||
TUG.setBoundarySideConstant!(boundary, LEFT, 5.0)
|
||||
simulation = TUG.Simulation(grid, boundary, BTCS, 20, 0.01)
|
||||
TUG.run(simulation)
|
||||
expected_concentrations = [1.9866377371338924 3.67421468453773 14.255058363518529 3.5916629034159486 1.1419105589005596; 1.98663773713389 3.674214684537723 14.255058363518497 3.5916629034159406 1.1419105589005576; 1.9866377371338884 3.6742146845377186 14.255058363518481 3.591662903415937 1.1419105589005565; 1.9866377371338895 3.674214684537725 14.255058363518502 3.5916629034159424 1.1419105589005574; 1.9866377371338952 3.6742146845377377 14.255058363518547 3.591662903415955 1.141910558900562]
|
||||
@test isapprox(TUG.getConcentrations(grid), expected_concentrations, atol=1e-6)
|
||||
expected_concentrations = [
|
||||
1.9866377371338924 3.67421468453773 14.255058363518529 3.5916629034159486 1.1419105589005596
|
||||
1.98663773713389 3.674214684537723 14.255058363518497 3.5916629034159406 1.1419105589005576
|
||||
1.9866377371338884 3.6742146845377186 14.255058363518481 3.591662903415937 1.1419105589005565
|
||||
1.9866377371338895 3.674214684537725 14.255058363518502 3.5916629034159424 1.1419105589005574
|
||||
1.9866377371338952 3.6742146845377377 14.255058363518547 3.591662903415955 1.141910558900562
|
||||
]
|
||||
@test isapprox(TUG.getConcentrations(grid), expected_concentrations, atol = 1e-6)
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user