perf: optimize FTCS calculation for enhanced performance
Refactored calculation functions to combine and simplify logic. Revised functions to accept direct parameters instead of operating on the entire grid. Resulted in significant performance improvements through enhanced compiler optimization. [skip ci]
This commit is contained in:
parent
97e318ff5d
commit
51705e3eef
@ -7,152 +7,88 @@ include("../Boundary.jl")
|
||||
include("../Grid.jl")
|
||||
include("Utils.jl")
|
||||
|
||||
function calcHorizontalChange(grid::Grid{T}, row::Int, col::Int) where {T}
|
||||
return calcAlphaIntercell(getAlphaX(grid)[row, col+1],
|
||||
getAlphaX(grid)[row, col]) *
|
||||
getConcentrations(grid)[row, col+1] -
|
||||
(calcAlphaIntercell(getAlphaX(grid)[row, col+1],
|
||||
getAlphaX(grid)[row, col]) +
|
||||
calcAlphaIntercell(getAlphaX(grid)[row, col-1],
|
||||
getAlphaX(grid)[row, col])) *
|
||||
getConcentrations(grid)[row, col] +
|
||||
calcAlphaIntercell(getAlphaX(grid)[row, col-1],
|
||||
getAlphaX(grid)[row, col]) *
|
||||
getConcentrations(grid)[row, col-1]
|
||||
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)
|
||||
|
||||
return intercellAlpha_next * concentration_next -
|
||||
(intercellAlpha_next + intercellAlpha_prev) * concentration_current +
|
||||
intercellAlpha_prev * concentration_prev
|
||||
end
|
||||
|
||||
function calcHorizontalChangeLeftBoundary(grid::Grid{T}, bc::Boundary{T}, row::Int, col::Int) where {T}
|
||||
if getBoundaryElementType(bc, LEFT, row) == CONSTANT
|
||||
return calcHorizontalChangeLeftBoundaryConstant(grid, bc, row, col)
|
||||
elseif getBoundaryElementType(bc, LEFT, row) == CLOSED
|
||||
return calcHorizontalChangeLeftBoundaryClosed(grid, row, col)
|
||||
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
|
||||
return intercellAlpha * concentration_next -
|
||||
(intercellAlpha + 2 * alphaX_current) * concentration_current +
|
||||
2 * alphaX_current * boundaryValue
|
||||
elseif boundaryType == CLOSED
|
||||
return intercellAlpha * (concentration_next - concentration_current)
|
||||
else
|
||||
error("Undefined Boundary Condition Type!")
|
||||
end
|
||||
end
|
||||
|
||||
function calcHorizontalChangeLeftBoundaryConstant(grid::Grid{T}, bc::Boundary{T}, row::Int, col::Int) where {T}
|
||||
return calcAlphaIntercell(getAlphaX(grid)[row, col+1],
|
||||
getAlphaX(grid)[row, col]) *
|
||||
getConcentrations(grid)[row, col+1] -
|
||||
(calcAlphaIntercell(getAlphaX(grid)[row, col+1],
|
||||
getAlphaX(grid)[row, col]) +
|
||||
2 * getAlphaX(grid)[row, col]) *
|
||||
getConcentrations(grid)[row, col] +
|
||||
2 * getAlphaX(grid)[row, col] *
|
||||
getBoundaryElementValue(bc, LEFT, row)
|
||||
end
|
||||
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)
|
||||
|
||||
function calcHorizontalChangeLeftBoundaryClosed(grid::Grid{T}, row::Int, col::Int) where {T}
|
||||
return calcAlphaIntercell(getAlphaX(grid)[row, col+1],
|
||||
getAlphaX(grid)[row, col]) *
|
||||
(getConcentrations(grid)[row, col+1] -
|
||||
getConcentrations(grid)[row, col])
|
||||
end
|
||||
|
||||
|
||||
function calcHorizontalChangeRightBoundary(grid::Grid{T}, bc::Boundary{T}, row::Int, col::Int) where {T}
|
||||
if getBoundaryElementType(bc, RIGHT, row) == CONSTANT
|
||||
return calcHorizontalChangeRightBoundaryConstant(grid, bc, row, col)
|
||||
elseif getBoundaryElementType(bc, RIGHT, row) == CLOSED
|
||||
return calcHorizontalChangeRightBoundaryClosed(grid, row, col)
|
||||
if boundaryType == CONSTANT
|
||||
return 2 * alphaX_current * boundaryValue -
|
||||
(intercellAlpha + 2 * alphaX_current) * concentration_current +
|
||||
intercellAlpha * concentration_prev
|
||||
elseif boundaryType == CLOSED
|
||||
return -intercellAlpha * (concentration_current - concentration_prev)
|
||||
else
|
||||
error("Undefined Boundary Condition Type!")
|
||||
end
|
||||
end
|
||||
|
||||
function calcHorizontalChangeRightBoundaryConstant(grid::Grid{T}, bc::Boundary{T}, row::Int, col::Int) where {T}
|
||||
return 2 * getAlphaX(grid)[row, col] *
|
||||
getBoundaryElementValue(bc, RIGHT, row) -
|
||||
(calcAlphaIntercell(getAlphaX(grid)[row, col-1],
|
||||
getAlphaX(grid)[row, col]) +
|
||||
2 * getAlphaX(grid)[row, col]) *
|
||||
getConcentrations(grid)[row, col] +
|
||||
calcAlphaIntercell(getAlphaX(grid)[row, col-1],
|
||||
getAlphaX(grid)[row, col]) *
|
||||
getConcentrations(grid)[row, col-1]
|
||||
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)
|
||||
|
||||
return intercellAlpha_above * concentration_above -
|
||||
(intercellAlpha_above + intercellAlpha_below) * concentration_current +
|
||||
intercellAlpha_below * concentration_below
|
||||
end
|
||||
|
||||
function calcHorizontalChangeRightBoundaryClosed(grid::Grid{T}, row::Int, col::Int) where {T}
|
||||
return -(calcAlphaIntercell(getAlphaX(grid)[row, col-1],
|
||||
getAlphaX(grid)[row, col]) *
|
||||
(getConcentrations(grid)[row, col] -
|
||||
getConcentrations(grid)[row, col-1]))
|
||||
end
|
||||
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)
|
||||
|
||||
|
||||
function calcVerticalChange(grid::Grid{T}, row::Int, col::Int) where {T}
|
||||
return calcAlphaIntercell(getAlphaY(grid)[row+1, col],
|
||||
getAlphaY(grid)[row, col]) *
|
||||
getConcentrations(grid)[row+1, col] -
|
||||
(calcAlphaIntercell(getAlphaY(grid)[row+1, col],
|
||||
getAlphaY(grid)[row, col]) +
|
||||
calcAlphaIntercell(getAlphaY(grid)[row-1, col],
|
||||
getAlphaY(grid)[row, col])) *
|
||||
getConcentrations(grid)[row, col] +
|
||||
calcAlphaIntercell(getAlphaY(grid)[row-1, col],
|
||||
getAlphaY(grid)[row, col]) *
|
||||
getConcentrations(grid)[row-1, col]
|
||||
end
|
||||
|
||||
function calcVerticalChangeTopBoundary(grid::Grid{T}, bc::Boundary{T}, row::Int, col::Int) where {T}
|
||||
if getBoundaryElementType(bc, TOP, col) == CONSTANT
|
||||
return calcVerticalChangeTopBoundaryConstant(grid, bc, row, col)
|
||||
elseif getBoundaryElementType(bc, TOP, col) == CLOSED
|
||||
return calcVerticalChangeTopBoundaryClosed(grid, row, col)
|
||||
if boundaryType == CONSTANT
|
||||
return intercellAlpha * concentration_above -
|
||||
(intercellAlpha + 2 * alphaY_current) * concentration_current +
|
||||
2 * alphaY_current * boundaryValue
|
||||
elseif boundaryType == CLOSED
|
||||
return intercellAlpha * (concentration_above - concentration_current)
|
||||
else
|
||||
error("Undefined Boundary Condition Type!")
|
||||
end
|
||||
end
|
||||
|
||||
function calcVerticalChangeTopBoundaryConstant(grid::Grid{T}, bc::Boundary{T}, row::Int, col::Int) where {T}
|
||||
return calcAlphaIntercell(getAlphaY(grid)[row+1, col],
|
||||
getAlphaY(grid)[row, col]) *
|
||||
getConcentrations(grid)[row+1, col] -
|
||||
(calcAlphaIntercell(getAlphaY(grid)[row+1, col],
|
||||
getAlphaY(grid)[row, col]) +
|
||||
2 * getAlphaY(grid)[row, col]) *
|
||||
getConcentrations(grid)[row, col] +
|
||||
2 * getAlphaY(grid)[row, col] *
|
||||
getBoundaryElementValue(bc, TOP, col)
|
||||
end
|
||||
|
||||
function calcVerticalChangeTopBoundaryClosed(grid::Grid{T}, row::Int, col::Int) where {T}
|
||||
return calcAlphaIntercell(getAlphaY(grid)[row+1, col],
|
||||
getAlphaY(grid)[row, col]) *
|
||||
(getConcentrations(grid)[row+1, col] -
|
||||
getConcentrations(grid)[row, col])
|
||||
end
|
||||
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)
|
||||
|
||||
function calcVerticalChangeBottomBoundary(grid::Grid{T}, bc::Boundary{T}, row::Int, col::Int) where {T}
|
||||
if getBoundaryElementType(bc, BOTTOM, col) == CONSTANT
|
||||
return calcVerticalChangeBottomBoundaryConstant(grid, bc, row, col)
|
||||
elseif getBoundaryElementType(bc, BOTTOM, col) == CLOSED
|
||||
return calcVerticalChangeBottomBoundaryClosed(grid, row, col)
|
||||
if boundaryType == CONSTANT
|
||||
return 2 * alphaY_current * boundaryValue -
|
||||
(intercellAlpha + 2 * alphaY_current) * concentration_current +
|
||||
intercellAlpha * concentration_below
|
||||
elseif boundaryType == CLOSED
|
||||
return -intercellAlpha * (concentration_current - concentration_below)
|
||||
else
|
||||
error("Undefined Boundary Condition Type!")
|
||||
end
|
||||
end
|
||||
|
||||
function calcVerticalChangeBottomBoundaryConstant(grid::Grid{T}, bc::Boundary{T}, row::Int, col::Int) where {T}
|
||||
return 2 * getAlphaY(grid)[row, col] *
|
||||
getBoundaryElementValue(bc, BOTTOM, col) -
|
||||
(calcAlphaIntercell(getAlphaY(grid)[row, col],
|
||||
getAlphaY(grid)[row-1, col]) +
|
||||
2 * getAlphaY(grid)[row, col]) *
|
||||
getConcentrations(grid)[row, col] +
|
||||
calcAlphaIntercell(getAlphaY(grid)[row, col],
|
||||
getAlphaY(grid)[row-1, col]) *
|
||||
getConcentrations(grid)[row-1, col]
|
||||
end
|
||||
|
||||
function calcVerticalChangeBottomBoundaryClosed(grid::Grid{T}, row::Int, col::Int) where {T}
|
||||
return -(calcAlphaIntercell(getAlphaY(grid)[row, col],
|
||||
getAlphaY(grid)[row-1, col]) *
|
||||
(getConcentrations(grid)[row, col] -
|
||||
getConcentrations(grid)[row-1, col]))
|
||||
end
|
||||
|
||||
|
||||
|
||||
function FTCS_1D(grid::Grid{T}, bc::Boundary{T}, timestep::T) where {T}
|
||||
@ -160,78 +96,119 @@ function FTCS_1D(grid::Grid{T}, bc::Boundary{T}, timestep::T) where {T}
|
||||
sx = timestep / (getDeltaCol(grid)^2)
|
||||
|
||||
concentrations = getConcentrations(grid)
|
||||
alphaX = getAlphaX(grid)
|
||||
concentrations_t1 = copy(concentrations)
|
||||
|
||||
# only one row in 1D case -> row constant at index 1
|
||||
row = 1
|
||||
|
||||
# inner cells
|
||||
# independent of boundary condition type
|
||||
for col = 2:colMax-1
|
||||
concentrations_t1[row, col] += sx * calcHorizontalChange(grid, 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; hold column constant at index 1
|
||||
concentrations_t1[row, 1] += sx * calcHorizontalChangeLeftBoundary(grid, bc, row, 1)
|
||||
# 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)
|
||||
|
||||
# right boundary; hold column constant at max index
|
||||
concentrations_t1[row, colMax] += sx * calcHorizontalChangeRightBoundary(grid, bc, row, colMax)
|
||||
# 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)
|
||||
|
||||
# overwrite obsolete concentrations
|
||||
setConcentrations!(grid, concentrations_t1)
|
||||
end
|
||||
|
||||
|
||||
function FTCS_2D(grid::Grid{T}, bc::Boundary{T}, timestep::T) where {T}
|
||||
rowMax = getRows(grid)
|
||||
colMax = getCols(grid)
|
||||
sx = timestep / (getDeltaCol(grid)^2)
|
||||
sy = timestep / (getDeltaRow(grid)^2)
|
||||
|
||||
alphaX = getAlphaX(grid)
|
||||
alphaY = getAlphaY(grid)
|
||||
concentrations = getConcentrations(grid)
|
||||
concentrations_t1 = copy(concentrations)
|
||||
|
||||
# Currently boundary sides can only be set for the whole side, not for each cell individually
|
||||
leftBoundaryType = getBoundaryElementType(bc, LEFT, 1)
|
||||
rightBoundaryType = getBoundaryElementType(bc, RIGHT, 1)
|
||||
topBoundaryType = getBoundaryElementType(bc, TOP, 1)
|
||||
bottomBoundaryType = getBoundaryElementType(bc, BOTTOM, 1)
|
||||
|
||||
Threads.@threads for row = 2:rowMax-1
|
||||
# inner cells
|
||||
for col = 2:colMax-1
|
||||
concentrations_t1[row, col] += sy * calcVerticalChange(grid, row, col) +
|
||||
sx * calcHorizontalChange(grid, 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
|
||||
|
||||
# left boundary without corners
|
||||
concentrations_t1[row, 1] += sx * calcHorizontalChangeLeftBoundary(grid, bc, row, 1) +
|
||||
sy * calcVerticalChange(grid, row, 1)
|
||||
# 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])
|
||||
|
||||
# right boundary without corners
|
||||
concentrations_t1[row, colMax] += sx * calcHorizontalChangeRightBoundary(grid, bc, row, colMax) +
|
||||
sy * calcVerticalChange(grid, row, colMax)
|
||||
# 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])
|
||||
end
|
||||
|
||||
# top / bottom without corners / looping over columns
|
||||
# Handle top/bottom boundaries
|
||||
Threads.@threads for col = 2:colMax-1
|
||||
# top
|
||||
concentrations_t1[1, col] += sy * calcVerticalChangeTopBoundary(grid, bc, 1, col) +
|
||||
sx * calcHorizontalChange(grid, 1, col)
|
||||
# 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])
|
||||
|
||||
# bottom
|
||||
concentrations_t1[rowMax, col] += sy * calcVerticalChangeBottomBoundary(grid, bc, rowMax, col) +
|
||||
sx * calcHorizontalChange(grid, rowMax, 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])
|
||||
end
|
||||
|
||||
# corner top left
|
||||
concentrations_t1[1, 1] += sx * calcHorizontalChangeLeftBoundary(grid, bc, 1, 1) +
|
||||
sy * calcVerticalChangeTopBoundary(grid, bc, 1, 1)
|
||||
# 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)
|
||||
|
||||
# corner top right
|
||||
concentrations_t1[1, colMax] += sx * calcHorizontalChangeRightBoundary(grid, bc, 1, colMax) +
|
||||
sy * calcVerticalChangeTopBoundary(grid, bc, 1, colMax)
|
||||
# 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)
|
||||
|
||||
# corner bottom left
|
||||
concentrations_t1[rowMax, 1] += sx * calcHorizontalChangeLeftBoundary(grid, bc, rowMax, 1) +
|
||||
sy * calcVerticalChangeBottomBoundary(grid, bc, rowMax, 1)
|
||||
# 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)
|
||||
|
||||
# corner bottom right
|
||||
concentrations_t1[rowMax, colMax] += sx * calcHorizontalChangeRightBoundary(grid, bc, rowMax, colMax) +
|
||||
sy * calcVerticalChangeBottomBoundary(grid, bc, rowMax, colMax)
|
||||
# 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)
|
||||
|
||||
setConcentrations!(grid, concentrations_t1)
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user