diff --git a/Project.toml b/Project.toml index 164996dd6..4c39d987b 100644 --- a/Project.toml +++ b/Project.toml @@ -1,10 +1,11 @@ name = "VoronoiFVM" uuid = "82b139dc-5afc-11e9-35da-9b9bdfd336f3" authors = ["Jürgen Fuhrmann ", "Dilara Abdel", "Jan Weidner", "Alexander Seiler", "Patricio Farrell", "Matthias Liero"] -version = "1.15.1" +version = "1.16.0" [deps] BandedMatrices = "aae01518-5342-5314-be14-df237901396f" +Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" CommonSolve = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" DiffResults = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" @@ -28,6 +29,7 @@ Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" [compat] BandedMatrices = "0.17,1" +Colors = "0.12" CommonSolve = "0.2" DiffResults = "1" DocStringExtensions = "0.8,0.9" @@ -40,7 +42,7 @@ LinearAlgebra = "1.6" LinearSolve = "2.2" Printf = "1.6" Random = "1.6" -RecursiveArrayTools = "^2.14.2" +RecursiveArrayTools = "^2.14.2,3" RecursiveFactorization = "0.2.18" SparseArrays = "1.6" SparseDiffTools = "^1.19, 2" diff --git a/docs/src/changes.md b/docs/src/changes.md index 03937ba1e..d001be4b6 100644 --- a/docs/src/changes.md +++ b/docs/src/changes.md @@ -1,4 +1,9 @@ # Changes +## v1.16.0 Dec 15, 2023 +- Bugfix for assembly of outflow bc +- Bugfix for matrixtype=:banded +- Updated [`plothistory`](@ref): + ## v1.15.0 Dec 1, 2023 - Adjusted time/embedding stepping scheme, added `num_final_steps` to [`VoronoiFVM.SolverControl`](@ref). This may lead to sligthly different results when solving time dependent problems. Some unit test values have been adapted. Before, diff --git a/examples/Example120_ThreeRegions1D.jl b/examples/Example120_ThreeRegions1D.jl index a9d35b604..ba431f743 100644 --- a/examples/Example120_ThreeRegions1D.jl +++ b/examples/Example120_ThreeRegions1D.jl @@ -7,6 +7,7 @@ using Printf using VoronoiFVM using ExtendableGrids using GridVisualize +using LinearSolve function main(; n = 30, Plotter = nothing, plot_grid = false, verbose = false, unknown_storage = :sparse, tend = 10, @@ -124,22 +125,24 @@ function main(; n = 30, Plotter = nothing, plot_grid = false, verbose = false, clear = false, show = true) 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), post = plot_timestep, verbose = verbose, Δu_opt = 1.0e-5, + method_linear=KLUFactorization()) return testval end using Test + function runtests() testval = 0.359448515181824 - @test main(; unknown_storage = :sparse, rely_on_corrections = false, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :dense, rely_on_corrections = false, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :sparse, rely_on_corrections = true, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :dense, rely_on_corrections = true, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :sparse, rely_on_corrections = false, assembly = :cellwise) ≈ testval && - main(; unknown_storage = :dense, rely_on_corrections = false, assembly = :cellwise) ≈ testval && - main(; unknown_storage = :sparse, rely_on_corrections = true, assembly = :cellwise) ≈ testval && - main(; unknown_storage = :dense, rely_on_corrections = true, assembly = :cellwise) ≈ testval + @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 + @test main(; unknown_storage = :dense, rely_on_corrections = true, assembly = :edgewise) ≈ testval + @test main(; unknown_storage = :sparse, rely_on_corrections = false, assembly = :cellwise) ≈ testval + @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 end end diff --git a/src/.JuliaFormatter.toml b/src/.JuliaFormatter.toml index 905ee5359..5d28f1b62 100644 --- a/src/.JuliaFormatter.toml +++ b/src/.JuliaFormatter.toml @@ -1,4 +1,7 @@ style = "sciml" +pipe_to_function_call=false always_for_in = false separate_kwargs_with_semicolon = true margin = 132 +yas_style_nesting=true +ignore = "examples/PlutoGridFactory.jl" \ No newline at end of file diff --git a/src/gridvisualize.jl b/src/gridvisualize.jl index 74f2024da..f5a8c642c 100644 --- a/src/gridvisualize.jl +++ b/src/gridvisualize.jl @@ -1,5 +1,6 @@ # Extend GridVisualize methods import GridVisualize +import Colors """ $(TYPEDSIGNATURES) @@ -79,14 +80,18 @@ end """ plothistory(sys, tsol; - plots=[:timesteps,:newtonsteps,:updates], - size=(700,400), + plots=[:timestepsizes, + :timestepupdates, + :newtonsteps, + :newtonupdates], + size=(700,600), Plotter=GridVisualize.default_plotter(), kwargs...) Plot solution history stored in `tsol`. The `plots` argument allows to choose which plots are shown. """ -function plothistory(sys, tsol; plots=[:timesteps,:newtonsteps,:updates], size=(700,400), Plotter=GridVisualize.default_plotter(), kwargs...) +function plothistory(tsol::TransientSolution; plots=[:timestepsizes,:timestepupdates,:newtonsteps,:newtonupdates], + size=(700,150*length(plots)), Plotter=GridVisualize.default_plotter(), kwargs...) hist=history(tsol) t=hist.times if length(t)==0 @@ -96,17 +101,37 @@ function plothistory(sys, tsol; plots=[:timesteps,:newtonsteps,:updates], size=( vis=GridVisualize.GridVisualizer(;layout=(nplots,1), size, Plotter, kwargs...) for iplot in eachindex(plots) - if plots[iplot]==:timesteps + if plots[iplot]==:timestepsizes GridVisualize.scalarplot!(vis[iplot,1],t[1:(end - 1)], t[2:end] - t[1:(end - 1)]; title = "Time step sizes", xlabel = "t/s", ylabel = "Δt/s", color=:red, kwargs...) + elseif plots[iplot]==:timestepupdates + GridVisualize.scalarplot!(vis[iplot,1],t, hist.updates,xlabel = "t/s", ylabel = "du", + title="Time step updates", color=:red, kwargs...) elseif plots[iplot]==:newtonsteps newtons=map(h->length(h.updatenorm),hist.histories) GridVisualize.scalarplot!(vis[iplot,1],t, newtons,xlabel = "t/s", ylabel = "n", - title="Newton iterations", color=:red, limits=(0,maximum(newtons)+1), kwargs...) - elseif plots[iplot]==:updates - GridVisualize.scalarplot!(vis[iplot,1],t, hist.updates,xlabel = "t/s", ylabel = "du", - title="Time step updates", color=:red, kwargs...) + title="Newton steps", color=:red, limits=(0,maximum(newtons)+1), kwargs...) + elseif plots[iplot]==:newtonupdates + nhist=length(hist) + dc=1/nhist + r=0.0 + b=1.0 + g=0.0 + for h in hist + GridVisualize.scalarplot!(vis[iplot,1], + 1:length(h),h, + xlabel="step", + ylabel="du", + clear=false, + yscale=:log, + color=Colors.RGB(r,g,b), + linewidth=0.5, title="Newton updates") + r+=dc + b-=dc + end end end GridVisualize.reveal(vis) end + +plothistory(sys,tsol;kwargs...)=plothistory(tsol,kwargs...) diff --git a/src/vfvm_assembly.jl b/src/vfvm_assembly.jl index a177905ad..1b3abbf4a 100644 --- a/src/vfvm_assembly.jl +++ b/src/vfvm_assembly.jl @@ -273,7 +273,7 @@ function eval_and_assemble( system.matrix, idofK, jdofL, - -jac_outflow[ispec, jspec+nspecies], + jac_outflow[ispec, jspec+nspecies], edge.fac ) end @@ -283,7 +283,7 @@ function eval_and_assemble( system.matrix, idofL, jdofK, - +jac_outflow[ispec, jspec], + -jac_outflow[ispec, jspec], edge.fac ) _addnz( diff --git a/src/vfvm_linsolve.jl b/src/vfvm_linsolve.jl index 4898a9d79..cf2bc13ae 100644 --- a/src/vfvm_linsolve.jl +++ b/src/vfvm_linsolve.jl @@ -228,11 +228,14 @@ function LinearAlgebra.ldiv!(u, cache::LinearSolve.LinearCache, b) copyto!(u, sol.u) end +canonical_matrix(A)=A +canonical_matrix(A::ExtendableSparseMatrix)=SparseMatrixCSC(A) + function _solve_linear!(u, system, nlhistory, control, method_linear, A, b) if isnothing(system.linear_cache) - Pl = control.precon_linear(SparseMatrixCSC(A)) + Pl = control.precon_linear(canonical_matrix(A)) nlhistory.nlu += 1 - p = LinearProblem(SparseMatrixCSC(A), b) + p = LinearProblem(canonical_matrix(A), b) system.linear_cache = init( p, method_linear; @@ -242,11 +245,11 @@ function _solve_linear!(u, system, nlhistory, control, method_linear, A, b) Pl, ) else - system.linear_cache.A=SparseMatrixCSC(A) + system.linear_cache.A=canonical_matrix(A) system.linear_cache.b=b if control.keepcurrent_linear nlhistory.nlu += 1 - system.linear_cache.Pl=control.precon_linear(SparseMatrixCSC(A)) + system.linear_cache.Pl=control.precon_linear(canonical_matrix(A)) end end diff --git a/src/vfvm_solver.jl b/src/vfvm_solver.jl index bb0177df5..db1d69743 100644 --- a/src/vfvm_solver.jl +++ b/src/vfvm_solver.jl @@ -29,18 +29,16 @@ function _solve_timestep!(solution::AbstractMatrix{Tv}, # old time step solution update = system.update _initialize!(solution, system; time, λ = embedparam, params) - method_linear = control.method_linear - if isnothing(method_linear) + method_linear = system.matrixtype == :sparse ? control.method_linear : nothing; + if isnothing(method_linear) && system.matrixtype == :sparse if Tv != Float64 method_linear = SparspakFactorization() + elseif dim_space(system.grid)==1 + method_linear = KLUFactorization() + elseif dim_space(system.grid)==2 + method_linear = SparspakFactorization() else - if dim_grid(system.grid) == 1 - method_linear = KLUFactorization() - elseif dim_grid(system.grid) == 2 - method_linear = SparspakFactorization() - else - method_linear = UMFPACKFactorization() - end + method_linear = UMFPACKFactorization() # seems to do the best pivoting end end