From f6c2f20453c0b30bf0f47bc0cdd19dc76d981a5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Fuhrmann?= Date: Fri, 11 Oct 2024 22:33:41 +0200 Subject: [PATCH 1/9] modernized Example120 --- examples/Example120_ThreeRegions1D.jl | 171 ++++++++++++++------------ 1 file changed, 92 insertions(+), 79 deletions(-) diff --git a/examples/Example120_ThreeRegions1D.jl b/examples/Example120_ThreeRegions1D.jl index decfd04f5..34bb4540a 100644 --- a/examples/Example120_ThreeRegions1D.jl +++ b/examples/Example120_ThreeRegions1D.jl @@ -9,16 +9,79 @@ using ExtendableGrids using GridVisualize using LinearSolve +function reaction(f, u, node, data) + k=data.k + if node.region == 1 + f[1] = k[1] * u[1] + f[2] = -k[1] * u[1] + elseif node.region == 3 + f[2] = k[3] * u[2] + f[3] = -k[3] * u[2] + else + f[1] = 0 + end +end + +function source(f, node, data) + if node.region == 1 + f[1] = 1.0e-4 * (3.0 - node[1]) + end +end + +## Since 0.17.0 one can +## write into the result also where +## the corresponding species has not been enabled +## Species information is used to prevent the assembly. +function correctionflux(f, u, edge, data) + eps=data.eps + for i = 1:3 + f[i] = eps[i] * (u[i, 1] - u[i, 2]) + end +end + +function correctionstorage(f, u, node, data) + f .= u +end + +## This is the "old" way: +## Write into result only where +## the corresponding species has been enabled +function pickyflux(f, u, edge, data) + eps=data.eps + if edge.region == 1 + f[1] = eps[1] * (u[1, 1] - u[1, 2]) + f[2] = eps[2] * (u[2, 1] - u[2, 2]) + elseif edge.region == 2 + f[2] = eps[2] * (u[2, 1] - u[2, 2]) + elseif edge.region == 3 + f[2] = eps[2] * (u[2, 1] - u[2, 2]) + f[3] = eps[3] * (u[3, 1] - u[3, 2]) + end +end + +function pickystorage(f, u, node, data) + if node.region == 1 + f[1] = u[1] + f[2] = u[2] + elseif node.region == 2 + f[2] = u[2] + elseif node.region == 3 + f[2] = u[2] + f[3] = u[3] + end +end + + function main(; n = 30, Plotter = nothing, plot_grid = false, verbose = false, unknown_storage = :sparse, tend = 10, rely_on_corrections = false, assembly = :edgewise) - h = 3.0 / (n - 1) - X = collect(0:h:3.0) + + X=range(0,3,length=n) grid = simplexgrid(X) cellmask!(grid, [0.0], [1.0], 1) cellmask!(grid, [1.0], [2.1], 2) cellmask!(grid, [1.9], [3.0], 3) - + subgrid1 = subgrid(grid, [1]) subgrid2 = subgrid(grid, [1, 2, 3]) subgrid3 = subgrid(grid, [3]) @@ -27,73 +90,15 @@ function main(; n = 30, Plotter = nothing, plot_grid = false, verbose = false, plotgrid(grid; Plotter = Plotter) return end - - eps = [1, 1, 1] - k = [1, 1, 1] - - function reaction(f, u, node, data) - if node.region == 1 - f[1] = k[1] * u[1] - f[2] = -k[1] * u[1] - elseif node.region == 3 - f[2] = k[3] * u[2] - f[3] = -k[3] * u[2] - else - f[1] = 0 - end - end - - function source(f, node, data) - if node.region == 1 - f[1] = 1.0e-4 * (3.0 - node[1]) - end - end - - if rely_on_corrections - ## Since 0.17.0 one can - ## write into the result also where - ## the corresponding species has not been enabled - ## Species information is used to prevent the assembly. - flux = function (f, u, edge, data) - for i = 1:3 - f[i] = eps[i] * (u[i, 1] - u[i, 2]) - end - end - - storage = function (f, u, node, data) - f .= u - end - else - ## This is the "old" way: - ## Write into result only where - ## the corresponding species has been enabled - flux = function (f, u, edge, data) - if edge.region == 1 - f[1] = eps[1] * (u[1, 1] - u[1, 2]) - f[2] = eps[2] * (u[2, 1] - u[2, 2]) - elseif edge.region == 2 - f[2] = eps[2] * (u[2, 1] - u[2, 2]) - elseif edge.region == 3 - f[2] = eps[2] * (u[2, 1] - u[2, 2]) - f[3] = eps[3] * (u[3, 1] - u[3, 2]) - end - end - - storage = function (f, u, node, data) - if node.region == 1 - f[1] = u[1] - f[2] = u[2] - elseif node.region == 2 - f[2] = u[2] - elseif node.region == 3 - f[2] = u[2] - f[3] = u[3] - end - end - end - - sys = VoronoiFVM.System(grid; flux, reaction, storage, source, - unknown_storage = unknown_storage, assembly = assembly) + + data=(eps = [1, 1, 1], k = [1, 1, 1]) + + flux = rely_on_corrections ? correctionflux : pickyflux + storage = rely_on_corrections ? correctionstorage : pickystorage + + sys = VoronoiFVM.System(grid; data, + flux, reaction, storage, source, + unknown_storage, assembly) enable_species!(sys, 1, [1]) enable_species!(sys, 2, [1, 2, 3]) @@ -104,18 +109,11 @@ function main(; n = 30, Plotter = nothing, plot_grid = false, verbose = false, testval = 0 p = GridVisualizer(; Plotter = Plotter, layout = (1, 1)) - testval = 0.0 - function plot_timestep(U, Uold, time, Δt) + function plot_timestep(U,time) U1 = view(U[1, :], subgrid1) U2 = view(U[2, :], subgrid2) U3 = view(U[3, :], subgrid3) - testval += sum(U2) - - if Plotter == nothing - return - end - scalarplot!(p[1, 1], subgrid1, U1; label = "spec1", color = (0.5, 0, 0), xlimits = (0, 3), flimits = (0, 1e-3), title = @sprintf("three regions t=%.3g", time)) @@ -123,11 +121,26 @@ function main(; n = 30, Plotter = nothing, plot_grid = false, verbose = false, clear = false) scalarplot!(p[1, 1], subgrid3, U3; label = "spec3", color = (0.0, 0.0, 0.5), clear = false, show = true) + if ismakie(Plotter) + sleep(0.02) + end end - tsol = solve(sys; inival = 0, times = (0, tend), post = plot_timestep, verbose = verbose, Δu_opt = 1.0e-5, + tsol = solve(sys; inival = 0, times = (0, tend), + verbose, Δu_opt = 1.0e-5, method_linear=KLUFactorization()) + testval = 0.0 + for i=2:length(tsol.t) + ui=view(tsol,2,:,i) + testval+=sum(view(ui,subgrid2)) + end + + if !isnothing(Plotter) + for i=2:length(tsol.t) + plot_timestep(tsol.u[i],tsol.t[i]) + end + end return testval end From f10a89e894306f07e397956598c203c48226250c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Fuhrmann?= Date: Fri, 11 Oct 2024 23:51:59 +0200 Subject: [PATCH 2/9] replace vec() and values() by dofs() ... in both cases it was either type piracy or duplicate definition. Also fixes #119. --- examples/Example120_ThreeRegions1D.jl | 7 +++++++ src/vfvm_assembly.jl | 9 +++++---- src/vfvm_densesolution.jl | 8 +++----- src/vfvm_diffeq_interface.jl | 8 ++++---- src/vfvm_impedance.jl | 8 ++++---- src/vfvm_solver.jl | 6 +++--- src/vfvm_solvercontrol.jl | 4 ++-- src/vfvm_sparsesolution.jl | 6 +++--- src/vfvm_testfunctions.jl | 2 +- 9 files changed, 32 insertions(+), 26 deletions(-) diff --git a/examples/Example120_ThreeRegions1D.jl b/examples/Example120_ThreeRegions1D.jl index 34bb4540a..f84326b83 100644 --- a/examples/Example120_ThreeRegions1D.jl +++ b/examples/Example120_ThreeRegions1D.jl @@ -8,6 +8,8 @@ using VoronoiFVM using ExtendableGrids using GridVisualize using LinearSolve +using OrdinaryDiffEqRosenbrock +using SciMLBase: NoInit function reaction(f, u, node, data) k=data.k @@ -129,7 +131,12 @@ function main(; n = 30, Plotter = nothing, plot_grid = false, verbose = false, tsol = solve(sys; inival = 0, times = (0, tend), verbose, Δu_opt = 1.0e-5, method_linear=KLUFactorization()) + # inival=unknowns(sys,inival=0) + # problem = ODEProblem(sys,inival,(0,tend)) + # odesol = solve(problem,Rosenbrock23(), initializealg=NoInit()) + # tsol=reshape(odesol,sys) + testval = 0.0 for i=2:length(tsol.t) ui=view(tsol,2,:,i) diff --git a/src/vfvm_assembly.jl b/src/vfvm_assembly.jl index b24b1d3e4..b1c426075 100644 --- a/src/vfvm_assembly.jl +++ b/src/vfvm_assembly.jl @@ -7,6 +7,7 @@ Re-exported from ForwardDiff.jl """ const value = ForwardDiff.value + """ $(SIGNATURES) @@ -559,8 +560,8 @@ function _eval_and_assemble_generic_operator(system::AbstractSystem, matrix, U, return end generic_operator(f, u) = system.physics.generic_operator(f, u, system) - vecF = values(F) - vecU = values(U) + vecF = dofs(F) + vecU = dofs(U) y = similar(vecF) generic_operator(y, vecU) vecF .+= y @@ -583,8 +584,8 @@ function _eval_generic_operator(system::AbstractSystem, U, F) return end generic_operator(f, u) = system.physics.generic_operator(f, u, system) - vecF = values(F) - vecU = values(U) + vecF = dofs(F) + vecU = dofs(U) y = similar(vecF) generic_operator(y, vecU) vecF .+= y diff --git a/src/vfvm_densesolution.jl b/src/vfvm_densesolution.jl index 280bf0170..2f630dce0 100644 --- a/src/vfvm_densesolution.jl +++ b/src/vfvm_densesolution.jl @@ -51,9 +51,6 @@ Return indices for dense solution array. unknown_indices(a::DenseSolutionArray) = LinearIndices(a) - -Base.vec(a::DenseSolutionArray) = vec(a.u) - Base.copy(a::DenseSolutionArray) = DenseSolutionArray(copy(a.u)) Base.similar(a::DenseSolutionArray) = DenseSolutionArray(similar(a.u)) @@ -61,9 +58,10 @@ Base.similar(a::DenseSolutionArray) = DenseSolutionArray(similar(a.u)) """ $(SIGNATURES) -Array of values in solution array. +Vector of degrees of freedom in solution array. """ -values(a::DenseSolutionArray) = vec(a) +dofs(a::DenseSolutionArray) = vec(a.u) +dofs(a::Array)=vec(a) """ $(TYPEDSIGNATURES) diff --git a/src/vfvm_diffeq_interface.jl b/src/vfvm_diffeq_interface.jl index 19cc3dfa9..9021f0b62 100644 --- a/src/vfvm_diffeq_interface.jl +++ b/src/vfvm_diffeq_interface.jl @@ -23,7 +23,7 @@ rhs function for [`SciMLBase.ODEFunction`](@ref). """ function eval_rhs!(du, u, state, t) _eval_res_jac!(state, u, t) - du .= -vec(state.residual) + du .= -dofs(state.residual) state.history.nf += 1 nothing end @@ -121,7 +121,7 @@ For more documentation, see [`SciMLBase.ODEFunction(state::VoronoiFVM.SystemStat function SciMLBase.ODEFunction(state::VoronoiFVM.SystemState; jacval = unknowns(sys, 0), tjac = 0) SciMLBase.ODEFunction(eval_rhs!; jac = eval_jacobian!, - jac_prototype = prepare_diffeq!(state, vec(jacval), tjac), + jac_prototype = prepare_diffeq!(state, dofs(jacval), tjac), mass_matrix = mass_matrix(state)) end @@ -152,8 +152,8 @@ for more documentation. Defined in VoronoiFVM.jl. """ function SciMLBase.ODEProblem(state::VoronoiFVM.SystemState, inival, tspan; callback = SciMLBase.CallbackSet()) - odefunction = SciMLBase.ODEFunction(state; jacval = vec(inival), tjac = tspan[1]) - SciMLBase.ODEProblem(odefunction, vec(inival), tspan, state, callback) + odefunction = SciMLBase.ODEFunction(state; jacval = dofs(inival), tjac = tspan[1]) + SciMLBase.ODEProblem(odefunction, dofs(inival), tspan, state, callback) end """ diff --git a/src/vfvm_impedance.jl b/src/vfvm_impedance.jl index c4316bfd2..4d6a5846a 100644 --- a/src/vfvm_impedance.jl +++ b/src/vfvm_impedance.jl @@ -221,7 +221,7 @@ function CommonSolve.solve!(UZ::AbstractMatrix{Complex{Tv}}, impedance_system::I end lufact = LinearAlgebra.lu(matrix) - ldiv!(values(UZ), lufact, values(impedance_system.F)) + ldiv!(dofs(UZ), lufact, dofs(impedance_system.F)) end """ @@ -248,7 +248,7 @@ function measurement_derivative(system::AbstractSystem, measurement_functional, colors = matrix_colors(jac) # Use Julia automatic differentiation for the calculation of the Jacobian - forwarddiff_color_jacobian!(jac, measurement_functional, values(U0); colorvec = colors) + forwarddiff_color_jacobian!(jac, measurement_functional, dofs(U0); colorvec = colors) # Drop any zero entries dropzeros!(jac) @@ -285,8 +285,8 @@ function impedance(impedance_system::ImpedanceSystem, # frequency domain system solve!(UZ, impedance_system, ω) # obtain measurement in frequency domain - m_stdy = dmeas_stdy * values(UZ) - m_tran = dmeas_tran * values(UZ) + m_stdy = dmeas_stdy * dofs(UZ) + m_tran = dmeas_tran * dofs(UZ) # Calculate complex measurement z = m_stdy[1] + iω * m_tran[1] diff --git a/src/vfvm_solver.jl b/src/vfvm_solver.jl index 3d2b03bae..622a5c208 100644 --- a/src/vfvm_solver.jl +++ b/src/vfvm_solver.jl @@ -83,15 +83,15 @@ function solve_step!(state, end end - tlinsolve += @elapsed _solve_linear!(values(update), + tlinsolve += @elapsed _solve_linear!(dofs(update), state, nlhistory, control, method_linear, state.matrix, - values(residual)) + dofs(residual)) - values(solution) .-= damp * values(update) + dofs(solution) .-= damp * dofs(update) if state.system.is_linear converged = true diff --git a/src/vfvm_solvercontrol.jl b/src/vfvm_solvercontrol.jl index f8f095222..ae8979328 100644 --- a/src/vfvm_solvercontrol.jl +++ b/src/vfvm_solvercontrol.jl @@ -89,12 +89,12 @@ Base.@kwdef mutable struct SolverControl """ Calculation of Newton update norm """ - unorm::Function = (u) -> LinearAlgebra.norm(values(u), Inf) # norm for update calculation + unorm::Function = (u) -> LinearAlgebra.norm(dofs(u), Inf) # norm for update calculation """ Functional for roundoff error calculation """ - rnorm::Function = (u) -> LinearAlgebra.norm(values(u), 1) + rnorm::Function = (u) -> LinearAlgebra.norm(dofs(u), 1) """ Solver method for linear systems (see LinearSolve.jl). If given `nothing`, as default diff --git a/src/vfvm_sparsesolution.jl b/src/vfvm_sparsesolution.jl index cc51d8003..447736e1c 100644 --- a/src/vfvm_sparsesolution.jl +++ b/src/vfvm_sparsesolution.jl @@ -51,10 +51,10 @@ Base.getindex(idx::SparseSolutionIndices, i, j) = dof(idx.a, i, j) """ $(SIGNATURES) -Array of values in sparse solution array. +Vector of degrees of freedom in sparse solution array. """ -values(a::SparseSolutionArray) = a.u.nzval -values(a::SparseMatrixCSC) = a.nzval +dofs(a::SparseSolutionArray) = a.u.nzval +dofs(a::SparseMatrixCSC) = a.nzval Base.size(a::SparseSolutionArray)=size(a.u) ################################################################## diff --git a/src/vfvm_testfunctions.jl b/src/vfvm_testfunctions.jl index 63981ff01..8bbecdd60 100644 --- a/src/vfvm_testfunctions.jl +++ b/src/vfvm_testfunctions.jl @@ -82,7 +82,7 @@ function testfunction(factory::TestFunctionFactory{Tv}, bc0, bc1) where {Tv} method_linear = UMFPACKFactorization() end - p = LinearProblem(SparseMatrixCSC(factory.state.matrix), vec(f)) + p = LinearProblem(SparseMatrixCSC(factory.state.matrix), dofs(f)) sol = solve(p, method_linear) sol.u end From bc5428de0889ecd815ec423de7f56666f1c8f2f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Fuhrmann?= Date: Sat, 12 Oct 2024 00:17:20 +0200 Subject: [PATCH 3/9] fix type piracy with VoronoiFVM.values --- src/VoronoiFVM.jl | 2 +- src/vfvm_assembly.jl | 7 ------- src/vfvm_linsolve.jl | 1 + src/vfvm_physics.jl | 1 - 4 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/VoronoiFVM.jl b/src/VoronoiFVM.jl index 135731925..de4b05869 100644 --- a/src/VoronoiFVM.jl +++ b/src/VoronoiFVM.jl @@ -33,7 +33,7 @@ using ExtendableSparse: ExtendableSparse, BlockPreconditioner, PointBlockILUZeroPreconditioner, factorize!, flush!, nnz, rawupdateindex!, sparse, updateindex!, nnznew -using ForwardDiff: ForwardDiff +using ForwardDiff: ForwardDiff, value using GridVisualize: GridVisualize, GridVisualizer using InteractiveUtils: InteractiveUtils using JLD2: JLD2, jldopen diff --git a/src/vfvm_assembly.jl b/src/vfvm_assembly.jl index b1c426075..9610bded4 100644 --- a/src/vfvm_assembly.jl +++ b/src/vfvm_assembly.jl @@ -1,11 +1,4 @@ ################################################################## -""" -$(SIGNATURES) - -Extract value from dual number. Use to debug physics callbacks. -Re-exported from ForwardDiff.jl -""" -const value = ForwardDiff.value """ diff --git a/src/vfvm_linsolve.jl b/src/vfvm_linsolve.jl index 28d37e9b7..b21d0fec0 100644 --- a/src/vfvm_linsolve.jl +++ b/src/vfvm_linsolve.jl @@ -198,6 +198,7 @@ VoronoiFVM.SolverControl(::Nothing, sys; kwargs...) = SolverControl(; kwargs...) ################################################################ # These are needed to enable iterative solvers to work with dual numbers +# TODO: Remove this Pirate's nest Base.Float64(x::ForwardDiff.Dual) = value(x) function Random.rand(rng::AbstractRNG, ::Random.SamplerType{ForwardDiff.Dual{T, V, N}}) where {T, V, N} diff --git a/src/vfvm_physics.jl b/src/vfvm_physics.jl index 6d23cd5ed..793ec36f1 100644 --- a/src/vfvm_physics.jl +++ b/src/vfvm_physics.jl @@ -49,7 +49,6 @@ Pretty print [`AbstractData`](@ref) """ Base.show(io::IO, ::MIME"text/plain", this::AbstractData) = _showstruct(io, this) -ForwardDiff.value(x::Real) = x # # Dummy callbacks From e3262e51402304997581ddcda9ffd0ea20d39811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Fuhrmann?= Date: Sat, 12 Oct 2024 00:19:16 +0200 Subject: [PATCH 4/9] add dofs to docs --- docs/src/internal.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/internal.md b/docs/src/internal.md index c7bc2cbb1..b2c9cba8d 100644 --- a/docs/src/internal.md +++ b/docs/src/internal.md @@ -82,6 +82,7 @@ VoronoiFVM.getspecies VoronoiFVM.getnodedof VoronoiFVM.increase_num_species! VoronoiFVM.addzrows +VoronoiFVM.dofs ``` From 4fc1c31f0e26b22b426d0d4d299def9dad1fd261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Fuhrmann?= Date: Sat, 12 Oct 2024 00:49:30 +0200 Subject: [PATCH 5/9] Add docstring to re-exported ForwardDiff.value --- src/vfvm_physics.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vfvm_physics.jl b/src/vfvm_physics.jl index 793ec36f1..5225a747d 100644 --- a/src/vfvm_physics.jl +++ b/src/vfvm_physics.jl @@ -49,6 +49,12 @@ Pretty print [`AbstractData`](@ref) """ Base.show(io::IO, ::MIME"text/plain", this::AbstractData) = _showstruct(io, this) +@doc """ + value(x) + +Return the value of a dual number (for debugging in callback functions). +Re-exported from ForwardDiff. +""" value # # Dummy callbacks From a7ab1a107ad217754708744dcacc02364ddb025d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Fuhrmann?= Date: Sat, 12 Oct 2024 00:56:54 +0200 Subject: [PATCH 6/9] changed testval calculation in example120 --- examples/Example120_ThreeRegions1D.jl | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/examples/Example120_ThreeRegions1D.jl b/examples/Example120_ThreeRegions1D.jl index f84326b83..9a1317a3f 100644 --- a/examples/Example120_ThreeRegions1D.jl +++ b/examples/Example120_ThreeRegions1D.jl @@ -76,6 +76,7 @@ end function main(; n = 30, Plotter = nothing, plot_grid = false, verbose = false, unknown_storage = :sparse, tend = 10, + diffeq=false, rely_on_corrections = false, assembly = :edgewise) X=range(0,3,length=n) @@ -128,19 +129,22 @@ function main(; n = 30, Plotter = nothing, plot_grid = false, verbose = false, end end - tsol = solve(sys; inival = 0, times = (0, tend), - verbose, Δu_opt = 1.0e-5, - method_linear=KLUFactorization()) - # inival=unknowns(sys,inival=0) - # problem = ODEProblem(sys,inival,(0,tend)) - # odesol = solve(problem,Rosenbrock23(), initializealg=NoInit()) - # tsol=reshape(odesol,sys) - + if diffeq + inival=unknowns(sys,inival=0) + problem = ODEProblem(sys,inival,(0,tend)) + odesol = solve(problem,Rosenbrock23(), initializealg=NoInit()) + tsol=reshape(odesol,sys) + else + tsol = solve(sys; inival = 0, times = (0, tend), + verbose, Δu_opt = 1.0e-5, + method_linear=KLUFactorization()) + end testval = 0.0 for i=2:length(tsol.t) ui=view(tsol,2,:,i) - testval+=sum(view(ui,subgrid2)) + Δt=tsol.t[i]-tsol.t[i-1] + testval+=sum(view(ui,subgrid2))*Δt end if !isnothing(Plotter) @@ -154,7 +158,7 @@ end using Test function runtests() - testval = 0.359448515181824 + testval = 0.06922262169719146 @test main(; unknown_storage = :sparse, rely_on_corrections = false, assembly = :edgewise) ≈ testval @test main(; unknown_storage = :dense, rely_on_corrections = false, assembly = :edgewise) ≈ testval @test main(; unknown_storage = :sparse, rely_on_corrections = true, assembly = :edgewise) ≈ testval From 6af67c7a1968913068a1882ad7187399e6c6e727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Fuhrmann?= Date: Sat, 12 Oct 2024 01:12:23 +0200 Subject: [PATCH 7/9] add diffeq based tests to Example120 --- examples/Example120_ThreeRegions1D.jl | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/examples/Example120_ThreeRegions1D.jl b/examples/Example120_ThreeRegions1D.jl index 9a1317a3f..bdbc0a53f 100644 --- a/examples/Example120_ThreeRegions1D.jl +++ b/examples/Example120_ThreeRegions1D.jl @@ -132,7 +132,8 @@ function main(; n = 30, Plotter = nothing, plot_grid = false, verbose = false, if diffeq inival=unknowns(sys,inival=0) problem = ODEProblem(sys,inival,(0,tend)) - odesol = solve(problem,Rosenbrock23(), initializealg=NoInit()) + ## use fixed timesteps just for the purpose of CI + odesol = solve(problem,Rosenbrock23(), initializealg=NoInit(), dt=1.0e-2, adaptive=false) tsol=reshape(odesol,sys) else tsol = solve(sys; inival = 0, times = (0, tend), @@ -159,6 +160,7 @@ using Test function runtests() testval = 0.06922262169719146 + testvaldiffeq = 0.06889809741891571 @test main(; unknown_storage = :sparse, rely_on_corrections = false, assembly = :edgewise) ≈ testval @test main(; unknown_storage = :dense, rely_on_corrections = false, assembly = :edgewise) ≈ testval @test main(; unknown_storage = :sparse, rely_on_corrections = true, assembly = :edgewise) ≈ testval @@ -167,6 +169,17 @@ function runtests() @test main(; unknown_storage = :dense, rely_on_corrections = false, assembly = :cellwise) ≈ testval @test main(; unknown_storage = :sparse, rely_on_corrections = true, assembly = :cellwise) ≈ testval @test main(; unknown_storage = :dense, rely_on_corrections = true, assembly = :cellwise) ≈ testval + + + @test main(; diffeq=true, unknown_storage = :sparse, rely_on_corrections = false, assembly = :edgewise) ≈ testvaldiffeq + @test main(; diffeq=true, unknown_storage = :dense, rely_on_corrections = false, assembly = :edgewise) ≈ testvaldiffeq + @test main(; diffeq=true, unknown_storage = :sparse, rely_on_corrections = true, assembly = :edgewise) ≈ testvaldiffeq + @test main(; diffeq=true, unknown_storage = :dense, rely_on_corrections = true, assembly = :edgewise) ≈ testvaldiffeq + @test main(; diffeq=true, unknown_storage = :sparse, rely_on_corrections = false, assembly = :cellwise) ≈ testvaldiffeq + @test main(; diffeq=true, unknown_storage = :dense, rely_on_corrections = false, assembly = :cellwise) ≈ testvaldiffeq + @test main(; diffeq=true, unknown_storage = :sparse, rely_on_corrections = true, assembly = :cellwise) ≈ testvaldiffeq + @test main(; diffeq=true, unknown_storage = :dense, rely_on_corrections = true, assembly = :cellwise) ≈ testvaldiffeq + end end From 94eb8fe5ec20fadad088169516bcbee7f66ef08e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Fuhrmann?= Date: Sat, 12 Oct 2024 01:22:15 +0200 Subject: [PATCH 8/9] add diffeq based test to Example115 ... this fixes a bug with boundary variables in the diffeq case --- .../Example115_HeterogeneousCatalysis1D.jl | 35 ++++++++++++++----- src/vfvm_diffeq_interface.jl | 2 +- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/examples/Example115_HeterogeneousCatalysis1D.jl b/examples/Example115_HeterogeneousCatalysis1D.jl index b07dbcea8..80548e568 100644 --- a/examples/Example115_HeterogeneousCatalysis1D.jl +++ b/examples/Example115_HeterogeneousCatalysis1D.jl @@ -59,9 +59,12 @@ using VoronoiFVM using ExtendableGrids using GridVisualize using LinearAlgebra +using OrdinaryDiffEqRosenbrock +using SciMLBase: NoInit function main(; n = 10, Plotter = nothing, verbose = false, tend = 1, - unknown_storage = :sparse, assembly = :edgewise) + unknown_storage = :sparse, assembly = :edgewise, + diffeq=false) h = 1.0 / convert(Float64, n) X = collect(0.0:h:1.0) N = length(X) @@ -154,10 +157,17 @@ function main(; n = 10, Plotter = nothing, verbose = false, tend = 1, ## Data to store surface concentration vs time p = GridVisualizer(; Plotter = Plotter, layout = (3, 1)) - - control = fixed_timesteps!(VoronoiFVM.NewtonControl(), tstep) - tsol = solve(sys; inival, times = [0, tend], control, verbose = verbose) - + if diffeq + inival=unknowns(sys,inival=0) + problem = ODEProblem(sys,inival,(0,tend)) + ## use fixed timesteps just for the purpose of CI + odesol = solve(problem,Rosenbrock23(); initializealg=NoInit(), dt=tstep, adaptive=false) + tsol=reshape(odesol,sys) + else + control = fixed_timesteps!(VoronoiFVM.NewtonControl(), tstep) + tsol = solve(sys; inival, times = [0, tend], control, verbose = verbose) + end + p = GridVisualizer(; Plotter = Plotter, layout = (3, 1), fast = true) for it = 1:length(tsol) time = tsol.t[it] @@ -175,9 +185,16 @@ end using Test function runtests() testval = 0.87544440641274 - @test isapprox(main(; unknown_storage = :sparse, assembly = :edgewise), testval; rtol = 1.0e-12) && - isapprox(main(; unknown_storage = :dense, assembly = :edgewise), testval; rtol = 1.0e-12) && - isapprox(main(; unknown_storage = :sparse, assembly = :cellwise), testval; rtol = 1.0e-12) && - isapprox(main(; unknown_storage = :dense, assembly = :cellwise), testval; rtol = 1.0e-12) + testvaldiffeq = 0.8891082547874963 + @test isapprox(main(; unknown_storage = :sparse, assembly = :edgewise), testval; rtol = 1.0e-12) + @test isapprox(main(; unknown_storage = :dense, assembly = :edgewise), testval; rtol = 1.0e-12) + @test isapprox(main(; unknown_storage = :sparse, assembly = :cellwise), testval; rtol = 1.0e-12) + @test isapprox(main(; unknown_storage = :dense, assembly = :cellwise), testval; rtol = 1.0e-12) + + @test isapprox(main(; diffeq=true, unknown_storage = :sparse, assembly = :edgewise), testvaldiffeq; rtol = 1.0e-12) + @test isapprox(main(; diffeq=true, unknown_storage = :dense, assembly = :edgewise), testvaldiffeq; rtol = 1.0e-12) + @test isapprox(main(; diffeq=true, unknown_storage = :sparse, assembly = :cellwise), testvaldiffeq; rtol = 1.0e-12) + @test isapprox(main(; diffeq=true, unknown_storage = :dense, assembly = :cellwise), testvaldiffeq; rtol = 1.0e-12) + end end diff --git a/src/vfvm_diffeq_interface.jl b/src/vfvm_diffeq_interface.jl index 9021f0b62..146db96d5 100644 --- a/src/vfvm_diffeq_interface.jl +++ b/src/vfvm_diffeq_interface.jl @@ -84,7 +84,7 @@ function mass_matrix(state::SystemState{Tv, TMatrix, TSolArray, TData}) where {T @views evaluate!(bstor_eval, U[:, K]) jac_bstor = jac(bstor_eval) asm_jac(idof, jdof, ispec, jspec) = _addnz(M, idof, jdof, jac_bstor[ispec, jspec], bnode.fac) - assemble_res_jac(node, system, asm_res, asm_jac, asm_param) + assemble_res_jac(node, state.system, asm_res, asm_jac, asm_param) end end end From d8d04ba0ab2542ae2a2369a2714a422be6b2bd9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Fuhrmann?= Date: Sat, 12 Oct 2024 13:52:14 +0200 Subject: [PATCH 9/9] bump version, changelog --- CHANGELOG.md | 13 +++++++++++++ Project.toml | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eacc3b4af..5561fd28b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,19 @@ # Changes + ## v3.0 Planned (pending some improvements in LinearSolve) - use `precs` based linear solver API, see https://github.com/SciML/LinearSolve.jl/pull/514 + - stop re-exporting ForwardDiff.value + - try to remove type piracies + +## v2.0.2 October 12, 2024 + - Bugfixes + - replace internally used `values` and `vec` methods by new `dofs` + - fix #119, update Example115, Example120, test sparse unknown storage & ODE solver + - directly re-export ForwardDiff.value, dont type-pirate a new method + +## v2.0.1 October 7, 2024 + - Bugfixes + - fix case where the last element of a time solution is used as initial value for a next `solve` ## v2.0.0 September 12, 2024 diff --git a/Project.toml b/Project.toml index 26f91b6f4..2192e0442 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "VoronoiFVM" uuid = "82b139dc-5afc-11e9-35da-9b9bdfd336f3" authors = ["Jürgen Fuhrmann ", "Patrick Jaap", "Dilara Abdel", "Jan Weidner", "Alexander Seiler", "Patricio Farrell", "Matthias Liero"] -version = "2.0.1" +version = "2.0.2" [deps] BandedMatrices = "aae01518-5342-5314-be14-df237901396f"