diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 83a49f5a2..6a982cb58 100755 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,6 +15,10 @@ repos: rev: v8.16.3 hooks: - id: gitleaks +- repo: https://github.com/fredrikekre/runic-pre-commit + rev: v1.0.0 + hooks: + - id: runic - repo: https://github.com/codespell-project/codespell rev: v2.2.4 hooks: diff --git a/Project.toml b/Project.toml index 18921f018..a889e720d 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", "Daniel Runge", "Dilara Abdel", "Jan Weidner", "Alexander Seiler", "Patricio Farrell", "Matthias Liero"] -version = "2.6" +version = "2.6.1" [deps] BandedMatrices = "aae01518-5342-5314-be14-df237901396f" diff --git a/docs/make.jl b/docs/make.jl index afe5b9160..adf8fb461 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -3,23 +3,25 @@ using ExtendableGrids, GridVisualize, LinearAlgebra, RecursiveArrayTools, SciMLB using ExtendableFEMBase, ExtendableFEM -using OrdinaryDiffEqBDF, OrdinaryDiffEqLowOrderRK, OrdinaryDiffEqRosenbrock, OrdinaryDiffEqSDIRK, OrdinaryDiffEqTsit5 +using OrdinaryDiffEqBDF, OrdinaryDiffEqLowOrderRK, OrdinaryDiffEqRosenbrock, OrdinaryDiffEqSDIRK, OrdinaryDiffEqTsit5 -function make(; with_examples = true, - with_notebooks = true) +function make(; + with_examples = true, + with_notebooks = true + ) bib = CitationBibliography( joinpath(@__DIR__, "..", "CITATIONS.bib"); - style=:numeric + style = :numeric ) - + ExampleJuggler.verbose!(true) cleanexamples() notebookdir = joinpath(@__DIR__, "..", "pluto-examples") exampledir = joinpath(@__DIR__, "..", "examples") - size_threshold_ignore=[] + size_threshold_ignore = [] pages = [ "Home" => "index.md", @@ -36,16 +38,17 @@ function make(; with_examples = true, "internal.md", "allindex.md", "devel.md", - "extensions.md"] + "extensions.md", + ], ] - + if with_notebooks notebooks = [ - "OrdinaryDiffEq.jl nonlinear diffusion" => "ode-diffusion1d.jl", - "OrdinaryDiffEq.jl 1D wave equation" => "ode-wave1d.jl", - "OrdinaryDiffEq.jl changing mass matrix" => "ode-nlstorage1d.jl", - "OrdinaryDiffEq.jl brusselator" => "ode-brusselator.jl", + "OrdinaryDiffEq.jl nonlinear diffusion" => "ode-diffusion1d.jl", + "OrdinaryDiffEq.jl 1D wave equation" => "ode-wave1d.jl", + "OrdinaryDiffEq.jl changing mass matrix" => "ode-nlstorage1d.jl", + "OrdinaryDiffEq.jl brusselator" => "ode-brusselator.jl", "Coupling with Catalyst.jl" => "heterogeneous-catalysis.jl", "Outflow boundary conditions" => "outflow.jl", "Obtaining vector fields" => "flux-reconstruction.jl", @@ -55,7 +58,7 @@ function make(; with_examples = true, "Bernoulli function test" => "bernoulli.jl", "API Updates" => "api-update.jl", ] - notebook_examples = @docplutonotebooks(notebookdir, notebooks, iframe=false) + notebook_examples = @docplutonotebooks(notebookdir, notebooks, iframe = false) notebook_examples = vcat(["About the notebooks" => "notebooks.md"], notebook_examples) size_threshold_ignore = last.(notebook_examples) push!(pages, "Tutorial Notebooks" => notebook_examples) @@ -63,32 +66,36 @@ function make(; with_examples = true, if with_examples modules = filter(ex -> splitext(ex)[2] == ".jl", basename.(readdir(exampledir))) - module_examples = @docmodules(exampledir, modules, use_module_titles=true) + module_examples = @docmodules(exampledir, modules, use_module_titles = true) module_examples = vcat(["About the examples" => "runexamples.md"], module_examples) push!(pages, "Examples" => module_examples) end - makedocs(; sitename="VoronoiFVM.jl", - modules=[ - VoronoiFVM, - # define extension modules manually: https://github.com/JuliaDocs/Documenter.jl/issues/2124#issuecomment-1557473415 - Base.get_extension(VoronoiFVM, :VoronoiFVMExtendableFEMBaseExt) - ], - plugins=[bib], - checkdocs=:all, - clean = false, - doctest = false, - authors = "J. Fuhrmann", - repo = "https://github.com/WIAS-PDELib/VoronoiFVM.jl", - format = Documenter.HTML(; size_threshold_ignore, - assets=String["assets/citations.css"], - mathengine = MathJax3()), - pages) - - + makedocs(; + sitename = "VoronoiFVM.jl", + modules = [ + VoronoiFVM, + # define extension modules manually: https://github.com/JuliaDocs/Documenter.jl/issues/2124#issuecomment-1557473415 + Base.get_extension(VoronoiFVM, :VoronoiFVMExtendableFEMBaseExt), + ], + plugins = [bib], + checkdocs = :all, + clean = false, + doctest = false, + authors = "J. Fuhrmann", + repo = "https://github.com/WIAS-PDELib/VoronoiFVM.jl", + format = Documenter.HTML(; + size_threshold_ignore, + assets = String["assets/citations.css"], + mathengine = MathJax3() + ), + pages + ) + + cleanexamples() - if !isinteractive() + return if !isinteractive() deploydocs(; repo = "github.com/WIAS-PDELib/VoronoiFVM.jl.git") end end diff --git a/examples/Example001_Solvers.jl b/examples/Example001_Solvers.jl index a86dc7094..fd0eda15f 100644 --- a/examples/Example001_Solvers.jl +++ b/examples/Example001_Solvers.jl @@ -30,111 +30,140 @@ function main(; n = 10, Plotter = nothing, assembly = :edgwwise, kwargs...) function reaction(f, u, node, data) f[1] = u[1]^2 + return nothing end function flux(f, u, edge, data) f[1] = eps * (u[1, 1]^2 - u[1, 2]^2) + return nothing end function source(f, node, data) x1 = node[1] - 0.5 x2 = node[2] - 0.5 f[1] = exp(-20.0 * (x1^2 + x2^2)) + return nothing end function storage(f, u, node, data) f[1] = u[1] + return nothing end function bcondition(f, u, node, data) - boundary_dirichlet!(f, - u, - node; - species = 1, - region = 2, - value = ramp(node.time; dt = (0, 0.1), du = (0, 1))) - boundary_dirichlet!(f, - u, - node; - species = 1, - region = 4, - value = ramp(node.time; dt = (0, 0.1), du = (0, 1))) + boundary_dirichlet!( + f, + u, + node; + species = 1, + region = 2, + value = ramp(node.time; dt = (0, 0.1), du = (0, 1)) + ) + boundary_dirichlet!( + f, + u, + node; + species = 1, + region = 4, + value = ramp(node.time; dt = (0, 0.1), du = (0, 1)) + ) + return nothing end - sys = VoronoiFVM.System(grid; reaction, flux, source, storage, bcondition, assembly, - species = [1]) + sys = VoronoiFVM.System( + grid; reaction, flux, source, storage, bcondition, assembly, + species = [1] + ) @info "UMFPACK:" umf_sol = solve(sys; inival = 0.5, method_linear = UMFPACKFactorization(), kwargs...) @info "KLU:" sol = solve(sys; inival = 0.5, method_linear = KLUFactorization(), kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 - + @test norm(sol - umf_sol, Inf) < 1.0e-7 + @info "Sparspak:" sol = solve(sys; inival = 0.5, method_linear = SparspakFactorization(), kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 + @test norm(sol - umf_sol, Inf) < 1.0e-7 @info "Krylov-ilu0:" - sol = solve(sys; - inival = 0.5, - method_linear = KrylovJL_BICGSTAB(), - precon_linear = ILUZeroPreconditioner(), - kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 + sol = solve( + sys; + inival = 0.5, + method_linear = KrylovJL_BICGSTAB(), + precon_linear = ILUZeroPreconditioner(), + kwargs... + ) + @test norm(sol - umf_sol, Inf) < 1.0e-7 @info "Krylov-block1" - sol = solve(sys; - inival = 0.5, - method_linear = KrylovJL_BICGSTAB(), - precon_linear = BlockPreconditioner(; partitioning = [1:(nn ÷ 2), (nn ÷ 2 + 1):nn], - factorization = ILU0Preconditioner()), - kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 + sol = solve( + sys; + inival = 0.5, + method_linear = KrylovJL_BICGSTAB(), + precon_linear = BlockPreconditioner(; + partitioning = [1:(nn ÷ 2), (nn ÷ 2 + 1):nn], + factorization = ILU0Preconditioner() + ), + kwargs... + ) + @test norm(sol - umf_sol, Inf) < 1.0e-7 @info "Krylov-block2" - sol = solve(sys; - inival = 0.5, - method_linear = KrylovJL_BICGSTAB(), - precon_linear = BlockPreconditioner(; partitioning = [1:2:nn, 2:2:nn], - factorization = UMFPACKFactorization()), - kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 + sol = solve( + sys; + inival = 0.5, + method_linear = KrylovJL_BICGSTAB(), + precon_linear = BlockPreconditioner(; + partitioning = [1:2:nn, 2:2:nn], + factorization = UMFPACKFactorization() + ), + kwargs... + ) + @test norm(sol - umf_sol, Inf) < 1.0e-7 @info "Krylov - delayed factorization:" - sol = solve(sys; - inival = 0.5, - method_linear = KrylovJL_BICGSTAB(), - precon_linear = SparspakFactorization(), - keepcurrent_linear =false, - kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 + sol = solve( + sys; + inival = 0.5, + method_linear = KrylovJL_BICGSTAB(), + precon_linear = SparspakFactorization(), + keepcurrent_linear = false, + kwargs... + ) + @test norm(sol - umf_sol, Inf) < 1.0e-7 @info "Krylov - jacobi:" - sol = solve(sys; - inival = 0.5, - method_linear = KrylovJL_BICGSTAB(), - precon_linear = JacobiPreconditioner(), - keepcurrent_linear = true, - kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 - + sol = solve( + sys; + inival = 0.5, + method_linear = KrylovJL_BICGSTAB(), + precon_linear = JacobiPreconditioner(), + keepcurrent_linear = true, + kwargs... + ) + @test norm(sol - umf_sol, Inf) < 1.0e-7 + @info "Krylov - SA_AMG:" - sol = solve(sys; - inival = 0.5, - method_linear = KrylovJL_BICGSTAB(), - precon_linear = SA_AMGPreconditioner(), - keepcurrent_linear = true, - kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 + sol = solve( + sys; + inival = 0.5, + method_linear = KrylovJL_BICGSTAB(), + precon_linear = SA_AMGPreconditioner(), + keepcurrent_linear = true, + kwargs... + ) + @test norm(sol - umf_sol, Inf) < 1.0e-7 @info "Krylov - AMGCL_AMG:" - sol = solve(sys; - inival = 0.5, - method_linear = KrylovJL_BICGSTAB(), - precon_linear = AMGCL_AMGPreconditioner(), - keepcurrent_linear = true, - kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 + sol = solve( + sys; + inival = 0.5, + method_linear = KrylovJL_BICGSTAB(), + precon_linear = AMGCL_AMGPreconditioner(), + keepcurrent_linear = true, + kwargs... + ) + return @test norm(sol - umf_sol, Inf) < 1.0e-7 end @@ -145,5 +174,6 @@ function runtests() @testset "cellwise" begin main(; assembly = :cellwise) end + return nothing end end diff --git a/examples/Example002_EdgeReaction.jl b/examples/Example002_EdgeReaction.jl index 1da9ef91b..bd878ecda 100644 --- a/examples/Example002_EdgeReaction.jl +++ b/examples/Example002_EdgeReaction.jl @@ -48,10 +48,12 @@ function main(; nref = 0, dim = 2, Plotter = nothing, verbose = "and", case = :c function storage!(y, u, node, data) y[1] = u[1] + return nothing end function flux!(y, u, edge, data) y[1] = u[1, 1] - u[1, 2] + return nothing end # Three ways to give a constant reaction term. As a consequence, @@ -59,6 +61,7 @@ function main(; nref = 0, dim = 2, Plotter = nothing, verbose = "and", case = :c # 1: classical node reaction, multiplied by control volume size function reaction!(y, u, node, data) y[1] = -1 + return nothing end # 2: Edge reaction. Here we give it as a constant, and wie need @@ -67,18 +70,19 @@ function main(; nref = 0, dim = 2, Plotter = nothing, verbose = "and", case = :c # # Half diamond volume calculation # /|\ - # / | \ + # / | \ # / |s \ - # ------- + # ------- # h # A=s*h/2d . Our formfactor: σ=s/h => A=σ*h^2 # - make transfer area to volume # - # τ=1/h v= s*h/2d = σ*h^2/2d - # + # τ=1/h v= s*h/2d = σ*h^2/2d + # function edgereaction!(y, u, edge, data) h = meas(edge) y[1] = -1 * h^2 / (2 * dim) + return nothing end # @@ -92,6 +96,7 @@ function main(; nref = 0, dim = 2, Plotter = nothing, verbose = "and", case = :c ϕK = ϕ[edge.node[1]] ϕL = ϕ[edge.node[2]] y[1] = -(ϕK - ϕL) * (ϕK - ϕL) / 2 + return nothing end if case == :compare_max @@ -102,28 +107,39 @@ function main(; nref = 0, dim = 2, Plotter = nothing, verbose = "and", case = :c boundary_dirichlet!(y, u, node; species = 1, region = 4, value = 0) boundary_dirichlet!(y, u, node; species = 1, region = 5, value = 0) boundary_dirichlet!(y, u, node; species = 1, region = 6, value = 0) + return nothing end - sys_noderea = VoronoiFVM.System(grid; bcondition = bcondition!, flux = flux!, - reaction = reaction!, storage = storage!, - species = [1], is_linear = true, assembly) - sys_edgerea = VoronoiFVM.System(grid; bcondition = bcondition!, flux = flux!, - edgereaction = edgereaction!, storage = storage!, - species = [1], is_linear = true, assembly) - sys_edgerea2 = VoronoiFVM.System(grid; bcondition = bcondition!, flux = flux!, - edgereaction = edgereaction2!, storage = storage!, - species = [1], is_linear = true, assembly) + sys_noderea = VoronoiFVM.System( + grid; bcondition = bcondition!, flux = flux!, + reaction = reaction!, storage = storage!, + species = [1], is_linear = true, assembly + ) + sys_edgerea = VoronoiFVM.System( + grid; bcondition = bcondition!, flux = flux!, + edgereaction = edgereaction!, storage = storage!, + species = [1], is_linear = true, assembly + ) + sys_edgerea2 = VoronoiFVM.System( + grid; bcondition = bcondition!, flux = flux!, + edgereaction = edgereaction2!, storage = storage!, + species = [1], is_linear = true, assembly + ) sol_noderea = solve(sys_noderea; verbose) sol_edgerea = solve(sys_edgerea; verbose) sol_edgerea2 = solve(sys_edgerea2; verbose) vis = GridVisualizer(; Plotter, layout = (2, 2)) - scalarplot!(vis[1, 1], grid, sol_noderea[1, :]; title = "node reaction", - colormap = :hot) + scalarplot!( + vis[1, 1], grid, sol_noderea[1, :]; title = "node reaction", + colormap = :hot + ) scalarplot!(vis[2, 1], grid, sol_edgerea[1, :]; title = "edgerea1", colormap = :hot) - scalarplot!(vis[1, 2], grid, sol_edgerea2[1, :]; title = "edgerea2", - colormap = :hot) + scalarplot!( + vis[1, 2], grid, sol_edgerea2[1, :]; title = "edgerea2", + colormap = :hot + ) reveal(vis) return maximum.([sol_noderea, sol_edgerea, sol_edgerea2]) @@ -132,17 +148,24 @@ function main(; nref = 0, dim = 2, Plotter = nothing, verbose = "and", case = :c if case == :compare_flux function bcondition2!(y, u, node, data) boundary_dirichlet!(y, u, node; species = 1, region = i1, value = 0) + return nothing end - sys2_noderea = VoronoiFVM.System(grid; bcondition = bcondition2!, flux = flux!, - reaction = reaction!, storage = storage!, - species = [1], is_linear = true) - sys2_edgerea = VoronoiFVM.System(grid; bcondition = bcondition2!, flux = flux!, - edgereaction = edgereaction!, storage = storage!, - species = [1], is_linear = true) - sys2_edgerea2 = VoronoiFVM.System(grid; bcondition = bcondition2!, flux = flux!, - edgereaction = edgereaction2!, storage = storage!, - species = [1], is_linear = true) + sys2_noderea = VoronoiFVM.System( + grid; bcondition = bcondition2!, flux = flux!, + reaction = reaction!, storage = storage!, + species = [1], is_linear = true + ) + sys2_edgerea = VoronoiFVM.System( + grid; bcondition = bcondition2!, flux = flux!, + edgereaction = edgereaction!, storage = storage!, + species = [1], is_linear = true + ) + sys2_edgerea2 = VoronoiFVM.System( + grid; bcondition = bcondition2!, flux = flux!, + edgereaction = edgereaction2!, storage = storage!, + species = [1], is_linear = true + ) sol2_noderea = solve(sys2_noderea; verbose) sol2_edgerea = solve(sys2_edgerea; verbose) @@ -158,12 +181,18 @@ function main(; nref = 0, dim = 2, Plotter = nothing, verbose = "and", case = :c tfc2_edgerea2 = testfunction(tfac2_edgerea2, [i0], [i1]) vis = GridVisualizer(; Plotter, layout = (2, 2)) - scalarplot!(vis[1, 1], grid, sol2_noderea[1, :]; title = "node reaction", - colormap = :hot) - scalarplot!(vis[2, 1], grid, sol2_edgerea[1, :]; title = "edgerea1", - colormap = :hot) - scalarplot!(vis[1, 2], grid, sol2_edgerea2[1, :]; title = "edgerea2", - colormap = :hot) + scalarplot!( + vis[1, 1], grid, sol2_noderea[1, :]; title = "node reaction", + colormap = :hot + ) + scalarplot!( + vis[2, 1], grid, sol2_edgerea[1, :]; title = "edgerea1", + colormap = :hot + ) + scalarplot!( + vis[1, 2], grid, sol2_edgerea2[1, :]; title = "edgerea2", + colormap = :hot + ) reveal(vis) I_noderea = integrate(sys2_noderea, tfc2_noderea, sol2_noderea) @@ -177,28 +206,29 @@ end using Test function runtests() res = fill(false, 3) - for dim = 1:3 + for dim in 1:3 result_max = main(; case = :compare_max, assembly = :cellwise) result_flux = main(; case = :compare_flux, assembly = :cellwise) res[dim] = isapprox(result_max[1], result_max[2]; atol = 1.0e-6) && - isapprox(result_max[1], result_max[3]; atol = 1.0e-3) && - isapprox(result_flux[1], result_flux[2]; atol = 1.0e-10) && - isapprox(result_flux[1], result_flux[3]; atol = 1.0e-10) + isapprox(result_max[1], result_max[3]; atol = 1.0e-3) && + isapprox(result_flux[1], result_flux[2]; atol = 1.0e-10) && + isapprox(result_flux[1], result_flux[3]; atol = 1.0e-10) end res1 = all(a -> a, res) res = fill(false, 3) - for dim = 1:3 + for dim in 1:3 result_max = main(; case = :compare_max, assembly = :edgwise) result_flux = main(; case = :compare_flux, assembly = :edgwise) res[dim] = isapprox(result_max[1], result_max[2]; atol = 1.0e-6) && - isapprox(result_max[1], result_max[3]; atol = 1.0e-3) && - isapprox(result_flux[1], result_flux[2]; atol = 1.0e-10) && - isapprox(result_flux[1], result_flux[3]; atol = 1.0e-10) + isapprox(result_max[1], result_max[3]; atol = 1.0e-3) && + isapprox(result_flux[1], result_flux[2]; atol = 1.0e-10) && + isapprox(result_flux[1], result_flux[3]; atol = 1.0e-10) end res2 = all(a -> a, res) @test res1 && res2 + return nothing end end diff --git a/examples/Example003_Solvers.jl b/examples/Example003_Solvers.jl index 49a5cc86d..a29af902f 100644 --- a/examples/Example003_Solvers.jl +++ b/examples/Example003_Solvers.jl @@ -35,116 +35,143 @@ function main(; n = 10, Plotter = nothing, assembly = :edgwwise, kwargs...) function reaction(f, u, node, data) f[1] = u[1]^2 + return nothing end function flux(f, u, edge, data) f[1] = eps * (u[1, 1]^2 - u[1, 2]^2) + return nothing end function source(f, node, data) x1 = node[1] - 0.5 x2 = node[2] - 0.5 f[1] = exp(-20.0 * (x1^2 + x2^2)) + return nothing end function storage(f, u, node, data) f[1] = u[1] + return nothing end function bcondition(f, u, node, data) - boundary_dirichlet!(f, - u, - node; - species = 1, - region = 2, - value = ramp(node.time; dt = (0, 0.1), du = (0, 1))) - boundary_dirichlet!(f, - u, - node; - species = 1, - region = 4, - value = ramp(node.time; dt = (0, 0.1), du = (0, 1))) + boundary_dirichlet!( + f, + u, + node; + species = 1, + region = 2, + value = ramp(node.time; dt = (0, 0.1), du = (0, 1)) + ) + boundary_dirichlet!( + f, + u, + node; + species = 1, + region = 4, + value = ramp(node.time; dt = (0, 0.1), du = (0, 1)) + ) + return nothing end - sys = VoronoiFVM.System(grid; reaction, flux, source, storage, bcondition, assembly, - species = [1]) + sys = VoronoiFVM.System( + grid; reaction, flux, source, storage, bcondition, assembly, + species = [1] + ) @info "UMFPACK:" umf_sol = solve(sys; inival = 0.5, method_linear = LinearSolve.UMFPACKFactorization(), kwargs...) @info "KLU:" sol = solve(sys; inival = 0.5, method_linear = LinearSolve.KLUFactorization(), kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 - + @test norm(sol - umf_sol, Inf) < 1.0e-7 + @info "Sparspak:" sol = solve(sys; inival = 0.5, method_linear = LinearSolve.SparspakFactorization(), kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 + @test norm(sol - umf_sol, Inf) < 1.0e-7 @info "Krylov-ilu0:" - sol = solve(sys; - inival = 0.5, - method_linear = KrylovJL_BICGSTAB(precs=ILUZeroPreconBuilder()), - kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 + sol = solve( + sys; + inival = 0.5, + method_linear = KrylovJL_BICGSTAB(precs = ILUZeroPreconBuilder()), + kwargs... + ) + @test norm(sol - umf_sol, Inf) < 1.0e-7 @info "Krylov-block1" - precs=BlockPreconBuilder(;precs=ILUZeroPreconBuilder(), partitioning= A-> [1:(size(A,1) ÷ 2), (size(A,1) ÷ 2 + 1):size(A,1)]) - sol = solve(sys; - inival = 0.5, - method_linear = KrylovJL_BICGSTAB(;precs), - kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 + precs = BlockPreconBuilder(; precs = ILUZeroPreconBuilder(), partitioning = A -> [1:(size(A, 1) ÷ 2), (size(A, 1) ÷ 2 + 1):size(A, 1)]) + sol = solve( + sys; + inival = 0.5, + method_linear = KrylovJL_BICGSTAB(; precs), + kwargs... + ) + @test norm(sol - umf_sol, Inf) < 1.0e-7 @info "Krylov-block2" - precs=BlockPreconBuilder(;precs=ILUZeroPreconBuilder(), partitioning= A-> [1:2:size(A,1), 2:2:size(A,1)]) - sol = solve(sys; - inival = 0.5, - method_linear = KrylovJL_BICGSTAB(;precs), - log=true, - kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 - + precs = BlockPreconBuilder(; precs = ILUZeroPreconBuilder(), partitioning = A -> [1:2:size(A, 1), 2:2:size(A, 1)]) + sol = solve( + sys; + inival = 0.5, + method_linear = KrylovJL_BICGSTAB(; precs), + log = true, + kwargs... + ) + @test norm(sol - umf_sol, Inf) < 1.0e-7 + @info "Krylov - delayed factorization:" - sol = solve(sys; - inival = 0.5, - method_linear = KrylovJL_BICGSTAB(;precs=LinearSolvePreconBuilder(SparspakFactorization())), - keepcurrent_linear =false, - log=true, - kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 + sol = solve( + sys; + inival = 0.5, + method_linear = KrylovJL_BICGSTAB(; precs = LinearSolvePreconBuilder(SparspakFactorization())), + keepcurrent_linear = false, + log = true, + kwargs... + ) + @test norm(sol - umf_sol, Inf) < 1.0e-7 @test summary(history(sol)).factorizations == 1 - + @info "Krylov - jacobi:" - sol = solve(sys; - inival = 0.5, - method_linear = KrylovJL_BICGSTAB(;precs=JacobiPreconBuilder()), - keepcurrent_linear = true, log=true, - kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 + sol = solve( + sys; + inival = 0.5, + method_linear = KrylovJL_BICGSTAB(; precs = JacobiPreconBuilder()), + keepcurrent_linear = true, log = true, + kwargs... + ) + @test norm(sol - umf_sol, Inf) < 1.0e-7 @test summary(history(sol)).factorizations > 1 - + @info "Krylov - SA_AMG:" - sol = solve(sys; - inival = 0.5, - method_linear = KrylovJL_BICGSTAB(;precs=SmoothedAggregationPreconBuilder()), - keepcurrent_linear = true, - kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 + sol = solve( + sys; + inival = 0.5, + method_linear = KrylovJL_BICGSTAB(; precs = SmoothedAggregationPreconBuilder()), + keepcurrent_linear = true, + kwargs... + ) + @test norm(sol - umf_sol, Inf) < 1.0e-7 @info "Krylov - AMGCL_AMG:" - sol = solve(sys; - inival = 0.5, - method_linear = KrylovJL_BICGSTAB(;precs=AMGPreconBuilder()), - keepcurrent_linear = true, - kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 + sol = solve( + sys; + inival = 0.5, + method_linear = KrylovJL_BICGSTAB(; precs = AMGPreconBuilder()), + keepcurrent_linear = true, + kwargs... + ) + @test norm(sol - umf_sol, Inf) < 1.0e-7 @info "Krylov - AMGnCL_RLX:" - sol = solve(sys; - inival = 0.5, - method_linear = KrylovJL_BICGSTAB(;precs=RLXPreconBuilder()), - keepcurrent_linear = true, - kwargs...) - @test norm(sol - umf_sol, Inf)<1.0e-7 + sol = solve( + sys; + inival = 0.5, + method_linear = KrylovJL_BICGSTAB(; precs = RLXPreconBuilder()), + keepcurrent_linear = true, + kwargs... + ) + return @test norm(sol - umf_sol, Inf) < 1.0e-7 end function runtests() @@ -154,5 +181,6 @@ function runtests() @testset "cellwise" begin main(; assembly = :cellwise) end + return nothing end end diff --git a/examples/Example101_Laplace1D.jl b/examples/Example101_Laplace1D.jl index f84ce9b6e..2c7468a85 100644 --- a/examples/Example101_Laplace1D.jl +++ b/examples/Example101_Laplace1D.jl @@ -98,11 +98,13 @@ function main() ## between neighboring control volumes function flux!(f, u, edge, data) f[1] = u[1, 1] - u[1, 2] + return nothing end function bcond!(f, u, node, data) boundary_dirichlet!(f, u, node; region = 1, value = 0) boundary_dirichlet!(f, u, node; region = 2, value = 1) + return nothing end ## Create a one dimensional discretization grid @@ -110,7 +112,7 @@ function main() ## By default, there is only one region numbered with 1 grid = simplexgrid(0:0.2:1) - ## Create a finite volume system + ## Create a finite volume system sys = VoronoiFVM.System(grid; flux = flux!, breaction = bcond!, species = ispec) ## Solve stationary problem @@ -123,6 +125,7 @@ end using Test function runtests() @test main() ≈ 3.0 + return nothing end end diff --git a/examples/Example102_StationaryConvectionDiffusion1D.jl b/examples/Example102_StationaryConvectionDiffusion1D.jl index 8ab80cde0..c34c11648 100644 --- a/examples/Example102_StationaryConvectionDiffusion1D.jl +++ b/examples/Example102_StationaryConvectionDiffusion1D.jl @@ -42,6 +42,7 @@ function central_flux!(f, u, edge, data) f_diff = data.D * (u[1, 1] - u[1, 2]) vh = project(edge, data.v) f[1] = f_diff + vh * (u[1, 1] + u[1, 2]) / 2 + return nothing end ## The simple upwind flux corrects the monotonicity properties essentially @@ -56,6 +57,7 @@ function upwind_flux!(f, u, edge, data) else f[1] = fdiff + vh * u[1, 2] end + return nothing end ## The exponential fitting flux has the proper monotonicity properties and @@ -76,6 +78,7 @@ function exponential_flux!(f, u, edge, data) Bplus = data.D * bernoulli(vh / data.D) Bminus = data.D * bernoulli(-vh / data.D) f[1] = Bminus * u[1, 1] - Bplus * u[1, 2] + return nothing end function calculate(grid, data, flux, verbose) @@ -128,6 +131,7 @@ using Test function runtests() testval = 2.523569744561089 @test main() ≈ testval + return nothing end end diff --git a/examples/Example103_ConvectionDiffusion1D.jl b/examples/Example103_ConvectionDiffusion1D.jl index b1cf73700..309bd2ed0 100644 --- a/examples/Example103_ConvectionDiffusion1D.jl +++ b/examples/Example103_ConvectionDiffusion1D.jl @@ -31,12 +31,14 @@ function exponential_flux!(f, u, edge, data) Bplus = data.D * bernoulli(vh / data.D) Bminus = data.D * bernoulli(-vh / data.D) f[1] = Bminus * u[1, 1] - Bplus * u[1, 2] + return nothing end function outflow!(f, u, node, data) if node.region == 2 f[1] = data.v[1] * u[1] end + return nothing end function main(; n = 10, Plotter = nothing, D = 0.01, v = 1.0, tend = 100) @@ -47,9 +49,13 @@ function main(; n = 10, Plotter = nothing, D = 0.01, v = 1.0, tend = 100) data = (v = [v], D = D) - sys = VoronoiFVM.System(grid, - VoronoiFVM.Physics(; flux = exponential_flux!, data = data, - breaction = outflow!)) + sys = VoronoiFVM.System( + grid, + VoronoiFVM.Physics(; + flux = exponential_flux!, data = data, + breaction = outflow! + ) + ) ## Add species 1 to region 1 enable_species!(sys, 1, [1]) @@ -69,18 +75,21 @@ function main(; n = 10, Plotter = nothing, D = 0.01, v = 1.0, tend = 100) tsol = solve(sys; inival, times = [0, tend], control) vis = GridVisualizer(; Plotter = Plotter) - for i = 1:length(tsol.t) - scalarplot!(vis[1, 1], grid, tsol[1, :, i]; flimits = (0, 1), - title = "t=$(tsol.t[i])", show = true) + for i in 1:length(tsol.t) + scalarplot!( + vis[1, 1], grid, tsol[1, :, i]; flimits = (0, 1), + title = "t=$(tsol.t[i])", show = true + ) sleep(0.01) end - tsol + return tsol end using Test function runtests() tsol = main() @test maximum(tsol) <= 1.0 && maximum(tsol.u[end]) < 1.0e-20 + return nothing end end diff --git a/examples/Example105_NonlinearPoisson1D.jl b/examples/Example105_NonlinearPoisson1D.jl index 4f23cfff8..f447e0b6c 100644 --- a/examples/Example105_NonlinearPoisson1D.jl +++ b/examples/Example105_NonlinearPoisson1D.jl @@ -40,6 +40,7 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s ## between neighboring control volumes function flux!(f, u, edge, data) f[1] = ϵ * (u[1, 1] - u[1, 2]) + return nothing end ## Source term @@ -49,17 +50,21 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s else f[1] = -1 end + return nothing end ## Reaction term function reaction!(f, u, node, data) f[1] = exp(u[1]) - exp(-u[1]) + return nothing end ## Create a physics structure - physics = VoronoiFVM.Physics(; flux = flux!, - source = source!, - reaction = reaction!) + physics = VoronoiFVM.Physics(; + flux = flux!, + source = source!, + reaction = reaction! + ) ## Create a finite volume system - either ## in the dense or the sparse version. @@ -90,9 +95,10 @@ using Test function runtests() testval = 1.5247901344230088 @test main(; unknown_storage = :sparse, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && - main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && + main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && + main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + return nothing end end diff --git a/examples/Example106_NonlinearDiffusion1D.jl b/examples/Example106_NonlinearDiffusion1D.jl index 40a4e75dc..376464f35 100644 --- a/examples/Example106_NonlinearDiffusion1D.jl +++ b/examples/Example106_NonlinearDiffusion1D.jl @@ -34,8 +34,10 @@ function barenblatt(x, t, m) return tx * xx^(1.0 / (m - 1.0)) end -function main(; n = 20, m = 2, Plotter = nothing, verbose = false, - unknown_storage = :sparse, tend = 0.01, tstep = 0.0001, assembly = :edgewise) +function main(; + n = 20, m = 2, Plotter = nothing, verbose = false, + unknown_storage = :sparse, tend = 0.01, tstep = 0.0001, assembly = :edgewise + ) ## Create a one-dimensional discretization h = 1.0 / convert(Float64, n / 2) @@ -46,16 +48,20 @@ function main(; n = 20, m = 2, Plotter = nothing, verbose = false, ## between neighboring control volumes function flux!(f, u, edge, data) f[1] = u[1, 1]^m - u[1, 2]^m + return nothing end ## Storage term function storage!(f, u, node, data) f[1] = u[1] + return nothing end ## Create a physics structure - physics = VoronoiFVM.Physics(; flux = flux!, - storage = storage!) + physics = VoronoiFVM.Physics(; + flux = flux!, + storage = storage! + ) ## Create a finite volume system - either ## in the dense or the sparse version. @@ -84,14 +90,18 @@ function main(; n = 20, m = 2, Plotter = nothing, verbose = false, tsol = solve(sys; inival, times = [t0, tend], control) p = GridVisualizer(; Plotter = Plotter, layout = (1, 1), fast = true) - for i = 1:length(tsol) + for i in 1:length(tsol) time = tsol.t[i] - scalarplot!(p[1, 1], grid, tsol[1, :, i]; title = @sprintf("t=%.3g", time), - color = :red, label = "numerical", - markershape = :circle, markevery = 1) - scalarplot!(p[1, 1], grid, map(x -> barenblatt(x, time, m), grid); clear = false, - color = :green, - label = "exact", markershape = :none) + scalarplot!( + p[1, 1], grid, tsol[1, :, i]; title = @sprintf("t=%.3g", time), + color = :red, label = "numerical", + markershape = :circle, markevery = 1 + ) + scalarplot!( + p[1, 1], grid, map(x -> barenblatt(x, time, m), grid); clear = false, + color = :green, + label = "exact", markershape = :none + ) reveal(p) sleep(1.0e-2) end @@ -101,10 +111,11 @@ end using Test function runtests() testval = 46.66666666647518 - @test main(; unknown_storage = :sparse, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && - main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + return @test main(; unknown_storage = :sparse, assembly = :edgewise) ≈ testval && + main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && + main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && + main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + nothing end end diff --git a/examples/Example107_NonlinearStorage1D.jl b/examples/Example107_NonlinearStorage1D.jl index d731e5dc1..cfc05945b 100644 --- a/examples/Example107_NonlinearStorage1D.jl +++ b/examples/Example107_NonlinearStorage1D.jl @@ -30,8 +30,10 @@ function barenblatt(x, t, m) return tx * xx^(1.0 / (m - 1.0)) end -function main(; n = 20, m = 2.0, Plotter = nothing, verbose = false, - unknown_storage = :sparse, tend = 0.01, tstep = 0.0001, assembly = :edgewise) +function main(; + n = 20, m = 2.0, Plotter = nothing, verbose = false, + unknown_storage = :sparse, tend = 0.01, tstep = 0.0001, assembly = :edgewise + ) ## Create a one-dimensional discretization h = 1.0 / convert(Float64, n / 2) @@ -42,6 +44,7 @@ function main(; n = 20, m = 2.0, Plotter = nothing, verbose = false, ## between neighboring control volumes function flux!(f, u, edge, data) f[1] = u[1, 1] - u[1, 2] + return nothing end ϵ = 1.0e-10 @@ -51,11 +54,14 @@ function main(; n = 20, m = 2.0, Plotter = nothing, verbose = false, ## at 0 is infinity function storage!(f, u, node, data) f[1] = (ϵ + u[1])^(1.0 / m) + return nothing end ## Create a physics structure - physics = VoronoiFVM.Physics(; flux = flux!, - storage = storage!) + physics = VoronoiFVM.Physics(; + flux = flux!, + storage = storage! + ) ## Create a finite volume system - either ## in the dense or the sparse version. @@ -83,12 +89,16 @@ function main(; n = 20, m = 2.0, Plotter = nothing, verbose = false, if Plotter != nothing p = GridVisualizer(; Plotter = Plotter, layout = (1, 1), fast = true) - for i = 1:length(tsol) + for i in 1:length(tsol) time = tsol.t[i] - scalarplot!(p[1, 1], grid, tsol[1, :, i]; title = @sprintf("t=%.3g", time), - color = :red, label = "numerical") - scalarplot!(p[1, 1], grid, map(x -> barenblatt(x, time, m)^m, grid); clear = false, - color = :green, label = "exact") + scalarplot!( + p[1, 1], grid, tsol[1, :, i]; title = @sprintf("t=%.3g", time), + color = :red, label = "numerical" + ) + scalarplot!( + p[1, 1], grid, map(x -> barenblatt(x, time, m)^m, grid); clear = false, + color = :green, label = "exact" + ) reveal(p) sleep(1.0e-2) end @@ -99,10 +109,12 @@ end using Test function runtests() testval = 174.72418935404414 - @test main(; unknown_storage = :sparse, assembly = :edgewise)≈testval rtol=1.0e-5 - @test main(; unknown_storage = :dense, assembly = :edgewise)≈testval rtol=1.0e-5 - @test main(; unknown_storage = :sparse, assembly = :cellwise)≈testval rtol=1.0e-5 - @test main(; unknown_storage = :dense, assembly = :cellwise)≈testval rtol=1.0e-5 + @test main(; unknown_storage = :sparse, assembly = :edgewise) ≈ testval rtol = 1.0e-5 + @test main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval rtol = 1.0e-5 + @test main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval rtol = 1.0e-5 + @test main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval rtol = 1.0e-5 + + return nothing end end diff --git a/examples/Example108_OrdinaryDiffEq1D.jl b/examples/Example108_OrdinaryDiffEq1D.jl index 300411feb..207478212 100644 --- a/examples/Example108_OrdinaryDiffEq1D.jl +++ b/examples/Example108_OrdinaryDiffEq1D.jl @@ -34,8 +34,10 @@ function barenblatt(x, t, m) return tx * xx^(1.0 / (m - 1.0)) end -function main(; n = 20, m = 2, Plotter = nothing, verbose = false, - unknown_storage = :sparse, tend = 0.01, assembly = :edgewise, solver=Rosenbrock23()) +function main(; + n = 20, m = 2, Plotter = nothing, verbose = false, + unknown_storage = :sparse, tend = 0.01, assembly = :edgewise, solver = Rosenbrock23() + ) ## Create a one-dimensional discretization h = 1.0 / convert(Float64, n / 2) @@ -46,16 +48,20 @@ function main(; n = 20, m = 2, Plotter = nothing, verbose = false, ## between neighboring control volumes function flux!(f, u, edg, data) f[1] = u[1, 1]^m - u[1, 2]^m + return nothing end ## Storage term function storage!(f, u, node, data) f[1] = u[1] + return nothing end ## Create a physics structure - physics = VoronoiFVM.Physics(; flux = flux!, - storage = storage!) + physics = VoronoiFVM.Physics(; + flux = flux!, + storage = storage! + ) ## Create a finite volume system - either ## in the dense or the sparse version. @@ -73,20 +79,24 @@ function main(; n = 20, m = 2, Plotter = nothing, verbose = false, ## Broadcast the initial value inival[1, :] .= map(x -> barenblatt(x, t0, m), X) - problem = ODEProblem(sys,inival,(t0,tend)) - odesol = solve(problem,solver) - tsol=reshape(odesol,sys) - + problem = ODEProblem(sys, inival, (t0, tend)) + odesol = solve(problem, solver) + tsol = reshape(odesol, sys) + p = GridVisualizer(; Plotter = Plotter, layout = (1, 1), fast = true) - for i = 1:length(tsol) + for i in 1:length(tsol) time = tsol.t[i] - scalarplot!(p[1, 1], grid, tsol[1, :, i]; title = @sprintf("t=%.3g", time), - color = :red, label = "numerical", - markershape = :circle, markevery = 1) - scalarplot!(p[1, 1], grid, map(x -> barenblatt(x, time, m), grid); clear = false, - color = :green, - label = "exact", markershape = :none) + scalarplot!( + p[1, 1], grid, tsol[1, :, i]; title = @sprintf("t=%.3g", time), + color = :red, label = "numerical", + markershape = :circle, markevery = 1 + ) + scalarplot!( + p[1, 1], grid, map(x -> barenblatt(x, time, m), grid); clear = false, + color = :green, + label = "exact", markershape = :none + ) reveal(p) sleep(1.0e-2) end @@ -97,9 +107,10 @@ using Test function runtests() testval = 46.66666666671521 @test main(; unknown_storage = :sparse, assembly = :edgewise) ≈ testval - @test main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval + @test main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval @test main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval @test main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + return nothing end end diff --git a/examples/Example110_ReactionDiffusion1D_TwoSpecies.jl b/examples/Example110_ReactionDiffusion1D_TwoSpecies.jl index beda3b922..0efba86fb 100644 --- a/examples/Example110_ReactionDiffusion1D_TwoSpecies.jl +++ b/examples/Example110_ReactionDiffusion1D_TwoSpecies.jl @@ -2,18 +2,18 @@ # ([source code](@__SOURCE_URL__)) # # Solve the nonlinear coupled reaction diffusion problem -# +# # ```math # -\nabla (0.01+2u_2)\nabla u_1 + u_1u_2= 0.0001(0.01+x) # ``` -# +# # ```math # -\nabla (0.01+2u_1)\nabla u_2 - u_1u_2 = 0.0001(1.01-x) # ``` -# -# +# +# # in $\Omega=(0,1)$ with boundary condition $u_1(0)=1$, $u_2(0)=0$ and $u_1(1)=1$, $u_2(1)=1$. -# +# module Example110_ReactionDiffusion1D_TwoSpecies @@ -29,23 +29,30 @@ function main(; n = 100, Plotter = nothing, verbose = false, unknown_storage = : eps::Vector{Float64} = [1.0, 1.0] physics = VoronoiFVM.Physics( - ; reaction = function (f, u, node, data) - f[1] = u[1] * u[2] - f[2] = -u[1] * u[2] - end, - flux = function (f, u, edge, data) - nspecies = 2 - f[1] = eps[1] * (u[1, 1] - u[1, 2]) * - (0.01 + u[2, 1] + u[2, 2]) - f[2] = eps[2] * (u[2, 1] - u[2, 2]) * - (0.01 + u[1, 1] + u[1, 2]) - end, source = function (f, node, data) - f[1] = 1.0e-4 * (0.01 + node[1]) - f[2] = 1.0e-4 * (0.01 + 1.0 - node[1]) - end, storage = function (f, u, node, data) - f[1] = u[1] - f[2] = u[2] - end) + ; reaction = function (f, u, node, data) + f[1] = u[1] * u[2] + f[2] = -u[1] * u[2] + return nothing + end, + flux = function (f, u, edge, data) + nspecies = 2 + f[1] = eps[1] * (u[1, 1] - u[1, 2]) * + (0.01 + u[2, 1] + u[2, 2]) + f[2] = eps[2] * (u[2, 1] - u[2, 2]) * + (0.01 + u[1, 1] + u[1, 2]) + return nothing + end, + source = function (f, node, data) + f[1] = 1.0e-4 * (0.01 + node[1]) + f[2] = 1.0e-4 * (0.01 + 1.0 - node[1]) + return nothing + end, + storage = function (f, u, node, data) + f[1] = u[1] + f[2] = u[2] + return nothing + end + ) sys = VoronoiFVM.System(grid, physics; unknown_storage = unknown_storage) @@ -70,8 +77,10 @@ function main(; n = 100, Plotter = nothing, verbose = false, unknown_storage = : eps = [xeps, xeps] U = solve(sys; inival = U, control) scalarplot!(p[1, 1], grid, U[1, :]; clear = true, title = "U1, eps=$(xeps)") - scalarplot!(p[2, 1], grid, U[2, :]; clear = true, title = "U2, eps=$(xeps)", - reveal = true) + scalarplot!( + p[2, 1], grid, U[2, :]; clear = true, title = "U2, eps=$(xeps)", + reveal = true + ) sleep(0.2) u5 = U[5] end @@ -83,8 +92,10 @@ function runtests() testval = 0.7117546972922056 @test main(; unknown_storage = :sparse, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && - main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && + main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && + main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + + return nothing end end diff --git a/examples/Example115_HeterogeneousCatalysis1D.jl b/examples/Example115_HeterogeneousCatalysis1D.jl index 80548e568..49511830c 100644 --- a/examples/Example115_HeterogeneousCatalysis1D.jl +++ b/examples/Example115_HeterogeneousCatalysis1D.jl @@ -62,9 +62,11 @@ using LinearAlgebra using OrdinaryDiffEqRosenbrock using SciMLBase: NoInit -function main(; n = 10, Plotter = nothing, verbose = false, tend = 1, - unknown_storage = :sparse, assembly = :edgewise, - diffeq=false) +function main(; + n = 10, Plotter = nothing, verbose = false, tend = 1, + unknown_storage = :sparse, assembly = :edgewise, + diffeq = false + ) h = 1.0 / convert(Float64, n) X = collect(0.0:h:1.0) N = length(X) @@ -83,25 +85,28 @@ function main(; n = 10, Plotter = nothing, verbose = false, tend = 1, function flux!(f, u, edge, data) f[iA] = D_A * (u[iA, 1] - u[iA, 2]) f[iB] = D_B * (u[iB, 1] - u[iB, 2]) + return nothing end ## Storage term of species A and B function storage!(f, u, node, data) f[iA] = u[iA] f[iB] = u[iB] + return nothing end ## Source term for species a around 0.5 function source!(f, node, data) x1 = node[1] - 0.5 f[iA] = exp(-100 * x1^2) + return nothing end ## Reaction constants (p = + , m = -) ## Chosen to prefer path A-> C -> B ## More over, A reacts faster than to C than C to B ## leading to "catalyst poisoning", i.e. C taking up most of the - ## available catalyst sites + ## available catalyst sites kp_AC = 100.0 km_AC = 1.0 @@ -119,6 +124,7 @@ function main(; n = 10, Plotter = nothing, verbose = false, tend = 1, f[iB] = S * R_BC(u[iB], u[iC]) f[iC] = -R_BC(u[iB], u[iC]) - R_AC(u[iA], u[iC]) end + return nothing end ## This is for the term \partial_t u_C at the boundary @@ -126,13 +132,16 @@ function main(; n = 10, Plotter = nothing, verbose = false, tend = 1, if node.region == 1 f[iC] = u[iC] end + return nothing end - physics = VoronoiFVM.Physics(; breaction = breaction!, - bstorage = bstorage!, - flux = flux!, - storage = storage!, - source = source!) + physics = VoronoiFVM.Physics(; + breaction = breaction!, + bstorage = bstorage!, + flux = flux!, + storage = storage!, + source = source! + ) sys = VoronoiFVM.System(grid, physics; unknown_storage = unknown_storage) @@ -158,25 +167,31 @@ function main(; n = 10, Plotter = nothing, verbose = false, tend = 1, p = GridVisualizer(; Plotter = Plotter, layout = (3, 1)) if diffeq - inival=unknowns(sys,inival=0) - problem = ODEProblem(sys,inival,(0,tend)) + 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) + 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) + for it in 1:length(tsol) time = tsol.t[it] - scalarplot!(p[1, 1], grid, tsol[iA, :, it]; clear = true, - title = @sprintf("[A]: (%.3f,%.3f)", extrema(tsol[iA, :, it])...)) - scalarplot!(p[2, 1], grid, tsol[iB, :, it]; clear = true, - title = @sprintf("[B]: (%.3f,%.3f)", extrema(tsol[iB, :, it])...)) - scalarplot!(p[3, 1], tsol.t[1:it], tsol[iC, 1, 1:it]; title = @sprintf("[C]"), - clear = true, show = true) + scalarplot!( + p[1, 1], grid, tsol[iA, :, it]; clear = true, + title = @sprintf("[A]: (%.3f,%.3f)", extrema(tsol[iA, :, it])...) + ) + scalarplot!( + p[2, 1], grid, tsol[iB, :, it]; clear = true, + title = @sprintf("[B]: (%.3f,%.3f)", extrema(tsol[iB, :, it])...) + ) + scalarplot!( + p[3, 1], tsol.t[1:it], tsol[iC, 1, 1:it]; title = @sprintf("[C]"), + clear = true, show = true + ) end return tsol[iC, 1, end] @@ -186,15 +201,15 @@ using Test function runtests() testval = 0.87544440641274 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 = :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) - + @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) + return nothing end end diff --git a/examples/Example120_ThreeRegions1D.jl b/examples/Example120_ThreeRegions1D.jl index e067d42ab..09e8c369e 100644 --- a/examples/Example120_ThreeRegions1D.jl +++ b/examples/Example120_ThreeRegions1D.jl @@ -12,7 +12,7 @@ using OrdinaryDiffEqRosenbrock using SciMLBase: NoInit function reaction(f, u, node, data) - k=data.k + k = data.k if node.region == 1 f[1] = k[1] * u[1] f[2] = -k[1] * u[1] @@ -22,34 +22,38 @@ function reaction(f, u, node, data) else f[1] = 0 end + return nothing end function source(f, node, data) if node.region == 1 f[1] = 1.0e-4 * (3.0 - node[1]) end + return nothing end -## Since 0.17.0 one can +## 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 + eps = data.eps + for i in 1:3 f[i] = eps[i] * (u[i, 1] - u[i, 2]) end + return nothing end function correctionstorage(f, u, node, data) f .= u + return nothing 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 + 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]) @@ -59,9 +63,10 @@ function pickyflux(f, u, edge, data) f[2] = eps[2] * (u[2, 1] - u[2, 2]) f[3] = eps[3] * (u[3, 1] - u[3, 2]) end + return nothing end -function pickystorage(f, u, node, data) +function pickystorage(f, u, node, data) if node.region == 1 f[1] = u[1] f[2] = u[2] @@ -71,20 +76,23 @@ function pickystorage(f, u, node, data) f[2] = u[2] f[3] = u[3] end + return nothing 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) +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) 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]) @@ -93,15 +101,17 @@ function main(; n = 30, Plotter = nothing, plot_grid = false, verbose = false, plotgrid(grid; Plotter = Plotter) return end - - data=(eps = [1, 1, 1], k = [1, 1, 1]) - + + 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) + + sys = VoronoiFVM.System( + grid; data, + flux, reaction, storage, source, + unknown_storage, assembly + ) enable_species!(sys, 1, [1]) enable_species!(sys, 2, [1, 2, 3]) @@ -112,45 +122,53 @@ function main(; n = 30, Plotter = nothing, plot_grid = false, verbose = false, testval = 0 p = GridVisualizer(; Plotter = Plotter, layout = (1, 1)) - function plot_timestep(U,time) + function plot_timestep(U, time) U1 = view(U[1, :], subgrid1) U2 = view(U[2, :], subgrid2) U3 = view(U[3, :], subgrid3) - scalarplot!(p[1, 1], subgrid1, U1; label = "spec1", color = :darkred, - xlimits = (0, 3), flimits = (0, 1e-3), - title = @sprintf("three regions t=%.3g", time)) - scalarplot!(p[1, 1], subgrid2, U2; label = "spec2", color = :green, - clear = false) - scalarplot!(p[1, 1], subgrid3, U3; label = "spec3", color = :navyblue, - clear = false, show = true) - if ismakie(Plotter) + scalarplot!( + p[1, 1], subgrid1, U1; label = "spec1", color = :darkred, + xlimits = (0, 3), flimits = (0, 1.0e-3), + title = @sprintf("three regions t=%.3g", time) + ) + scalarplot!( + p[1, 1], subgrid2, U2; label = "spec2", color = :green, + clear = false + ) + scalarplot!( + p[1, 1], subgrid3, U3; label = "spec3", color = :navyblue, + clear = false, show = true + ) + return if ismakie(Plotter) sleep(0.02) end end if diffeq - inival=unknowns(sys,inival=0) - problem = ODEProblem(sys,inival,(0,tend)) + 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=1.0e-2, adaptive=false) - tsol=reshape(odesol,sys) + 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), - verbose, Δu_opt = 1.0e-5, - method_linear=KLUFactorization()) - end - + 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) - Δt=tsol.t[i]-tsol.t[i-1] - testval+=sum(view(ui,subgrid2))*Δt + for i in 2:length(tsol.t) + ui = view(tsol, 2, :, i) + Δt = tsol.t[i] - tsol.t[i - 1] + testval += sum(view(ui, subgrid2)) * Δt end - + if !isnothing(Plotter) - for i=2:length(tsol.t) - plot_timestep(tsol.u[i],tsol.t[i]) + for i in 2:length(tsol.t) + plot_timestep(tsol.u[i], tsol.t[i]) end end return testval @@ -171,15 +189,15 @@ function runtests() @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 - + @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 + return nothing end end diff --git a/examples/Example121_PoissonPointCharge1D.jl b/examples/Example121_PoissonPointCharge1D.jl index bb1658264..5da9c5a5b 100644 --- a/examples/Example121_PoissonPointCharge1D.jl +++ b/examples/Example121_PoissonPointCharge1D.jl @@ -19,8 +19,10 @@ using VoronoiFVM using ExtendableGrids using GridVisualize -function main(; nref = 0, Plotter = nothing, verbose = false, unknown_storage = :sparse, - brea = false, assembly = :edgewise) +function main(; + nref = 0, Plotter = nothing, verbose = false, unknown_storage = :sparse, + brea = false, assembly = :edgewise + ) ## Create grid in (-1,1) refined around 0 hmax = 0.2 / 2.0^nref @@ -42,9 +44,11 @@ function main(; nref = 0, Plotter = nothing, verbose = false, unknown_storage = function flux!(f, u, edge, data) f[1] = u[1, 1] - u[1, 2] + return nothing end function storage!(f, u, node, data) f[1] = u[1] + return nothing end ## Define boundary reaction defining charge @@ -53,12 +57,15 @@ function main(; nref = 0, Plotter = nothing, verbose = false, unknown_storage = if node.region == 3 f[1] = -Q end + return nothing end ## Create physics - physics = VoronoiFVM.Physics(; flux = flux!, - storage = storage!, - breaction = breaction!) + physics = VoronoiFVM.Physics(; + flux = flux!, + storage = storage!, + breaction = breaction! + ) ## Create system sys = VoronoiFVM.System(grid, physics; unknown_storage = :dense, assembly = assembly) @@ -93,8 +100,10 @@ function main(; nref = 0, Plotter = nothing, verbose = false, unknown_storage = ## Plot data - scalarplot!(vis, grid, U[1, :]; title = @sprintf("Q=%.2f", q), clear = true, - show = true) + scalarplot!( + vis, grid, U[1, :]; title = @sprintf("Q=%.2f", q), clear = true, + show = true + ) end return sum(U) end @@ -103,6 +112,7 @@ using Test function runtests() testval = 20.254591679579015 @test main(; assembly = :edgewise) ≈ testval && - main(; assembly = :cellwise) ≈ testval + main(; assembly = :cellwise) ≈ testval + return nothing end end diff --git a/examples/Example125_TestFunctions1D.jl b/examples/Example125_TestFunctions1D.jl index 12fe0abeb..020362d03 100644 --- a/examples/Example125_TestFunctions1D.jl +++ b/examples/Example125_TestFunctions1D.jl @@ -19,16 +19,20 @@ function main(; n = 100, Plotter = nothing, verbose = false, unknown_storage = : eps::Vector{Float64} = [1, 1.0e-1] physics = VoronoiFVM.Physics( - ; reaction = function (f, u, node, data) - f[1] = 10 * (u[1] - u[2]) - f[2] = 10 * (u[2] - u[1]) - end, flux = function (f, u, edge, data) - f[1] = eps[1] * (u[1, 1] - u[1, 2]) - f[2] = eps[2] * (u[2, 1] - u[2, 2]) - end, storage = function (f, u, node, data) - f[1] = u[1] - f[2] = u[2] - end) + ; reaction = function (f, u, node, data) + f[1] = 10 * (u[1] - u[2]) + f[2] = 10 * (u[2] - u[1]) + return nothing + end, flux = function (f, u, edge, data) + f[1] = eps[1] * (u[1, 1] - u[1, 2]) + f[2] = eps[2] * (u[2, 1] - u[2, 2]) + return nothing + end, storage = function (f, u, node, data) + f[1] = u[1] + f[2] = u[2] + return nothing + end + ) sys = VoronoiFVM.System(grid, physics; unknown_storage = unknown_storage, assembly = assembly) enable_species!(sys, 1, [1]) @@ -70,6 +74,7 @@ function runtests() @test main(; unknown_storage = :sparse, assembly = :edgewise) ≈ testval @test main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval @test main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval - @test main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval + @test main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval + return nothing end end diff --git a/examples/Example150_Impedance1D.jl b/examples/Example150_Impedance1D.jl index 124b5a116..54aac9f58 100644 --- a/examples/Example150_Impedance1D.jl +++ b/examples/Example150_Impedance1D.jl @@ -31,9 +31,11 @@ using VoronoiFVM using ExtendableGrids: geomspace, simplexgrid using GridVisualize -function main(; nref = 0, Plotter = nothing, verbose = false, unknown_storage = :sparse, assembly = :edgewise, - L = 1.0, R = 1.0, D = 1.0, C = 1.0, - ω0 = 1.0e-3, ω1 = 5.0e1) +function main(; + nref = 0, Plotter = nothing, verbose = false, unknown_storage = :sparse, assembly = :edgewise, + L = 1.0, R = 1.0, D = 1.0, C = 1.0, + ω0 = 1.0e-3, ω1 = 5.0e1 + ) # Create array which is refined close to 0 h0 = 0.005 / 2.0^nref @@ -50,14 +52,17 @@ function main(; nref = 0, Plotter = nothing, verbose = false, unknown_storage = # Declare constitutive functions flux = function (f, u, edge, data) f[1] = data.D * (u[1, 1] - u[1, 2]) + return nothing end storage = function (f, u, node, data) f[1] = data.C * u[1] + return nothing end reaction = function (f, u, node, data) f[1] = data.R * u[1] + return nothing end excited_bc = 1 @@ -66,10 +71,12 @@ function main(; nref = 0, Plotter = nothing, verbose = false, unknown_storage = meas_bc = 2 # Create physics struct - physics = VoronoiFVM.Physics(; data = data, - flux = flux, - storage = storage, - reaction = reaction) + physics = VoronoiFVM.Physics(; + data = data, + flux = flux, + storage = storage, + reaction = reaction + ) # Create discrete system and enable species sys = VoronoiFVM.System(grid, physics; unknown_storage = unknown_storage, assembly = assembly) @@ -88,13 +95,13 @@ function main(; nref = 0, Plotter = nothing, verbose = false, unknown_storage = function meas_stdy(meas, U) u = reshape(U, sys) meas[1] = -VoronoiFVM.integrate_stdy(sys, measurement_testfunction, u)[excited_spec] - nothing + return nothing end function meas_tran(meas, U) u = reshape(U, sys) meas[1] = -VoronoiFVM.integrate_tran(sys, measurement_testfunction, u)[excited_spec] - nothing + return nothing end dmeas_stdy = measurement_derivative(sys, meas_stdy, steadystate) @@ -144,21 +151,26 @@ function main(; nref = 0, Plotter = nothing, verbose = false, unknown_storage = end p = GridVisualizer(; Plotter = Plotter) - scalarplot!(p, real(allIxL), imag(allIxL); label = "exact", color = :red, - linestyle = :dot) - scalarplot!(p, real(allIL), imag(allIL); label = "calc", show = true, clear = false, - color = :blue, linestyle = :solid) - - sum(allIL) + scalarplot!( + p, real(allIxL), imag(allIxL); label = "exact", color = :red, + linestyle = :dot + ) + scalarplot!( + p, real(allIL), imag(allIL); label = "calc", show = true, clear = false, + color = :blue, linestyle = :solid + ) + + return sum(allIL) end using Test function runtests() testval = 57.92710286186797 + 23.163945443946027im @test main(; unknown_storage = :sparse, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && - main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && + main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && + main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + return nothing end end diff --git a/examples/Example151_Impedance1D.jl b/examples/Example151_Impedance1D.jl index f37477d61..bc346b6b7 100644 --- a/examples/Example151_Impedance1D.jl +++ b/examples/Example151_Impedance1D.jl @@ -36,11 +36,13 @@ using ExtendableGrids: geomspace, simplexgrid using GridVisualize using OrdinaryDiffEqSDIRK -function main(; nref = 0, Plotter = nothing, verbose = false, - unknown_storage = :sparse, assembly = :edgewise, - time_embedding = :none, - L = 1.0, R = 1.0, D = 1.0, C = 1.0, - ω0 = 1.0e-3, ω1 = 5.0e1) +function main(; + nref = 0, Plotter = nothing, verbose = false, + unknown_storage = :sparse, assembly = :edgewise, + time_embedding = :none, + L = 1.0, R = 1.0, D = 1.0, C = 1.0, + ω0 = 1.0e-3, ω1 = 5.0e1 + ) # Create array which is refined close to 0 h0 = 0.005 / 2.0^nref @@ -57,17 +59,20 @@ function main(; nref = 0, Plotter = nothing, verbose = false, # Declare constitutive functions flux = function (f, u, edge, data) f[1] = data.D * (u[1, 1] - u[1, 2]) + return nothing end storage = function (f, u, node, data) f[1] = data.C * u[1] + return nothing end reaction = function (f, u, node, data) f[1] = data.R * u[1] + return nothing end - excited_bc= 1 + excited_bc = 1 excited_bcval = 1.0 excited_spec = 1 meas_bc = 2 @@ -76,34 +81,37 @@ function main(; nref = 0, Plotter = nothing, verbose = false, p = parameters(u) boundary_dirichlet!(f, u, node; region = excited_bc, value = p[1]) boundary_dirichlet!(f, u, node; region = meas_bc, value = 0.0) + return nothing end # Create discrete system and enable species - sys = VoronoiFVM.System(grid; unknown_storage = unknown_storage, - data = data, - flux = flux, - storage = storage, - reaction = reaction, - bcondition = bc, - nparams = 1, - species = 1, assembly = assembly) + sys = VoronoiFVM.System( + grid; unknown_storage = unknown_storage, + data = data, + flux = flux, + storage = storage, + reaction = reaction, + bcondition = bc, + nparams = 1, + species = 1, assembly = assembly + ) # Create test functions for current measurement factory = TestFunctionFactory(sys) measurement_testfunction = testfunction(factory, [excited_bc], [meas_bc]) - tend=1.0 + tend = 1.0 if time_embedding == :builtin - tsol=solve(sys; inival = 0.0, params = [1.0], times=(0.0,tend),force_first_step=true) - steadystate=tsol.u[end] + tsol = solve(sys; inival = 0.0, params = [1.0], times = (0.0, tend), force_first_step = true) + steadystate = tsol.u[end] elseif time_embedding == :ordinarydiffeq - inival=unknowns(sys,inival=0) - problem = ODEProblem(sys,inival,(0,tend); params = [1.0]) - odesol = solve(problem,ImplicitEuler()) - tsol=reshape(odesol,sys) - steadystate=tsol.u[end] - elseif time_embedding==:none + inival = unknowns(sys, inival = 0) + problem = ODEProblem(sys, inival, (0, tend); params = [1.0]) + odesol = solve(problem, ImplicitEuler()) + tsol = reshape(odesol, sys) + steadystate = tsol.u[end] + elseif time_embedding == :none steadystate = solve(sys; inival = 0.0, params = [1.0]) else error("time_embedding must be one of :builtin, :ordinarydiffeq, :none") @@ -112,13 +120,13 @@ function main(; nref = 0, Plotter = nothing, verbose = false, function meas_stdy(meas, U) u = reshape(U, sys) meas[1] = -VoronoiFVM.integrate_stdy(sys, measurement_testfunction, u)[excited_spec] - nothing + return nothing end function meas_tran(meas, U) u = reshape(U, sys) meas[1] = -VoronoiFVM.integrate_tran(sys, measurement_testfunction, u)[excited_spec] - nothing + return nothing end dmeas_stdy = measurement_derivative(sys, meas_stdy, steadystate) @@ -168,12 +176,16 @@ function main(; nref = 0, Plotter = nothing, verbose = false, end vis = GridVisualizer(; Plotter = Plotter) - scalarplot!(vis, real(allIxL), imag(allIxL); label = "exact", color = :red, - linestyle = :dot) - scalarplot!(vis, real(allIL), imag(allIL); label = "calc", show = true, clear = false, - color = :blue, linestyle = :solid) - - sum(allIL) + scalarplot!( + vis, real(allIxL), imag(allIxL); label = "exact", color = :red, + linestyle = :dot + ) + scalarplot!( + vis, real(allIL), imag(allIL); label = "calc", show = true, clear = false, + color = :blue, linestyle = :solid + ) + + return sum(allIL) end using Test @@ -181,11 +193,12 @@ function runtests() testval = 57.92710286186797 + 23.163945443946027im for unknown_storage in (:sparse, :dense) for assembly in (:edgewise, :cellwise) - for time_embedding in (:none, :builtin, :ordinarydiffeq) + for time_embedding in (:none, :builtin, :ordinarydiffeq) @test main(; unknown_storage, assembly, time_embedding) ≈ testval end end end + return nothing end end diff --git a/examples/Example160_UnipolarDriftDiffusion1D.jl b/examples/Example160_UnipolarDriftDiffusion1D.jl index 5672706df..abd1ae27d 100644 --- a/examples/Example160_UnipolarDriftDiffusion1D.jl +++ b/examples/Example160_UnipolarDriftDiffusion1D.jl @@ -46,6 +46,7 @@ function classflux!(f, u, edge, data) f[iphi] = data.eps * (u[iphi, 1] - u[iphi, 2]) bp, bm = fbernoulli_pm(u[iphi, 1] - u[iphi, 2]) f[ic] = bm * u[ic, 1] - bp * u[ic, 2] + return nothing end function storage!(f, u, node, data) @@ -53,6 +54,7 @@ function storage!(f, u, node, data) iphi = data.iphi f[iphi] = 0 f[ic] = u[ic] + return nothing end function reaction!(f, u, node, data) @@ -60,16 +62,18 @@ function reaction!(f, u, node, data) iphi = data.iphi f[iphi] = data.z * (1 - 2 * u[ic]) f[ic] = 0 + return nothing end -const eps_reg=1.0e-10 +const eps_reg = 1.0e-10 function sedanflux!(f, u, edge, data) ic = data.ic iphi = data.iphi f[iphi] = data.eps * (u[iphi, 1] - u[iphi, 2]) - mu1 = -log1p(max(-1+eps_reg, -u[ic, 1])) - mu2 = -log1p(max(-1+eps_reg, -u[ic, 2])) + mu1 = -log1p(max(-1 + eps_reg, -u[ic, 1])) + mu2 = -log1p(max(-1 + eps_reg, -u[ic, 2])) bp, bm = fbernoulli_pm(data.z * 2 * (u[iphi, 1] - u[iphi, 2]) + (mu1 - mu2)) f[ic] = bm * u[ic, 1] - bp * u[ic, 2] + return nothing end function bcondition!(f, u, bnode, data) @@ -77,17 +81,19 @@ function bcondition!(f, u, bnode, data) boundary_dirichlet!(f, u, bnode; species = data.iphi, region = 1, value = V) boundary_dirichlet!(f, u, bnode; species = data.iphi, region = 2, value = 0) boundary_dirichlet!(f, u, bnode; species = data.ic, region = 2, value = 0.5) + return nothing end function main(; - n = 20, - Plotter = nothing, - dlcap = false, - verbose = false, - phimax = 1, - dphi = 1.0e-1, - unknown_storage = :sparse, - assembly = :edgewise,) + n = 20, + Plotter = nothing, + dlcap = false, + verbose = false, + phimax = 1, + dphi = 1.0e-1, + unknown_storage = :sparse, + assembly = :edgewise, + ) h = 1.0 / convert(Float64, n) grid = simplexgrid(collect(0:h:1)) @@ -101,17 +107,20 @@ function main(; iphi = data.iphi physics = VoronoiFVM.Physics(; - data = data, - flux = sedanflux!, - reaction = reaction!, - breaction = bcondition!, - storage = storage!,) - - sys = VoronoiFVM.System(grid, - physics; - unknown_storage = unknown_storage, - species = [1, 2], - assembly = assembly,) + data = data, + flux = sedanflux!, + reaction = reaction!, + breaction = bcondition!, + storage = storage!, + ) + + sys = VoronoiFVM.System( + grid, + physics; + unknown_storage = unknown_storage, + species = [1, 2], + assembly = assembly, + ) inival = unknowns(sys) @views inival[iphi, :] .= 0 @@ -129,30 +138,36 @@ function main(; control.Δu_opt = 0.1 control.damp_initial = 0.5 - tsol = solve(sys; - method_linear = UMFPACKFactorization(), - inival, - times = [0.0, 10], - control = control,) + tsol = solve( + sys; + method_linear = UMFPACKFactorization(), + inival, + times = [0.0, 10], + control = control, + ) vis = GridVisualizer(; Plotter = Plotter, layout = (1, 1), fast = true) - for log10t = -4:0.025:0 + for log10t in -4:0.025:0 time = 10^(log10t) sol = tsol(time) - scalarplot!(vis[1, 1], - grid, - sol[iphi, :]; - label = "ϕ", - title = @sprintf("time=%.3g", time), - flimits = (0, 5), - color = :green,) - scalarplot!(vis[1, 1], - grid, - sol[ic, :]; - label = "c", - flimits = (0, 5), - clear = false, - color = :red,) + scalarplot!( + vis[1, 1], + grid, + sol[iphi, :]; + label = "ϕ", + title = @sprintf("time=%.3g", time), + flimits = (0, 5), + color = :green, + ) + scalarplot!( + vis[1, 1], + grid, + sol[ic, :]; + label = "c", + flimits = (0, 5), + clear = false, + color = :red, + ) reveal(vis) end return sum(tsol.u[end]) @@ -175,7 +190,7 @@ function main(; vis = GridVisualizer(; Plotter = Plotter, layout = (2, 1), fast = true) for dir in [1, -1] phi = 0.0 - U.=inival + U .= inival while phi < phimax data.V = dir * phi U = solve(sys; inival = U, control, time = 1.0) @@ -186,21 +201,25 @@ function main(; cdl = (Qdelta[iphi] - Q[iphi]) / delta if Plotter != nothing - scalarplot!(vis[1, 1], - grid, - U[iphi, :]; - label = "ϕ", - title = @sprintf("Δϕ=%.3g", phi), - flimits = (-5, 5), - clear = true, - color = :green,) - scalarplot!(vis[1, 1], - grid, - U[ic, :]; - label = "c", - flimits = (0, 5), - clear = false, - color = :red,) + scalarplot!( + vis[1, 1], + grid, + U[iphi, :]; + label = "ϕ", + title = @sprintf("Δϕ=%.3g", phi), + flimits = (-5, 5), + clear = true, + color = :green, + ) + scalarplot!( + vis[1, 1], + grid, + U[ic, :]; + label = "c", + flimits = (0, 5), + clear = false, + color = :red, + ) end if dir == 1 push!(vplus, dir * phi) @@ -216,12 +235,14 @@ function main(; v = vcat(reverse(vminus), vplus) c = vcat(reverse(cdlminus), cdlplus) if length(v) >= 2 - scalarplot!(vis[2, 1], - v, - c; - color = :green, - clear = false, - title = "C_dl",) + scalarplot!( + vis[2, 1], + v, + c; + color = :green, + clear = false, + title = "C_dl", + ) end phi += dphi @@ -236,33 +257,50 @@ end using Test function runtests() - + evolval = 18.721369939565655 dlcapval = 0.025657355479449806 rtol = 1.0e-5 - @test isapprox(main(; unknown_storage = :sparse, dlcap = false, assembly = :edgewise), - evolval; - rtol = rtol,) - @test isapprox(main(; unknown_storage = :sparse, dlcap = true, assembly = :edgewise), - dlcapval; - rtol = rtol,) - @test isapprox(main(; unknown_storage = :dense, dlcap = false, assembly = :edgewise), - evolval; - rtol = rtol,) - @test isapprox(main(; unknown_storage = :dense, dlcap = true, assembly = :edgewise), - dlcapval; - rtol = rtol,) - @test isapprox(main(; unknown_storage = :sparse, dlcap = false, assembly = :cellwise), - evolval; - rtol = rtol,) - @test isapprox(main(; unknown_storage = :sparse, dlcap = true, assembly = :cellwise), - dlcapval; - rtol = rtol,) - @test isapprox(main(; unknown_storage = :dense, dlcap = false, assembly = :cellwise), - evolval; - rtol = rtol,) - @test isapprox(main(; unknown_storage = :dense, dlcap = true, assembly = :cellwise), - dlcapval; - rtol = rtol,) + @test isapprox( + main(; unknown_storage = :sparse, dlcap = false, assembly = :edgewise), + evolval; + rtol = rtol, + ) + @test isapprox( + main(; unknown_storage = :sparse, dlcap = true, assembly = :edgewise), + dlcapval; + rtol = rtol, + ) + @test isapprox( + main(; unknown_storage = :dense, dlcap = false, assembly = :edgewise), + evolval; + rtol = rtol, + ) + @test isapprox( + main(; unknown_storage = :dense, dlcap = true, assembly = :edgewise), + dlcapval; + rtol = rtol, + ) + @test isapprox( + main(; unknown_storage = :sparse, dlcap = false, assembly = :cellwise), + evolval; + rtol = rtol, + ) + @test isapprox( + main(; unknown_storage = :sparse, dlcap = true, assembly = :cellwise), + dlcapval; + rtol = rtol, + ) + @test isapprox( + main(; unknown_storage = :dense, dlcap = false, assembly = :cellwise), + evolval; + rtol = rtol, + ) + @test isapprox( + main(; unknown_storage = :dense, dlcap = true, assembly = :cellwise), + dlcapval; + rtol = rtol, + ) + return nothing end end diff --git a/examples/Example201_Laplace2D.jl b/examples/Example201_Laplace2D.jl index 4ff3f9065..a840d7ce1 100644 --- a/examples/Example201_Laplace2D.jl +++ b/examples/Example201_Laplace2D.jl @@ -16,6 +16,7 @@ import Metis ## between neighboring control volumes function g!(f, u, edge, data) f[1] = u[1, 1] - u[1, 2] + return nothing end function main(; Plotter = nothing, n = 5, is_linear = true, assembly = :edgewise) @@ -23,7 +24,7 @@ function main(; Plotter = nothing, n = 5, is_linear = true, assembly = :edgewise ispec = 1 X = collect(0:(1.0 / n):1) grid = simplexgrid(X, X) - grid=partition(grid, PlainMetisPartitioning(npart=20)) + grid = partition(grid, PlainMetisPartitioning(npart = 20)) @show grid physics = VoronoiFVM.Physics(; flux = g!) sys = VoronoiFVM.System(grid, physics; is_linear = is_linear, assembly = assembly) @@ -34,7 +35,7 @@ function main(; Plotter = nothing, n = 5, is_linear = true, assembly = :edgewise nf = nodeflux(sys, solution) vis = GridVisualizer(; Plotter = Plotter) scalarplot!(vis, grid, solution[1, :]; clear = true, colormap = :summer) - vectorplot!(vis, grid, nf[:, 1, :]; clear = false, vscale = 0.5, rasterpoints=10) + vectorplot!(vis, grid, nf[:, 1, :]; clear = false, vscale = 0.5, rasterpoints = 10) reveal(vis) return norm(solution) + norm(nf) end @@ -46,7 +47,8 @@ function runtests() testval = 9.63318042491699 @test main(; assembly = :edgewise) ≈ testval && - main(; assembly = :cellwise) ≈ testval + main(; assembly = :cellwise) ≈ testval + return nothing end end diff --git a/examples/Example203_CoordinateSystems.jl b/examples/Example203_CoordinateSystems.jl index 6d886becd..6e833ac76 100644 --- a/examples/Example203_CoordinateSystems.jl +++ b/examples/Example203_CoordinateSystems.jl @@ -14,11 +14,12 @@ using GridVisualize function plot(grid, numerical, exact, Plotter) vis = GridVisualizer(; Plotter = Plotter, layout = (2, 1)) scalarplot!(vis[1, 1], grid, numerical[1, :]; title = "numerical") - scalarplot!(vis[2, 1], grid, exact; title = "exact", show = true) + return scalarplot!(vis[2, 1], grid, exact; title = "exact", show = true) end function flux(f, u, edge, data) f[1] = u[1, 1] - u[1, 2] + return nothing end """ @@ -47,7 +48,7 @@ function maindisk(; nref = 0, r2 = 5.0, Plotter = nothing, assembly = :edgewise) sol = solve(sys) exact = symlapdisk.(coordinates(grid)[1, :], r2) plot(grid, sol, exact, Plotter) - norm(sol[1, :] - exact, Inf) < 1.0e-14 + return norm(sol[1, :] - exact, Inf) < 1.0e-14 end """ @@ -59,12 +60,13 @@ on disk of radius r2, exact solution is `(r_2^2-r^2)/4`. In this case, the discretization appears to be exact. """ function maincylinder(; - nref = 0, - r2 = 5.0, - z1 = 0.0, - z2 = 1.0, - Plotter = nothing, - assembly = :edgewise,) + nref = 0, + r2 = 5.0, + z1 = 0.0, + z2 = 1.0, + Plotter = nothing, + assembly = :edgewise, + ) h = 0.1 * 2.0^(-nref) R = collect(0:h:r2) Z = collect(z1:h:z2) @@ -76,7 +78,7 @@ function maincylinder(; sol = solve(sys) exact = symlapdisk.(coordinates(grid)[1, :], r2) plot(grid, sol, exact, Plotter) - norm(sol[1, :] - exact, Inf) < 1.0e-14 + return norm(sol[1, :] - exact, Inf) < 1.0e-14 end """ @@ -88,8 +90,9 @@ on disk of radius r2, exact solution is `(r_2^2-r^2)/4`. In this case, the discretization appears to be exact. """ function maincylinder_unstruct(; - Plotter = nothing, - assembly = :edgewise) + Plotter = nothing, + assembly = :edgewise + ) if VERSION < v"1.7" # no pkdir return true @@ -107,7 +110,7 @@ function maincylinder_unstruct(; sol = solve(sys) exact = symlapdisk.(coordinates(grid)[1, :], r2) plot(grid, sol, exact, Plotter) - norm(sol[1, :] - exact, Inf) < 0.0012 + return norm(sol[1, :] - exact, Inf) < 0.0012 end """ @@ -136,7 +139,7 @@ function mainring(; nref = 0, r1 = 1.0, r2 = 5.0, Plotter = nothing, assembly = sol = solve(sys) exact = symlapring.(coordinates(grid)[1, :], r1, r2) plot(grid, sol, exact, Plotter) - norm(sol[1, :] - exact, Inf) / h^2 < 0.01 + return norm(sol[1, :] - exact, Inf) / h^2 < 0.01 end """ @@ -146,13 +149,14 @@ of Dirichlet problem `-Δu=0` on cylindershell between radii r1 and r2, with boundary value 1 at r1 and 0 at r2. Test of quadratic convergence. """ function maincylindershell(; - nref = 0, - r1 = 1.0, - r2 = 5.0, - z1 = 0.0, - z2 = 1.0, - Plotter = nothing, - assembly = :edgewise,) + nref = 0, + r1 = 1.0, + r2 = 5.0, + z1 = 0.0, + z2 = 1.0, + Plotter = nothing, + assembly = :edgewise, + ) h = 0.1 * 2.0^(-nref) R = collect(r1:h:r2) Z = collect(z1:h:z2) @@ -165,7 +169,7 @@ function maincylindershell(; sol = solve(sys) exact = symlapring.(coordinates(grid)[1, :], r1, r2) plot(grid, sol, exact, Plotter) - norm(sol[1, :] - exact, Inf) / h^2 < 0.01 + return norm(sol[1, :] - exact, Inf) / h^2 < 0.01 end """ @@ -194,7 +198,7 @@ function mainsphere(; nref = 0, r2 = 5.0, Plotter = nothing, assembly = :edgewis sol = solve(sys) exact = symlapsphere.(coordinates(grid)[1, :], r2) plot(grid, sol, exact, Plotter) - norm(sol[1, :] - exact, Inf) < 1.0e-14 + return norm(sol[1, :] - exact, Inf) < 1.0e-14 end """ @@ -212,11 +216,12 @@ of Dirichlet problem `-Δu=0` on sphereshell between radii r1 and r2, with boundary value 1 at r1 and 0 at r2. Test of quadratic convergence. """ function mainsphereshell(; - nref = 0, - r1 = 1.0, - r2 = 5.0, - Plotter = nothing, - assembly = :edgewise,) + nref = 0, + r1 = 1.0, + r2 = 5.0, + Plotter = nothing, + assembly = :edgewise, + ) h = 0.1 * 2.0^(-nref) R = collect(r1:h:r2) grid = simplexgrid(R) @@ -228,28 +233,29 @@ function mainsphereshell(; sol = solve(sys) exact = symlapsphereshell.(coordinates(grid)[1, :], r1, r2) plot(grid, sol, exact, Plotter) - norm(sol[1, :] - exact, Inf) / h^2 < 0.04 + return norm(sol[1, :] - exact, Inf) / h^2 < 0.04 end # # Called by unit test -using Test# +using Test # function runtests() @test maindisk(; assembly = :edgewise) && - mainring(; assembly = :edgewise) && - maincylinder(; assembly = :edgewise) && - maincylinder_unstruct(; assembly = :edgewise) && - maincylindershell(; assembly = :edgewise) && - mainsphere(; assembly = :edgewise) && - mainsphereshell(; assembly = :edgewise) && - maindisk(; assembly = :cellwise) && - mainring(; assembly = :cellwise) && - maincylinder(; assembly = :cellwise) && - maincylinder_unstruct(; assembly = :cellwise) && - maincylindershell(; assembly = :cellwise) && - mainsphere(; assembly = :cellwise) && - mainsphereshell(; assembly = :cellwise) + mainring(; assembly = :edgewise) && + maincylinder(; assembly = :edgewise) && + maincylinder_unstruct(; assembly = :edgewise) && + maincylindershell(; assembly = :edgewise) && + mainsphere(; assembly = :edgewise) && + mainsphereshell(; assembly = :edgewise) && + maindisk(; assembly = :cellwise) && + mainring(; assembly = :cellwise) && + maincylinder(; assembly = :cellwise) && + maincylinder_unstruct(; assembly = :cellwise) && + maincylindershell(; assembly = :cellwise) && + mainsphere(; assembly = :cellwise) && + mainsphereshell(; assembly = :cellwise) + return nothing end end diff --git a/examples/Example204_HagenPoiseuille.jl b/examples/Example204_HagenPoiseuille.jl index 6a2595e2b..b89ed0955 100644 --- a/examples/Example204_HagenPoiseuille.jl +++ b/examples/Example204_HagenPoiseuille.jl @@ -21,8 +21,10 @@ using GridVisualize function main(; nref = 0, Plotter = nothing, D = 0.01, v = 1.0, tend = 100, cin = 1.0, assembly = :edgewise) H = 1.0 L = 5.0 - grid = simplexgrid(range(0, L; length = 20 * 2^nref), - range(0, H; length = 5 * 2^nref)) + grid = simplexgrid( + range(0, L; length = 20 * 2^nref), + range(0, H; length = 5 * 2^nref) + ) function fhp(x, y) yh = y / H @@ -37,12 +39,14 @@ function main(; nref = 0, Plotter = nothing, D = 0.01, v = 1.0, tend = 100, cin bp = fbernoulli(vd) bm = fbernoulli(-vd) f[1] = D * (bp * u[1] - bm * u[2]) + return nothing end function outflow!(f, u, node, data) if node.region == 2 f[1] = bfvelo[node.ibnode, node.ibface] * u[1] end + return nothing end ispec = 1 @@ -61,19 +65,22 @@ function main(; nref = 0, Plotter = nothing, D = 0.01, v = 1.0, tend = 100, cin tsol = solve(sys; inival = 0, times = [0, tend], control = control) vis = GridVisualizer(; Plotter = Plotter) - for i = 1:length(tsol.t) - scalarplot!(vis[1, 1], grid, tsol[1, :, i]; flimits = (0, cin + 1.0e-5), - title = @sprintf("time=%3f", tsol.t[i]), show = true) + for i in 1:length(tsol.t) + scalarplot!( + vis[1, 1], grid, tsol[1, :, i]; flimits = (0, cin + 1.0e-5), + title = @sprintf("time=%3f", tsol.t[i]), show = true + ) end - tsol + return tsol end using Test function runtests() tsol1 = main(; assembly = :edgewise) tsol2 = main(; assembly = :cellwise) - @test all(tsol1.u[end] .≈ 1) @test all(tsol1.u[end] .≈ 1) + @test all(tsol1.u[end] .≈ 1) + return nothing end end diff --git a/examples/Example205_StagnationPoint.jl b/examples/Example205_StagnationPoint.jl index 7f01e4923..5bf2674dc 100644 --- a/examples/Example205_StagnationPoint.jl +++ b/examples/Example205_StagnationPoint.jl @@ -39,8 +39,10 @@ function main(; nref = 0, gridname = nothing, Plotter = nothing, D = 0.01, v = 1 if !isnothing(gridname) grid = simplexgrid(gridname) else - grid = simplexgrid(range(0, L; length = 10 * 2^nref), - range(0, H; length = 10 * 2^nref)) + grid = simplexgrid( + range(0, L; length = 10 * 2^nref), + range(0, H; length = 10 * 2^nref) + ) bfacemask!(grid, [0, H], [0.25L, H], 5) end circular_symmetric!(grid) @@ -55,12 +57,14 @@ function main(; nref = 0, gridname = nothing, Plotter = nothing, D = 0.01, v = 1 bp = fbernoulli(vd) bm = fbernoulli(-vd) f[1] = D * (bp * u[1] - bm * u[2]) + return nothing end function outflow!(f, u, node, data) if node.region == Γ_out f[1] = bfvelo[node.ibnode, node.ibface] * u[1] end + return nothing end ispec = 1 @@ -92,7 +96,7 @@ function main(; nref = 0, gridname = nothing, Plotter = nothing, D = 0.01, v = 1 div = VoronoiFVM.calc_divergences(sys, evelo, bfvelo) test4 = all(x -> abs(x) < 1.0e-12, div) - test1 && test2 && test3 && test4 + return test1 && test2 && test3 && test4 end using Test @@ -104,6 +108,7 @@ function runtests() test0 = test0 && main(; assembly = :edgewise, gridname) && main(; assembly = :cellwise, gridname) end @test test0 && main(; assembly = :edgewise) && main(; assembly = :cellwise) + return nothing end end diff --git a/examples/Example206_JouleHeat.jl b/examples/Example206_JouleHeat.jl index 854165c01..27b0e38e5 100644 --- a/examples/Example206_JouleHeat.jl +++ b/examples/Example206_JouleHeat.jl @@ -26,8 +26,10 @@ using LinearSolve import Triangulate import Metis -function main(; nref = 0, Plotter = nothing, verbose = "and", unknown_storage = :sparse, assembly = :edgewise, - ythin = 0.25) +function main(; + nref = 0, Plotter = nothing, verbose = "and", unknown_storage = :sparse, assembly = :edgewise, + ythin = 0.25 + ) ## Create grid b = SimplexGridBuilder(; Generator = Triangulate) @@ -50,7 +52,7 @@ function main(; nref = 0, Plotter = nothing, verbose = "and", unknown_storage = facet!(b, p02, p00) grid = simplexgrid(b; maxvolume = 0.01 * 4.0^(-nref)) - grid=partition(grid, PlainMetisPartitioning(npart=20); nodes=true, edges=true) + grid = partition(grid, PlainMetisPartitioning(npart = 20); nodes = true, edges = true) @show grid ## Describe problem iϕ::Int = 1 @@ -63,6 +65,7 @@ function main(; nref = 0, Plotter = nothing, verbose = "and", unknown_storage = function storage!(y, u, node, data) y[iT] = c * u[iT] + return nothing end κ(T) = κ0 * exp(α * (T - T0)) @@ -70,12 +73,14 @@ function main(; nref = 0, Plotter = nothing, verbose = "and", unknown_storage = function flux!(y, u, edge, data) y[iϕ] = κ(y[iT]) * (u[iϕ, 1] - u[iϕ, 2]) y[iT] = λ * (u[iT, 1] - u[iT, 2]) + return nothing end ## The convention in VoronoiFVM.jl is to have all terms depending on the solution ## on the left hand side of the equation. That is why we have the minus sign here. function jouleheat!(y, u, edge, data) y[iT] = -κ(y[iT]) * (u[iϕ, 1] - u[iϕ, 2]) * (u[iϕ, 1] - u[iϕ, 2]) + return nothing end function bcondition!(y, u, node, data) @@ -86,28 +91,33 @@ function main(; nref = 0, Plotter = nothing, verbose = "and", unknown_storage = boundary_robin!(y, u, node; species = iT, region = 2, value = T0, factor = 0.5) boundary_robin!(y, u, node; species = iT, region = 3, value = T0, factor = 0.5) boundary_robin!(y, u, node; species = iT, region = 4, value = T0, factor = 0.5) + return nothing end - sys = VoronoiFVM.System(grid; bcondition = bcondition!, flux = flux!, - edgereaction = jouleheat!, storage = storage!, - species = [iϕ, iT], assembly = assembly) - - sol = solve(sys; verbose, - method_linear = KrylovJL_BICGSTAB(precs=LinearSolvePreconBuilder(UMFPACKFactorization())), - keepcurrent_linear =false - ) + sys = VoronoiFVM.System( + grid; bcondition = bcondition!, flux = flux!, + edgereaction = jouleheat!, storage = storage!, + species = [iϕ, iT], assembly = assembly + ) + + sol = solve( + sys; verbose, + method_linear = KrylovJL_BICGSTAB(precs = LinearSolvePreconBuilder(UMFPACKFactorization())), + keepcurrent_linear = false + ) vis = GridVisualizer(; Plotter, layout = (2, 1)) scalarplot!(vis[1, 1], grid, sol[iϕ, :]; title = "ϕ", colormap = :bwr) scalarplot!(vis[2, 1], grid, sol[iT, :]; title = "T", colormap = :hot) reveal(vis) - norm(sol, Inf) + return norm(sol, Inf) end using Test function runtests() testval = 24.639120035942938 @test main(; assembly = :edgewise) ≈ testval && - main(; assembly = :cellwise) ≈ testval + main(; assembly = :cellwise) ≈ testval + return nothing end end diff --git a/examples/Example207_NonlinearPoisson2D.jl b/examples/Example207_NonlinearPoisson2D.jl index e70e03168..07081f35a 100644 --- a/examples/Example207_NonlinearPoisson2D.jl +++ b/examples/Example207_NonlinearPoisson2D.jl @@ -11,8 +11,10 @@ using GridVisualize using LinearSolve using ILUZero -function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :sparse, - method_linear = nothing, assembly = :edgewise) +function main(; + n = 10, Plotter = nothing, verbose = false, unknown_storage = :sparse, + method_linear = nothing, assembly = :edgewise + ) h = 1.0 / convert(Float64, n) X = collect(0.0:h:1.0) Y = collect(0.0:h:1.0) @@ -21,17 +23,23 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s eps = 1.0e-2 - physics = VoronoiFVM.Physics(; reaction = function (f, u, node, data) - f[1] = u[1]^2 - end, flux = function (f, u, edge, data) - f[1] = eps * (u[1, 1]^2 - u[1, 2]^2) - end, source = function (f, node, data) - x1 = node[1] - 0.5 - x2 = node[2] - 0.5 - f[1] = exp(-20.0 * (x1^2 + x2^2)) - end, storage = function (f, u, node, data) - f[1] = u[1] - end) + physics = VoronoiFVM.Physics(; + reaction = function (f, u, node, data) + f[1] = u[1]^2 + return nothing + end, flux = function (f, u, edge, data) + f[1] = eps * (u[1, 1]^2 - u[1, 2]^2) + return nothing + end, source = function (f, node, data) + x1 = node[1] - 0.5 + x2 = node[2] - 0.5 + f[1] = exp(-20.0 * (x1^2 + x2^2)) + return nothing + end, storage = function (f, u, node, data) + f[1] = u[1] + return nothing + end + ) sys = VoronoiFVM.System(grid, physics; unknown_storage, assembly = assembly) enable_species!(sys, 1, [1]) @@ -66,16 +74,25 @@ function runtests() # test at once for iterative solution here testval = 0.3554284760906605 @test main(; unknown_storage = :sparse, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :sparse, method_linear = KrylovJL_CG(precs=ILUZeroPreconBuilder()), - assembly = :edgewise) ≈ testval && - main(; unknown_storage = :dense, method_linear = KrylovJL_CG(precs=ILUZeroPreconBuilder()), - assembly = :edgewise) ≈ testval && - main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && - main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval && - main(; unknown_storage = :sparse, method_linear = KrylovJL_CG(precs=ILUZeroPreconBuilder()), - assembly = :cellwise) ≈ testval && - main(; unknown_storage = :dense, method_linear = KrylovJL_CG(precs=ILUZeroPreconBuilder()), - assembly = :cellwise) ≈ testval + main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && + main(; + unknown_storage = :sparse, method_linear = KrylovJL_CG(precs = ILUZeroPreconBuilder()), + assembly = :edgewise + ) ≈ testval && + main(; + unknown_storage = :dense, method_linear = KrylovJL_CG(precs = ILUZeroPreconBuilder()), + assembly = :edgewise + ) ≈ testval && + main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && + main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval && + main(; + unknown_storage = :sparse, method_linear = KrylovJL_CG(precs = ILUZeroPreconBuilder()), + assembly = :cellwise + ) ≈ testval && + main(; + unknown_storage = :dense, method_linear = KrylovJL_CG(precs = ILUZeroPreconBuilder()), + assembly = :cellwise + ) ≈ testval + return nothing end end diff --git a/examples/Example210_NonlinearPoisson2D_Reaction.jl b/examples/Example210_NonlinearPoisson2D_Reaction.jl index 7fcbac7d8..3d23504ee 100644 --- a/examples/Example210_NonlinearPoisson2D_Reaction.jl +++ b/examples/Example210_NonlinearPoisson2D_Reaction.jl @@ -16,36 +16,42 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s grid = simplexgrid(X, Y) - grid=partition(grid, PlainMetisPartitioning(npart=10)) + grid = partition(grid, PlainMetisPartitioning(npart = 10)) @show grid data = (eps = 1.0e-2, k = 1.0) function reaction!(f, u, node, data) f[1] = data.k * (u[1] - u[2]) f[2] = data.k * (u[2] - u[1]) + return nothing end function flux!(f, u, edge, data) f[1] = data.eps * (u[1, 1] - u[1, 2]) f[2] = data.eps * (u[2, 1] - u[2, 2]) + return nothing end function source!(f, node, data) x1 = node[1] - 0.5 x2 = node[2] - 0.5 f[1] = exp(-20 * (x1^2 + x2^2)) + return nothing end function storage!(f, u, node, data) f[1] = u[1] f[2] = u[2] + return nothing end - physics = VoronoiFVM.Physics(; data = data, - flux = flux!, - storage = storage!, - reaction = reaction!, - source = source!) + physics = VoronoiFVM.Physics(; + data = data, + flux = flux!, + storage = storage!, + reaction = reaction!, + source = source! + ) sys = VoronoiFVM.System(grid, physics; unknown_storage = unknown_storage, assembly = assembly) @@ -60,17 +66,17 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s tstep = 0.01 time = 0.0 istep = 0 - testval=0 + testval = 0 p = GridVisualizer(; Plotter = Plotter, layout = (2, 1)) @time while time < 1 time = time + tstep U = solve(sys; inival, control, tstep) inival .= U - testval=sum(U) + testval = sum(U) tstep *= 1.0 istep = istep + 1 - scalarplot!(p[1, 1], grid, U[1, :]; clear = true, limits=(0,0.5)) - scalarplot!(p[2, 1], grid, U[2, :]; show = true, limits=(0,0.5)) + scalarplot!(p[1, 1], grid, U[1, :]; clear = true, limits = (0, 0.5)) + scalarplot!(p[2, 1], grid, U[2, :]; show = true, limits = (0, 0.5)) end return testval end @@ -79,9 +85,10 @@ using Test function runtests() testval = 16.01812472041518 @test main(; unknown_storage = :sparse, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && - main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && + main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && + main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + return nothing end end diff --git a/examples/Example215_NonlinearPoisson2D_BoundaryReaction.jl b/examples/Example215_NonlinearPoisson2D_BoundaryReaction.jl index dd3a5fe7d..2030fd044 100644 --- a/examples/Example215_NonlinearPoisson2D_BoundaryReaction.jl +++ b/examples/Example215_NonlinearPoisson2D_BoundaryReaction.jl @@ -9,8 +9,10 @@ using ExtendableGrids using GridVisualize using ExtendableSparse -function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :sparse, assembly = :edgewise, - tend = 100) +function main(; + n = 10, Plotter = nothing, verbose = false, unknown_storage = :sparse, assembly = :edgewise, + tend = 100 + ) h = 1.0 / convert(Float64, n) X = collect(0.0:h:1.0) Y = collect(0.0:h:1.0) @@ -18,21 +20,26 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s grid = simplexgrid(X, Y) eps = 1.0e-2 - physics = VoronoiFVM.Physics(; breaction = function (f, u, node, data) - if node.region == 2 - f[1] = 1 * (u[1] - u[2]) - f[2] = 1 * (u[2] - u[1]) - else - f[1] = 0 - f[2] = 0 - end - end, flux = function (f, u, edge, data) - f[1] = eps * (u[1, 1] - u[1, 2]) - f[2] = eps * (u[2, 1] - u[2, 2]) - end, storage = function (f, u, node, data) - f[1] = u[1] - f[2] = u[2] - end) + physics = VoronoiFVM.Physics(; + breaction = function (f, u, node, data) + if node.region == 2 + f[1] = 1 * (u[1] - u[2]) + f[2] = 1 * (u[2] - u[1]) + else + f[1] = 0 + f[2] = 0 + end + return nothing + end, flux = function (f, u, edge, data) + f[1] = eps * (u[1, 1] - u[1, 2]) + f[2] = eps * (u[2, 1] - u[2, 2]) + return nothing + end, storage = function (f, u, node, data) + f[1] = u[1] + f[2] = u[2] + return nothing + end + ) sys = VoronoiFVM.System(grid, physics; unknown_storage = unknown_storage, assembly = assembly) enable_species!(sys, 1, [1]) @@ -64,11 +71,15 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s tstep *= 1.2 istep = istep + 1 u25 = U[25] - scalarplot!(p[1, 1], grid, U[1, :]; - title = @sprintf("U1: %.3g U1+U2:%8.3g", I[1, 1], Uall), - flimits = (0, 1)) - scalarplot!(p[2, 1], grid, U[2, :]; title = @sprintf("U2: %.3g", I[2, 1]), - flimits = (0, 1)) + scalarplot!( + p[1, 1], grid, U[1, :]; + title = @sprintf("U1: %.3g U1+U2:%8.3g", I[1, 1], Uall), + flimits = (0, 1) + ) + scalarplot!( + p[2, 1], grid, U[2, :]; title = @sprintf("U2: %.3g", I[2, 1]), + flimits = (0, 1) + ) reveal(p) end return u25 @@ -78,7 +89,8 @@ using Test function runtests() testval = 0.2760603343272377 @test main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && - main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && + main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + return nothing end end diff --git a/examples/Example220_NonlinearPoisson2D_BoundarySpecies.jl b/examples/Example220_NonlinearPoisson2D_BoundarySpecies.jl index 0d556beb0..00b6e9cd7 100644 --- a/examples/Example220_NonlinearPoisson2D_BoundarySpecies.jl +++ b/examples/Example220_NonlinearPoisson2D_BoundarySpecies.jl @@ -18,27 +18,33 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s k = 1.0 eps::Float64 = 1.0 physics = VoronoiFVM.Physics(; - breaction = function (f, u, node, data) - if node.region == 2 - f[1] = k * (u[1] - u[3]) - f[3] = k * (u[3] - u[1]) + k * (u[3] - u[2]) - f[2] = k * (u[2] - u[3]) - end - end, bstorage = function (f, u, node, data) - if node.region == 2 - f[3] = u[3] - end - end, flux = function (f, u, edge, data) - f[1] = eps * (u[1, 1] - u[1, 2]) - f[2] = eps * (u[2, 1] - u[2, 2]) - end, source = function (f, node, data) - x1 = node[1] - 0.5 - x2 = node[2] - 0.5 - f[1] = exp(-20.0 * (x1^2 + x2^2)) - end, storage = function (f, u, node, data) - f[1] = u[1] - f[2] = u[2] - end) + breaction = function (f, u, node, data) + if node.region == 2 + f[1] = k * (u[1] - u[3]) + f[3] = k * (u[3] - u[1]) + k * (u[3] - u[2]) + f[2] = k * (u[2] - u[3]) + end + return nothing + end, bstorage = function (f, u, node, data) + if node.region == 2 + f[3] = u[3] + end + return nothing + end, flux = function (f, u, edge, data) + f[1] = eps * (u[1, 1] - u[1, 2]) + f[2] = eps * (u[2, 1] - u[2, 2]) + return nothing + end, source = function (f, node, data) + x1 = node[1] - 0.5 + x2 = node[2] - 0.5 + f[1] = exp(-20.0 * (x1^2 + x2^2)) + return nothing + end, storage = function (f, u, node, data) + f[1] = u[1] + f[2] = u[2] + return nothing + end + ) sys = VoronoiFVM.System(grid, physics; unknown_storage = unknown_storage) @@ -47,7 +53,7 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s enable_boundary_species!(sys, 3, [2]) function tran32!(a, b) - a[1] = b[2] + return a[1] = b[2] end bgrid2 = subgrid(grid, [2]; boundary = true, transform = tran32!) @@ -88,5 +94,6 @@ using Test function runtests() @test main(; unknown_storage = :sparse) ≈ 0.0020781361856598 main(; unknown_storage = :dense) ≈ 0.0020781361856598 + return nothing end end diff --git a/examples/Example221_EquationBlockPrecon.jl b/examples/Example221_EquationBlockPrecon.jl index 552f20a64..030680342 100644 --- a/examples/Example221_EquationBlockPrecon.jl +++ b/examples/Example221_EquationBlockPrecon.jl @@ -11,36 +11,38 @@ using VoronoiFVM, GridVisualize, ExtendableGrids, Printf using AMGCLWrap, ExtendableSparse using Test -function main(;dim=1, nref=0, Plotter = nothing, plot_grid = false, verbose = false, - unknown_storage = :sparse, assembly = :edgewise,strategy = nothing) - - nx=30*2^nref+1 - ny=9*2^nref - - X = range(0,3,length=nx) - Y = range(-0.5,0.5,length=ny) - if dim==1 +function main(; + dim = 1, nref = 0, Plotter = nothing, plot_grid = false, verbose = false, + unknown_storage = :sparse, assembly = :edgewise, strategy = nothing + ) + + nx = 30 * 2^nref + 1 + ny = 9 * 2^nref + + X = range(0, 3, length = nx) + Y = range(-0.5, 0.5, length = ny) + if dim == 1 grid = simplexgrid(X) - Γ_in=1 - Γ_out=2 - elseif dim==2 - grid = simplexgrid(X,Y) - Γ_in=4 - Γ_out=2 + Γ_in = 1 + Γ_out = 2 + elseif dim == 2 + grid = simplexgrid(X, Y) + Γ_in = 4 + Γ_out = 2 else - grid = simplexgrid(X,Y,Y) - Γ_in=4 - Γ_out=2 + grid = simplexgrid(X, Y, Y) + Γ_in = 4 + Γ_out = 2 end - cellmask!(grid, [0.0,-0.5,-0.5], [1.0,0.5,0.5], 1) - cellmask!(grid, [1.0,-0.5,-0.5], [2.0,0.5,0.5], 2) - cellmask!(grid, [2.0,-0.5,-0.5], [3.0,0.5,0.5], 3) + cellmask!(grid, [0.0, -0.5, -0.5], [1.0, 0.5, 0.5], 1) + cellmask!(grid, [1.0, -0.5, -0.5], [2.0, 0.5, 0.5], 2) + cellmask!(grid, [2.0, -0.5, -0.5], [3.0, 0.5, 0.5], 3) + - subgrid1 = subgrid(grid, [1]) subgrid2 = subgrid(grid, [1, 2, 3]) subgrid3 = subgrid(grid, [3]) - + if plot_grid return gridplot(grid; Plotter = Plotter) end @@ -58,12 +60,14 @@ function main(;dim=1, nref=0, Plotter = nothing, plot_grid = false, verbose = fa else f[1] = 0 end + return nothing end function source(f, node, data) if node.region == 1 f[1] = 1.0e-4 * (3.0 - node[1]) end + return nothing end flux = function (f, u, edge, data) @@ -76,6 +80,7 @@ function main(;dim=1, nref=0, Plotter = nothing, plot_grid = false, verbose = fa f[2] = eps[2] * (u[2, 1] - u[2, 2]) f[3] = eps[3] * (u[3, 1] - u[3, 2]) end + return nothing end storage = function (f, u, node, data) @@ -88,10 +93,13 @@ function main(;dim=1, nref=0, Plotter = nothing, plot_grid = false, verbose = fa f[2] = u[2] f[3] = u[3] end + return nothing end - sys = VoronoiFVM.System(grid; flux, reaction, storage, source, - unknown_storage , assembly, is_linear=true) + sys = VoronoiFVM.System( + grid; flux, reaction, storage, source, + unknown_storage, assembly, is_linear = true + ) enable_species!(sys, 1, [1]) enable_species!(sys, 2, [1, 2, 3]) @@ -100,13 +108,15 @@ function main(;dim=1, nref=0, Plotter = nothing, plot_grid = false, verbose = fa boundary_dirichlet!(sys, 3, 2, 0.0) control = SolverControl(strategy, sys) - U=solve(sys;control) + U = solve(sys; control) @info num_dof(U) - p = GridVisualizer(; Plotter = Plotter, layout = (3,1), - limits = (0, 1e-3), - xlimits=(0,3)) - + p = GridVisualizer(; + Plotter = Plotter, layout = (3, 1), + limits = (0, 1.0e-3), + xlimits = (0, 3) + ) + U1 = view(U[1, :], subgrid1) U2 = view(U[2, :], subgrid2) U3 = view(U[3, :], subgrid3) @@ -115,17 +125,18 @@ function main(;dim=1, nref=0, Plotter = nothing, plot_grid = false, verbose = fa scalarplot!(p[2, 1], subgrid2, U2; title = "spec2", color = :green) scalarplot!(p[3, 1], subgrid3, U3; title = "spec3", color = :navyblue) reveal(p) - U + return U end function runtests() - strategy=BICGstabIteration(AMGCL_AMGPreconditioner()) - @test sum(main(;dim=1,strategy, unknown_storage=:dense)[2,:]) ≈ 0.014101758266210086 - @test sum(main(;dim=1,strategy, unknown_storage=:sparse)[2,:]) ≈ 0.014101758266210086 - @test sum(main(;dim=2,strategy, unknown_storage=:dense)[2,:]) ≈ 0.12691582439590407 - @test sum(main(;dim=2,strategy, unknown_storage=:sparse)[2,:]) ≈ 0.12691582439590407 - @test sum(main(;dim=3,strategy, unknown_storage=:dense)[2,:]) ≈ 1.1422561017685693 - @test sum(main(;dim=3,strategy, unknown_storage=:sparse)[2,:]) ≈ 1.1422561017685693 + strategy = BICGstabIteration(AMGCL_AMGPreconditioner()) + @test sum(main(; dim = 1, strategy, unknown_storage = :dense)[2, :]) ≈ 0.014101758266210086 + @test sum(main(; dim = 1, strategy, unknown_storage = :sparse)[2, :]) ≈ 0.014101758266210086 + @test sum(main(; dim = 2, strategy, unknown_storage = :dense)[2, :]) ≈ 0.12691582439590407 + @test sum(main(; dim = 2, strategy, unknown_storage = :sparse)[2, :]) ≈ 0.12691582439590407 + @test sum(main(; dim = 3, strategy, unknown_storage = :dense)[2, :]) ≈ 1.1422561017685693 + @test sum(main(; dim = 3, strategy, unknown_storage = :sparse)[2, :]) ≈ 1.1422561017685693 + return nothing end end diff --git a/examples/Example225_TestFunctions2D.jl b/examples/Example225_TestFunctions2D.jl index f7c8f3ace..5588909c4 100644 --- a/examples/Example225_TestFunctions2D.jl +++ b/examples/Example225_TestFunctions2D.jl @@ -108,8 +108,10 @@ module Example225_TestFunctions2D using VoronoiFVM, GridVisualize, ExtendableGrids -function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :sparse, assembly = :edgewise, - dim = 2, tend = 5, dt = 0.2) +function main(; + n = 10, Plotter = nothing, verbose = false, unknown_storage = :sparse, assembly = :edgewise, + dim = 2, tend = 5, dt = 0.2 + ) n = [101, 21, 5] X = collect(range(0.0, 1; length = n[dim])) if dim == 1 @@ -128,11 +130,13 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s function storage(f, u, node, data) f .= u + return nothing end function flux(f, u, edge, data) f[1] = u[1, 1] - u[1, 2] f[2] = u[2, 1] - u[2, 2] + return nothing end r(u1, u2) = u1 - 0.1 * u2 @@ -140,16 +144,20 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s function reaction(f, u, node, data) f[1] = r(u[1], u[2]) f[2] = -r(u[1], u[2]) + return nothing end function source(f, node, data) f[1] = 1.0 + return nothing end - physics = VoronoiFVM.Physics(; flux = flux, - storage = storage, - reaction = reaction, - source = source) + physics = VoronoiFVM.Physics(; + flux = flux, + storage = storage, + reaction = reaction, + source = source + ) system = VoronoiFVM.System(grid, physics; assembly = assembly) @@ -159,8 +167,10 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s sol = solve(system; inival = 0.0) - vis = GridVisualizer(; Plotter = Plotter, layout = (1, 2), resolution = (600, 300), - fignumber = 1) + vis = GridVisualizer(; + Plotter = Plotter, layout = (1, 2), resolution = (600, 300), + fignumber = 1 + ) scalarplot!(vis[1, 1], grid, sol[1, :]; flimits = (0, 1.5), title = "u_1") scalarplot!(vis[1, 2], grid, sol[2, :]; flimits = (0, 1.5), title = "u_2", show = true) @@ -197,28 +207,32 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s tsol = solve(system; inival = 0.0, times = [t0, tend], control) - vis1 = GridVisualizer(; Plotter = Plotter, layout = (1, 2), resolution = (600, 300), - fignumber = 4) + vis1 = GridVisualizer(; + Plotter = Plotter, layout = (1, 2), resolution = (600, 300), + fignumber = 4 + ) - for i = 1:length(tsol) + for i in 1:length(tsol) sol = tsol.u[i] scalarplot!(vis1[1, 1], grid, sol[1, :]; flimits = (0, 1.5), clear = true) scalarplot!(vis1[1, 2], grid, sol[2, :]; flimits = (0, 1.5), show = true) end outflow_rate = Float64[] - for i = 2:length(tsol) + for i in 2:length(tsol) ofr = integrate(system, T, tsol.u[i], tsol.u[i - 1], tsol.t[i] - tsol.t[i - 1]) push!(outflow_rate, ofr[2]) end - vis2 = GridVisualizer(; Plotter = Plotter, layout = (1, 1), resolution = (600, 300), - fignumber = 2) + vis2 = GridVisualizer(; + Plotter = Plotter, layout = (1, 1), resolution = (600, 300), + fignumber = 2 + ) scalarplot!(vis2[1, 1], [0, tend], -[I[2], I[2]]; label = "stationary", clear = true) scalarplot!(vis2[1, 1], tsol.t[2:end], -outflow_rate; label = "transient", show = true) all_outflow = 0.0 - for i = 1:(length(tsol) - 1) + for i in 1:(length(tsol) - 1) all_outflow -= outflow_rate[i] * (tsol.t[i + 1] - tsol.t[i]) end @@ -226,8 +240,8 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s isapprox(F[1], R[1]; rtol = 1.0e-12) ? true : return false isapprox(I[1], 0.0; atol = 1.0e-12) ? true : return false isapprox(R[2], I[2]; rtol = 1.0e-12) ? true : return false - isapprox(F[1] * (tend - t0), (Uend[1] + Uend[2] + all_outflow); rtol = 1.0e-12) ? true : - return false + return isapprox(F[1] * (tend - t0), (Uend[1] + Uend[2] + all_outflow); rtol = 1.0e-12) ? true : + return false end using Test @@ -245,6 +259,7 @@ function runtests() @test main(; dim = 2, unknown_storage = :dense, assembly = :cellwise) @test main(; dim = 3, unknown_storage = :sparse, assembly = :cellwise) @test main(; dim = 3, unknown_storage = :dense, assembly = :cellwise) + return nothing end end diff --git a/examples/Example226_BoundaryIntegral.jl b/examples/Example226_BoundaryIntegral.jl index 428e25baa..9d4997f29 100644 --- a/examples/Example226_BoundaryIntegral.jl +++ b/examples/Example226_BoundaryIntegral.jl @@ -9,8 +9,10 @@ module Example226_BoundaryIntegral using VoronoiFVM, GridVisualize, ExtendableGrids -function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :sparse, - dim = 2, assembly = :edgewise) +function main(; + n = 10, Plotter = nothing, verbose = false, unknown_storage = :sparse, + dim = 2, assembly = :edgewise + ) n = [101, 21, 5] X = collect(range(0.0, 1; length = n[dim])) if dim == 1 @@ -29,21 +31,26 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s function storage(f, u, node, data) f .= u + return nothing end function flux(f, u, edge, data) f[1] = u[1, 1] - u[1, 2] + return nothing end function breaction(f, u, node, data) if node.region == Γ_where_T_equal_1[1] f[1] = u[1]^2 end + return nothing end - physics = VoronoiFVM.Physics(; flux = flux, - storage = storage, - breaction = breaction) + physics = VoronoiFVM.Physics(; + flux = flux, + storage = storage, + breaction = breaction + ) system = VoronoiFVM.System(grid, physics; assembly = assembly) enable_species!(system, 1, [1]) @@ -57,7 +64,7 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s scalarplot(grid, U[1, :]; Plotter = Plotter, zplane = 0.50001) I = integrate(system, T, U) B = integrate(system, breaction, U; boundary = true) - isapprox(-I[1], B[Γ_where_T_equal_1[1]]; rtol = 1.0e-12) + return isapprox(-I[1], B[Γ_where_T_equal_1[1]]; rtol = 1.0e-12) end using Test @@ -75,6 +82,7 @@ function runtests() @test main(; dim = 2, unknown_storage = :dense, assembly = :cellwise) @test main(; dim = 3, unknown_storage = :sparse, assembly = :cellwise) @test main(; dim = 3, unknown_storage = :dense, assembly = :cellwise) + return nothing end end diff --git a/examples/Example230_BoundaryFlux.jl b/examples/Example230_BoundaryFlux.jl index 4983cd548..d391922c2 100644 --- a/examples/Example230_BoundaryFlux.jl +++ b/examples/Example230_BoundaryFlux.jl @@ -29,11 +29,13 @@ using VoronoiFVM using ExtendableGrids using GridVisualize -function main(; n = 2 * 10, # n musst be an even number - d1 = 5.0, db = 5.0, # prefactors (before diffusive part) - kmax = 2.0, cmax = 3.0, - Plotter = nothing, - unknown_storage = :sparse, assembly = :edgewise) +function main(; + n = 2 * 10, # n musst be an even number + d1 = 5.0, db = 5.0, # prefactors (before diffusive part) + kmax = 2.0, cmax = 3.0, + Plotter = nothing, + unknown_storage = :sparse, assembly = :edgewise + ) ########################################################################### ###################### 1D problem ###################### @@ -60,31 +62,42 @@ function main(; n = 2 * 10, # n musst be an even number function flux!(f, u, edge, data) f[1] = d1 * (u[1, 1] - u[1, 2]) + return nothing end function reaction!(f, u, node, data) f[1] = k1[node.index] * u[1] + return nothing end function source!(f, node::VoronoiFVM.Node, data) f[1] = c1[node.index] + return nothing end - sys_1D = VoronoiFVM.System(grid_1D, - VoronoiFVM.Physics(; flux = flux!, reaction = reaction!, - source = source!)) + sys_1D = VoronoiFVM.System( + grid_1D, + VoronoiFVM.Physics(; + flux = flux!, reaction = reaction!, + source = source! + ) + ) - # enable species in only region + # enable species in only region enable_species!(sys_1D, ispec_1D, [bulk_1D]) ## Stationary solution of both problems sol_1D = solve(sys_1D; inival = 0) - p = GridVisualizer(; Plotter = Plotter, layout = (2, 1), clear = true, - resolution = (800, 500)) + p = GridVisualizer(; + Plotter = Plotter, layout = (2, 1), clear = true, + resolution = (800, 500) + ) - scalarplot!(p[1, 1], grid_1D, sol_1D[1, :]; show = true, - title = "1D calculation (d1 = $d1, kmax = $kmax, cmax = $cmax)") + scalarplot!( + p[1, 1], grid_1D, sol_1D[1, :]; show = true, + title = "1D calculation (d1 = $d1, kmax = $kmax, cmax = $cmax)" + ) ########################################################################### ###################### 2D problem ###################### @@ -105,14 +118,17 @@ function main(; n = 2 * 10, # n musst be an even number #### discretization functions for bulk species #### function flux2D!(f, u, edge, data) f[ispec_2D] = d2 * (u[ispec_2D, 1] - u[ispec_2D, 2]) + return nothing end function reaction2D!(f, u, node, data) f[ispec_2D] = k2 * u[ispec_2D] + return nothing end function source2D!(f, node, data) f[ispec_2D] = c2 + return nothing end #### discretization functions for boundary species at active boundary #### @@ -120,6 +136,7 @@ function main(; n = 2 * 10, # n musst be an even number if bedge.region == active_boundary f[ispec_boundary] = db * (u[ispec_boundary, 1] - u[ispec_boundary, 2]) end + return nothing end function breaction!(f, u, bnode, data) @@ -132,6 +149,7 @@ function main(; n = 2 * 10, # n musst be an even number f[ispec_boundary] = kb * u[ispec_boundary] end + return nothing end function bsource!(f, bnode, data) @@ -144,16 +162,21 @@ function main(; n = 2 * 10, # n musst be an even number f[ispec_boundary] = cb end + return nothing end - sys_2D = VoronoiFVM.System(grid_2D, - VoronoiFVM.Physics(; flux = flux2D!, reaction = reaction2D!, - source = source2D!, - bflux = bflux!, breaction = breaction!, - bsource = bsource!); - unknown_storage = unknown_storage, assembly = assembly) - - # enable species in only region + sys_2D = VoronoiFVM.System( + grid_2D, + VoronoiFVM.Physics(; + flux = flux2D!, reaction = reaction2D!, + source = source2D!, + bflux = bflux!, breaction = breaction!, + bsource = bsource! + ); + unknown_storage = unknown_storage, assembly = assembly + ) + + # enable species in only region enable_species!(sys_2D, ispec_2D, [bulk_2D]) enable_boundary_species!(sys_2D, ispec_boundary, [active_boundary]) @@ -162,14 +185,17 @@ function main(; n = 2 * 10, # n musst be an even number # this is for variable transformation, since we consider right outer boundary and want to transform to x-axis. function tran32!(a, b) a[1] = b[2] + return nothing end # note that if adjusting active_boundary to 3 or 4, then transform needs to be deleted. bgrid_2D = subgrid(grid_2D, [active_boundary]; boundary = true, transform = tran32!) sol_bound = view(sol_2D[ispec_boundary, :], bgrid_2D) - scalarplot!(p[2, 1], bgrid_2D, sol_bound; show = true, cellwise = true, - title = "Active boundary in 2D (db = $db, kb = $kmax, cb = $cmax)") + scalarplot!( + p[2, 1], bgrid_2D, sol_bound; show = true, cellwise = true, + title = "Active boundary in 2D (db = $db, kb = $kmax, cb = $cmax)" + ) errorsol = VoronoiFVM.norm(sys_1D, sol_bound - sol_1D', 2) @@ -179,9 +205,10 @@ end # main using Test function runtests() @test main(; unknown_storage = :dense, assembly = :edgewise) < 1.0e-14 && - main(; unknown_storage = :sparse, assembly = :edgewise) < 1.0e-14 && - main(; unknown_storage = :dense, assembly = :cellwise) < 1.0e-14 && - main(; unknown_storage = :sparse, assembly = :cellwise) < 1.0e-14 + main(; unknown_storage = :sparse, assembly = :edgewise) < 1.0e-14 && + main(; unknown_storage = :dense, assembly = :cellwise) < 1.0e-14 && + main(; unknown_storage = :sparse, assembly = :cellwise) < 1.0e-14 + return nothing end end # module diff --git a/examples/Example240_FiniteElementVelocities.jl b/examples/Example240_FiniteElementVelocities.jl index a666e879c..ba780562f 100644 --- a/examples/Example240_FiniteElementVelocities.jl +++ b/examples/Example240_FiniteElementVelocities.jl @@ -38,7 +38,7 @@ function stagnation_flow_cartesian(x, y) end # In the cylindrical case: since the reconstruction space $\mathtt{HDIVBDM2}$ -# is only quadratic, but we have to reconstruct $r \, \mathbf{v}(r,z)$ for a +# is only quadratic, but we have to reconstruct $r \, \mathbf{v}(r,z)$ for a # (reconstructed) divergence-free solution, # we can only resolve at most the linear case exactly. function stagnation_flow_cylindrical(r, z) @@ -48,11 +48,13 @@ end function inflow_cylindrical(u, qpinfo) x = qpinfo.x u .= stagnation_flow_cylindrical(x[1], x[2]) + return nothing end function inflow_cartesian(u, qpinfo) x = qpinfo.x u .= stagnation_flow_cartesian(x[1], x[2]) + return nothing end function flux!(f, u, edge, data) @@ -60,6 +62,7 @@ function flux!(f, u, edge, data) bp = fbernoulli(vd) bm = fbernoulli(-vd) f[1] = data.D * (bp * u[1] - bm * u[2]) + return nothing end function bconditions!(f, u, node, data) @@ -77,6 +80,7 @@ function bconditions!(f, u, node, data) if node.region == 3 boundary_dirichlet!(f, u, node, 1, node.region, data.cin) end + return nothing end mutable struct Data @@ -110,8 +114,9 @@ The passed flags regulate the following behavior: =# function main(; cylindrical_grid = false, usefem = true, reconst = cylindrical_grid, use_different_grids = false, nref = 1, - Plotter = nothing, μ = 1.0e-02, D = 0.01, cin = 1.0, assembly = :edgewise, - interpolation_eps = 1.0e-09) + Plotter = nothing, μ = 1.0e-2, D = 0.01, cin = 1.0, assembly = :edgewise, + interpolation_eps = 1.0e-9 + ) H = 1.0 L = 5.0 @@ -121,15 +126,19 @@ function main(; coord_system = Cartesian2D end - flowgrid = simplexgrid(range(0, L; length = 20 * 2^nref), - range(0, H; length = 5 * 2^nref)) + flowgrid = simplexgrid( + range(0, L; length = 20 * 2^nref), + range(0, H; length = 5 * 2^nref) + ) if use_different_grids - h_fine = 1.0e-01 - X_bottom = geomspace(0.0, L / 2, 5.0e-01, h_fine) + h_fine = 1.0e-1 + X_bottom = geomspace(0.0, L / 2, 5.0e-1, h_fine) X_cat = range(L / 2, L; step = h_fine) - chemgrid = simplexgrid([X_bottom; X_cat[2:end]], - geomspace(0.0, H, 1.0e-03, 1.0e-01)) + chemgrid = simplexgrid( + [X_bottom; X_cat[2:end]], + geomspace(0.0, H, 1.0e-3, 1.0e-1) + ) bfacemask!(chemgrid, [L / 2, 0.0], [3 * L / 4, 0.0], 5) else chemgrid = deepcopy(flowgrid) @@ -138,7 +147,8 @@ function main(; if usefem velocity = compute_velocity( - flowgrid, cylindrical_grid, reconst, μ; interpolation_eps) + flowgrid, cylindrical_grid, reconst, μ; interpolation_eps + ) DivIntegrator = L2NormIntegrator([div(1)]; quadorder = 2 * 2, resultdim = 1) div_v = sqrt(sum(evaluate(DivIntegrator, [velocity]))) @info "||div(R(v))||_2 = $(div_v)" @@ -160,7 +170,7 @@ function main(; ## since the velocity calculation works by adjusting ## the kernels for the Stokes operator directly while ## the finite volume machinery relies upon the CoordinateSystem - ## for selecting the correct geometrical factors for the + ## for selecting the correct geometrical factors for the ## Voronoi cell contributions if cylindrical_grid chemgrid[CoordinateSystem] = Cylindrical2D @@ -187,8 +197,10 @@ function main(; vis = GridVisualizer(; Plotter = Plotter) - scalarplot!(vis[1, 1], chemgrid, sol[1, :]; flimits = (0, cin + 1.0e-5), - show = true) + scalarplot!( + vis[1, 1], chemgrid, sol[1, :]; flimits = (0, cin + 1.0e-5), + show = true + ) minmax = extrema(sol) @info "Minimal/maximal values of concentration: $(minmax)" @@ -201,19 +213,23 @@ function runtests() cin = 1.0 for cylindrical_grid in [false, true] sol_analytical, evelo_analytical, bfvelo_analytical, minmax_analytical = main(; - cylindrical_grid, cin, usefem = false) + cylindrical_grid, cin, usefem = false + ) sol_fem, evelo_fem, bfvelo_fem, minmax_fem = main(; - cylindrical_grid, cin, usefem = true) + cylindrical_grid, cin, usefem = true + ) @test norm(evelo_analytical .- evelo_fem, Inf) ≤ 1.0e-11 - @test norm(bfvelo_analytical .- bfvelo_fem, Inf) ≤ 1.0e-09 + @test norm(bfvelo_analytical .- bfvelo_fem, Inf) ≤ 1.0e-9 @test norm(sol_analytical .- sol_fem, Inf) ≤ 1.0e-10 - @test norm(minmax_analytical .- [0.,cin], Inf) ≤ 1.0e-15 - @test norm(minmax_fem .- [0.,cin], Inf) ≤ 1.0e-11 + @test norm(minmax_analytical .- [0.0, cin], Inf) ≤ 1.0e-15 + @test norm(minmax_fem .- [0.0, cin], Inf) ≤ 1.0e-11 end + return nothing end function compute_velocity( - flowgrid, cylindrical_grid, reconst, μ = 1.0e-02; interpolation_eps = 1.0e-10) + flowgrid, cylindrical_grid, reconst, μ = 1.0e-2; interpolation_eps = 1.0e-10 + ) ## define finite element spaces FE_v, FE_p = H1P2B{2, 2}, L2P1{1} reconst_FEType = HDIVBDM2{2} @@ -227,20 +243,25 @@ function compute_velocity( assign_unknown!(Problem, p) ## assign stokes operator - assign_operator!(Problem, + assign_operator!( + Problem, BilinearOperator( kernel_stokes!, cylindrical_grid ? [id(v), grad(v), id(p)] : [grad(v), id(p)]; bonus_quadorder = 2, store = false, - params = [μ, cylindrical_grid])) + params = [μ, cylindrical_grid] + ) + ) - ## assign Dirichlet boundary conditions on all boundary regions to + ## assign Dirichlet boundary conditions on all boundary regions to ## enforce match with analytical solution if cylindrical_grid assign_operator!( - Problem, InterpolateBoundaryData(v, inflow_cylindrical; regions = [1, 2, 3, 4])) + Problem, InterpolateBoundaryData(v, inflow_cylindrical; regions = [1, 2, 3, 4]) + ) else assign_operator!( - Problem, InterpolateBoundaryData(v, inflow_cartesian; regions = [1, 2, 3, 4])) + Problem, InterpolateBoundaryData(v, inflow_cartesian; regions = [1, 2, 3, 4]) + ) end velocity_solution = solve(Problem, FES) @@ -250,12 +271,15 @@ function compute_velocity( R = FEVector(FES_reconst) if reconst if cylindrical_grid - lazy_interpolate!(R[1], velocity_solution, [id(v)]; postprocess = multiply_r, - bonus_quadorder = 2, eps = interpolation_eps) + lazy_interpolate!( + R[1], velocity_solution, [id(v)]; postprocess = multiply_r, + bonus_quadorder = 2, eps = interpolation_eps + ) else lazy_interpolate!( R[1], velocity_solution, [id(v)]; - bonus_quadorder = 2, eps = interpolation_eps) + bonus_quadorder = 2, eps = interpolation_eps + ) end else return velocity_solution[1] diff --git a/examples/Example301_Laplace3D.jl b/examples/Example301_Laplace3D.jl index ff98fa1db..e06221b55 100644 --- a/examples/Example301_Laplace3D.jl +++ b/examples/Example301_Laplace3D.jl @@ -14,11 +14,13 @@ using GridVisualize ## between neighboring control volumes function g!(f, u, edge, data) f[1] = u[1, 1] - u[1, 2] + return nothing end function s(f, node, data) n = view(node.coord, :, node.index) f[1] = n[1] * sin(5.0 * n[2]) * exp(n[3]) + return nothing end function main(; Plotter = nothing, n = 5, assembly = :edgewise) @@ -42,7 +44,8 @@ using Test function runtests() testval = 0.012234524449380824 @test main(; assembly = :edgewise) ≈ testval && - main(; assembly = :cellwise) ≈ testval + main(; assembly = :cellwise) ≈ testval + return nothing end end diff --git a/examples/Example311_HeatEquation_BoundaryDiffusion.jl b/examples/Example311_HeatEquation_BoundaryDiffusion.jl index fae3907f7..de18a111a 100644 --- a/examples/Example311_HeatEquation_BoundaryDiffusion.jl +++ b/examples/Example311_HeatEquation_BoundaryDiffusion.jl @@ -38,37 +38,45 @@ function main(n = 1; assembly = :edgewise) eps = 1.0e0 # bulk heat conduction coefficient eps_surf = 1.0e-2 # surface diffusion coefficient k = 1.0 # transmission coefficient - physics = VoronoiFVM.Physics(; flux = function (f, u, edge, data) - f[1] = eps * (u[1, 1] - u[1, 2]) - end, - bflux = function (f, u, edge, data) - if edge.region == breg - f[2] = eps_surf * (u[2, 1] - u[2, 2]) - else - f[2] = 0.0 - end - end, - breaction = function (f, u, node, data) - if node.region == breg - f[1] = k * (u[1] - u[2]) - f[2] = k * (u[2] - u[1]) - else - f[1] = 0.0 - f[2] = 0.0 - end - end, - bsource = function (f, bnode, data) - x1 = bnode[1] - 0.5 - x2 = bnode[2] - 0.5 - x3 = bnode[3] - 0.5 - f[2] = 1.0e4 * exp(-20.0 * (x1^2 + x2^2 + x3^2)) - end, bstorage = function (f, u, node, data) - if node.region == breg - f[2] = u[2] - end - end, storage = function (f, u, node, data) - f[1] = u[1] - end) + physics = VoronoiFVM.Physics(; + flux = function (f, u, edge, data) + f[1] = eps * (u[1, 1] - u[1, 2]) + return nothing + end, + bflux = function (f, u, edge, data) + if edge.region == breg + f[2] = eps_surf * (u[2, 1] - u[2, 2]) + else + f[2] = 0.0 + end + return nothing + end, + breaction = function (f, u, node, data) + if node.region == breg + f[1] = k * (u[1] - u[2]) + f[2] = k * (u[2] - u[1]) + else + f[1] = 0.0 + f[2] = 0.0 + end + return nothing + end, + bsource = function (f, bnode, data) + x1 = bnode[1] - 0.5 + x2 = bnode[2] - 0.5 + x3 = bnode[3] - 0.5 + f[2] = 1.0e4 * exp(-20.0 * (x1^2 + x2^2 + x3^2)) + return nothing + end, bstorage = function (f, u, node, data) + if node.region == breg + f[2] = u[2] + end + return nothing + end, storage = function (f, u, node, data) + f[1] = u[1] + return nothing + end + ) sys = VoronoiFVM.System(grid, physics; unknown_storage = :sparse, assembly) enable_species!(sys, 1, [1]) @@ -76,6 +84,7 @@ function main(n = 1; assembly = :edgewise) function tran32!(a, b) a[1] = b[2] + return nothing end bgrid2 = subgrid(grid, [breg]; boundary = true, transform = tran32!) @@ -86,7 +95,7 @@ function main(n = 1; assembly = :edgewise) control = VoronoiFVM.NewtonControl() control.verbose = false control.reltol_linear = 1.0e-5 - control.keepcurrent_linear=false + control.keepcurrent_linear = false tstep = 0.1 time = 0.0 @@ -100,15 +109,16 @@ function main(n = 1; assembly = :edgewise) end U_surf = view(U[2, :], bgrid2) - sum(U_surf) + return sum(U_surf) end using Test function runtests() testval = 1509.8109057757858 testval = 1508.582565216869 - @test isapprox(main(; assembly = :edgewise), testval; rtol = 1.0e-12) + @test isapprox(main(; assembly = :edgewise), testval; rtol = 1.0e-12) @test isapprox(main(; assembly = :cellwise), testval; rtol = 1.0e-12) + return nothing end end diff --git a/examples/Example405_GenericOperator.jl b/examples/Example405_GenericOperator.jl index f525d9c85..373956f26 100644 --- a/examples/Example405_GenericOperator.jl +++ b/examples/Example405_GenericOperator.jl @@ -14,7 +14,7 @@ using ExtendableGrids using GridVisualize function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :sparse) - ## Same as Example102 with upwind + ## Same as Example102 with upwind ## Create a one-dimensional discretization h = 1.0 / convert(Float64, n) @@ -32,12 +32,13 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s ## using Symbolics.jl function generic_operator!(f, u, sys) f .= 0.0 - for i = 1:(length(X) - 1) + for i in 1:(length(X) - 1) du = D * (u[idx[1, i]] - u[idx[1, i + 1]]) / (X[i + 1] - X[i]) + - v * (v > 0 ? u[idx[1, i]] : u[idx[1, i + 1]]) + v * (v > 0 ? u[idx[1, i]] : u[idx[1, i + 1]]) f[idx[1, i]] += du f[idx[1, i + 1]] -= du end + return nothing end ## Create a physics structure @@ -66,8 +67,10 @@ function main(; n = 10, Plotter = nothing, verbose = false, unknown_storage = :s ## Stationary solution of the problem solution = solve(sys; inival = 0.5, verbose) - scalarplot(grid, solution[1, :]; title = "Nonlinear Poisson", Plotter = Plotter, - resolution = (300, 300)) + scalarplot( + grid, solution[1, :]; title = "Nonlinear Poisson", Plotter = Plotter, + resolution = (300, 300) + ) return sum(solution) end @@ -75,7 +78,8 @@ using Test function runtests() testval = 1.099999999614456 @test main(; unknown_storage = :sparse) ≈ testval && - main(; unknown_storage = :dense) ≈ testval + main(; unknown_storage = :dense) ≈ testval + return nothing end end diff --git a/examples/Example406_WeirdReaction.jl b/examples/Example406_WeirdReaction.jl index 97b12e3a6..9c91d2192 100644 --- a/examples/Example406_WeirdReaction.jl +++ b/examples/Example406_WeirdReaction.jl @@ -51,12 +51,14 @@ using SparseArrays using ExtendableGrids using GridVisualize -function main(; n = 10, - Plotter = nothing, - verbose = false, - tend = 1, - unknown_storage = :sparse, - autodetect_sparsity = true) +function main(; + n = 10, + Plotter = nothing, + verbose = false, + tend = 1, + unknown_storage = :sparse, + autodetect_sparsity = true + ) h = 1.0 / convert(Float64, n) X = collect(0.0:h:1.0) N = length(X) @@ -75,18 +77,21 @@ function main(; n = 10, function flux!(f, u, edge, data) f[iA] = D_A * (u[iA, 1] - u[iA, 2]) f[iB] = D_B * (u[iB, 1] - u[iB, 2]) + return nothing end ## Storage term of species A and B function storage!(f, u, node, data) f[iA] = u[iA] f[iB] = u[iB] + return nothing end ## Source term for species a around 0.5 function source!(f, node, data) x1 = node[1] - 0.5 f[iA] = exp(-100 * x1^2) + return nothing end ## Reaction constants (p = + , m = -) @@ -100,6 +105,7 @@ function main(; n = 10, f[iA] += R f[iB] -= R end + return nothing end ## This generic operator works on the full solution seen as linear vector, and indexing @@ -110,7 +116,8 @@ function main(; n = 10, function generic_operator!(f, u, sys) f .= 0 f[idx[iC, 1]] = u[idx[iC, 1]] + - 0.1 * (u[idx[iA, 1]] - u[idx[iA, 2]]) / (X[2] - X[1]) + 0.1 * (u[idx[iA, 1]] - u[idx[iA, 2]]) / (X[2] - X[1]) + return nothing end # If we know the sparsity pattern, we can here create a @@ -123,22 +130,26 @@ function main(; n = 10, sparsity[idx[iC, 1], idx[iC, 1]] = 1 sparsity[idx[iC, 1], idx[iA, 1]] = 1 sparsity[idx[iC, 1], idx[iA, 2]] = 1 - sparsity + return sparsity end if autodetect_sparsity - physics = VoronoiFVM.Physics(; breaction = breaction!, - generic = generic_operator!, - flux = flux!, - storage = storage!, - source = source!) + physics = VoronoiFVM.Physics(; + breaction = breaction!, + generic = generic_operator!, + flux = flux!, + storage = storage!, + source = source! + ) else - physics = VoronoiFVM.Physics(; breaction = breaction!, - generic = generic_operator!, - generic_sparsity = generic_operator_sparsity, - flux = flux!, - storage = storage!, - source = source!) + physics = VoronoiFVM.Physics(; + breaction = breaction!, + generic = generic_operator!, + generic_sparsity = generic_operator_sparsity, + flux = flux!, + storage = storage!, + source = source! + ) end sys = VoronoiFVM.System(grid, physics; unknown_storage = unknown_storage) @@ -176,9 +187,13 @@ function main(; n = 10, push!(T, time) push!(u_C, U[iC, 1]) - scalarplot!(p[1, 1], grid, U[iA, :]; label = "[A]", - title = @sprintf("max_A=%.5f max_B=%.5f u_C=%.5f", maximum(U[iA, :]), - maximum(U[iB, :]), u_C[end]), color = :red) + scalarplot!( + p[1, 1], grid, U[iA, :]; label = "[A]", + title = @sprintf( + "max_A=%.5f max_B=%.5f u_C=%.5f", maximum(U[iA, :]), + maximum(U[iB, :]), u_C[end] + ), color = :red + ) scalarplot!(p[1, 1], grid, U[iB, :]; label = "[B]", clear = false, color = :blue) scalarplot!(p[2, 1], copy(T), copy(u_C); label = "[C]", clear = true, show = true) end @@ -189,9 +204,10 @@ using Test function runtests() testval = 0.007027597470502758 @test main(; unknown_storage = :sparse) ≈ testval && - main(; unknown_storage = :dense) ≈ testval && - main(; unknown_storage = :sparse, autodetect_sparsity = false) ≈ testval && - main(; unknown_storage = :dense, autodetect_sparsity = false) ≈ testval + main(; unknown_storage = :dense) ≈ testval && + main(; unknown_storage = :sparse, autodetect_sparsity = false) ≈ testval && + main(; unknown_storage = :dense, autodetect_sparsity = false) ≈ testval + return nothing end end diff --git a/examples/Example410_ManySpecies.jl b/examples/Example410_ManySpecies.jl index 1bebc4eaa..267db72f7 100644 --- a/examples/Example410_ManySpecies.jl +++ b/examples/Example410_ManySpecies.jl @@ -18,28 +18,30 @@ function main(; n = 11, nspec = 50, Plotter = nothing, unknown_storage = :dense, grid = simplexgrid(range(0, 1; length = n)) function flux(f, u, edge, data) - for ispec = 1:nspec + for ispec in 1:nspec f[ispec] = u[ispec, 1] - u[ispec, 2] end + return nothing end physics = VoronoiFVM.Physics(; flux = flux) sys = VoronoiFVM.System(grid, physics; unknown_storage = unknown_storage, assembly = assembly) - for ispec = 1:nspec + for ispec in 1:nspec enable_species!(sys, ispec, [1]) boundary_dirichlet!(sys, ispec, 1, 0) boundary_dirichlet!(sys, ispec, 2, 1) end sol = solve(sys) - norm(sol) + return norm(sol) end using Test function runtests() testval = 13.874436925511608 @test main(; unknown_storage = :sparse, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && - main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && + main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && + main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + return nothing end end diff --git a/examples/Example420_DiscontinuousQuantities.jl b/examples/Example420_DiscontinuousQuantities.jl index 43230eabc..0f3ea6df6 100644 --- a/examples/Example420_DiscontinuousQuantities.jl +++ b/examples/Example420_DiscontinuousQuantities.jl @@ -17,19 +17,19 @@ using LinearAlgebra function main(; N = 5, Plotter = nothing, unknown_storage = :sparse, assembly = :edgewise) XX = collect(0:0.1:1) xcoord = XX - for i = 1:(N - 1) + for i in 1:(N - 1) xcoord = glue(xcoord, XX .+ i) end grid2 = simplexgrid(xcoord) - for i = 1:N + for i in 1:N cellmask!(grid2, [i - 1], [i], i) end - for i = 1:(N - 1) + for i in 1:(N - 1) bfacemask!(grid2, [i], [i], i + 2) end params = zeros(2, num_cellregions(grid2)) - for i = 1:num_cellregions(grid2) + for i in 1:num_cellregions(grid2) params[1, i] = i params[2, i] = 10 * i end @@ -40,7 +40,7 @@ function main(; N = 5, Plotter = nothing, unknown_storage = :sparse, assembly = cspec = ContinuousQuantity(system, 1:N; ispec = 1, id = 1) ## A discontinuous quantity can be introduced as well. by default, each reagion gets a new species number. This can be overwritten by the user. - dspec = DiscontinuousQuantity(system, 1:N; regionspec = [2 + i % 2 for i = 1:N], id = 2) + dspec = DiscontinuousQuantity(system, 1:N; regionspec = [2 + i % 2 for i in 1:N], id = 2) # check 1D array access with quantities carrierList = [cspec dspec] @@ -48,26 +48,26 @@ function main(; N = 5, Plotter = nothing, unknown_storage = :sparse, assembly = params2 = zeros(1, numberCarriers) - for icc ∈ carrierList + for icc in carrierList params2[icc] = 2 end - for i = 1:numberCarriers + for i in 1:numberCarriers @assert params2[i] == 2 end # check 2D array access with quantities - for i = 1:num_cellregions(grid2) + for i in 1:num_cellregions(grid2) @assert params[cspec, i] == i @assert params[dspec, i] == 10 * i end - for i = 1:num_cellregions(grid2) + for i in 1:num_cellregions(grid2) params[cspec, i] = -i params[dspec, i] = -10 * i end - for i = 1:num_cellregions(grid2) + for i in 1:num_cellregions(grid2) @assert params[1, i] == -i @assert params[2, i] == -10 * i end @@ -77,6 +77,7 @@ function main(; N = 5, Plotter = nothing, unknown_storage = :sparse, assembly = function flux(f, u, edge, data) f[dspec] = u[dspec, 1] - u[dspec, 2] f[cspec] = u[cspec, 1] - u[cspec, 2] + return nothing end d1 = 1 @@ -96,10 +97,15 @@ function main(; N = 5, Plotter = nothing, unknown_storage = :sparse, assembly = f[dspec, 2] = -react f[cspec] = -q1 * u[cspec] end + return nothing end - physics!(system, VoronoiFVM.Physics(; flux = flux, - breaction = breaction)) + physics!( + system, VoronoiFVM.Physics(; + flux = flux, + breaction = breaction + ) + ) ## Set boundary conditions boundary_dirichlet!(system, dspec, 2, 0.1) @@ -113,23 +119,28 @@ function main(; N = 5, Plotter = nothing, unknown_storage = :sparse, assembly = cvws = views(U, cspec, subgrids, system) vis = GridVisualizer(; resolution = (600, 300), Plotter = Plotter) for i in eachindex(dvws) - scalarplot!(vis, subgrids[i], dvws[i]; flimits = (-0.5, 1.5), clear = false, - color = :red) - scalarplot!(vis, subgrids[i], cvws[i]; flimits = (-0.5, 1.5), clear = false, - color = :green) + scalarplot!( + vis, subgrids[i], dvws[i]; flimits = (-0.5, 1.5), clear = false, + color = :red + ) + scalarplot!( + vis, subgrids[i], cvws[i]; flimits = (-0.5, 1.5), clear = false, + color = :green + ) end reveal(vis) I = integrate(system, system.physics.storage, U) - sum(I[dspec, :]) + sum(I[cspec, :]) + return sum(I[dspec, :]) + sum(I[cspec, :]) end using Test function runtests() testval = 4.2 @test main(; unknown_storage = :sparse, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && - main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && + main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && + main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + return nothing end end diff --git a/examples/Example421_AbstractQuantities_TestFunctions.jl b/examples/Example421_AbstractQuantities_TestFunctions.jl index fb4356b08..136e6a637 100644 --- a/examples/Example421_AbstractQuantities_TestFunctions.jl +++ b/examples/Example421_AbstractQuantities_TestFunctions.jl @@ -27,14 +27,14 @@ end function main(; N = 3, Plotter = nothing, unknown_storage = :sparse, assembly = :edgewise) XX = collect(0:0.1:1) xcoord = XX - for i = 1:(N - 1) + for i in 1:(N - 1) xcoord = glue(xcoord, XX .+ i) end grid = simplexgrid(xcoord) - for i = 1:N + for i in 1:N cellmask!(grid, [i - 1], [i], i) end - for i = 1:(N - 1) + for i in 1:(N - 1) bfacemask!(grid, [i], [i], i + 2) end @@ -49,6 +49,7 @@ function main(; N = 3, Plotter = nothing, unknown_storage = :sparse, assembly = function fluxQ(f, u, edge, data) # For both quantities, we define simple diffusion fluxes f[dspec] = u[dspec, 1] - u[dspec, 2] f[cspec] = u[cspec, 1] - u[cspec, 2] + return nothing end function breactionQ(f, u, bnode, data) @@ -58,22 +59,30 @@ function main(; N = 3, Plotter = nothing, unknown_storage = :sparse, assembly = f[dspec, 1] = react f[dspec, 2] = -react end + return nothing end - physics!(sysQ, VoronoiFVM.Physics(; data = data, - flux = fluxQ, - breaction = breactionQ)) + physics!( + sysQ, VoronoiFVM.Physics(; + data = data, + flux = fluxQ, + breaction = breactionQ + ) + ) ########################################################## icc = 1 # for system without AbstractQuantities function flux!(f, u, edge, data) # analogous as for other system f[icc] = u[icc, 1] - u[icc, 2] + return nothing end # other system to which we compare current calculation - sys = VoronoiFVM.System(grid; flux = flux!, species = icc, - unknown_storage = unknown_storage) + sys = VoronoiFVM.System( + grid; flux = flux!, species = icc, + unknown_storage = unknown_storage + ) ## Set left boundary conditions boundary_dirichlet!(sysQ, dspec, 1, 0.0) @@ -135,22 +144,34 @@ function main(; N = 3, Plotter = nothing, unknown_storage = :sparse, assembly = vis = GridVisualizer(; layout = (2, 1), resolution = (600, 300), Plotter = Plotter) for i in eachindex(dvws) - scalarplot!(vis[1, 1], subgrids[i], dvws[i]; flimits = (-0.5, 1.5), - title = @sprintf("Solution with rate=%.2f", data.rate), - label = "discont quantity", clear = false, color = :red) - scalarplot!(vis[1, 1], subgrids[i], cvws[i]; label = "cont quantity", - clear = false, color = :green) + scalarplot!( + vis[1, 1], subgrids[i], dvws[i]; flimits = (-0.5, 1.5), + title = @sprintf("Solution with rate=%.2f", data.rate), + label = "discont quantity", clear = false, color = :red + ) + scalarplot!( + vis[1, 1], subgrids[i], cvws[i]; label = "cont quantity", + clear = false, color = :green + ) end - scalarplot!(vis[1, 1], grid, U[icc, :]; label = "without quantity", clear = false, - linestyle = :dot, color = :blue) - - scalarplot!(vis[2, 1], biasval, Idspec; clear = false, - title = @sprintf("IV with rate=%.2f", data.rate), - label = "discont quantity", color = :red) - scalarplot!(vis[2, 1], biasval, Icspec; clear = false, title = "Current", - label = "cont quantity", color = :green) - scalarplot!(vis[2, 1], biasval, Iicc; clear = false, label = "discont quantity", - linestyle = :dot, color = :blue, show = true) + scalarplot!( + vis[1, 1], grid, U[icc, :]; label = "without quantity", clear = false, + linestyle = :dot, color = :blue + ) + + scalarplot!( + vis[2, 1], biasval, Idspec; clear = false, + title = @sprintf("IV with rate=%.2f", data.rate), + label = "discont quantity", color = :red + ) + scalarplot!( + vis[2, 1], biasval, Icspec; clear = false, title = "Current", + label = "cont quantity", color = :green + ) + scalarplot!( + vis[2, 1], biasval, Iicc; clear = false, label = "discont quantity", + linestyle = :dot, color = :blue, show = true + ) reveal(vis) sleep(0.2) @@ -165,9 +186,10 @@ using Test function runtests() testval = 6.085802139465579e-7 @test main(; unknown_storage = :sparse, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && - main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && + main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && + main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + return nothing end end diff --git a/examples/Example422_InterfaceQuantities.jl b/examples/Example422_InterfaceQuantities.jl index 8f2fd634f..b9a2a6ceb 100644 --- a/examples/Example422_InterfaceQuantities.jl +++ b/examples/Example422_InterfaceQuantities.jl @@ -14,8 +14,10 @@ using VoronoiFVM using ExtendableGrids using GridVisualize -function main(; n = 5, Plotter = nothing, tend = 20.0, unknown_storage = :sparse, - reactionN = 5.0e0, reactionP = 5.0e0, assembly = :edgewise) +function main(; + n = 5, Plotter = nothing, tend = 20.0, unknown_storage = :sparse, + reactionN = 5.0e0, reactionP = 5.0e0, assembly = :edgewise + ) ################################################################################ #### grid @@ -76,6 +78,7 @@ function main(; n = 5, Plotter = nothing, tend = 20.0, unknown_storage = :sparse f[iphip] = exp(etap) f[ipsi] = 0.0 + return nothing end function reaction!(f, u, node, data) @@ -89,6 +92,7 @@ function main(; n = 5, Plotter = nothing, tend = 20.0, unknown_storage = :sparse f[iphin] = -recomb f[iphip] = recomb + return nothing end function flux!(f, u, node, data) @@ -105,6 +109,7 @@ function main(; n = 5, Plotter = nothing, tend = 20.0, unknown_storage = :sparse f[iphin] = (bm * exp(etan2) - bp * exp(etan1)) f[iphip] = -(bp * exp(etap2) - bm * exp(etap1)) + return nothing end function breaction!(f, u, bnode, data) @@ -134,6 +139,7 @@ function main(; n = 5, Plotter = nothing, tend = 20.0, unknown_storage = :sparse f[iphinb] = -(f[iphin, 1] + f[iphin, 2]) f[iphipb] = -(f[iphip, 1] + f[iphip, 2]) end + return nothing end function bstorage!(f, u, bnode, data) @@ -146,14 +152,19 @@ function main(; n = 5, Plotter = nothing, tend = 20.0, unknown_storage = :sparse f[iphinb] = -exp(etan) f[iphipb] = exp(etap) end + return nothing end - physics!(sys, - VoronoiFVM.Physics(; flux = flux!, - storage = storage!, - reaction = reaction!, - breaction = breaction!, - bstorage = bstorage!)) + physics!( + sys, + VoronoiFVM.Physics(; + flux = flux!, + storage = storage!, + reaction = reaction!, + breaction = breaction!, + bstorage = bstorage! + ) + ) boundary_dirichlet!(sys, iphin, bregion1, 4.0) boundary_dirichlet!(sys, iphip, bregion1, 4.0) @@ -173,7 +184,7 @@ function main(; n = 5, Plotter = nothing, tend = 20.0, unknown_storage = :sparse ntsteps = 10 tvalues = range(t0; stop = tend, length = ntsteps) - for istep = 2:ntsteps + for istep in 2:ntsteps t = tvalues[istep] # Actual time Δt = t - tvalues[istep - 1] # Time step size @@ -203,7 +214,7 @@ function main(; n = 5, Plotter = nothing, tend = 20.0, unknown_storage = :sparse I = integrate(sys, tf, sol) val = 0.0 - for ii = 1:(length(I) - 1) + for ii in 1:(length(I) - 1) val = val + I[ii] end @@ -239,9 +250,10 @@ using Test function runtests() testval = 0.35545473758267826 @test main(; unknown_storage = :sparse, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && - main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && - main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + main(; unknown_storage = :dense, assembly = :edgewise) ≈ testval && + main(; unknown_storage = :sparse, assembly = :cellwise) ≈ testval && + main(; unknown_storage = :dense, assembly = :cellwise) ≈ testval + return nothing end end # module diff --git a/examples/Example424_AbstractQuantitiesInit.jl b/examples/Example424_AbstractQuantitiesInit.jl index fc9bcffab..7bbf1bb37 100644 --- a/examples/Example424_AbstractQuantitiesInit.jl +++ b/examples/Example424_AbstractQuantitiesInit.jl @@ -31,7 +31,7 @@ function main(; N = 5, Plotter = nothing, unknown_storage = :sparse, assembly = function init(u, node) ireg = node.region - if ireg == 1 + return if ireg == 1 u[dspec] = 1 u[cspec] = 10 else @@ -51,7 +51,7 @@ function main(; N = 5, Plotter = nothing, unknown_storage = :sparse, assembly = (cuviews[2] == fill(20.0, (N - 1) ÷ 2 + 1)) |> psh! (cuviews[1][1:(end - 1)] == fill(10.0, (N - 1) ÷ 2)) |> psh! - all(result) + return all(result) end ## "Classical" solution creation @@ -64,15 +64,15 @@ function main(; N = 5, Plotter = nothing, unknown_storage = :sparse, assembly = w = unknowns(system) map!(init, w, system) - check(u) && check(v) && check(w) + return check(u) && check(v) && check(w) end using Test function runtests() - @test main(; unknown_storage = :sparse, assembly = :edgewise) && - main(; unknown_storage = :dense, assembly = :edgewise) && - main(; unknown_storage = :sparse, assembly = :cellwise) && - main(; unknown_storage = :dense, assembly = :cellwise) + return @test main(; unknown_storage = :sparse, assembly = :edgewise) && + main(; unknown_storage = :dense, assembly = :edgewise) && + main(; unknown_storage = :sparse, assembly = :cellwise) && + main(; unknown_storage = :dense, assembly = :cellwise) end end diff --git a/examples/Example430_ParameterDerivativesStationary.jl b/examples/Example430_ParameterDerivativesStationary.jl index c4f8e3e2c..719d6aba8 100644 --- a/examples/Example430_ParameterDerivativesStationary.jl +++ b/examples/Example430_ParameterDerivativesStationary.jl @@ -30,25 +30,30 @@ function f(P; n = 10) function flux!(f, u, edge, data) f[1] = (1 + p) * (u[1, 1]^2 - u[1, 2]^2) + return nothing end function r!(f, u, edge, data) f[1] = p * u[1]^5 + return nothing end function bc!(f, u, node, data) boundary_dirichlet!(f, u, node, ispec, 1, 0.0) boundary_dirichlet!(f, u, node, ispec, 3, p) + return nothing end X = collect(0:(1.0 / n):1) grid = simplexgrid(X, X) - sys = VoronoiFVM.System(grid; valuetype, species = [1], flux = flux!, reaction = r!, - bcondition = bc!) + sys = VoronoiFVM.System( + grid; valuetype, species = [1], flux = flux!, reaction = r!, + bcondition = bc! + ) tff = VoronoiFVM.TestFunctionFactory(sys) tfc = testfunction(tff, [1], [3]) sol = solve(sys; inival = 0.5) - [integrate(sys, tfc, sol)[1]] + return [integrate(sys, tfc, sol)[1]] end """ @@ -63,7 +68,7 @@ function runf(; Plotter = nothing, n = 10) F = zeros(0) DF = zeros(0) ff(p) = f(p; n) - @time for p ∈ P + @time for p in P ForwardDiff.jacobian!(dresult, ff, [p]) push!(F, DiffResults.value(dresult)[1]) push!(DF, DiffResults.jacobian(dresult)[1]) @@ -71,20 +76,23 @@ function runf(; Plotter = nothing, n = 10) vis = GridVisualizer(; Plotter, legend = :lt) scalarplot!(vis, P, F; color = :red, label = "f") scalarplot!(vis, P, DF; color = :blue, label = "df", clear = false, show = true) - sum(DF) + return sum(DF) end function fluxg!(f, u, edge, data) f[1] = (1 + data.p) * (u[1, 1]^2 - u[1, 2]^2) + return nothing end function rg!(f, u, edge, data) f[1] = data.p * u[1]^5 + return nothing end function bcg!(f, u, node, data) boundary_dirichlet!(f, u, node, 1, 1, 0.0) boundary_dirichlet!(f, u, node, 1, 3, data.p) + return nothing end Base.@kwdef mutable struct MyData{Tv} @@ -110,15 +118,17 @@ function rung(; Plotter = nothing, method_linear = SparspakFactorization(), n = Tv = eltype(P) if isnothing(sys) data = MyData(one(Tv)) - sys = VoronoiFVM.System(grid; valuetype = Tv, species = [1], flux = fluxg!, - reaction = rg!, bcondition = bcg!, data, - unknown_storage = :dense) + sys = VoronoiFVM.System( + grid; valuetype = Tv, species = [1], flux = fluxg!, + reaction = rg!, bcondition = bcg!, data, + unknown_storage = :dense + ) tff = VoronoiFVM.TestFunctionFactory(sys) tfc = testfunction(tff, [1], [3]) end data.p = P[1] sol = solve(sys; inival = 0.5, method_linear) - [integrate(sys, tfc, sol)[1]] + return [integrate(sys, tfc, sol)[1]] end dresult = DiffResults.JacobianResult(ones(1)) @@ -126,7 +136,7 @@ function rung(; Plotter = nothing, method_linear = SparspakFactorization(), n = P = 0.1:0.05:2 G = zeros(0) DG = zeros(0) - @time for p ∈ P + @time for p in P ForwardDiff.jacobian!(dresult, g, [p]) push!(G, DiffResults.value(dresult)[1]) push!(DG, DiffResults.jacobian(dresult)[1]) @@ -135,7 +145,7 @@ function rung(; Plotter = nothing, method_linear = SparspakFactorization(), n = vis = GridVisualizer(; Plotter, legend = :lt) scalarplot!(vis, P, G; color = :red, label = "g") scalarplot!(vis, P, DG; color = :blue, label = "dg", clear = false, show = true) - sum(DG) + return sum(DG) end ######################################################################### @@ -143,17 +153,20 @@ end function fluxh!(f, u, edge, data) p = parameters(u)[1] f[1] = (1 + p) * (u[1, 1]^2 - u[1, 2]^2) + return nothing end function rh!(f, u, edge, data) p = parameters(u)[1] f[1] = p * u[1]^5 + return nothing end function bch!(f, u, node, data) p = parameters(u)[1] boundary_dirichlet!(f, u, node, 1, 1, 0.0) boundary_dirichlet!(f, u, node, 1, 3, p) + return nothing end """ @@ -169,15 +182,17 @@ function runh(; Plotter = nothing, n = 10) X = collect(0:(1.0 / n):1) grid = simplexgrid(X, X) - sys = VoronoiFVM.System(grid; species = [1], flux = fluxh!, reaction = rh!, - bcondition = bch!, unknown_storage = :dense, nparams = 1) + sys = VoronoiFVM.System( + grid; species = [1], flux = fluxh!, reaction = rh!, + bcondition = bch!, unknown_storage = :dense, nparams = 1 + ) tff = VoronoiFVM.TestFunctionFactory(sys) tfc = testfunction(tff, [1], [3]) function measp(params, u) Tp = eltype(params) up = Tp.(u) - integrate(sys, tfc, up; params = params)[1] + return integrate(sys, tfc, up; params = params)[1] end params = [0.0] @@ -185,18 +200,18 @@ function runh(; Plotter = nothing, n = 10) function mymeas!(meas, U) u = reshape(U, sys) meas[1] = integrate(sys, tfc, u; params)[1] - nothing + return nothing end dp = 0.05 P = 0.1:dp:2 - state=VoronoiFVM.SystemState(sys) + state = VoronoiFVM.SystemState(sys) U0 = solve!(state; inival = 0.5, params = [P[1]]) ndof = num_dof(sys) - colptr = [i for i = 1:(ndof + 1)] - rowval = [1 for i = 1:ndof] - nzval = [1.0 for in = 1:ndof] + colptr = [i for i in 1:(ndof + 1)] + rowval = [1 for i in 1:ndof] + nzval = [1.0 for in in 1:ndof] ∂m∂u = zeros(1, ndof) colors = matrix_colors(∂m∂u) @@ -205,7 +220,7 @@ function runh(; Plotter = nothing, n = 10) DHx = zeros(0) m = zeros(1) - @time for p ∈ P + @time for p in P params[1] = p sol = solve!(state; inival = 0.5, params) @@ -226,15 +241,16 @@ function runh(; Plotter = nothing, n = 10) vis = GridVisualizer(; Plotter, legend = :lt) scalarplot!(vis, P, H; color = :red, label = "h") scalarplot!(vis, P, DH; color = :blue, label = "dh", clear = false, show = true) - sum(DH) + return sum(DH) end using Test function runtests() testval = 489.3432830184927 - @test runf() ≈ testval - @test rung() ≈ testval - @test runh() ≈ testval + @test runf() ≈ testval + @test rung() ≈ testval + @test runh() ≈ testval + return nothing end end diff --git a/examples/Example440_ParallelState.jl b/examples/Example440_ParallelState.jl index 274e45dc1..8cf31ab87 100644 --- a/examples/Example440_ParallelState.jl +++ b/examples/Example440_ParallelState.jl @@ -13,46 +13,49 @@ using VoronoiFVM, ExtendableGrids using GridVisualize using ChunkSplitters -function flux(y,u,node,data) - y[1]=u[1,1]^2-u[1,2]^2 +function flux(y, u, node, data) + y[1] = u[1, 1]^2 - u[1, 2]^2 + return nothing end -function bcondition(y,u,node,data) - boundary_dirichlet!(y,u,node, species=1, region=1, value=0.1) - boundary_neumann!(y,u,node,species=1,region=2,value=data.influx) +function bcondition(y, u, node, data) + boundary_dirichlet!(y, u, node, species = 1, region = 1, value = 0.1) + boundary_neumann!(y, u, node, species = 1, region = 2, value = data.influx) + return nothing end -function main(;nref=5, Plotter=nothing) - grid=simplexgrid(range(0,1,length=10*2^nref+1)) - sys=VoronoiFVM.System(grid;flux,bcondition, species=[1], data=(influx=0.0,)) +function main(; nref = 5, Plotter = nothing) + grid = simplexgrid(range(0, 1, length = 10 * 2^nref + 1)) + sys = VoronoiFVM.System(grid; flux, bcondition, species = [1], data = (influx = 0.0,)) ## Initial state. First solution creates the matrix - state0=VoronoiFVM.SystemState(sys) - sol=solve!(state0;inival=0.1) + state0 = VoronoiFVM.SystemState(sys) + sol = solve!(state0; inival = 0.1) ## Prepare parameter and result data - influxes=range(0.0,10.0, length=100) - masses=similar(influxes) + influxes = range(0.0, 10.0, length = 100) + masses = similar(influxes) ## Split the index range in as many chunks as threads - Threads.@threads for indexes in chunks(1:length(influxes);n=Threads.nthreads()) + Threads.@threads for indexes in chunks(1:length(influxes); n = Threads.nthreads()) ## Create a new state sharing the system - one for each chunk - state=similar(state0) + state = similar(state0) ## Solve for all data values in chunk for iflux in indexes - data=(influx=influxes[iflux],) - sol=solve!(state;data, inival=0.1, verbose="") - masses[iflux]=integrate(sys,sol)[1,1] + data = (influx = influxes[iflux],) + sol = solve!(state; data, inival = 0.1, verbose = "") + masses[iflux] = integrate(sys, sol)[1, 1] end end - scalarplot(influxes, masses;Plotter, xlabel="influx", ylabel="mass") - sum(masses) + scalarplot(influxes, masses; Plotter, xlabel = "influx", ylabel = "mass") + return sum(masses) end using Test function runtests() - testval=140.79872772042577 + testval = 140.79872772042577 @test main() ≈ testval + return nothing end end diff --git a/examples/Example510_Mixture.jl b/examples/Example510_Mixture.jl index 753bb1a3b..92b27325c 100644 --- a/examples/Example510_Mixture.jl +++ b/examples/Example510_Mixture.jl @@ -83,14 +83,14 @@ function flux_strided(f, u, edge, data) du = StrideArray{T}(undef, StaticInt(nspec(data))) ipiv = StrideArray{Int}(undef, StaticInt(nspec(data))) - for ispec = 1:nspec(data) + for ispec in 1:nspec(data) M[ispec, ispec] = 1.0 / data.DKnudsen[ispec] du[ispec] = u[ispec, 1] - u[ispec, 2] au[ispec] = 0.5 * (u[ispec, 1] + u[ispec, 2]) end - for ispec = 1:nspec(data) - for jspec = 1:nspec(data) + for ispec in 1:nspec(data) + for jspec in 1:nspec(data) if ispec != jspec M[ispec, ispec] += au[jspec] / data.DBinary[ispec, jspec] M[ispec, jspec] = -au[ispec] / data.DBinary[ispec, jspec] @@ -106,9 +106,10 @@ function flux_strided(f, u, edge, data) @gc_preserve inplace_linsolve!(M, du) end - for ispec = 1:nspec(data) + for ispec in 1:nspec(data) f[ispec] = du[ispec] end + return end function flux_marray(f, u, edge, data) @@ -120,14 +121,14 @@ function flux_marray(f, u, edge, data) du = MVector{nspec(data), T}(undef) ipiv = MVector{nspec(data), Int}(undef) - for ispec = 1:nspec(data) + for ispec in 1:nspec(data) M[ispec, ispec] = 1.0 / data.DKnudsen[ispec] du[ispec] = u[ispec, 1] - u[ispec, 2] au[ispec] = 0.5 * (u[ispec, 1] + u[ispec, 2]) end - for ispec = 1:nspec(data) - for jspec = 1:nspec(data) + for ispec in 1:nspec(data) + for jspec in 1:nspec(data) if ispec != jspec M[ispec, ispec] += au[jspec] / data.DBinary[ispec, jspec] M[ispec, jspec] = -au[ispec] / data.DBinary[ispec, jspec] @@ -140,32 +141,40 @@ function flux_marray(f, u, edge, data) ## Starting with Julia 1.8 one also can use callsite @inline. inplace_linsolve!(M, du) - for ispec = 1:nspec(data) + for ispec in 1:nspec(data) f[ispec] = du[ispec] end + return nothing end function bcondition(f, u, node, data) - for species = 1:nspec(data) - boundary_dirichlet!(f, u, node; species, region = data.diribc[1], - value = species % 2) - boundary_dirichlet!(f, u, node; species, region = data.diribc[2], - value = 1 - species % 2) + for species in 1:nspec(data) + boundary_dirichlet!( + f, u, node; species, region = data.diribc[1], + value = species % 2 + ) + boundary_dirichlet!( + f, u, node; species, region = data.diribc[2], + value = 1 - species % 2 + ) end + return nothing end -function main(; n = 11, nspec = 5, - dim = 2, - Plotter = nothing, - verbose = false, - unknown_storage = :dense, - flux = :flux_strided, - strategy = nothing, - assembly = :cellwise) +function main(; + n = 11, nspec = 5, + dim = 2, + Plotter = nothing, + verbose = false, + unknown_storage = :dense, + flux = :flux_strided, + strategy = nothing, + assembly = :cellwise + ) h = 1.0 / convert(Float64, n - 1) X = collect(0.0:h:1.0) DBinary = Symmetric(fill(0.1, nspec, nspec)) - for ispec = 1:nspec + for ispec in 1:nspec DBinary[ispec, ispec] = 0 end @@ -184,25 +193,26 @@ function main(; n = 11, nspec = 5, function storage(f, u, node, data) f .= u + return nothing end _flux = flux == :flux_strided ? flux_strided : flux_marray data = MyData{nspec}(DBinary, DKnudsen, diribc) - sys = VoronoiFVM.System(grid; flux = _flux, storage, bcondition, species = 1:nspec, data, assembly,unknown_storage) + sys = VoronoiFVM.System(grid; flux = _flux, storage, bcondition, species = 1:nspec, data, assembly, unknown_storage) if verbose @info "Strategy: $(strategy)" end - if !isnothing(strategy) && hasproperty(strategy,:precs) + if !isnothing(strategy) && hasproperty(strategy, :precs) if isa(strategy.precs, BlockPreconBuilder) - strategy.precs.partitioning=A->partitioning(sys, Equationwise()) + strategy.precs.partitioning = A -> partitioning(sys, Equationwise()) end - if isa(strategy.precs, ILUZeroPreconBuilder) && strategy.precs.blocksize!=1 - strategy.precs.blocksize=nspec + if isa(strategy.precs, ILUZeroPreconBuilder) && strategy.precs.blocksize != 1 + strategy.precs.blocksize = nspec end end - control = SolverControl(method_linear=strategy) + control = SolverControl(method_linear = strategy) control.maxiters = 500 if verbose @info control.method_linear @@ -211,19 +221,20 @@ function main(; n = 11, nspec = 5, if verbose @show norm(u) end - norm(u) + return norm(u) end using Test function runtests() - strategies = [UMFPACKFactorization(), - KrylovJL_GMRES(precs=LinearSolvePreconBuilder(UMFPACKFactorization())), - KrylovJL_GMRES(precs=BlockPreconBuilder(precs=LinearSolvePreconBuilder(UMFPACKFactorization()))), - KrylovJL_GMRES(precs=BlockPreconBuilder(precs=AMGPreconBuilder())), - KrylovJL_BICGSTAB(precs=BlockPreconBuilder(precs=AMGPreconBuilder())), - KrylovJL_GMRES(precs=ILUZeroPreconBuilder()), - KrylovJL_GMRES(precs=BlockPreconBuilder(precs=ILUZeroPreconBuilder())), - KrylovJL_GMRES(precs=ILUZeroPreconBuilder(blocksize=5)), + strategies = [ + UMFPACKFactorization(), + KrylovJL_GMRES(precs = LinearSolvePreconBuilder(UMFPACKFactorization())), + KrylovJL_GMRES(precs = BlockPreconBuilder(precs = LinearSolvePreconBuilder(UMFPACKFactorization()))), + KrylovJL_GMRES(precs = BlockPreconBuilder(precs = AMGPreconBuilder())), + KrylovJL_BICGSTAB(precs = BlockPreconBuilder(precs = AMGPreconBuilder())), + KrylovJL_GMRES(precs = ILUZeroPreconBuilder()), + KrylovJL_GMRES(precs = BlockPreconBuilder(precs = ILUZeroPreconBuilder())), + KrylovJL_GMRES(precs = ILUZeroPreconBuilder(blocksize = 5)), ] val1D = 4.788926530387466 @@ -238,5 +249,7 @@ function runtests() @test main(; dim = 2, flux = :flux_marray, assembly = :cellwise) ≈ val2D @test main(; dim = 3, flux = :flux_marray, assembly = :cellwise) ≈ val3D @test all(map(strategy -> main(; dim = 2, flux = :flux_marray, strategy) ≈ val2D, strategies)) + return nothing end + end diff --git a/ext/VoronoiFVMExtendableFEMBaseExt.jl b/ext/VoronoiFVMExtendableFEMBaseExt.jl index c1f4b134d..38e1861bf 100644 --- a/ext/VoronoiFVMExtendableFEMBaseExt.jl +++ b/ext/VoronoiFVMExtendableFEMBaseExt.jl @@ -19,10 +19,10 @@ using DocStringExtensions: DocStringExtensions, SIGNATURES id(u) = (u, Identity) -dist(p1,p2) = sqrt( (p1[1] - p2[1] )^2 + (p1[2] -p2[2])^2 ) +dist(p1, p2) = sqrt((p1[1] - p2[1])^2 + (p1[2] - p2[2])^2) function iscloser(pint, p1, p2, eps) - return dist(pint,p2) < dist(p2,p1) - eps + return dist(pint, p2) < dist(p2, p1) - eps end #This is the FEVectorBlock with lots of info from ExtendableFEMBase @@ -48,7 +48,6 @@ end function AugmentedFEVectorBlock(vel, seg_integrator, point_evaluator, cf, flowgrid) - bp1 = zeros(Float64, 3) bp2 = zeros(Float64, 3) result = zeros(Float64, 2) @@ -58,14 +57,16 @@ function AugmentedFEVectorBlock(vel, seg_integrator, point_evaluator, cf, flowgr bary = [1 / 3, 1 / 3, 1 / 3] - AugmentedFEVectorBlock(vel, seg_integrator, point_evaluator, cf, flowgrid, - bp1, - bp2, - result, - summand, - pint, - bpint, - bary) + return AugmentedFEVectorBlock( + vel, seg_integrator, point_evaluator, cf, flowgrid, + bp1, + bp2, + result, + summand, + pint, + bpint, + bary + ) end @@ -76,7 +77,7 @@ function multiply_r(result, input, qpinfo) return nothing end -function prepare_segment_integration(vel; axisymmetric=false, reconst=false, kwargs...) +function prepare_segment_integration(vel; axisymmetric = false, reconst = false, kwargs...) flowgrid = vel.FES.xgrid # reference mappings not implemented for other coord types @@ -86,7 +87,7 @@ function prepare_segment_integration(vel; axisymmetric=false, reconst=false, kwa if reconst seg_integrator = SegmentIntegrator(Edge1D, [id(1)]) else - seg_integrator = SegmentIntegrator(Edge1D, multiply_r, [id(1)]; bonus_quadorder=1) + seg_integrator = SegmentIntegrator(Edge1D, multiply_r, [id(1)]; bonus_quadorder = 1) end else seg_integrator = SegmentIntegrator(Edge1D, [id(1)]) @@ -148,21 +149,21 @@ end # We need two explicitly type-annotated methods for a working method specialization. # This one... function VoronoiFVM.integrate(::Type{<:Cartesian2D}, p1, p2, hnormal, aug_vec_block::AugmentedFEVectorBlock; kwargs...) - _integrate_along_segments(p1, p2, hnormal, aug_vec_block; kwargs...) + return _integrate_along_segments(p1, p2, hnormal, aug_vec_block; kwargs...) end # ... and that one. function VoronoiFVM.integrate(::Type{<:Cylindrical2D}, p1, p2, hnormal, aug_vec_block::AugmentedFEVectorBlock; kwargs...) - _integrate_along_segments(p1, p2, hnormal, aug_vec_block; kwargs...) + return _integrate_along_segments(p1, p2, hnormal, aug_vec_block; kwargs...) end # compute the path integral for the velocity in aug_vec_block between p1 and p2 by # incrementally walking through each cell in the grid between p1 and p2 # and summing up each cell's contribution -function _integrate_along_segments(p1, p2, hnormal, aug_vec_block::AugmentedFEVectorBlock{TVB, TSE, TPE, TCF, TFG}; interpolate_eps=1.0e-12, axisymmetric=false, kwargs...) where {TVB, TSE, TPE, TCF, TFG} - edge_length = dist(p1,p2) +function _integrate_along_segments(p1, p2, hnormal, aug_vec_block::AugmentedFEVectorBlock{TVB, TSE, TPE, TCF, TFG}; interpolate_eps = 1.0e-12, axisymmetric = false, kwargs...) where {TVB, TSE, TPE, TCF, TFG} + edge_length = dist(p1, p2) avg_r = (p1[1] + p2[1]) / 2 - (; bp1, result, summand, bp2, pint, bpint, bary)= aug_vec_block + (; bp1, result, summand, bp2, pint, bpint, bary) = aug_vec_block if axisymmetric && avg_r < eps() @@ -170,7 +171,7 @@ function _integrate_along_segments(p1, p2, hnormal, aug_vec_block::AugmentedFEVe end CF = aug_vec_block.cellfinder - icell::Int = gFindLocal!(bp1, CF, p1; eps=interpolate_eps) + icell::Int = gFindLocal!(bp1, CF, p1; eps = interpolate_eps) if edge_length ≤ interpolate_eps point_evaluator = aug_vec_block.point_evaluator evaluate_bary!(p2, point_evaluator, bp1, icell) @@ -200,15 +201,15 @@ function _integrate_along_segments(p1, p2, hnormal, aug_vec_block::AugmentedFEVe p1_temp3 = @MVector zeros(3) function calc_barycentric_coords!(bp, p) - for j = 1:2 + for j in 1:2 cx[j] = p[j] - L2Gb[j] end fill!(bp, 0) - for j = 1:2, k = 1:2 + for j in 1:2, k in 1:2 bp[k] += invA[j, k] * cx[j] end - postprocess_xreftest!(bp, CF.xCellGeometries[icell]) + return postprocess_xreftest!(bp, CF.xCellGeometries[icell]) end while (true) @@ -232,7 +233,7 @@ function _integrate_along_segments(p1, p2, hnormal, aug_vec_block::AugmentedFEVe # a cell containing p1 in the direction of (p2-p1) if count(<=(interpolate_eps), bp1) == 2 # 10^(-13) @. p1_temp2 = p1 + 10 * interpolate_eps * (p2 - p1) - icell_new = gFindLocal!(bp1, CF, p1_temp2; eps=10 * interpolate_eps, icellstart=icell) #!!! allocates + icell_new = gFindLocal!(bp1, CF, p1_temp2; eps = 10 * interpolate_eps, icellstart = icell) #!!! allocates if icell_new == 0 # TODO: test the following # icell_new = gFindBruteForce!(bp1, CF, p1_temp[1:2]) @@ -280,8 +281,8 @@ function _integrate_along_segments(p1, p2, hnormal, aug_vec_block::AugmentedFEVe p1_temp3 .= 0 while !iscloser(pint, p1, p2, interpolate_eps) || - (any(x->x<= -interpolate_eps, bpint) || any(x->x>= 1 + interpolate_eps, bpint)) || - dist(bpint,bp1) <= interpolate_eps #!!! .< allocates a temp vector + (any(x -> x <= -interpolate_eps, bpint) || any(x -> x >= 1 + interpolate_eps, bpint)) || + dist(bpint, bp1) <= interpolate_eps #!!! .< allocates a temp vector # check if pint takes us closer to p2 and if bpint is inside the cell *and* if we actually moved with pint from p1 imin += 1 if imin == 4 @@ -292,9 +293,9 @@ function _integrate_along_segments(p1, p2, hnormal, aug_vec_block::AugmentedFEVe t = bp1[imin] / (bp1[imin] - bp2[imin]) bpint = bp1 + t * (bp2 - bp1) eval_trafo!(pint, L2G, bpint) - if dist(pint,p2) < closestdist && ((all(x->x>= -interpolate_eps, bpint) && all(x->x<= 1 + interpolate_eps, bpint))) + if dist(pint, p2) < closestdist && ((all(x -> x >= -interpolate_eps, bpint) && all(x -> x <= 1 + interpolate_eps, bpint))) closestimin = imin - closestdist = dist(pint,p2) + closestdist = dist(pint, p2) p1_temp3 .= bpint end end diff --git a/pluto-examples/api-update.jl b/pluto-examples/api-update.jl index d57b1d168..593cd67cd 100644 --- a/pluto-examples/api-update.jl +++ b/pluto-examples/api-update.jl @@ -6,8 +6,12 @@ using InteractiveUtils # This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). macro bind(def, element) - quote - local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end + return quote + local iv = try + Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value + catch + b -> missing + end local el = $(esc(element)) global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) el @@ -79,45 +83,56 @@ begin const eps = 1.0e-2 function reaction(f, u, node, data) f[1] = u[1]^2 + return nothing end function flux(f, u, edge, data) f[1] = eps * (u[1, 1]^2 - u[1, 2]^2) + return nothing end function source(f, node, data) x1 = node[1] - 0.5 x2 = node[2] - 0.5 f[1] = exp(-20.0 * (x1^2 + x2^2)) + return nothing end function storage(f, u, node, data) f[1] = u[1] + return nothing end function bcondition(f, u, node, data) - boundary_dirichlet!(f, - u, - node; - species = 1, - region = 2, - value = ramp(node.time; dt = (0, 0.1), du = (0, 1))) - boundary_dirichlet!(f, - u, - node; - species = 1, - region = 4, - value = ramp(node.time; dt = (0, 0.1), du = (0, 1))) + boundary_dirichlet!( + f, + u, + node; + species = 1, + region = 2, + value = ramp(node.time; dt = (0, 0.1), du = (0, 1)) + ) + boundary_dirichlet!( + f, + u, + node; + species = 1, + region = 4, + value = ramp(node.time; dt = (0, 0.1), du = (0, 1)) + ) + return nothing end - sys0 = VoronoiFVM.System(0.0:h:1.0, - 0.0:h:1.0; - reaction, - flux, - source, - storage, - bcondition, - species = [1],) + sys0 = VoronoiFVM.System( + 0.0:h:1.0, + 0.0:h:1.0; + reaction, + flux, + source, + storage, + bcondition, + species = [1], + ) end # ╔═╡ 4279ae2e-a948-4358-9037-0c6895ecb809 @@ -202,11 +217,13 @@ The Jacobi preconditioner is defined in ExtendableSparse.jl. """ # ╔═╡ b70524fc-b8b1-4dee-b77d-e3f8d6d2837b -krydiag_sol = solve(sys0; - inival = 0.1, - method_linear = KrylovJL_BICGSTAB(), - precon_linear = JacobiPreconditioner, - verbose = true,) +krydiag_sol = solve( + sys0; + inival = 0.1, + method_linear = KrylovJL_BICGSTAB(), + precon_linear = JacobiPreconditioner, + verbose = true, +) # ╔═╡ d21d3236-b3d7-4cf8-ab9d-b0be44c9970b @test isapprox(krydiag_sol, sol0, atol = 1.0e-5) @@ -217,11 +234,13 @@ md""" """ # ╔═╡ 4c7f8bbf-40c4-45b9-a62e-99ffaae30af1 -krydel_sol = solve(sys0; - inival = 0.1, - method_linear = KrylovJL_BICGSTAB(), - precon_linear = SparspakFactorization(), - verbose = "nlad",) +krydel_sol = solve( + sys0; + inival = 0.1, + method_linear = KrylovJL_BICGSTAB(), + precon_linear = SparspakFactorization(), + verbose = "nlad", +) # ╔═╡ 4fa1c608-19b2-4eaa-8c0a-5881b373807c @test isapprox(krydel_sol, sol0, atol = 1.0e-5) @@ -234,11 +253,13 @@ wraps the predonditioner defined in ILUZero.jl . """ # ╔═╡ 6895cdf9-8291-47ce-bd1d-4c5beec594ea -kryilu0_sol = solve(sys0; - inival = 0.5, - method_linear = KrylovJL_BICGSTAB(), - precon_linear = ILUZeroPreconditioner, - verbose = true,) +kryilu0_sol = solve( + sys0; + inival = 0.5, + method_linear = KrylovJL_BICGSTAB(), + precon_linear = ILUZeroPreconditioner, + verbose = true, +) # ╔═╡ d341f60e-191d-4cf9-9df9-fbe25c84a7da @test isapprox(kryilu0_sol, sol0, atol = 1.0e-5) @@ -268,7 +289,7 @@ D = 0.1 # ╔═╡ 2ff77259-7a81-4c54-a291-cbc20ee56c5d function xflux(f, u, edge, data) - f[1] = D * (u[1, 1]^2 - u[1, 2]^2) + return f[1] = D * (u[1, 1]^2 - u[1, 2]^2) end # ╔═╡ b0a845d7-95d7-4212-9620-e1948698c596 @@ -304,6 +325,7 @@ const D1 = 0.1 # ╔═╡ c40f1954-4fb7-48b2-ab4c-cdf6459b7383 function xflux1(f, u, edge, data) f[1] = D1 * (u[1, 1]^2 - u[1, 2]^2) + return nothing end # ╔═╡ cec5152b-0597-4ea4-8387-b08e1e4ffcde @@ -334,23 +356,27 @@ grid1 = simplexgrid(0:0.1:1); # ╔═╡ 90bbf212-c6c8-44f0-8132-4a98f094750e function multispecies_flux(y, u, edge, data) - for i = 1:(edge.nspec) + for i in 1:(edge.nspec) y[i] = u[i, 1] - u[i, 2] end + return nothing end # ╔═╡ adff41d1-9398-4a66-9a8e-e03809973fa6 function test_reaction(y, u, node, data) y[1] = u[1] y[2] = -u[1] + return nothing end # ╔═╡ 5e6d83ab-65c7-4f33-b0a8-29cd5717b4d6 begin - system1 = VoronoiFVM.System(grid1; - flux = multispecies_flux, - reaction = test_reaction, - species = [1, 2]) + system1 = VoronoiFVM.System( + grid1; + flux = multispecies_flux, + reaction = test_reaction, + species = [1, 2] + ) boundary_dirichlet!(system1; species = 1, region = 1, value = 1) boundary_dirichlet!(system1; species = 2, region = 2, value = 0) end; @@ -381,15 +407,18 @@ space and time dependent boundary conditions. One can specify them either in `br function bcond2(y, u, bnode, data) boundary_neumann!(y, u, bnode; species = 1, region = 1, value = sin(bnode.time)) boundary_dirichlet!(y, u, bnode; species = 2, region = 2, value = 0) + return nothing end; # ╔═╡ c86e8a0f-299f-42ab-96f8-0cd62d50f196 -system2 = VoronoiFVM.System(grid1; - flux = multispecies_flux, - reaction = test_reaction, - species = [1, 2], - bcondition = bcond2, - check_allocs = false); +system2 = VoronoiFVM.System( + grid1; + flux = multispecies_flux, + reaction = test_reaction, + species = [1, 2], + bcondition = bcond2, + check_allocs = false +); # ╔═╡ b3d936fe-69ab-4013-b787-2f0b5410638a sol2 = solve(system2; times = (0, 10), Δt_max = 0.01); @@ -406,13 +435,15 @@ time: $(@bind t2 PlutoUI.Slider(0:0.01:10; default=5,show_value=true)) let s = sol2(t2) scalarplot!(vis2, grid1, s[1, :]; color = :red, label = "species1") - scalarplot!(vis2, - grid1, - s[2, :]; - color = :green, - label = "species2", - clear = false, - title = "time=$(t2)") + scalarplot!( + vis2, + grid1, + s[2, :]; + color = :green, + label = "species2", + clear = false, + title = "time=$(t2)" + ) reveal(vis2) end @@ -434,14 +465,17 @@ This example also demonstrates position dependent boundary values. function bcond3(y, u, bnode, data) boundary_dirichlet!(y, u, bnode; region = 4, value = bnode[2]) boundary_dirichlet!(y, u, bnode; region = 2, value = -bnode[2]) + return nothing end; # ╔═╡ a514231a-e465-4f05-ba4c-b20aa968d96f -system3 = VoronoiFVM.System(-1:0.1:1, - -1:0.1:1; - flux = multispecies_flux, - bcondition = bcond3, - species = 1); +system3 = VoronoiFVM.System( + -1:0.1:1, + -1:0.1:1; + flux = multispecies_flux, + bcondition = bcond3, + species = 1 +); # ╔═╡ d55f615c-d586-4ef7-adf9-5faf052b75ac sol3 = solve(system3); @@ -477,22 +511,26 @@ reaction4(y, u, bnode, data) = y[1] = -bnode[1]^2 + u[1]^4; bc4(f, u, node, data) = boundary_dirichlet!(f, u, node; value = 0); # ╔═╡ fe424654-f070-46a9-850a-738b1d4aca8f -system4 = VoronoiFVM.System(-10:0.1:10; - species = [1], - reaction = reaction4, - flux = multispecies_flux, - bcondition = bc4); +system4 = VoronoiFVM.System( + -10:0.1:10; + species = [1], + reaction = reaction4, + flux = multispecies_flux, + bcondition = bc4 +); # ╔═╡ 37fc8816-5ccd-436e-8335-ebb1218d8a35 sol4 = solve(system4; log = true, damp_initial = 0.001, damp_growth = 3); # ╔═╡ 6a256a29-f15f-4d82-8e84-7ceacb786715 -scalarplot(system4, - sol4; - resolution = (500, 300), - xlabel = "x", - ylabel = "u", - title = "solution") +scalarplot( + system4, + sol4; + resolution = (500, 300), + xlabel = "x", + ylabel = "u", + title = "solution" +) # ╔═╡ 5c2a3836-dc81-4950-88e5-7f603514b1c0 @test isapprox(sum(sol4), 418.58515700568535, rtol = 1.0e-14) diff --git a/pluto-examples/bernoulli.jl b/pluto-examples/bernoulli.jl index a50751f85..6cf754527 100644 --- a/pluto-examples/bernoulli.jl +++ b/pluto-examples/bernoulli.jl @@ -30,7 +30,7 @@ md""" # ╔═╡ b47b781b-ec11-485a-9de6-061ad0957f46 function B_Big(x) bx = BigFloat(x) - Float64(bx / expm1(bx)) + return Float64(bx / expm1(bx)) end # ╔═╡ 33f6b010-e0c4-4c7b-9cbd-460b8ba0f606 @@ -39,7 +39,7 @@ function DB_Big(x) bone = one(BigFloat) bex = exp(bx) b = -(x * bex - bex + bone) / ((bex - bone) * (bex - bone)) - Float64(b) + return Float64(b) end # ╔═╡ a0e3bf41-e5ca-4395-a26e-941a8b897705 @@ -48,7 +48,7 @@ md""" """ # ╔═╡ c95c09fe-ac77-4032-a455-2a13b0d7edc2 -B(x)=x/expm1(x) +B(x) = x / expm1(x) # ╔═╡ c3fd0ff2-7111-4165-ad93-d6d7257301fa md""" @@ -70,13 +70,13 @@ B(nextfloat(0.0)) fbernoulli(nextfloat(0.0)) # ╔═╡ cb10e915-b753-4cd5-9355-71558c83369c -derivative(B,0.0) +derivative(B, 0.0) # ╔═╡ a63959f9-ed7a-47dc-b253-78c763dd359f derivative(fbernoulli, 0.0) # ╔═╡ 16db7f90-7d23-4864-a059-38d09f3e5d3b -derivative(B,nextfloat(0.0)) +derivative(B, nextfloat(0.0)) # ╔═╡ 7678ad35-f29b-448c-bd85-247140d42456 derivative(fbernoulli, nextfloat(0.0)) @@ -89,7 +89,8 @@ let p = Figure( ; size = (600, 400), ) - ax = Axis(p[1, 1]; + ax = Axis( + p[1, 1]; title = "|B_Big(x)-B(x)|", xminorticksvisible = true, xminorgridvisible = true, @@ -97,13 +98,16 @@ let xticks = -0.5:0.1:0.5, yscale = log10, xlabel = "x", - ylabel = "error") + ylabel = "error" + ) - lines!(ax, + lines!( + ax, smallX, - abs.(B_Big.(smallX) .- B.(smallX)) .+ 1.0e-20; + abs.(B_Big.(smallX) .- B.(smallX)) .+ 1.0e-20 ) - ax2 = Axis(p[2, 1]; + ax2 = Axis( + p[2, 1]; title = "|B_Big(x)-VoronoiFVM.bernoulli_horner(x)|", xminorticksvisible = true, xminorgridvisible = true, @@ -111,10 +115,12 @@ let xticks = -0.5:0.1:0.5, yscale = log10, xlabel = "x", - ylabel = "error") - lines!(ax2, + ylabel = "error" + ) + lines!( + ax2, smallX, - abs.(B_Big.(smallX) .- VoronoiFVM.bernoulli_horner.(smallX)) .+ 1.0e-20; + abs.(B_Big.(smallX) .- VoronoiFVM.bernoulli_horner.(smallX)) .+ 1.0e-20 ) p end @@ -124,7 +130,8 @@ let p = Figure( ; size = (600, 400), ) - ax = Axis(p[1, 1]; + ax = Axis( + p[1, 1]; title = "|DB_Big(x)-derivative(B,x)|", xminorticksvisible = true, xminorgridvisible = true, @@ -132,13 +139,16 @@ let xticks = -0.5:0.1:0.5, yscale = log10, xlabel = "x", - ylabel = "error") + ylabel = "error" + ) - lines!(ax, + lines!( + ax, smallX, - abs.(DB_Big.(smallX) .- derivative.(B,smallX)) .+ 1.0e-20; + abs.(DB_Big.(smallX) .- derivative.(B, smallX)) .+ 1.0e-20 ) - ax2 = Axis(p[2, 1]; + ax2 = Axis( + p[2, 1]; title = "|DB_Big(x)-derivative(bernoulli_horner,x)|", xminorticksvisible = true, xminorgridvisible = true, @@ -146,10 +156,12 @@ let xticks = -0.5:0.1:0.5, yscale = log10, xlabel = "x", - ylabel = "error") - lines!(ax2, + ylabel = "error" + ) + lines!( + ax2, smallX, - abs.(DB_Big.(smallX) .- derivative.(VoronoiFVM.bernoulli_horner,smallX)) .+ 1.0e-20; + abs.(DB_Big.(smallX) .- derivative.(VoronoiFVM.bernoulli_horner, smallX)) .+ 1.0e-20 ) p end @@ -173,16 +185,19 @@ let vf = first.(fbernoulli_pm.(smallX)) err = abs.(bf - vf) ./ bf maxerr = maximum(err) - ax1 = Axis(p[1, 0:2]; + ax1 = Axis( + p[1, 0:2]; title = "Maximum relative error for small x: $maxerr", xminorticksvisible = true, xminorgridvisible = true, xminorticks = IntervalsBetween(10), xticks = -0.5:0.1:0.5, xlabel = "x", - ylabel = "error") + ylabel = "error" + ) - lines!(ax1, + lines!( + ax1, smallX, err; color = :red @@ -193,20 +208,24 @@ let err = abs.(bf - vf) maxerr = maximum(err) - ax2 = Axis(p[2, 0:2]; + ax2 = Axis( + p[2, 0:2]; title = "Maximum absolute error for large x: $maxerr", xminorticksvisible = true, xminorgridvisible = true, xminorticks = IntervalsBetween(4), xticks = -100:20:100, xlabel = "x", - ylabel = "error") + ylabel = "error" + ) - lines!(ax2, + lines!( + ax2, largeX, err; - color = :red) - save("bernoulli_posarg.png",p) + color = :red + ) + save("bernoulli_posarg.png", p) p end @@ -222,15 +241,18 @@ let err = abs.(bf - vf) ./ bf maxerr = maximum(err) - ax1 = Axis(p[1, 0:2]; + ax1 = Axis( + p[1, 0:2]; title = "Maximum relative error for small x: $(maxerr)", xminorticksvisible = true, xminorgridvisible = true, xminorticks = IntervalsBetween(10), xticks = -0.5:0.1:0.5, xlabel = "x", - ylabel = "error") - lines!(ax1, + ylabel = "error" + ) + lines!( + ax1, smallX, err; color = :red @@ -240,20 +262,24 @@ let vf = last.(fbernoulli_pm.(largeX)) err = abs.(bf - vf) maxerr = maximum(err) - ax2 = Axis(p[2, 0:2]; + ax2 = Axis( + p[2, 0:2]; title = "Maximum absolute error for large x: $maxerr", xminorticksvisible = true, xminorgridvisible = true, xminorticks = IntervalsBetween(4), xticks = -100:20:100, xlabel = "x", - ylabel = "error") + ylabel = "error" + ) - lines!(ax2, + lines!( + ax2, largeX, err; - color = :red) - save("bernoulli_negarg.png",p) + color = :red + ) + save("bernoulli_negarg.png", p) p end @@ -274,15 +300,18 @@ let err = abs.(bf - vf) ./ abs.(bf) maxerr = maximum(err) - ax1 = Axis(p[1, 0:2]; + ax1 = Axis( + p[1, 0:2]; title = "Maximum relative error for small x: $maxerr", xminorticksvisible = true, xminorgridvisible = true, xminorticks = IntervalsBetween(10), xticks = -0.5:0.1:0.5, xlabel = "x", - ylabel = "error") + ylabel = "error" + ) - lines!(ax1, + lines!( + ax1, smallX, err; color = :red @@ -292,20 +321,24 @@ let vf = derivative.(fbernoulli, largeX) err = abs.(bf - vf) maxerr = maximum(err) - ax2 = Axis(p[2, 0:2]; + ax2 = Axis( + p[2, 0:2]; title = "Maximum absolute error for large x: $maxerr", xminorticksvisible = true, xminorgridvisible = true, xminorticks = IntervalsBetween(4), xticks = -100:20:100, xlabel = "x", - ylabel = "error") + ylabel = "error" + ) - lines!(ax2, + lines!( + ax2, largeX, err; - color = :red) -save("bernoulli_derivative.png",p) + color = :red + ) + save("bernoulli_derivative.png", p) p end diff --git a/pluto-examples/flux-reconstruction.jl b/pluto-examples/flux-reconstruction.jl index dc7f7b6ef..4d2f08876 100644 --- a/pluto-examples/flux-reconstruction.jl +++ b/pluto-examples/flux-reconstruction.jl @@ -7,7 +7,7 @@ using InteractiveUtils # This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). macro bind(def, element) #! format: off - quote + return quote local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end local el = $(esc(element)) global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) @@ -55,13 +55,15 @@ Define a "Swiss cheese domain" with punched-out holes, where each hole boundary # ╔═╡ 928a70c5-4706-40a1-9387-abcb71c09443 function swiss_cheese_2d() function circlehole!(builder, center, radius; n = 20) - points = [point!(builder, center[1] + radius * sin(t), center[2] + radius * cos(t)) - for t in range(0, 2π; length = n)] - for i = 1:(n - 1) + points = [ + point!(builder, center[1] + radius * sin(t), center[2] + radius * cos(t)) + for t in range(0, 2π; length = n) + ] + for i in 1:(n - 1) facet!(builder, points[i], points[i + 1]) end facet!(builder, points[end], points[1]) - holepoint!(builder, center) + return holepoint!(builder, center) end builder = SimplexGridBuilder(; Generator = Triangulate) @@ -80,24 +82,26 @@ function swiss_cheese_2d() facet!(builder, p3, p4) facet!(builder, p4, p1) - holes = [1.0 2.0 - 8.0 9.0 - 2.0 8.0 - 8.0 4.0 - 9.0 1.0 - 3.0 4.0 - 4.0 6.0 - 7.0 9.0 - 4.0 7.0 - 7.0 5.0 - 2.0 1.0 - 4.0 1.0 - 4.0 8.0 - 3.0 6.0 - 4.0 9.0 - 6.0 9.0 - 3.0 5.0 - 1.0 4.0]' + holes = [ + 1.0 2.0 + 8.0 9.0 + 2.0 8.0 + 8.0 4.0 + 9.0 1.0 + 3.0 4.0 + 4.0 6.0 + 7.0 9.0 + 4.0 7.0 + 7.0 5.0 + 2.0 1.0 + 4.0 1.0 + 4.0 8.0 + 3.0 6.0 + 4.0 9.0 + 6.0 9.0 + 3.0 5.0 + 1.0 4.0 + ]' radii = [ 0.15, @@ -120,12 +124,12 @@ function swiss_cheese_2d() 0.25, ] - for i = 1:length(radii) + for i in 1:length(radii) facetregion!(builder, i + 1) circlehole!(builder, holes[:, i], radii[i]) end - simplexgrid(builder) + return simplexgrid(builder) end # ╔═╡ bc304085-69c3-4974-beb4-6f2b981ac0f1 @@ -165,6 +169,7 @@ function bc(y, u, bnode, data) boundary_dirichlet!(y, u, bnode; region = 2, value = 10.0) boundary_dirichlet!(y, u, bnode; region = 3, value = 0.0) boundary_dirichlet!(y, u, bnode; region = 11, value = data.val11) + return nothing end # ╔═╡ f4ebe6ad-4e04-4f33-9a66-6bec977adf4d @@ -249,17 +254,20 @@ flux1d(y, u, edge, data) = y[1] = u[1, 1]^2 - u[1, 2]^2 function bc1d(y, u, bnode, data) boundary_dirichlet!(y, u, bnode; region = 1, value = 0.01) boundary_dirichlet!(y, u, bnode; region = 2, value = 0.01) + return nothing end # ╔═╡ 159ffdb7-a5d9-45bd-a53f-ba3751c91ae5 grid1d = simplexgrid(-1:0.01:1) # ╔═╡ 29257fc4-d94b-4cf1-8432-30ba3fc4dc1b -sys1d = VoronoiFVM.System(grid1d; - flux = flux1d, - bcondition = bc1d, - source = source1d, - species = [1],) +sys1d = VoronoiFVM.System( + grid1d; + flux = flux1d, + bcondition = bc1d, + source = source1d, + species = [1], +) # ╔═╡ d8df038e-9cfc-4eb4-9845-2244ac95190b sol1d = solve(sys1d; inival = 0.1) diff --git a/pluto-examples/heterogeneous-catalysis.jl b/pluto-examples/heterogeneous-catalysis.jl index cde82a4c1..54dec3354 100644 --- a/pluto-examples/heterogeneous-catalysis.jl +++ b/pluto-examples/heterogeneous-catalysis.jl @@ -6,8 +6,12 @@ using InteractiveUtils # This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). macro bind(def, element) - quote - local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end + return quote + local iv = try + Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value + catch + b -> missing + end local el = $(esc(element)) global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) el @@ -17,10 +21,10 @@ end # ╔═╡ f75a3225-c7bf-4031-89c7-a792a592f639 # Some tricks helping to run the notebook during VoronoiFVM.jl CI begin - doplots=!haskey(ENV,"VORONOIFVM_RUNTESTS") + doplots = !haskey(ENV, "VORONOIFVM_RUNTESTS") import Pkg as _Pkg haskey(ENV, "PLUTO_PROJECT") && _Pkg.activate(ENV["PLUTO_PROJECT"]) - using Revise + using Revise end # ╔═╡ e04d9162-e6ed-4e9f-86ce-51b5175f8103 @@ -28,21 +32,21 @@ begin using SciMLBase: ODEProblem, solve using OrdinaryDiffEqLowOrderRK: DP5 using OrdinaryDiffEqRosenbrock: Rosenbrock23 - using OrdinaryDiffEqTsit5:Tsit5 + using OrdinaryDiffEqTsit5: Tsit5 using Catalyst using VoronoiFVM: VoronoiFVM, enable_species!, enable_boundary_species! - using VoronoiFVM: ramp, boundary_dirichlet! - using ExtendableGrids: simplexgrid - using GridVisualize: GridVisualize, GridVisualizer, reveal, scalarplot!, gridplot, available_kwargs - if doplots # defined in the Appendix - using Plots: Plots, plot, theme - using PlotThemes - Plots.gr() - Plots.theme(:dark) - GridVisualize.default_plotter!(Plots) - end + using VoronoiFVM: ramp, boundary_dirichlet! + using ExtendableGrids: simplexgrid + using GridVisualize: GridVisualize, GridVisualizer, reveal, scalarplot!, gridplot, available_kwargs + if doplots # defined in the Appendix + using Plots: Plots, plot, theme + using PlotThemes + Plots.gr() + Plots.theme(:dark) + GridVisualize.default_plotter!(Plots) + end import PlutoUI - using Test + using Test PlutoUI.TableOfContents(; depth = 4) end @@ -155,7 +159,7 @@ function example1(du, u, p, t) (; k_p, k_m) = p r1 = k_p * u[1] - k_m * u[2] du[1] = -r1 - du[2] = r1 + return du[2] = r1 end # ╔═╡ b68ec599-6e71-4522-ac1a-03dcd94b7668 @@ -205,7 +209,7 @@ the resulting reaction system. So we use this to build the same system: # ╔═╡ 6a246460-b389-4737-b264-cecfe19ecd4e rn1 = @reaction_network rn1 begin - @combinatoric_ratelaws false + @combinatoric_ratelaws false k_p, A --> B k_m, B --> A end @@ -342,14 +346,16 @@ end convert(ODESystem, rn3) # ╔═╡ 5cb92c3c-299f-4077-9ff8-012e24d3f9e8 -p3 = (k_0A = 0.5, k_0B = 1, - k_1p = 10, k_1m = 0.1, - k_2p = 10, k_2m = 0.1, - k_3p = 10, k_3m = 0.1, - k_4p = 10, k_4m = 0.1) +p3 = ( + k_0A = 0.5, k_0B = 1, + k_1p = 10, k_1m = 0.1, + k_2p = 10, k_2m = 0.1, + k_3p = 10, k_3m = 0.1, + k_4p = 10, k_4m = 0.1, +) # ╔═╡ 66500aa5-c2ec-4821-a926-658307614dd5 -Cini=40 +Cini = 40 # ╔═╡ 9f20138a-74fd-4468-8c4d-92109f39545a u3_ini = (A = 0, B = 0, CA = 0, CB = 0, CAB2 = 0, AB2 = 0, C = Cini) @@ -373,7 +379,7 @@ ctotal = rn3.C + rn3.CA + rn3.CB + rn3.CAB2 sol3[ctotal] # ╔═╡ 58a527cf-2873-4d2d-ae8f-ffbfe6b10e22 -@test sol3[ctotal]≈ fill(Cini,length(sol3)) +@test sol3[ctotal] ≈ fill(Cini, length(sol3)) # ╔═╡ 907c5c4d-e052-49ee-b96c-adcd37a9cf42 md""" @@ -468,7 +474,7 @@ rnv = @reaction_network rnv begin end # ╔═╡ f0501240-75e9-425b-8690-81a8284aef28 -odesys=convert(ODESystem, rnv) +odesys = convert(ODESystem, rnv) # ╔═╡ 68a4d03f-a526-4d37-a45e-c951432e20e7 eqns = equations(odesys); @@ -511,7 +517,7 @@ Grid: grid = simplexgrid(0:0.01:1) # ╔═╡ 8abc6bb4-afe6-42a8-84a6-a38c81d0bcc0 -gridplot(grid, size=(600,100)) +gridplot(grid, size = (600, 100)) # ╔═╡ 794d1fac-3c30-4c11-826b-50e198ddf874 md""" @@ -524,10 +530,12 @@ Reaction parameters: """ # ╔═╡ bcc319bc-6586-428d-ba56-7ea25b2deed9 -pcat = (k_1p = 50, k_1m = 0.1, - k_2p = 50, k_2m = 0.1, - k_3p = 10, k_3m = 0.1, - k_4p = 50, k_4m = 0.1) +pcat = ( + k_1p = 50, k_1m = 0.1, + k_2p = 50, k_2m = 0.1, + k_3p = 10, k_3m = 0.1, + k_4p = 50, k_4m = 0.1, +) # ╔═╡ 424a6774-9205-4da8-b8a5-943a50039934 md""" @@ -535,10 +543,12 @@ Parameters for the VoronoiFVM system: """ # ╔═╡ 5b7ed6f1-0969-4bdd-9c58-676c2e3f3635 -params = (D_A = 1.0, - D_B = 1.0, - D_AB2 = 1.0, - pcat = pcat) +params = ( + D_A = 1.0, + D_B = 1.0, + D_AB2 = 1.0, + pcat = pcat, +) # ╔═╡ e08ce9e1-2dd7-4852-91e6-75745a67d69f md""" @@ -571,7 +581,7 @@ First, define flux and storage functions for the bulk process: function storage(y, u, node, p) y[iA] = u[iA] y[iB] = u[iB] - y[iAB2] = u[iAB2] + return y[iAB2] = u[iAB2] end # ╔═╡ 249d1d2a-9dbd-4853-842b-a3efdb5d2012 @@ -579,7 +589,7 @@ function flux(y, u, edge, p) (; D_A, D_B, D_AB2) = p y[iA] = D_A * (u[iA, 1] - u[iA, 2]) y[iB] = D_B * (u[iB, 1] - u[iB, 2]) - y[iAB2] = D_A * (u[iAB2, 1] - u[iAB2, 2]) + return y[iAB2] = D_A * (u[iAB2, 1] - u[iAB2, 2]) end # ╔═╡ d5624271-dd74-480d-9b45-d276185243a9 @@ -592,7 +602,7 @@ function bstorage(y, u, bnode, p) y[iC] = u[iC] y[iCA] = u[iCA] y[iCB] = u[iCB] - y[iCAB2] = u[iCAB2] + return y[iCAB2] = u[iCAB2] end # ╔═╡ 3ca90bdc-ec53-4aea-b4ee-ecd2c348d262 @@ -608,9 +618,10 @@ instead of `pcat`. # ╔═╡ 1cfb9878-453a-438b-9383-ada79b44ad1f function catreaction(f, u, bnode, p) probv.f(f, u, probv.p, bnode.time) - for i = 1:length(f) + for i in 1:length(f) f[i] = -f[i] end + return end # ╔═╡ 063f72b8-f021-49a3-bdb2-79aef69fdcff @@ -623,7 +634,7 @@ function bulkbc(f, u, bnode, p) v = ramp(bnode.time; du = (0.0, 1.0), dt = (0.0, 0.01)) boundary_dirichlet!(f, u, bnode; species = iA, value = v, region = 2) boundary_dirichlet!(f, u, bnode; species = iB, value = v, region = 2) - boundary_dirichlet!(f, u, bnode; species = iAB2, value = 0, region = 2) + return boundary_dirichlet!(f, u, bnode; species = iAB2, value = 0, region = 2) end # ╔═╡ 8374742e-d557-4fef-9ae1-2d8644bbcd6c @@ -633,10 +644,10 @@ Dispatch the boundary conditions # ╔═╡ 461b603f-cee2-4731-825b-0a017fed162e function breaction(f, u, bnode, p) - if bnode.region == 1 - catreaction(f,u,bnode,p) + return if bnode.region == 1 + catreaction(f, u, bnode, p) else - bulkbc(f,u,bnode,p) + bulkbc(f, u, bnode, p) end end @@ -657,9 +668,11 @@ for the surface species values in the bulk. # ╔═╡ 41763843-a4fe-4adb-84af-c115a37bc265 begin - sys = VoronoiFVM.System(grid; data = params, - flux, breaction, bstorage, storage, - unknown_storage = :sparse) + sys = VoronoiFVM.System( + grid; data = params, + flux, breaction, bstorage, storage, + unknown_storage = :sparse + ) enable_species!(sys, iA, [1]) enable_species!(sys, iB, [1]) enable_species!(sys, iAB2, [1]) @@ -702,7 +715,7 @@ t: $(@bind log_t_plot PlutoUI.Slider(-4:0.1:log10(tvend), default = 0.4)) # ╔═╡ 7f50d186-fad5-413b-bbc4-2d087474a72f let t_plot = round(10^log_t_plot; sigdigits = 3) - vis = GridVisualizer(;size = (600, 300), flimits = (0, 1), title = "Bulk concentrations: t=$t_plot", legend = :lt) + vis = GridVisualizer(; size = (600, 300), flimits = (0, 1), title = "Bulk concentrations: t=$t_plot", legend = :lt) sol = tsol(t_plot) scalarplot!(vis, grid, sol[iA, :]; color = :red, label = "A") scalarplot!(vis, grid, sol[iB, :]; color = :green, label = "B", clear = false) @@ -714,14 +727,16 @@ end Ctotalv = tsol[iC, 1, :] + tsol[iCA, 1, :] + tsol[iCB, 1, :] + tsol[iCAB2, 1, :] # ╔═╡ a83e969e-ba25-4b6b-83e4-6febed1e8602 -@test Ctotalv≈ ones(length(tsol)) +@test Ctotalv ≈ ones(length(tsol)) # ╔═╡ 2eeb7d1a-25bc-4c09-bc86-a998a7bf3ca7 let - vis = GridVisualizer(; size = (600, 300), - xlabel="t", - flimits = (0, 1), xlimits = (1.0e-3, tvend), - legend = :lt, title = "Concentrations at x=0", xscale = :log10) + vis = GridVisualizer(; + size = (600, 300), + xlabel = "t", + flimits = (0, 1), xlimits = (1.0e-3, tvend), + legend = :lt, title = "Concentrations at x=0", xscale = :log10 + ) t = tsol.t scalarplot!(vis, t, tsol[iA, 1, :]; color = :darkred, label = "A") scalarplot!(vis, t, tsol[iCA, 1, :]; color = :red, label = "CA") diff --git a/pluto-examples/interfaces1d.jl b/pluto-examples/interfaces1d.jl index d9ca6cc3a..091625075 100644 --- a/pluto-examples/interfaces1d.jl +++ b/pluto-examples/interfaces1d.jl @@ -121,6 +121,7 @@ function flux!(f, u, edge, data) if edge.region == 2 f[2] = u[2, 1] - u[2, 2] end + return nothing end # ╔═╡ dbd27f10-9fd9-450d-9f78-89ea738d605b @@ -151,11 +152,11 @@ function make_system(breaction) enable_species!(sys, 2, [2]) ## Set boundary conditions - for ispec = 1:2 + for ispec in 1:2 boundary_dirichlet!(sys, ispec, 1, g_1) boundary_dirichlet!(sys, ispec, 2, g_2) end - sys + return sys end # ╔═╡ de251b03-dd3a-4a44-9440-b7e654c32dac @@ -168,7 +169,7 @@ function mysolve(sys) U = solve(sys) U1 = view(U[1, :], subgrid1) U2 = view(U[2, :], subgrid2) - U1, U2 + return U1, U2 end # ╔═╡ 0735c061-68e1-429f-80f1-d8410989a91d @@ -179,23 +180,27 @@ Plot the results # ╔═╡ 467dc381-3b3d-4de7-a7f9-bfc51300832b function plot(U1, U2; title = "") vis = GridVisualizer(; resolution = (600, 300)) - scalarplot!(vis, - subgrid1, - U1; - clear = false, - show = false, - color = :green, - label = "u1") - scalarplot!(vis, - subgrid2, - U2; - clear = false, - show = true, - color = :blue, - label = "u2", - legend = :rt, - title = title, - flimits = (-0.5, 1.5)) + scalarplot!( + vis, + subgrid1, + U1; + clear = false, + show = false, + color = :green, + label = "u1" + ) + return scalarplot!( + vis, + subgrid2, + U2; + clear = false, + show = true, + color = :blue, + label = "u2", + legend = :rt, + title = title, + flimits = (-0.5, 1.5) + ) end # ╔═╡ fa4fcc0d-1d3a-45a2-8857-50536bbe39cc @@ -206,7 +211,9 @@ This means we set ``f_1(u_1,u_2)=0`` and ``f_2(u_1,u_2)=0``. """ # ╔═╡ 8f210696-fcf4-47bc-a5a2-c561ad7efcbd -function noreaction(f, u, node, data) end +function noreaction(f, u, node, data) + return nothing +end # ╔═╡ 57e8515e-3be1-4478-af98-430501438ee7 system1 = make_system(noreaction); @@ -254,6 +261,7 @@ function mal_reaction(f, u, node, data) f[1] = react f[2] = -react end + return nothing end # ╔═╡ 610a0761-1c23-415d-a187-f7d93a1b7637 @@ -287,6 +295,7 @@ function penalty_reaction(f, u, node, data) f[1] = react f[2] = -react end + return nothing end # ╔═╡ 817738c0-f1a3-4779-9075-7ea051a81e73 @@ -312,6 +321,7 @@ function penalty_jump_reaction(f, u, node, data) f[1] = react f[2] = -react end + return nothing end # ╔═╡ 19b6dc1f-5e56-4487-be06-2ce90b030290 @@ -347,6 +357,7 @@ function recombination(f, u, node, data) f[1] = react f[2] = react end + return nothing end; # ╔═╡ 644149fb-2264-42bd-92c9-193ab07c08f6 @@ -395,6 +406,7 @@ function thinlayer(f, u, node, data) f[1] = react f[2] = -react end + return nothing end # ╔═╡ 8c0b4ab5-09da-4d8f-b001-5e15f823423c @@ -432,14 +444,14 @@ We define a grid with N=$(N) subregions begin XX = collect(0:0.1:1) local xcoord = XX - for i = 1:(N - 1) + for i in 1:(N - 1) xcoord = glue(xcoord, XX .+ i) end grid2 = simplexgrid(xcoord) - for i = 1:N + for i in 1:N cellmask!(grid2, [i - 1], [i], i) end - for i = 1:(N - 1) + for i in 1:(N - 1) bfacemask!(grid2, [i], [i], i + 2) end end @@ -469,7 +481,7 @@ A discontinuous quantity can be introduced as well. by default, each reagion get """ # ╔═╡ 90298676-fda7-4168-8a40-7ff53e7c761b -const dspec = DiscontinuousQuantity(system6, 1:N; regionspec = [2 + i % 2 for i = 1:N]) +const dspec = DiscontinuousQuantity(system6, 1:N; regionspec = [2 + i % 2 for i in 1:N]) # ╔═╡ cebabf33-e769-47bd-b6f1-ddf525fea895 md""" @@ -479,7 +491,7 @@ For both quantities, we define simple diffusion fluxes: # ╔═╡ 719f206a-5b9f-4d78-8778-1d89edb2bc4d function flux2(f, u, edge, data) f[dspec] = u[dspec, 1] - u[dspec, 2] - f[cspec] = u[cspec, 1] - u[cspec, 2] + return f[cspec] = u[cspec, 1] - u[cspec, 2] end # ╔═╡ 1d7f442f-c057-4379-8a40-c6ce3646ad5c @@ -511,6 +523,7 @@ function breaction2(f, u, node, data) f[cspec] = -q1 end + return nothing end # ╔═╡ 59c83a22-a4cc-4b51-a1cc-5eb39588eacd @@ -538,23 +551,27 @@ function plot2(U, subgrids, system6) dvws = VoronoiFVM.views(U, dspec, allsubgrids, system6) cvws = VoronoiFVM.views(U, cspec, allsubgrids, system6) vis = GridVisualizer(; resolution = (600, 300), legend = :rt) - scalarplot!(vis, - allsubgrids, - grid2, - dvws; - flimits = (-0.5, 1.5), - clear = false, - color = :red, - label = "discontinuous species") - scalarplot!(vis, - allsubgrids, - grid2, - cvws; - flimits = (-0.5, 1.5), - clear = false, - color = :green, - label = "continuous species") - reveal(vis) + scalarplot!( + vis, + allsubgrids, + grid2, + dvws; + flimits = (-0.5, 1.5), + clear = false, + color = :red, + label = "discontinuous species" + ) + scalarplot!( + vis, + allsubgrids, + grid2, + cvws; + flimits = (-0.5, 1.5), + clear = false, + color = :green, + label = "continuous species" + ) + return reveal(vis) end # ╔═╡ d58407fe-dcd4-47bb-a65e-db5fedb58edc @@ -579,34 +596,34 @@ begin highlight(mdstring, color) = htl"""
$(mdstring)
""" macro important_str(s) - :(highlight(Markdown.parse($s), "#ffcccc")) + return :(highlight(Markdown.parse($s), "#ffcccc")) end macro definition_str(s) - :(highlight(Markdown.parse($s), "#ccccff")) + return :(highlight(Markdown.parse($s), "#ccccff")) end macro statement_str(s) - :(highlight(Markdown.parse($s), "#ccffcc")) + return :(highlight(Markdown.parse($s), "#ccffcc")) end html""" - -""" + + """ end # ╔═╡ b5a87200-eea5-4164-bfd5-dee1045a0464 diff --git a/pluto-examples/interfaces2d.jl b/pluto-examples/interfaces2d.jl index aa7485e5b..0fa600f93 100644 --- a/pluto-examples/interfaces2d.jl +++ b/pluto-examples/interfaces2d.jl @@ -61,7 +61,7 @@ function tworegiongrid(; minangle = 20) 0.2 0.2 Ω_1 0.18 0.8 0.2 Ω_2 0.18 ]' - (triout, vorout) = triangulate("paAq$(angle)DQv", triin) + return (triout, vorout) = triangulate("paAq$(angle)DQv", triin) end # ╔═╡ 40795d22-6091-4498-bd07-f716fb07682e @@ -70,7 +70,7 @@ function plot_with_numbers(triout, vorout) Triangulate.plot_triangulateio(PyPlot, triout, voronoi = vorout) PyPlot.scatter(triout.pointlist[1, :], triout.pointlist[2, :], color = :red, alpha = 1) dxy = [-0.03, 0.01] - for ipoint = 1:size(triout.pointlist, 2) + for ipoint in 1:size(triout.pointlist, 2) PyPlot.text( (dxy .+ triout.pointlist[:, ipoint])..., "$(ipoint)", @@ -78,7 +78,7 @@ function plot_with_numbers(triout, vorout) color = :red, ) end - for ipoint = 1:size(vorout.pointlist, 2) + for ipoint in 1:size(vorout.pointlist, 2) PyPlot.text( (dxy .+ vorout.pointlist[:, ipoint])..., "$(ipoint)", @@ -86,7 +86,7 @@ function plot_with_numbers(triout, vorout) color = :green, ) end - PyPlot.gcf() + return PyPlot.gcf() end # ╔═╡ d55fdbfc-3f34-11eb-3f35-c3bcdb156288 @@ -303,7 +303,6 @@ We introduce the height of this thin layer by following variable as a variable f """ - # ╔═╡ 3b429e0c-c07a-40df-ab0b-1f71d515ece3 n = 3 @@ -318,28 +317,34 @@ begin else f[1] = dA_bulk * (u[1, 1] - u[1, 2]) end + return nothing end function fluxB!(f, u, edge) f[1] = dB_bulk * (u[1, 1] - u[1, 2]) + return nothing end function reaction!(f, u, node) f[1] = k * u[1] + return nothing end function source!(f, node) f[1] = c + return nothing end function bfluxB!(f, u, bedge) if bedge.region == 3 f[1] = thin_layer * dbB_interface * (u[1, 1] - u[1, 2]) end + return nothing end function bfluxA!(f, u, bedge) f[1] = 0.0 + return nothing end end @@ -574,7 +579,7 @@ begin ), ) - # enable species in all regions + # enable species in all regions enable_species!(sysA, ispec_flux, regionsA) enable_species!(sysB, ispec_flux, regionsB) @@ -587,8 +592,8 @@ begin ## Stationary solution of both problems - solA=solve(sysA) - solB=solve(sysB) + solA = solve(sysA) + solB = solve(sysB) end # ╔═╡ 80cfa231-23b1-48a3-a5ad-ee0e122da746 @@ -602,7 +607,7 @@ begin ) # this is for variable transformation, since we consider right outer boundary and want to transform to x-axis. function tran32!(a, b) - a[1] = b[2] + return a[1] = b[2] end # note that if adjusting active_boundary to 3 or 4, then transform needs to be deleted. diff --git a/pluto-examples/nbproto.jl b/pluto-examples/nbproto.jl index f6c763d69..45e2eb430 100644 --- a/pluto-examples/nbproto.jl +++ b/pluto-examples/nbproto.jl @@ -37,21 +37,21 @@ scalarplot(sin.(0:0.1:10), size = (500, 200)) @test 1 == 1 # ╔═╡ e7bb8e62-228b-4b80-824b-31ea22543fba -let figure=Figure() -axis=Axis(figure[1,1], aspect = DataAspect()) -X=0:0.1:1 -Y=0:0.1:1 -pts=[Point2f(x,y) for y in X, x in X] -li=LinearIndices(pts) -for j=1:length(Y)-1 - for i=1:length(X)-1 - t1=[li[i,j], li[i+1,j], li[i+1,j+1]] - @views poly!(axis,pts[t1], strokecolor=:black, color=:red, strokewidth=1) - t2=[li[i,j], li[i,j+1], li[i+1,j+1]] - @views poly!(axis,pts[t2], strokecolor=:black, color=:red, strokewidth=1) +let figure = Figure() + axis = Axis(figure[1, 1], aspect = DataAspect()) + X = 0:0.1:1 + Y = 0:0.1:1 + pts = [Point2f(x, y) for y in X, x in X] + li = LinearIndices(pts) + for j in 1:(length(Y) - 1) + for i in 1:(length(X) - 1) + t1 = [li[i, j], li[i + 1, j], li[i + 1, j + 1]] + @views poly!(axis, pts[t1], strokecolor = :black, color = :red, strokewidth = 1) + t2 = [li[i, j], li[i, j + 1], li[i + 1, j + 1]] + @views poly!(axis, pts[t2], strokecolor = :black, color = :red, strokewidth = 1) + end end -end -figure + figure end # ╔═╡ 9b8e9cd1-2b90-49b4-a7cf-51b8378e4db4 diff --git a/pluto-examples/nonlinear-solvers.jl b/pluto-examples/nonlinear-solvers.jl index f208d45cf..ff084dc51 100644 --- a/pluto-examples/nonlinear-solvers.jl +++ b/pluto-examples/nonlinear-solvers.jl @@ -58,12 +58,14 @@ function reaction(y, u, node, data) eplus = exp(u[1]) eminus = 1 / eplus y[1] = eplus - eminus + return nothing end # ╔═╡ eab04557-5084-4174-b275-b4d4399238e5 function bc(y, u, node, data) boundary_dirichlet!(y, u, node; region = 1, value = 100) boundary_dirichlet!(y, u, node; region = 2, value = 0.0) + return nothing end; # ╔═╡ 316112fd-6553-494a-8e4a-65b34829891d @@ -81,12 +83,14 @@ begin end; # ╔═╡ b9bb8020-5470-4964-818c-7f9b3bf2a8b4 -scalarplot(system, - sol; - resolution = (500, 200), - xlabel = "x", - ylable = "y", - title = "solution") +scalarplot( + system, + sol; + resolution = (500, 200), + xlabel = "x", + ylable = "y", + title = "solution" +) # ╔═╡ b3124c06-1f40-46f5-abee-9c2e8e538162 md""" @@ -101,13 +105,15 @@ The history can be plotted: # ╔═╡ 20e925f3-43fa-4db1-a656-79cf9c1c3303 function plothistory(h) - scalarplot(1:length(h), - h; - resolution = (500, 200), - yscale = :log, - xlabel = "step", - ylabel = "||δu||_∞", - title = "Maximum norm of Newton update") + return scalarplot( + 1:length(h), + h; + resolution = (500, 200), + yscale = :log, + xlabel = "step", + ylabel = "||δu||_∞", + title = "Maximum norm of Newton update" + ) end; # ╔═╡ ebdc2c82-f72e-4e35-a63f-4ba5154e294f @@ -197,28 +203,34 @@ If the solution is unsuccessful, the parameter stepsize is halved and solution i function pbc(y, u, node, data) boundary_dirichlet!(y, u, node; region = 1, value = 100 * embedparam(node)) boundary_dirichlet!(y, u, node; region = 2, value = 0) + return nothing end; # ╔═╡ 89435c65-0520-4430-8727-9d013df6182d -system2 = VoronoiFVM.System(X; - flux = flux, - reaction = function (y, u, node, data) - reaction(y, u, node, data) - - y[1] = y[1] * embedparam(node) - end, - bcondition = pbc, - species = 1,); +system2 = VoronoiFVM.System( + X; + flux = flux, + reaction = function (y, u, node, data) + reaction(y, u, node, data) + + y[1] = y[1] * embedparam(node) + return nothing + end, + bcondition = pbc, + species = 1, +); # ╔═╡ cb382145-c4f1-4222-aed7-32fa1e3bd7e4 begin - sol2 = solve(system2; - inival = 0, - log = true, - embed = (0, 1), - Δp = 0.1, - Δp_grow = 1.2, - Δu_opt = 15) + sol2 = solve( + system2; + inival = 0, + log = true, + embed = (0, 1), + Δp = 0.1, + Δp_grow = 1.2, + Δu_opt = 15 + ) history2 = history(sol2) end diff --git a/pluto-examples/ode-brusselator.jl b/pluto-examples/ode-brusselator.jl index b504ea940..a066a0d61 100644 --- a/pluto-examples/ode-brusselator.jl +++ b/pluto-examples/ode-brusselator.jl @@ -6,8 +6,12 @@ using InteractiveUtils # This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). macro bind(def, element) - quote - local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end + return quote + local iv = try + Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value + catch + b -> missing + end local el = $(esc(element)) global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) el @@ -18,20 +22,20 @@ end begin import Pkg as _Pkg haskey(ENV, "PLUTO_PROJECT") && _Pkg.activate(ENV["PLUTO_PROJECT"]) - using Test - using Revise - using Printf - using VoronoiFVM - using OrdinaryDiffEqBDF - using OrdinaryDiffEqRosenbrock - using OrdinaryDiffEqSDIRK - using LinearAlgebra - using PlutoUI - using ExtendableGrids - using DataStructures - using GridVisualize,CairoMakie + using Test + using Revise + using Printf + using VoronoiFVM + using OrdinaryDiffEqBDF + using OrdinaryDiffEqRosenbrock + using OrdinaryDiffEqSDIRK + using LinearAlgebra + using PlutoUI + using ExtendableGrids + using DataStructures + using GridVisualize, CairoMakie default_plotter!(CairoMakie) - CairoMakie.activate!(type="svg") + CairoMakie.activate!(type = "svg") end # ╔═╡ adea3b1c-854f-4f9d-9013-ab6a2a6f7fd7 @@ -52,60 +56,65 @@ Two species diffusing and interacting via a reaction # ╔═╡ 32107aac-050d-4f50-b95c-383e1bb38652 -begin - const bruss_A=2.25 - const bruss_B=7.0 - const bruss_D_1=0.025 - const bruss_D_2=0.25 - const pert=0.1 - const bruss_tend=150 +begin + const bruss_A = 2.25 + const bruss_B = 7.0 + const bruss_D_1 = 0.025 + const bruss_D_2 = 0.25 + const pert = 0.1 + const bruss_tend = 150 end; # ╔═╡ 2fb1c53a-7ff8-4ac9-ae78-83bcbc57c926 -function bruss_storage(f,u,node,data) - f[1]=u[1] - f[2]=u[2] +function bruss_storage(f, u, node, data) + f[1] = u[1] + f[2] = u[2] + return nothing end; # ╔═╡ 71b7e770-5cd4-4671-a76a-8e29eda04eec -function bruss_diffusion(f,u,edge,data) - f[1]=bruss_D_1*(u[1,1]-u[1,2]) - f[2]=bruss_D_2*(u[2,1]-u[2,2]) +function bruss_diffusion(f, u, edge, data) + f[1] = bruss_D_1 * (u[1, 1] - u[1, 2]) + f[2] = bruss_D_2 * (u[2, 1] - u[2, 2]) + return nothing end; # ╔═╡ f1e7a242-d631-4624-b0c0-ac44f139d77c -function bruss_reaction(f,u,node,data) - f[1]= (bruss_B+1.0)*u[1]-bruss_A-u[1]^2*u[2] - f[2]= u[1]^2*u[2]-bruss_B*u[1] +function bruss_reaction(f, u, node, data) + f[1] = (bruss_B + 1.0) * u[1] - bruss_A - u[1]^2 * u[2] + f[2] = u[1]^2 * u[2] - bruss_B * u[1] + return nothing end; # ╔═╡ 7e214c83-9c5c-40a9-8b00-db79dfec9a88 -diffeqmethods=OrderedDict( -"Rosenbrock23 (Rosenbrock)" => Rosenbrock23, -"QNDF2 (Like matlab's ode15s)" => QNDF2, -"FBDF" => FBDF, -"Implicit Euler" => ImplicitEuler +diffeqmethods = OrderedDict( + "Rosenbrock23 (Rosenbrock)" => Rosenbrock23, + "QNDF2 (Like matlab's ode15s)" => QNDF2, + "FBDF" => FBDF, + "Implicit Euler" => ImplicitEuler ) # ╔═╡ 95be1da7-5f98-4a15-bd8e-7db1ee324768 begin - - function ODESolver(system,inival,solver) - state=VoronoiFVM.SystemState(system) - problem = ODEProblem(state,inival,(0,bruss_tend)) - odesol = solve(problem, - solver, - dt=1.0e-5,reltol=1.0e-4) - reshape(odesol,system;state) -end; - sys0=VoronoiFVM.System(simplexgrid(0:0.1:1),species=[1,2],flux=bruss_diffusion, storage=bruss_storage, reaction=bruss_reaction); - problem0 = ODEProblem(sys0,unknowns(sys0),(0,0.1)) + function ODESolver(system, inival, solver) + state = VoronoiFVM.SystemState(system) + problem = ODEProblem(state, inival, (0, bruss_tend)) + odesol = solve( + problem, + solver, + dt = 1.0e-5, reltol = 1.0e-4 + ) + return reshape(odesol, system; state) + end + + sys0 = VoronoiFVM.System(simplexgrid(0:0.1:1), species = [1, 2], flux = bruss_diffusion, storage = bruss_storage, reaction = bruss_reaction) + problem0 = ODEProblem(sys0, unknowns(sys0), (0, 0.1)) - for method in diffeqmethods - solve(problem0,method.second())#precompile - end + for method in diffeqmethods + solve(problem0, method.second()) #precompile + end end # ╔═╡ 1462d783-93d3-4ad4-8701-90bde88c7553 @@ -114,48 +123,50 @@ dim:$(@bind bruss_dim Scrubbable(1:2,default=1)) ``\;`` method: $(@bind bruss_m """ # ╔═╡ d48ad585-9d0a-4b7e-a54b-3c76d8a5ca21 -if bruss_dim==1 - bruss_X=-1:0.01:1 - bruss_grid=simplexgrid(bruss_X) - else - bruss_X=-1:0.1:1 - bruss_grid=simplexgrid(bruss_X,bruss_X) +if bruss_dim == 1 + bruss_X = -1:0.01:1 + bruss_grid = simplexgrid(bruss_X) +else + bruss_X = -1:0.1:1 + bruss_grid = simplexgrid(bruss_X, bruss_X) end; # ╔═╡ 719a15e1-7a69-4e70-b20e-d75fa448458e -bruss_system=VoronoiFVM.System(bruss_grid,species=[1,2], - flux=bruss_diffusion, storage=bruss_storage, reaction=bruss_reaction); +bruss_system = VoronoiFVM.System( + bruss_grid, species = [1, 2], + flux = bruss_diffusion, storage = bruss_storage, reaction = bruss_reaction +); # ╔═╡ 62a1dad1-b095-4df9-b1f8-e6a97084d8f8 begin - inival=unknowns(bruss_system,inival=0) - coord=bruss_grid[Coordinates] - fpeak(x)=exp(-norm(10*x)^2) - for i=1:size(inival,2) - inival[1,i]=fpeak(coord[:,i]) - inival[2,i]=0 - # + inival = unknowns(bruss_system, inival = 0) + coord = bruss_grid[Coordinates] + fpeak(x) = exp(-norm(10 * x)^2) + for i in 1:size(inival, 2) + inival[1, i] = fpeak(coord[:, i]) + inival[2, i] = 0 + # end end # ╔═╡ e71a2ed0-5f39-473f-87a0-6f61748f2793 -t_run=@elapsed bruss_tsol=ODESolver(bruss_system,inival,diffeqmethods[bruss_method]()); +t_run = @elapsed bruss_tsol = ODESolver(bruss_system, inival, diffeqmethods[bruss_method]()); # ╔═╡ c1da7d8e-2921-4366-91f0-dc8e1834595b -(t_run=t_run,VoronoiFVM.history_details(bruss_tsol)...) +(t_run = t_run, VoronoiFVM.history_details(bruss_tsol)...) # ╔═╡ e7a8aae1-8e7a-4b7d-8ce6-701ea586b89a let -bruss_sol=bruss_tsol(t_bruss); - -vis=GridVisualizer(;layout=(1,2),size=(600,300)) - scalarplot!(vis[1,1],bruss_grid,bruss_sol[1,:],limits=(0,10),show=true,colormap=:summer) - scalarplot!(vis[1,2],bruss_grid,bruss_sol[2,:],limits=(0.5,3),show=true,colormap=:summer) + bruss_sol = bruss_tsol(t_bruss) + + vis = GridVisualizer(; layout = (1, 2), size = (600, 300)) + scalarplot!(vis[1, 1], bruss_grid, bruss_sol[1, :], limits = (0, 10), show = true, colormap = :summer) + scalarplot!(vis[1, 2], bruss_grid, bruss_sol[2, :], limits = (0.5, 3), show = true, colormap = :summer) end # ╔═╡ 4a4a2f78-4d4c-4b9b-883e-1e57de41c9a9 -scalarplot(bruss_tsol.t[1:end-1],bruss_tsol.t[2:end]-bruss_tsol.t[1:end-1],yscale=:log,resolution=(500,200),xlabel="t",ylabel="Δt",title="timesteps") +scalarplot(bruss_tsol.t[1:(end - 1)], bruss_tsol.t[2:end] - bruss_tsol.t[1:(end - 1)], yscale = :log, resolution = (500, 200), xlabel = "t", ylabel = "Δt", title = "timesteps") # ╔═╡ 00000000-0000-0000-0000-000000000001 PLUTO_PROJECT_TOML_CONTENTS = """ diff --git a/pluto-examples/ode-diffusion1d.jl b/pluto-examples/ode-diffusion1d.jl index 2fed0024a..0823b2ed5 100644 --- a/pluto-examples/ode-diffusion1d.jl +++ b/pluto-examples/ode-diffusion1d.jl @@ -6,8 +6,12 @@ using InteractiveUtils # This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). macro bind(def, element) - quote - local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end + return quote + local iv = try + Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value + catch + b -> missing + end local el = $(esc(element)) global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) el @@ -18,17 +22,17 @@ end begin import Pkg as _Pkg haskey(ENV, "PLUTO_PROJECT") && _Pkg.activate(ENV["PLUTO_PROJECT"]) - using Test - using Revise - using Printf - using VoronoiFVM - using OrdinaryDiffEqBDF - using OrdinaryDiffEqRosenbrock - using OrdinaryDiffEqSDIRK - using LinearAlgebra - using PlutoUI - using DataStructures - using GridVisualize,CairoMakie + using Test + using Revise + using Printf + using VoronoiFVM + using OrdinaryDiffEqBDF + using OrdinaryDiffEqRosenbrock + using OrdinaryDiffEqSDIRK + using LinearAlgebra + using PlutoUI + using DataStructures + using GridVisualize, CairoMakie end # ╔═╡ 02424193-41e8-4cec-8f52-6fd66173ace8 @@ -58,69 +62,70 @@ interface. """ # ╔═╡ 870b8b91-cd74-463e-b258-c092cd0af200 -function barenblatt(x,t,m) - tx=t^(-1.0/(m+1.0)) - xx=x*tx - xx=xx*xx - xx=1- xx*(m-1)/(2.0*m*(m+1)); - if xx<0.0 - xx=0.0 +function barenblatt(x, t, m) + tx = t^(-1.0 / (m + 1.0)) + xx = x * tx + xx = xx * xx + xx = 1 - xx * (m - 1) / (2.0 * m * (m + 1)) + if xx < 0.0 + xx = 0.0 end - return tx*xx^(1.0/(m-1.0)) + return tx * xx^(1.0 / (m - 1.0)) end # ╔═╡ 78208d7b-9d79-415c-ab3a-85948251e635 -function create_porous_medium_problem(n,m) - h=1.0/convert(Float64,n/2) - X=collect(-1:h:1) - grid=VoronoiFVM.Grid(X) - - function flux!(f,u,edge,data) - f[1]=u[1,1]^m-u[1,2]^m +function create_porous_medium_problem(n, m) + h = 1.0 / convert(Float64, n / 2) + X = collect(-1:h:1) + grid = VoronoiFVM.Grid(X) + + function flux!(f, u, edge, data) + f[1] = u[1, 1]^m - u[1, 2]^m + return nothing end - storage!(f,u,node,data)= f[1]=u[1] + storage!(f, u, node, data) = f[1] = u[1] - sys=VoronoiFVM.System(grid,flux=flux!,storage=storage!, species=1) - sys,X + sys = VoronoiFVM.System(grid, flux = flux!, storage = storage!, species = 1) + return sys, X end # ╔═╡ 4ef024a4-cb1d-443d-97fb-ab3a32a78ffd begin -function run_vfvm(;n=20,m=2,t0=0.001, tend=0.01,tstep=1.0e-6) - sys,X=create_porous_medium_problem(n,m) - inival=unknowns(sys) - inival[1,:].=map(x->barenblatt(x,t0,m),X) - sol=VoronoiFVM.solve(sys;inival,times=(t0,tend),Δt=tstep,Δu_opt=0.01,Δt_min=tstep,store_all=true,log=true, reltol=1.0e-3) - err=norm(sol[1,:,end]-map(x->barenblatt(x,tend,m),X)) - sol,sys,err -end -run_vfvm(m=2,n=10) # "Precompile" + function run_vfvm(; n = 20, m = 2, t0 = 0.001, tend = 0.01, tstep = 1.0e-6) + sys, X = create_porous_medium_problem(n, m) + inival = unknowns(sys) + inival[1, :] .= map(x -> barenblatt(x, t0, m), X) + sol = VoronoiFVM.solve(sys; inival, times = (t0, tend), Δt = tstep, Δu_opt = 0.01, Δt_min = tstep, store_all = true, log = true, reltol = 1.0e-3) + err = norm(sol[1, :, end] - map(x -> barenblatt(x, tend, m), X)) + return sol, sys, err + end + run_vfvm(m = 2, n = 10) # "Precompile" end; # ╔═╡ 2a8ac57e-486d-4825-95ab-f0402b910dbd -diffeqmethods=OrderedDict( -"Rosenbrock23 (Rosenbrock)" => Rosenbrock23, -"QNDF2 (Like matlab's ode15s)" => QNDF2, -"FBDF" => FBDF, -"Implicit Euler" => ImplicitEuler +diffeqmethods = OrderedDict( + "Rosenbrock23 (Rosenbrock)" => Rosenbrock23, + "QNDF2 (Like matlab's ode15s)" => QNDF2, + "FBDF" => FBDF, + "Implicit Euler" => ImplicitEuler ) # ╔═╡ 9239409b-6de0-4157-8a35-412c909efa96 begin - function run_diffeq(;n=20,m=2, t0=0.001,tend=0.01,solver=nothing) - sys,X=create_porous_medium_problem(n,m) - inival=unknowns(sys) - inival[1,:].=map(x->barenblatt(x,t0,m),X) - state=VoronoiFVM.SystemState(sys) - problem = ODEProblem(state,inival,(t0,tend)) - odesol = solve(problem,solver) - sol=reshape(odesol,sys; state) - err=norm(sol[1,:,end]-map(x->barenblatt(x,tend,m),X)) - sol, sys,err + function run_diffeq(; n = 20, m = 2, t0 = 0.001, tend = 0.01, solver = nothing) + sys, X = create_porous_medium_problem(n, m) + inival = unknowns(sys) + inival[1, :] .= map(x -> barenblatt(x, t0, m), X) + state = VoronoiFVM.SystemState(sys) + problem = ODEProblem(state, inival, (t0, tend)) + odesol = solve(problem, solver) + sol = reshape(odesol, sys; state) + err = norm(sol[1, :, end] - map(x -> barenblatt(x, tend, m), X)) + return sol, sys, err end for method in diffeqmethods - run_diffeq(m=2,n=10,solver=method.second()) # "Precompile" + run_diffeq(m = 2, n = 10, solver = method.second()) # "Precompile" end end; @@ -130,20 +135,20 @@ method: $(@bind method Select([keys(diffeqmethods)...])) """ # ╔═╡ 3e1e62ec-c50a-499e-b516-8478904429c5 -m=2; n=50; +m = 2; n = 50; # ╔═╡ 12ab322c-60ae-419f-9334-82f2f7ee7b59 -t1=@elapsed sol1,sys1,err1=run_vfvm(m=m,n=n);history_summary(sol1) +t1 = @elapsed sol1, sys1, err1 = run_vfvm(m = m, n = n);history_summary(sol1) # ╔═╡ 604898ba-1e8f-4c7c-9711-9958a8351854 -t2=@elapsed sol2,sys2,err2=run_diffeq(m=m,n=n,solver=diffeqmethods[method]());history_summary(sol2) +t2 = @elapsed sol2, sys2, err2 = run_diffeq(m = m, n = n, solver = diffeqmethods[method]());history_summary(sol2) # ╔═╡ 0676e28e-4e4e-4976-ab57-fb2d2e062625 let - aspect=600 - vis=GridVisualizer(Plotter=CairoMakie,layout=(1,2),resolution=(650,300)) - scalarplot!(vis[1,1],sys1,sol1;aspect) - scalarplot!(vis[1,2],sys2,sol2;aspect) + aspect = 600 + vis = GridVisualizer(Plotter = CairoMakie, layout = (1, 2), resolution = (650, 300)) + scalarplot!(vis[1, 1], sys1, sol1; aspect) + scalarplot!(vis[1, 2], sys2, sol2; aspect) reveal(vis) end @@ -155,7 +160,7 @@ Right: $(@sprintf(" %s: %.0f ms, e=%.2e",method,t2*1000,err2)) """ # ╔═╡ 84a29eb7-d936-4bd3-b15f-2886a4ca4985 -@test err2 missing; end + return quote + local iv = try + Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value + catch + b -> missing + end local el = $(esc(element)) global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) el @@ -18,19 +22,19 @@ end begin import Pkg as _Pkg haskey(ENV, "PLUTO_PROJECT") && _Pkg.activate(ENV["PLUTO_PROJECT"]) - using Test + using Test using Revise using Printf using VoronoiFVM - using SciMLBase: NoInit + using SciMLBase: NoInit using OrdinaryDiffEqBDF using OrdinaryDiffEqRosenbrock using OrdinaryDiffEqSDIRK using LinearAlgebra - using PlutoUI, HypertextLiteral,UUIDs + using PlutoUI, HypertextLiteral, UUIDs using DataStructures - using GridVisualize,CairoMakie - CairoMakie.activate!(type="svg") + using GridVisualize, CairoMakie + CairoMakie.activate!(type = "svg") end # ╔═╡ 57deb502-bac9-4093-86e3-e8d25eb02df2 @@ -39,7 +43,7 @@ md""" """ # ╔═╡ 785999c3-62d9-49ee-a890-70ec745211c1 -TableOfContents(aside=false) +TableOfContents(aside = false) # ╔═╡ a2dd09f8-ffe8-4b34-b2bf-21266ad97a76 md""" @@ -56,35 +60,35 @@ We can derive an exact solution from the Barenblatt solution of the equation for """ # ╔═╡ bf88f84f-8633-4ed3-aae6-5b937f8ea470 -function barenblatt(x,t,m) - tx=t^(-1.0/(m+1.0)) - xx=x*tx - xx=xx*xx - xx=1- xx*(m-1)/(2.0*m*(m+1)); - if xx<0.0 - xx=0.0 +function barenblatt(x, t, m) + tx = t^(-1.0 / (m + 1.0)) + xx = x * tx + xx = xx * xx + xx = 1 - xx * (m - 1) / (2.0 * m * (m + 1)) + if xx < 0.0 + xx = 0.0 end - return tx*xx^(1.0/(m-1.0)) + return tx * xx^(1.0 / (m - 1.0)) end # ╔═╡ 46a0da67-0418-4ac2-abc5-9dba3abf306c begin - const m=2 - const ε=1.0e-10 - const n=50 - const t0=1.0e-3 - const tend=1.0e-2 + const m = 2 + const ε = 1.0e-10 + const n = 50 + const t0 = 1.0e-3 + const tend = 1.0e-2 end # ╔═╡ f4eb15d1-4e0a-4738-bbc5-d5a7ced80289 -X=collect(-1:2.0/n:1) +X = collect(-1:(2.0 / n):1) # ╔═╡ c4f6f616-996b-4984-82c3-fd3f1301fb7c -u0=map(x->barenblatt(x,t0,m)^m,X) +u0 = map(x -> barenblatt(x, t0, m)^m, X) # ╔═╡ 27bd76a1-1739-4faf-9fd0-e095ee3f43f3 begin - grid=VoronoiFVM.Grid(X) + grid = VoronoiFVM.Grid(X) end # ╔═╡ 108cf7c1-17c7-4f56-b1f7-f38dfe8c857e @@ -93,9 +97,10 @@ md""" """ # ╔═╡ 54aef797-210b-4eea-95b4-e0bdcb478c1d - function flux!(f,u,edge,data) - f[1]=u[1,1]-u[1,2] - end +function flux!(f, u, edge, data) + f[1] = u[1, 1] - u[1, 2] + return nothing +end # ╔═╡ c33cfa04-7418-4b1b-868d-5e69b16ea2d9 md""" @@ -103,20 +108,22 @@ Storage term needs to be regularized as its derivative at 0 is infinity: """ # ╔═╡ 3790d063-8a3d-429b-8a59-05cfc35b6878 - function storage!(f,u,node,data) - f[1]=(ε+u[1])^(1.0/m) - end +function storage!(f, u, node, data) + f[1] = (ε + u[1])^(1.0 / m) + return nothing +end # ╔═╡ 62f5e4f1-3635-4de8-9052-1771fa3a31cf begin - physics=VoronoiFVM.Physics( - flux=flux!, - storage=storage!) - sys=VoronoiFVM.System(grid,physics,species=1) - inival=unknowns(sys) - inival[1,:]=u0 - control=VoronoiFVM.SolverControl() - tsol=VoronoiFVM.solve(sys;inival,times=(t0,tend),Δt_min=1.0e-4,Δt=1.0e-4,Δu_opt=0.1,force_first_step=true,log=true) + physics = VoronoiFVM.Physics( + flux = flux!, + storage = storage! + ) + sys = VoronoiFVM.System(grid, physics, species = 1) + inival = unknowns(sys) + inival[1, :] = u0 + control = VoronoiFVM.SolverControl() + tsol = VoronoiFVM.solve(sys; inival, times = (t0, tend), Δt_min = 1.0e-4, Δt = 1.0e-4, Δu_opt = 0.1, force_first_step = true, log = true) summary(tsol.history) end @@ -139,13 +146,15 @@ we see that the problem structure does not fit into the setting of that package """ # ╔═╡ d495a088-69dd-4f4e-964c-88638958799a -function dae_storage!(y,u,node,data) - y[1]=u[2] +function dae_storage!(y, u, node, data) + y[1] = u[2] + return nothing end # ╔═╡ 4c09ec49-c4d6-4c5a-8f73-8a736acaff61 -function dae_reaction!(y,u,node,data) - y[2]= u[2]^m-u[1] +function dae_reaction!(y, u, node, data) + y[2] = u[2]^m - u[1] + return nothing end # ╔═╡ 39e4fd5f-70a6-41e9-a02d-b11709762c19 @@ -155,17 +164,17 @@ First, we test this with the implicit Euler method of VoronoiFVM # ╔═╡ 89212312-7846-4a2f-a4b8-bd7b61235cf9 begin - dae_physics=VoronoiFVM.Physics( - flux=flux!, - storage=dae_storage!, - reaction=dae_reaction! - ) - dae_sys=VoronoiFVM.System(grid,dae_physics,species=[1,2]) - dae_inival=unknowns(dae_sys) - dae_inival[1,:].=u0 - dae_inival[2,:].=u0.^(1/m) - dae_control=VoronoiFVM.SolverControl() - dae_tsol=VoronoiFVM.solve(dae_sys;inival=dae_inival,times=(t0,tend),Δt_min=1.0e-4,Δt=1.0e-4,Δu_opt=0.1,force_first_step=true,log=true) + dae_physics = VoronoiFVM.Physics( + flux = flux!, + storage = dae_storage!, + reaction = dae_reaction! + ) + dae_sys = VoronoiFVM.System(grid, dae_physics, species = [1, 2]) + dae_inival = unknowns(dae_sys) + dae_inival[1, :] .= u0 + dae_inival[2, :] .= u0 .^ (1 / m) + dae_control = VoronoiFVM.SolverControl() + dae_tsol = VoronoiFVM.solve(dae_sys; inival = dae_inival, times = (t0, tend), Δt_min = 1.0e-4, Δt = 1.0e-4, Δu_opt = 0.1, force_first_step = true, log = true) summary(dae_tsol.history) end @@ -175,12 +184,12 @@ md""" """ # ╔═╡ 8079ba59-7595-4109-805a-32d135d383f9 -diffeqmethods=OrderedDict( -"QNDF2 (Like matlab's ode15s)" => QNDF2, -"Rodas5" => Rodas5, -"Rosenbrock23 (Rosenbrock)" => Rosenbrock23, -"FBDF" => FBDF, -"Implicit Euler" => ImplicitEuler +diffeqmethods = OrderedDict( + "QNDF2 (Like matlab's ode15s)" => QNDF2, + "Rodas5" => Rodas5, + "Rosenbrock23 (Rosenbrock)" => Rosenbrock23, + "FBDF" => FBDF, + "Implicit Euler" => ImplicitEuler ) @@ -192,16 +201,17 @@ method: $(@bind method Select([keys(diffeqmethods)...])) # ╔═╡ da7645c2-d254-4886-b2b6-28289368fc22 begin - de_sys=VoronoiFVM.System(grid,dae_physics,species=[1,2]) - problem = ODEProblem(de_sys,dae_inival,(t0,tend)) - de_odesol=solve(problem, - diffeqmethods[method](), - adaptive=true, - reltol=1.0e-3, - abstol=1.0e-3, - initializealg=NoInit() - ) - de_tsol=reshape(de_odesol,de_sys) + de_sys = VoronoiFVM.System(grid, dae_physics, species = [1, 2]) + problem = ODEProblem(de_sys, dae_inival, (t0, tend)) + de_odesol = solve( + problem, + diffeqmethods[method](), + adaptive = true, + reltol = 1.0e-3, + abstol = 1.0e-3, + initializealg = NoInit() + ) + de_tsol = reshape(de_odesol, de_sys) end; # ╔═╡ 1a5c5b50-8aea-47b9-9961-5d74e93e9d69 @@ -210,71 +220,73 @@ t=$(@bind t PlutoUI.Slider(range(t0,tend,length=10001),default=2*t0;show_value= """ # ╔═╡ f00b9313-518b-4f5e-93eb-1b1b2afc2599 -exact=map(x->barenblatt(x,tend,m).^m,X) +exact = map(x -> barenblatt(x, tend, m) .^ m, X) # ╔═╡ eb76c618-5bc4-45eb-96c6-61653aaba758 -@test norm(tsol[1,:,end]-exact,Inf)<0.1 +@test norm(tsol[1, :, end] - exact, Inf) < 0.1 # ╔═╡ 65220fd1-10a3-49d6-bae0-65a7b269cf63 -@test norm(dae_tsol[1,:,end]-exact,Inf)<0.1 +@test norm(dae_tsol[1, :, end] - exact, Inf) < 0.1 # ╔═╡ ef1cfc2a-89d7-426d-acee-4877481f9188 - @test norm(de_tsol[1,:,end]-exact,Inf)<0.05 +@test norm(de_tsol[1, :, end] - exact, Inf) < 0.05 # ╔═╡ 0488cf35-1e59-4761-99ed-e91c75259403 -function myaside(x;top=1) - uuid=uuid1() - @htl(""" - - - - - """) +function myaside(x; top = 1) + uuid = uuid1() + return @htl( + """ + + + + + """ + ) end # ╔═╡ 7fdef034-feac-49e4-9b98-bf579ac5fd94 function plotsolutions() - vis=GridVisualizer(resolution=(380,200),dim=1,Plotter=CairoMakie,legend=:lt); - u=tsol(t) - u_dae=dae_tsol(t) - u_de=de_tsol(t) - scalarplot!(vis,X,map(x->barenblatt(x,t,m).^m,X),clear=true,color=:red,linestyle=:solid,flimits=(0,100),label="exact") - scalarplot!(vis,grid,u_dae[1,:],clear=false,color=:green, linestyle=:solid,label="vfvm_dae") - scalarplot!(vis,grid,u_de[1,:],clear=false,color=:blue, markershape=:cross,linestyle=:dot,label="vfvm_diffeq") - scalarplot!(vis,grid,u[1,:],clear=false,color=:black,markershape=:none, linestyle=:dash,title="t=$(t)",label="vfvm_default") - reveal(vis) + vis = GridVisualizer(resolution = (380, 200), dim = 1, Plotter = CairoMakie, legend = :lt) + u = tsol(t) + u_dae = dae_tsol(t) + u_de = de_tsol(t) + scalarplot!(vis, X, map(x -> barenblatt(x, t, m) .^ m, X), clear = true, color = :red, linestyle = :solid, flimits = (0, 100), label = "exact") + scalarplot!(vis, grid, u_dae[1, :], clear = false, color = :green, linestyle = :solid, label = "vfvm_dae") + scalarplot!(vis, grid, u_de[1, :], clear = false, color = :blue, markershape = :cross, linestyle = :dot, label = "vfvm_diffeq") + scalarplot!(vis, grid, u[1, :], clear = false, color = :black, markershape = :none, linestyle = :dash, title = "t=$(t)", label = "vfvm_default") + return reveal(vis) end # ╔═╡ 9340c3a2-12f9-4f0e-9e5b-3c960388f9cc diff --git a/pluto-examples/ode-wave1d.jl b/pluto-examples/ode-wave1d.jl index c2f72d423..b0c84aa13 100644 --- a/pluto-examples/ode-wave1d.jl +++ b/pluto-examples/ode-wave1d.jl @@ -6,8 +6,12 @@ using InteractiveUtils # This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). macro bind(def, element) - quote - local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end + return quote + local iv = try + Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value + catch + b -> missing + end local el = $(esc(element)) global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) el @@ -18,19 +22,19 @@ end begin import Pkg as _Pkg haskey(ENV, "PLUTO_PROJECT") && _Pkg.activate(ENV["PLUTO_PROJECT"]) - using Test - using Revise - using Printf - using VoronoiFVM - using OrdinaryDiffEqBDF - using OrdinaryDiffEqRosenbrock - using OrdinaryDiffEqSDIRK - using LinearAlgebra - using PlutoUI - using ExtendableGrids - using DataStructures - using GridVisualize,CairoMakie - CairoMakie.activate!(type="png") + using Test + using Revise + using Printf + using VoronoiFVM + using OrdinaryDiffEqBDF + using OrdinaryDiffEqRosenbrock + using OrdinaryDiffEqSDIRK + using LinearAlgebra + using PlutoUI + using ExtendableGrids + using DataStructures + using GridVisualize, CairoMakie + CairoMakie.activate!(type = "png") end # ╔═╡ c9bf8371-95ec-4a4f-a6dc-5c570bccd94a @@ -62,16 +66,16 @@ This allows for a quick implementation in VoronoiFVM (which may be not the optim # ╔═╡ f4002117-f4c4-4191-9198-d75a2a2adc9a -const iu=1; const iv=2; +const iu = 1; const iv = 2; # ╔═╡ 335129d6-1da0-4d1f-ad14-02719e7fd215 -storage(y,u,node,data)=y.=u; +storage(y, u, node, data) = y .= u; # ╔═╡ 44f570e7-7834-4fae-a222-80e7ed29eb28 -reaction(y,u,node,data)= y[iu]=-u[iv]; +reaction(y, u, node, data) = y[iu] = -u[iv]; # ╔═╡ bee98dec-af80-422f-97ee-126154612708 -flux(y,u,edge,data)=y[iv]=data.c^2*(u[iu,1]-u[iu,2]); +flux(y, u, edge, data) = y[iv] = data.c^2 * (u[iu, 1] - u[iu, 2]); # ╔═╡ 5b233195-e614-407f-824d-ca4c3cb9287c md""" @@ -79,14 +83,15 @@ Implementation of transparent or mirror bc """ # ╔═╡ 7b195fdb-9190-4eb4-8341-5a32947278d2 -function brea(y,u,node,data) - if node.region==2 - if data.bctype==:transparent - y[iu]=data.c*u[iu] - elseif data.bctype==:mirror - boundary_dirichlet!(y,u,node,species=1,region=2,value=0) - end - end +function brea(y, u, node, data) + if node.region == 2 + if data.bctype == :transparent + y[iu] = data.c * u[iu] + elseif data.bctype == :mirror + boundary_dirichlet!(y, u, node, species = 1, region = 2, value = 0) + end + end + return nothing end; @@ -96,7 +101,7 @@ Wave velocity: """ # ╔═╡ f8d02094-e1ce-4099-bc35-e940bbf81033 -const c=0.1 +const c = 0.1 # ╔═╡ 9478f888-3722-4a1f-8981-e717b890ddf2 md""" @@ -104,16 +109,16 @@ Domain length: """ # ╔═╡ 90617940-a390-4446-96c1-5308482c4acb -L=4 +L = 4 # ╔═╡ ccf238c2-ad24-4f53-99a4-dc17d3ed249d -N=151 +N = 151 # ╔═╡ dfe4b7d9-47b9-45b5-b382-b609947f0a2b -dt=1.0e-2; tend=100.0; +dt = 1.0e-2; tend = 100.0; # ╔═╡ 2c3f949c-4d0d-4f54-a580-94e90a79ddb5 -grid=simplexgrid(range(-L,L,length=N)); +grid = simplexgrid(range(-L, L, length = N)); # ╔═╡ 8f5eac27-de80-4a02-b776-6205b8a805f8 md""" @@ -126,24 +131,24 @@ Boundary condition at x=L: $(@bind bc2type Select(["reflection","mirror","transp """ # ╔═╡ 3cf0f943-f692-4031-81e2-a05d0bc5448b -sys=VoronoiFVM.System(grid,storage=storage,flux=flux,breaction=brea, reaction=reaction,data=(c=c,bctype=Symbol(bc2type)), species=[1,2]) +sys = VoronoiFVM.System(grid, storage = storage, flux = flux, breaction = brea, reaction = reaction, data = (c = c, bctype = Symbol(bc2type)), species = [1, 2]) # ╔═╡ 5b33c8e6-f270-40bc-aa14-611804e1b265 -if bc2type=="reflection" - md"""Reflection (Neumann) bc ``\partial_x u|_{x=L}=0``""" -elseif bc2type=="mirror" - md"""Mirror (Dirichlet) bc ``u|_{x=L}=0``""" -elseif bc2type=="transparent" - md"""Transparent bc ``(\partial_t u - c\partial_xu)|_{x=0}=0`` """ +if bc2type == "reflection" + md"""Reflection (Neumann) bc ``\partial_x u|_{x=L}=0``""" +elseif bc2type == "mirror" + md"""Mirror (Dirichlet) bc ``u|_{x=L}=0``""" +elseif bc2type == "transparent" + md"""Transparent bc ``(\partial_t u - c\partial_xu)|_{x=0}=0`` """ end # ╔═╡ fc50e3fc-4dc9-4721-97a6-47d8f5ed8851 -diffeqmethods=OrderedDict( -"QNDF2" => QNDF2, -"FBDF" => FBDF, -"Rosenbrock23 (Rosenbrock)" => Rosenbrock23, -"Implicit Euler" => ImplicitEuler, -"Implicit Midpoint" => ImplicitMidpoint, +diffeqmethods = OrderedDict( + "QNDF2" => QNDF2, + "FBDF" => FBDF, + "Rosenbrock23 (Rosenbrock)" => Rosenbrock23, + "Implicit Euler" => ImplicitEuler, + "Implicit Midpoint" => ImplicitMidpoint, ) # ╔═╡ 46c6c09e-e610-4823-b0dc-fc6eaa557fc8 @@ -156,42 +161,43 @@ t=$(@bind t PlutoUI.Slider(range(0,tend,length=10001),default=tend/2;show_value # ╔═╡ e65b01d0-d0bd-4ac3-b94a-d9d36b7c42c3 begin - inival=unknowns(sys,inival=0) - inival[1,:].=map(x->cos(κ*π*x)*exp(-x^2/0.1) ,grid) + inival = unknowns(sys, inival = 0) + inival[1, :] .= map(x -> cos(κ * π * x) * exp(-x^2 / 0.1), grid) end; # ╔═╡ 05bac3fc-92de-494f-8ae1-098155ea506f -problem = ODEProblem(sys,inival,(0.0,tend)); +problem = ODEProblem(sys, inival, (0.0, tend)); # ╔═╡ 18f636ab-645f-446b-aef0-66dbdcc50384 -tsol=solve(problem,diffeqmethods[method](); - force_dtmin=true, - adaptive=true, - reltol=1.0e-4, - abstol=1.0e-5, - dtmin=dt, - progress=true, - progress_steps=1, - dt=dt); +tsol = solve( + problem, diffeqmethods[method](); + force_dtmin = true, + adaptive = true, + reltol = 1.0e-4, + abstol = 1.0e-5, + dtmin = dt, + progress = true, + progress_steps = 1, + dt = dt +); # ╔═╡ cbcd3633-a376-4c34-9eea-ed94534ae8b3 -tsol1=reshape(tsol,sys); +tsol1 = reshape(tsol, sys); # ╔═╡ 41ce301c-3e71-4f3f-80b8-f6e115b3b5e0 -let - vis=GridVisualizer(Plotter=CairoMakie) - scalarplot!(vis,sys,tsol1,colormap=:bwr,limits=(-1,1), levels=(-0.9:0.2:0.9)) - reveal(vis) +let + vis = GridVisualizer(Plotter = CairoMakie) + scalarplot!(vis, sys, tsol1, colormap = :bwr, limits = (-1, 1), levels = (-0.9:0.2:0.9)) + reveal(vis) end # ╔═╡ 7e5140d7-3304-4eac-be4c-981324dc346b let - u=tsol1(t) - scalarplot(grid,u[1,:],flimits=(-1,1),clear=true,show=true,title="t=$(t)",Plotter=CairoMakie,resolution=(600,150)) + u = tsol1(t) + scalarplot(grid, u[1, :], flimits = (-1, 1), clear = true, show = true, title = "t=$(t)", Plotter = CairoMakie, resolution = (600, 150)) end - # ╔═╡ 00000000-0000-0000-0000-000000000001 PLUTO_PROJECT_TOML_CONTENTS = """ [deps] diff --git a/pluto-examples/outflow.jl b/pluto-examples/outflow.jl index 8d021fbf5..ba4b54c45 100644 --- a/pluto-examples/outflow.jl +++ b/pluto-examples/outflow.jl @@ -86,6 +86,7 @@ function flux(y, u, edge, data) bp, bm = fbernoulli_pm(vh / data.D) y[data.ic] = data.D * (bm * u[data.ic, 1] - bp * u[data.ic, 2]) + return nothing end # ╔═╡ addf62a3-9a71-49b8-b54a-441f65a01d01 @@ -93,6 +94,7 @@ function bcondition(y, u, bnode, data) boundary_neumann!(y, u, bnode; species = data.ip, region = data.Γ_in, value = data.v_in) boundary_dirichlet!(y, u, bnode; species = data.ip, region = data.Γ_out, value = 0) boundary_dirichlet!(y, u, bnode; species = data.ic, region = data.Γ_in, value = data.c_in) + return nothing end # ╔═╡ e087d35c-47ca-47f4-ab20-32a7adf94f00 @@ -108,18 +110,21 @@ nodes, in that case it is assumed that the contribution is zero. In the present # ╔═╡ c5fb189b-e542-4313-bad2-d6fe64d70771 function boutflow(y, u, edge, data) y[data.ic] = -darcyvelo(u, data) * u[data.ic, outflownode(edge)] + return nothing end # ╔═╡ 210aeda9-9c37-4278-8466-8d0a62347367 function flowtransportsystem(grid; kwargs...) data = FlowTransportData(; kwargs...) - VoronoiFVM.System(grid; - flux, - bcondition, - boutflow, - data, - outflowboundaries = [data.Γ_out], - species = [1, 2],) + return VoronoiFVM.System( + grid; + flux, + bcondition, + boutflow, + data, + outflowboundaries = [data.Γ_out], + species = [1, 2], + ) end # ╔═╡ 3e6b27b4-066f-475e-99f4-8eba666f9dc2 @@ -128,7 +133,7 @@ function checkinout(sys, sol) tfact = TestFunctionFactory(sys) tf_in = testfunction(tfact, [data.Γ_out], [data.Γ_in]) tf_out = testfunction(tfact, [data.Γ_in], [data.Γ_out]) - (; in = integrate(sys, tf_in, sol), out = integrate(sys, tf_out, sol)) + return (; in = integrate(sys, tf_in, sol), out = integrate(sys, tf_out, sol)) end # ╔═╡ 3f273ed4-5522-4018-9551-b22a7db2e070 @@ -257,57 +262,57 @@ begin highlight(mdstring, color) = htl"""
$(mdstring)
""" macro important_str(s) - :(highlight(Markdown.parse($s), "#ffcccc")) + return :(highlight(Markdown.parse($s), "#ffcccc")) end macro definition_str(s) - :(highlight(Markdown.parse($s), "#ccccff")) + return :(highlight(Markdown.parse($s), "#ccccff")) end macro statement_str(s) - :(highlight(Markdown.parse($s), "#ccffcc")) + return :(highlight(Markdown.parse($s), "#ccffcc")) end html""" - -""" + + """ end # ╔═╡ 5beb3a0d-e57a-4aea-b7a0-59b8ce9ff5ce @@ -317,43 +322,45 @@ hrule() begin function floataside(text::Markdown.MD; top = 1) uuid = uuid1() - @htl(""" - - - - - """) + return @htl( + """ + + + + + """ + ) end floataside(stuff; kwargs...) = floataside(md"""$(stuff)"""; kwargs...) end; @@ -361,52 +368,52 @@ end; # ╔═╡ 4652157f-3288-45b6-877e-17ed8dc7d18e function slidemodeswitch() uuid = uuid1() - html""" - - """ + invalidation.then(() => {document.removeEventListener('keydown',func)}) + + """ end; # ╔═╡ 00000000-0000-0000-0000-000000000001 diff --git a/pluto-examples/pkgupdate.jl b/pluto-examples/pkgupdate.jl index d3cbd64d7..bed262f09 100755 --- a/pluto-examples/pkgupdate.jl +++ b/pluto-examples/pkgupdate.jl @@ -22,16 +22,14 @@ notebooks = [ "ode-brusselator.jl", "heterogeneous-catalysis.jl", "outflow.jl", - "bernoulli.jl" + "bernoulli.jl", ] - - - # # if we add one package too many, this triggers the action of PlutoPkg - # # when the NB is started - # Pkg.add("AbstractTrees") - # Pkg.update() +# # if we add one package too many, this triggers the action of PlutoPkg +# # when the NB is started +# Pkg.add("AbstractTrees") +# Pkg.update() """ force_update_notebook_environment(notebook) @@ -41,28 +39,28 @@ the compat entries in the Project.toml and thus seems to do nothing. """ function force_update_notebook_environment(notebook) # cache the current environment - thisproject=Pkg.project().path + thisproject = Pkg.project().path @info "Force updating packages in $(notebook):" - tmp=mktempdir() - tmpjl=joinpath(tmp,"tmp.jl") + tmp = mktempdir() + tmpjl = joinpath(tmp, "tmp.jl") - cp(joinpath(@__DIR__,notebook),tmpjl,force=true) + cp(joinpath(@__DIR__, notebook), tmpjl, force = true) # After this, notebook env + current env are in sync Pluto.activate_notebook_environment(tmpjl) Pkg.status() # Get list of current dependencies and their UUIDs: - pkgs=[PackageSpec(uuid=v) for (k,v) in Pkg.project().dependencies] - + pkgs = [PackageSpec(uuid = v) for (k, v) in Pkg.project().dependencies] + # Remove and re-add packages, thus ignoring compat - if length(pkgs)>0 + if length(pkgs) > 0 Pkg.rm(pkgs) Pkg.add(pkgs) end - + # let the environments sync sleep(1) @@ -71,10 +69,10 @@ function force_update_notebook_environment(notebook) @info "Updating of $(notebook) done\n" sleep(1) - cp(tmpjl,joinpath(@__DIR__,notebook),force=true) + cp(tmpjl, joinpath(@__DIR__, notebook), force = true) # Re-activate the current environment - Pkg.activate(thisproject) + return Pkg.activate(thisproject) end for notebook in notebooks @@ -85,7 +83,7 @@ end dirs = ["pluto-examples", "docs"] for dir in dirs println("updating $(dir) environment") - thisproject=Pkg.project().path + thisproject = Pkg.project().path Pkg.activate(joinpath(@__DIR__, "..", dir)) Pkg.status() Pkg.update() diff --git a/pluto-examples/problemcase.jl b/pluto-examples/problemcase.jl index 41b433cd1..60757c1fc 100644 --- a/pluto-examples/problemcase.jl +++ b/pluto-examples/problemcase.jl @@ -6,8 +6,12 @@ using InteractiveUtils # This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). macro bind(def, element) - quote - local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end + return quote + local iv = try + Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value + catch + b -> missing + end local el = $(esc(element)) global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) el @@ -265,7 +269,7 @@ function grid_2d(; nref = 0, ε_fix = 0.0) grid = simplexgrid(xc, yc) cellmask!(grid, [0, -W / 2], [L, W / 2], Ω_high) bfacemask!(grid, [0, -W / 2], [0, W / 2], Γ_in) - bfacemask!(grid, [L, -W / 2], [L, W / 2], Γ_out) + return bfacemask!(grid, [L, -W / 2], [L, W / 2], Γ_out) end # ╔═╡ 46a0f078-4165-4e37-9e69-e69af8584f6e @@ -282,7 +286,7 @@ function grid_1d(; nref = 0) cellmask!(grid, [0], [L], Ω_high) bfacemask!(grid, [0], [0], Γ_in) bfacemask!(grid, [L], [L], Γ_out) - grid + return grid end # ╔═╡ d772ac1b-3cda-4a2b-b0a9-b22b63b30653 @@ -316,10 +320,10 @@ function breakthrough(sys, tf, sol) of = similar(sol.t) t = sol.t of[1] = 0 - for i = 2:length(sol.t) + for i in 2:length(sol.t) of[i] = -integrate(sys, tf, sol.u[i], sol.u[i - 1], t[i] - t[i - 1])[ic] end - of + return of end # ╔═╡ 3df8bace-b4f1-4052-84f7-dff21d3a35f0 @@ -328,21 +332,25 @@ Transient solver: """ # ╔═╡ e866db69-9388-4691-99f7-879cf0658418 -function trsolve(grid; - κ = [1.0e-3, 5], - D = [1.0e-12, 1.0e-12], - Δp = 1.0, - ϕ = [1, 1], - tend = 100,) +function trsolve( + grid; + κ = [1.0e-3, 5], + D = [1.0e-12, 1.0e-12], + Δp = 1.0, + ϕ = [1, 1], + tend = 100, + ) function flux(y, u, edge, data) y[ip] = κ[edge.region] * (u[ip, 1] - u[ip, 2]) bp, bm = fbernoulli_pm(y[ip] / D[edge.region]) y[ic] = D[edge.region] * (bm * u[ic, 1] - bp * u[ic, 2]) + return nothing end function stor(y, u, node, data) y[ip] = 0 y[ic] = ϕ[node.region] * u[ic] + return nothing end dim = dim_space(grid) @@ -357,31 +365,36 @@ function trsolve(grid; boundary_dirichlet!(y, u, bnode, ip, Γ_left, Δp) boundary_dirichlet!(y, u, bnode, ip, Γ_right, 0) end + return nothing end - sys = VoronoiFVM.System(grid; - check_allocs = true, - flux = flux, - storage = stor, - bcondition = bc, - species = [ip, ic],) + sys = VoronoiFVM.System( + grid; + check_allocs = true, + flux = flux, + storage = stor, + bcondition = bc, + species = [ip, ic], + ) inival = solve(sys; inival = 0, time = 0.0) factory = TestFunctionFactory(sys) tfc = testfunction(factory, [Γ_in, Γ_left, Γ_top, Γ_bot], [Γ_out]) - sol = VoronoiFVM.solve(sys; - inival = inival, - times = [0, tend], - Δt = 1.0e-4, - Δt_min = 1.0e-6,) + sol = VoronoiFVM.solve( + sys; + inival = inival, + times = [0, tend], + Δt = 1.0e-4, + Δt_min = 1.0e-6, + ) bt = breakthrough(sys, tfc, sol) if dim == 1 bt = bt * W end - grid, sol, bt + return grid, sol, bt end # ╔═╡ cd88123a-b042-43e2-99b9-ec925a8794ed @@ -403,13 +416,15 @@ grid_1, sol_1, bt_1 = trsolve(grid_1d(; nref = nref); tend = tend); @test sum(bt_1) ≈ 20.66209910195916 # ╔═╡ e36d2aef-1b5a-45a7-9289-8d1e544bcedd -scalarplot(grid_1, - sol_1(t)[ic, :]; - levels = 0:0.2:1, - resolution = (500, 150), - xlabel = "x", - ylabel = "c", - title = "1D calculation, t=$t") +scalarplot( + grid_1, + sol_1(t)[ic, :]; + levels = 0:0.2:1, + resolution = (500, 150), + xlabel = "x", + ylabel = "c", + title = "1D calculation, t=$t" +) # ╔═╡ 76b77ec0-27b0-4a02-9ae4-43d756eb09dd grid_f, sol_f, bt_f = trsolve(grid_2d(; nref = nref, ε_fix = ε_fix); tend = tend); @@ -428,34 +443,42 @@ grid_ϕ, sol_ϕ, bt_ϕ = trsolve(grid_2d(; nref = nref); ϕ = [1.0e-3, 1], tend # ╔═╡ ce49bb25-b2d0-4d17-a8fe-d7b62e9b20be begin - p1 = GridVisualizer(; resolution = (500, 200), - xlabel = "t", - ylabel = "outflow", - legend = :rb, - title = "Breakthrough Curves") + p1 = GridVisualizer(; + resolution = (500, 200), + xlabel = "t", + ylabel = "outflow", + legend = :rb, + title = "Breakthrough Curves" + ) scalarplot!(p1, sol_n.t, bt_n; label = "naive grid", color = :red) - scalarplot!(p1, - sol_1.t, - bt_1; - label = "1D grid", - markershape = :x, - markersize = 10, - clear = false, - color = :green) - scalarplot!(p1, - sol_f.t, - bt_f; - label = "grid with fix", - markershape = :circle, - color = :green, - clear = false) - scalarplot!(p1, - sol_ϕ.t, - bt_ϕ; - label = "modified ϕ", - markershape = :cross, - color = :blue, - clear = false) + scalarplot!( + p1, + sol_1.t, + bt_1; + label = "1D grid", + markershape = :x, + markersize = 10, + clear = false, + color = :green + ) + scalarplot!( + p1, + sol_f.t, + bt_f; + label = "grid with fix", + markershape = :circle, + color = :green, + clear = false + ) + scalarplot!( + p1, + sol_ϕ.t, + bt_ϕ; + label = "modified ϕ", + markershape = :cross, + color = :blue, + clear = false + ) reveal(p1) end @@ -468,21 +491,26 @@ md""" function rdsolve(grid; D = [1.0e-12, 1.0], R = [1, 0.1]) function flux(y, u, edge, data) y[1] = D[edge.region] * (u[1, 1] - u[1, 2]) + return nothing end function rea(y, u, node, data) y[1] = R[node.region] * u[1] + return nothing end function bc(y, u, bnode, data) boundary_dirichlet!(y, u, bnode, 1, Γ_in, 1) boundary_dirichlet!(y, u, bnode, 1, Γ_out, 0) + return nothing end - sys = VoronoiFVM.System(grid; - flux = flux, - reaction = rea, - species = 1, - bcondition = bc, - check_allocs = true) + sys = VoronoiFVM.System( + grid; + flux = flux, + reaction = rea, + species = 1, + bcondition = bc, + check_allocs = true + ) dim = dim_space(grid) sol = VoronoiFVM.solve(sys) @@ -493,7 +521,7 @@ function rdsolve(grid; D = [1.0e-12, 1.0], R = [1, 0.1]) if dim == 1 fac = W end - grid, sol[1, :], of[1] * fac + return grid, sol[1, :], of[1] * fac end # ╔═╡ 2f560406-d169-4027-9cfe-7689494edf45 diff --git a/src/VoronoiFVM.jl b/src/VoronoiFVM.jl index c28013d08..6e15d358a 100644 --- a/src/VoronoiFVM.jl +++ b/src/VoronoiFVM.jl @@ -1,7 +1,7 @@ """ VoronoiFVM -$(read(joinpath(@__DIR__,"..","README.md"),String)) +$(read(joinpath(@__DIR__, "..", "README.md"), String)) """ module VoronoiFVM @@ -10,28 +10,28 @@ import Colors using CommonSolve: CommonSolve, solve, solve! using DiffResults: DiffResults using DocStringExtensions: DocStringExtensions, SIGNATURES, TYPEDEF, - TYPEDFIELDS, TYPEDSIGNATURES + TYPEDFIELDS, TYPEDSIGNATURES using ExtendableGrids: ExtendableGrids, BEdgeNodes, BFaceCells, BFaceEdges, - BFaceGeometries, BFaceNodes, BFaceNormals, BFaceRegions, - Cartesian1D, Cartesian2D, Cartesian3D, CellEdges, - CellGeometries, CellNodes, CellRegions, - CoordinateSystem, Coordinates, Cylindrical2D, Edge1D, - EdgeCells, EdgeNodes, ExtendableGrid, - Polar1D, Spherical1D, Tetrahedron3D, - Triangle2D, Vertex0D, VoronoiFaceCenters, coord_type, - dim_space, index_type, local_celledgenodes, num_bfaces, - num_cells, num_edges, num_nodes, num_cellregions, num_bfaceregions, num_targets, - simplexgrid, subgrid, tricircumcenter!, - num_partitions, pcolor_partitions, pcolors, num_pcolors, - PColorPartitions, PartitionCells, PartitionBFaces, PartitionNodes, PartitionEdges + BFaceGeometries, BFaceNodes, BFaceNormals, BFaceRegions, + Cartesian1D, Cartesian2D, Cartesian3D, CellEdges, + CellGeometries, CellNodes, CellRegions, + CoordinateSystem, Coordinates, Cylindrical2D, Edge1D, + EdgeCells, EdgeNodes, ExtendableGrid, + Polar1D, Spherical1D, Tetrahedron3D, + Triangle2D, Vertex0D, VoronoiFaceCenters, coord_type, + dim_space, index_type, local_celledgenodes, num_bfaces, + num_cells, num_edges, num_nodes, num_cellregions, num_bfaceregions, num_targets, + simplexgrid, subgrid, tricircumcenter!, + num_partitions, pcolor_partitions, pcolors, num_pcolors, + PColorPartitions, PartitionCells, PartitionBFaces, PartitionNodes, PartitionEdges using ExtendableSparse: ExtendableSparse, BlockPreconditioner, - ExtendableSparseMatrix, - ExtendableSparseMatrixCSC, - MTExtendableSparseMatrixCSC, - AbstractExtendableSparseMatrixCSC, - PointBlockILUZeroPreconditioner, factorize!, flush!, - nnz, rawupdateindex!, sparse, updateindex!, nnznew + ExtendableSparseMatrix, + ExtendableSparseMatrixCSC, + MTExtendableSparseMatrixCSC, + AbstractExtendableSparseMatrixCSC, + PointBlockILUZeroPreconditioner, factorize!, flush!, + nnz, rawupdateindex!, sparse, updateindex!, nnznew using ForwardDiff: ForwardDiff, value using GridVisualize: GridVisualize, GridVisualizer @@ -39,17 +39,17 @@ using InteractiveUtils: InteractiveUtils using JLD2: JLD2, jldopen using LinearAlgebra: LinearAlgebra, Diagonal, I, Tridiagonal, isdiag, ldiv!, norm using LinearSolve: LinearSolve, KrylovJL_BICGSTAB, - KrylovJL_CG, KrylovJL_GMRES, LinearProblem, - SparspakFactorization, UMFPACKFactorization, init, reinit! + KrylovJL_CG, KrylovJL_GMRES, LinearProblem, + SparspakFactorization, UMFPACKFactorization, init, reinit! using Printf: Printf, @printf, @sprintf using Random: Random, AbstractRNG using RecursiveArrayTools: RecursiveArrayTools, AbstractDiffEqArray import RecursiveFactorization using SciMLBase: SciMLBase using SparseArrays: SparseArrays, SparseMatrixCSC, dropzeros!, nonzeros, - nzrange, spzeros, issparse + nzrange, spzeros, issparse using SparseDiffTools: SparseDiffTools, forwarddiff_color_jacobian!, - matrix_colors + matrix_colors using StaticArrays: StaticArrays, @MVector, @SArray, @SMatrix using Statistics: Statistics, mean using Symbolics: Symbolics @@ -68,11 +68,11 @@ export AbstractGeometryItem Abstract type for stationary solution. Subtype of `AbstractArray`. """ -abstract type AbstractSolutionArray{T,N} <: AbstractArray{T,N} end -Base.getindex(a::AbstractSolutionArray, i::Int, j::Int)= getindex(a.u,i,j ) -Base.setindex!(a::AbstractSolutionArray,v, i::Int, j::Int) = setindex!(a.u,v,i,j) -Base.size(a::AbstractSolutionArray)=size(a.u) -solutionarray(a::AbstractSolutionArray)=a +abstract type AbstractSolutionArray{T, N} <: AbstractArray{T, N} end +Base.getindex(a::AbstractSolutionArray, i::Int, j::Int) = getindex(a.u, i, j) +Base.setindex!(a::AbstractSolutionArray, v, i::Int, j::Int) = setindex!(a.u, v, i, j) +Base.size(a::AbstractSolutionArray) = size(a.u) +solutionarray(a::AbstractSolutionArray) = a export AbstractSolutionArray @@ -95,7 +95,7 @@ export num_dof export dof export getdof export setdof! -export unknown_indices, SparseSolutionIndices +export unknown_indices, SparseSolutionIndices include("vfvm_transientsolution.jl") export TransientSolution diff --git a/src/gridvisualize.jl b/src/gridvisualize.jl index 039127e26..f9b327110 100644 --- a/src/gridvisualize.jl +++ b/src/gridvisualize.jl @@ -18,7 +18,7 @@ GridVisualize.gridplot!(vis, sys::AbstractSystem; kwargs...) = GridVisualize.gri Plot one species from solution """ function GridVisualize.scalarplot(sys::AbstractSystem, sol::AbstractMatrix; species = 1, scale = 1.0, kwargs...) - GridVisualize.scalarplot(sys.grid, sol[species, :] * scale; kwargs...) + return GridVisualize.scalarplot(sys.grid, sol[species, :] * scale; kwargs...) end """ @@ -27,7 +27,7 @@ end Plot one species from solution """ function GridVisualize.scalarplot!(vis, sys::AbstractSystem, sol::AbstractMatrix; species = 1, scale = 1.0, kwargs...) - GridVisualize.scalarplot!(vis, sys.grid, sol[species, :] * scale; kwargs...) + return GridVisualize.scalarplot!(vis, sys.grid, sol[species, :] * scale; kwargs...) end """ @@ -35,10 +35,12 @@ end Plot one species from transient solution """ -function GridVisualize.scalarplot(sys::AbstractSystem, sol::AbstractTransientSolution; species = 1, scale = 1.0, tscale = :identity, - kwargs...) - vis = GridVisualizer(;kwargs...) - if !isnothing(vis.Plotter) +function GridVisualize.scalarplot( + sys::AbstractSystem, sol::AbstractTransientSolution; species = 1, scale = 1.0, tscale = :identity, + kwargs... + ) + vis = GridVisualizer(; kwargs...) + return if !isnothing(vis.Plotter) GridVisualize.scalarplot!(vis[1, 1], sys, sol; species = species, scale = scale, tscale = tscale, kwargs...) GridVisualize.reveal(vis) end @@ -49,10 +51,12 @@ end Plot one species from transient solution """ -function GridVisualize.scalarplot!(vis, sys::AbstractSystem, sol::AbstractTransientSolution; species = 1, scale = 1.0, - tscale = :identity, tlabel = "t", - kwargs...) - if !isnothing(vis) +function GridVisualize.scalarplot!( + vis, sys::AbstractSystem, sol::AbstractTransientSolution; species = 1, scale = 1.0, + tscale = :identity, tlabel = "t", + kwargs... + ) + return if !isnothing(vis) grid = sys.grid @assert dim_space(grid) == 1 f = vec(sol[species, :, :]) * scale @@ -88,15 +92,19 @@ end Plot solution history stored in `tsol`. The `plots` argument allows to choose which plots are shown. """ -function plothistory(tsol::TransientSolution; - plots = [:timestepsizes, - :timestepupdates, - :newtonsteps, - :newtonupdates], - size = (700, 150 * length(plots)), - Plotter = GridVisualize.default_plotter(), - logmin = 1.0e-20, - kwargs...) +function plothistory( + tsol::TransientSolution; + plots = [ + :timestepsizes, + :timestepupdates, + :newtonsteps, + :newtonupdates, + ], + size = (700, 150 * length(plots)), + Plotter = GridVisualize.default_plotter(), + logmin = 1.0e-20, + kwargs... + ) hist = history(tsol) t = hist.times if length(t) == 0 @@ -107,20 +115,26 @@ function plothistory(tsol::TransientSolution; for iplot in eachindex(plots) 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...) + 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...) + 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 steps", color = :red, limits = (0, maximum(newtons) + 1), kwargs...) + GridVisualize.scalarplot!( + vis[iplot, 1], t, newtons; xlabel = "t/s", ylabel = "n", + title = "Newton steps", color = :red, limits = (0, maximum(newtons) + 1), kwargs... + ) elseif plots[iplot] == :newtonupdates nhist = length(hist) dc = 1 / nhist @@ -128,20 +142,22 @@ function plothistory(tsol::TransientSolution; 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") + 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) + return GridVisualize.reveal(vis) end plothistory(sys, tsol; kwargs...) = plothistory(tsol, kwargs...) diff --git a/src/precompile.jl b/src/precompile.jl index 2555c6cc1..a9b431cfa 100644 --- a/src/precompile.jl +++ b/src/precompile.jl @@ -21,18 +21,42 @@ using PrecompileTools boundary_dirichlet!(args...; region = 3, value = 1) end - solve(VoronoiFVM.System(simplexgrid(X); species = 1, flux = flux!, reaction = reaction!, breaction = bc!, - assembly = :cellwise); verbose = "") - solve(VoronoiFVM.System(simplexgrid(X, X); species = 1, flux = flux!, reaction = reaction!, breaction = bc!, - assembly = :cellwise); verbose = "") - solve(VoronoiFVM.System(simplexgrid(X, X, X); species = 1, flux = flux!, reaction = reaction!, breaction = bc!, - assembly = :cellwise); verbose = "") - solve(VoronoiFVM.System(simplexgrid(X); species = 1, flux = flux!, reaction = reaction!, breaction = bc!, - assembly = :edgewise); verbose = "") - solve(VoronoiFVM.System(simplexgrid(X, X); species = 1, flux = flux!, reaction = reaction!, breaction = bc!, - assembly = :edgewise); verbose = "") - solve(VoronoiFVM.System(simplexgrid(X, X, X); species = 1, flux = flux!, reaction = reaction!, breaction = bc!, - assembly = :edgewise); verbose = "") + solve( + VoronoiFVM.System( + simplexgrid(X); species = 1, flux = flux!, reaction = reaction!, breaction = bc!, + assembly = :cellwise + ); verbose = "" + ) + solve( + VoronoiFVM.System( + simplexgrid(X, X); species = 1, flux = flux!, reaction = reaction!, breaction = bc!, + assembly = :cellwise + ); verbose = "" + ) + solve( + VoronoiFVM.System( + simplexgrid(X, X, X); species = 1, flux = flux!, reaction = reaction!, breaction = bc!, + assembly = :cellwise + ); verbose = "" + ) + solve( + VoronoiFVM.System( + simplexgrid(X); species = 1, flux = flux!, reaction = reaction!, breaction = bc!, + assembly = :edgewise + ); verbose = "" + ) + solve( + VoronoiFVM.System( + simplexgrid(X, X); species = 1, flux = flux!, reaction = reaction!, breaction = bc!, + assembly = :edgewise + ); verbose = "" + ) + solve( + VoronoiFVM.System( + simplexgrid(X, X, X); species = 1, flux = flux!, reaction = reaction!, breaction = bc!, + assembly = :edgewise + ); verbose = "" + ) end lin1() end diff --git a/src/vfvm_assembly.jl b/src/vfvm_assembly.jl index 9610bded4..66efbe50f 100644 --- a/src/vfvm_assembly.jl +++ b/src/vfvm_assembly.jl @@ -10,7 +10,7 @@ Add value `v*fac` to matrix if `v` is nonzero if isnan(v) error("trying to assemble NaN") end - if v != zero(Tv) + return if v != zero(Tv) rawupdateindex!(matrix, +, v * fac, i, j, part) end end @@ -19,15 +19,17 @@ ExtendableSparse.rawupdateindex!(m::AbstractMatrix, op, v, i, j) = m[i, j] = op( function zero!(m::ExtendableSparseMatrix{Tv, Ti}) where {Tv, Ti} nzv = nonzeros(m) - nzv .= zero(Tv) + return nzv .= zero(Tv) end zero!(m::AbstractMatrix{T}) where {T} = m .= zero(T) -function assemble_nodes(system, matrix, dudp, time, tstepinv, λ, data, params, part, - U::AbstractMatrix{Tv}, # Actual solution iteration - UOld::AbstractMatrix{Tv}, # Old timestep solution - F::AbstractMatrix{Tv}) where {Tv} +function assemble_nodes( + system, matrix, dudp, time, tstepinv, λ, data, params, part, + U::AbstractMatrix{Tv}, # Actual solution iteration + UOld::AbstractMatrix{Tv}, # Old timestep solution + F::AbstractMatrix{Tv} + ) where {Tv} physics = system.physics nspecies::Int = num_species(system) nparams::Int = system.num_parameters @@ -69,24 +71,30 @@ function assemble_nodes(system, matrix, dudp, time, tstepinv, λ, data, params, oldstor = res(oldstor_evaluator) @inline function asm_res(idof, ispec) - _add(F, - idof, - node.fac * (res_react[ispec] - src[ispec] + - (res_stor[ispec] - oldstor[ispec]) * tstepinv)) + _add( + F, + idof, + node.fac * ( + res_react[ispec] - src[ispec] + + (res_stor[ispec] - oldstor[ispec]) * tstepinv + ) + ) end @inline function asm_jac(idof, jdof, ispec, jspec) - _addnz(matrix, - idof, - jdof, - jac_react[ispec, jspec] + jac_stor[ispec, jspec] * tstepinv, - node.fac, part) + _addnz( + matrix, + idof, + jdof, + jac_react[ispec, jspec] + jac_stor[ispec, jspec] * tstepinv, + node.fac, part + ) end @inline function asm_param(idof, ispec, iparam) jparam = nspecies + iparam dudp[iparam][ispec, idof] += (jac_react[ispec, jparam] + jac_stor[ispec, jparam] * tstepinv) * - node.fac + node.fac end assemble_res_jac(node, system, asm_res, asm_jac, asm_param) @@ -95,10 +103,12 @@ function assemble_nodes(system, matrix, dudp, time, tstepinv, λ, data, params, return ncalloc end -function assemble_edges(system, matrix, dudp, time, tstepinv, λ, data, params, part, - U::AbstractMatrix{Tv}, # Actual solution iteration - UOld::AbstractMatrix{Tv}, # Old timestep solution - F::AbstractMatrix{Tv}) where {Tv} +function assemble_edges( + system, matrix, dudp, time, tstepinv, λ, data, params, part, + U::AbstractMatrix{Tv}, # Actual solution iteration + UOld::AbstractMatrix{Tv}, # Old timestep solution + F::AbstractMatrix{Tv} + ) where {Tv} physics = system.physics nspecies::Int = num_species(system) nparams::Int = system.num_parameters @@ -112,7 +122,7 @@ function assemble_edges(system, matrix, dudp, time, tstepinv, λ, data, params, erea_evaluator = ResJacEvaluator(physics, data, :edgereaction, UKL, edge, nspecies) outflow_evaluator = ResJacEvaluator(physics, data, :boutflow, UKL, edge, nspecies) - @allocations for item in edgebatch(system.assembly_data, part) + return @allocations for item in edgebatch(system.assembly_data, part) for iedge in edgerange(system.assembly_data, item) _fill!(edge, system.assembly_data, iedge, item) @@ -132,16 +142,20 @@ function assemble_edges(system, matrix, dudp, time, tstepinv, λ, data, params, @inline function asm_jac(idofK, jdofK, idofL, jdofL, ispec, jspec) _addnz(matrix, idofK, jdofK, +jac_flux[ispec, jspec], edge.fac, part) _addnz(matrix, idofL, jdofK, -jac_flux[ispec, jspec], edge.fac, part) - _addnz(matrix, - idofK, - jdofL, - +jac_flux[ispec, jspec + nspecies], - edge.fac, part) - _addnz(matrix, - idofL, - jdofL, - -jac_flux[ispec, jspec + nspecies], - edge.fac, part) + _addnz( + matrix, + idofK, + jdofL, + +jac_flux[ispec, jspec + nspecies], + edge.fac, part + ) + _addnz( + matrix, + idofL, + jdofL, + -jac_flux[ispec, jspec + nspecies], + edge.fac, part + ) end @inline function asm_param(idofK, idofL, ispec, iparam) @@ -166,16 +180,20 @@ function assemble_edges(system, matrix, dudp, time, tstepinv, λ, data, params, @inline function ereaasm_jac(idofK, jdofK, idofL, jdofL, ispec, jspec) _addnz(matrix, idofK, jdofK, +jac_erea[ispec, jspec], edge.fac, part) _addnz(matrix, idofL, jdofK, -jac_erea[ispec, jspec], edge.fac, part) - _addnz(matrix, - idofK, - jdofL, - -jac_erea[ispec, jspec + nspecies], - edge.fac, part) - _addnz(matrix, - idofL, - jdofL, - +jac_erea[ispec, jspec + nspecies], - edge.fac, part) + _addnz( + matrix, + idofK, + jdofL, + -jac_erea[ispec, jspec + nspecies], + edge.fac, part + ) + _addnz( + matrix, + idofL, + jdofL, + +jac_erea[ispec, jspec + nspecies], + edge.fac, part + ) end @inline function ereaasm_param(idofK, idofL, ispec, iparam) @@ -208,29 +226,37 @@ function assemble_edges(system, matrix, dudp, time, tstepinv, λ, data, params, @inline function outflowasm_jac(idofK, jdofK, idofL, jdofL, ispec, jspec) if isoutflownode(edge, 1) - _addnz(matrix, - idofK, - jdofK, - +jac_outflow[ispec, jspec], - edge.fac, part) - _addnz(matrix, - idofK, - jdofL, - jac_outflow[ispec, jspec + nspecies], - edge.fac, part) + _addnz( + matrix, + idofK, + jdofK, + +jac_outflow[ispec, jspec], + edge.fac, part + ) + _addnz( + matrix, + idofK, + jdofL, + jac_outflow[ispec, jspec + nspecies], + edge.fac, part + ) end if isoutflownode(edge, 2) - _addnz(matrix, - idofL, - jdofK, - -jac_outflow[ispec, jspec], - edge.fac, part) - _addnz(matrix, - idofL, - jdofL, - -jac_outflow[ispec, jspec + nspecies], - edge.fac, part) + _addnz( + matrix, + idofL, + jdofK, + -jac_outflow[ispec, jspec], + edge.fac, part + ) + _addnz( + matrix, + idofL, + jdofL, + -jac_outflow[ispec, jspec + nspecies], + edge.fac, part + ) end end @@ -244,20 +270,24 @@ function assemble_edges(system, matrix, dudp, time, tstepinv, λ, data, params, end end - assemble_res_jac(edge, - system, - outflowasm_res, - outflowasm_jac, - outflowasm_param) + assemble_res_jac( + edge, + system, + outflowasm_res, + outflowasm_jac, + outflowasm_param + ) end end end end -function assemble_bnodes(system, matrix, dudp, time, tstepinv, λ, data, params, part, - U::AbstractMatrix{Tv}, # Actual solution iteration - UOld::AbstractMatrix{Tv}, # Old timestep solution - F::AbstractMatrix{Tv}) where {Tv} +function assemble_bnodes( + system, matrix, dudp, time, tstepinv, λ, data, params, part, + U::AbstractMatrix{Tv}, # Actual solution iteration + UOld::AbstractMatrix{Tv}, # Old timestep solution + F::AbstractMatrix{Tv} + ) where {Tv} physics = system.physics nspecies::Int = num_species(system) nparams::Int = system.num_parameters @@ -278,7 +308,7 @@ function assemble_bnodes(system, matrix, dudp, time, tstepinv, λ, data, params, bstor_evaluator = ResJacEvaluator(physics, data, :bstorage, UK, bnode, nspecies) oldbstor_evaluator = ResEvaluator(physics, data, :bstorage, UK, bnode, nspecies) - @allocations for item in nodebatch(system.boundary_assembly_data, part) + return @allocations for item in nodebatch(system.boundary_assembly_data, part) for ibnode in noderange(system.boundary_assembly_data, item) _fill!(bnode, system.boundary_assembly_data, ibnode, item) @@ -289,7 +319,7 @@ function assemble_bnodes(system, matrix, dudp, time, tstepinv, λ, data, params, # Assemble "standard" boundary conditions: Robin or # Dirichlet # valid only for interior species, currently not checked - for ispec = 1:nspecies + for ispec in 1:nspecies idof = dof(F, ispec, K) # If species is present, assemble the boundary condition if idof > 0 @@ -345,16 +375,20 @@ function assemble_bnodes(system, matrix, dudp, time, tstepinv, λ, data, params, evaluate!(oldbstor_evaluator, UKOld) oldbstor = res(oldbstor_evaluator) - asm_res2(idof, ispec) = _add(F, - idof, - bnode.fac * (res_bstor[ispec] - oldbstor[ispec]) * tstepinv) + asm_res2(idof, ispec) = _add( + F, + idof, + bnode.fac * (res_bstor[ispec] - oldbstor[ispec]) * tstepinv + ) function asm_jac2(idof, jdof, ispec, jspec) - _addnz(matrix, - idof, - jdof, - jac_bstor[ispec, jspec], - bnode.fac * tstepinv, part) + _addnz( + matrix, + idof, + jdof, + jac_bstor[ispec, jspec], + bnode.fac * tstepinv, part + ) end function asm_param2(idof, ispec, iparam) @@ -367,10 +401,12 @@ function assemble_bnodes(system, matrix, dudp, time, tstepinv, λ, data, params, end end -function assemble_bedges(system, matrix, dudp, time, tstepinv, λ, data, params, part, - U::AbstractMatrix{Tv}, # Actual solution iteration - UOld::AbstractMatrix{Tv}, # Old timestep solution - F::AbstractMatrix{Tv}) where {Tv} +function assemble_bedges( + system, matrix, dudp, time, tstepinv, λ, data, params, part, + U::AbstractMatrix{Tv}, # Actual solution iteration + UOld::AbstractMatrix{Tv}, # Old timestep solution + F::AbstractMatrix{Tv} + ) where {Tv} physics = system.physics bedge = BEdge(system, time, λ, params) nspecies::Int = num_species(system) @@ -380,7 +416,7 @@ function assemble_bedges(system, matrix, dudp, time, tstepinv, λ, data, params, UKL[(2 * nspecies + 1):end] .= params end bflux_evaluator = ResJacEvaluator(physics, data, :bflux, UKL, bedge, nspecies) - if isnontrivial(bflux_evaluator) + return if isnontrivial(bflux_evaluator) @allocations for item in edgebatch(system.boundary_assembly_data, part) for ibedge in edgerange(system.boundary_assembly_data, item) _fill!(bedge, system.boundary_assembly_data, ibedge, item) @@ -399,16 +435,20 @@ function assemble_bedges(system, matrix, dudp, time, tstepinv, λ, data, params, function asm_jac(idofK, jdofK, idofL, jdofL, ispec, jspec) _addnz(matrix, idofK, jdofK, +jac_bflux[ispec, jspec], bedge.fac, part) _addnz(matrix, idofL, jdofK, -jac_bflux[ispec, jspec], bedge.fac, part) - _addnz(matrix, - idofK, - jdofL, - +jac_bflux[ispec, jspec + nspecies], - bedge.fac, part) - _addnz(matrix, - idofL, - jdofL, - -jac_bflux[ispec, jspec + nspecies], - bedge.fac, part) + _addnz( + matrix, + idofK, + jdofL, + +jac_bflux[ispec, jspec + nspecies], + bedge.fac, part + ) + _addnz( + matrix, + idofL, + jdofL, + -jac_bflux[ispec, jspec + nspecies], + bedge.fac, part + ) end function asm_param(idofK, idofL, ispec, iparam) @@ -432,18 +472,20 @@ Main assembly method. Evaluate solution with result in right hand side F and assemble Jacobi matrix into system.matrix. """ -function eval_and_assemble(system, - U::AbstractMatrix{Tv}, # Actual solution iteration - UOld::AbstractMatrix{Tv}, # Old timestep solution - F::AbstractMatrix{Tv},# Right hand side - matrix::AbstractMatrix, - dudp, - time, - tstep,# time step size. Inf means stationary solution - λ, - data, - params::AbstractVector; - edge_cutoff = 0.0,) where {Tv} +function eval_and_assemble( + system, + U::AbstractMatrix{Tv}, # Actual solution iteration + UOld::AbstractMatrix{Tv}, # Old timestep solution + F::AbstractMatrix{Tv}, # Right hand side + matrix::AbstractMatrix, + dudp, + time, + tstep, # time step size. Inf means stationary solution + λ, + data, + params::AbstractVector; + edge_cutoff = 0.0, + ) where {Tv} _complete!(system) # needed here as well for test function system which does not use newton grid = system.grid @@ -456,7 +498,7 @@ function eval_and_assemble(system, nparams::Int = system.num_parameters @assert length(params) == nparams - for iparam = 1:nparams + for iparam in 1:nparams dudp[iparam] .= 0.0 end # Inverse of timestep @@ -542,7 +584,7 @@ function eval_and_assemble(system, _eval_and_assemble_generic_operator(system, matrix, U, F) _eval_and_assemble_inactive_species(system, matrix, U, UOld, F) - allncallocs, allnballocs, neval + return allncallocs, allnballocs, neval end """ @@ -558,18 +600,21 @@ function _eval_and_assemble_generic_operator(system::AbstractSystem, matrix, U, y = similar(vecF) generic_operator(y, vecU) vecF .+= y - forwarddiff_color_jacobian!(system.generic_matrix, - generic_operator, - vecU; - colorvec = system.generic_matrix_colors,) + forwarddiff_color_jacobian!( + system.generic_matrix, + generic_operator, + vecU; + colorvec = system.generic_matrix_colors, + ) rowval = system.generic_matrix.rowval colptr = system.generic_matrix.colptr nzval = system.generic_matrix.nzval - for i = 1:(length(colptr) - 1) - for j = colptr[i]:(colptr[i + 1] - 1) + for i in 1:(length(colptr) - 1) + for j in colptr[i]:(colptr[i + 1] - 1) updateindex!(matrix, +, nzval[j], rowval[j], i) end end + return end function _eval_generic_operator(system::AbstractSystem, U, F) @@ -581,5 +626,5 @@ function _eval_generic_operator(system::AbstractSystem, U, F) vecU = dofs(U) y = similar(vecF) generic_operator(y, vecU) - vecF .+= y + return vecF .+= y end diff --git a/src/vfvm_assemblydata.jl b/src/vfvm_assemblydata.jl index 6e12d9f1b..734a71c30 100644 --- a/src/vfvm_assemblydata.jl +++ b/src/vfvm_assemblydata.jl @@ -58,7 +58,7 @@ ExtendableGrids.num_pcolors(a::AbstractAssemblyData) = length(a.pcolor_partition ExtendableGrids.pcolors(a::AbstractAssemblyData) = 1:num_pcolors(a) function ExtendableGrids.pcolor_partitions(a::AbstractAssemblyData, color) colpart = a.pcolor_partitions - @inbounds colpart[color]:(colpart[color + 1] - 1) + return @inbounds colpart[color]:(colpart[color + 1] - 1) end ExtendableGrids.num_partitions(a::AbstractAssemblyData) = length(a.partition_cells) - 1 @@ -96,20 +96,20 @@ nodebatch(asmdata::CellwiseAssemblyData{Tv, Ti}) where {Tv, Ti} = 1:size(asmdata edgebatch(asmdata::CellwiseAssemblyData{Tv, Ti}) where {Tv, Ti} = 1:size(asmdata.edgefactors, 2) function nodebatch(asmdata::CellwiseAssemblyData{Tv, Ti}, ipart) where {Tv, Ti} - asmdata.partition_cells[ipart]:(asmdata.partition_cells[ipart + 1] - 1) + return asmdata.partition_cells[ipart]:(asmdata.partition_cells[ipart + 1] - 1) end function edgebatch(asmdata::CellwiseAssemblyData{Tv, Ti}, ipart) where {Tv, Ti} - asmdata.partition_cells[ipart]:(asmdata.partition_cells[ipart + 1] - 1) + return asmdata.partition_cells[ipart]:(asmdata.partition_cells[ipart + 1] - 1) end nodebatch(asmdata::EdgewiseAssemblyData{Tv, Ti}) where {Tv, Ti} = 1:size(asmdata.nodefactors, 2) edgebatch(asmdata::EdgewiseAssemblyData{Tv, Ti}) where {Tv, Ti} = 1:size(asmdata.edgefactors, 2) function nodebatch(asmdata::EdgewiseAssemblyData{Tv, Ti}, ipart) where {Tv, Ti} - asmdata.partition_nodes[ipart]:(asmdata.partition_nodes[ipart + 1] - 1) + return asmdata.partition_nodes[ipart]:(asmdata.partition_nodes[ipart + 1] - 1) end function edgebatch(asmdata::EdgewiseAssemblyData{Tv, Ti}, ipart) where {Tv, Ti} - asmdata.partition_edges[ipart]:(asmdata.partition_edges[ipart + 1] - 1) + return asmdata.partition_edges[ipart]:(asmdata.partition_edges[ipart + 1] - 1) end noderange(asmdata::EdgewiseAssemblyData{Tv, Ti}, inode) where {Tv, Ti} = nzrange(asmdata.nodefactors, inode) @@ -123,14 +123,16 @@ edgerange(asmdata::CellwiseAssemblyData{Tv, Ti}, icell) where {Tv, Ti} = 1:size( Fill node with the help of assemblydata. """ -function _fill!(node::Node, - asmdata::CellwiseAssemblyData{Tv, Ti}, - inode, - icell) where {Tv, Ti} +function _fill!( + node::Node, + asmdata::CellwiseAssemblyData{Tv, Ti}, + inode, + icell + ) where {Tv, Ti} node.index = node.cellnodes[inode, icell] node.region = node.cellregions[icell] node.fac = asmdata.nodefactors[inode, icell] - node.icell = icell + return node.icell = icell end """ @@ -138,21 +140,23 @@ end Fill boundary node with the help of assemblydata. """ -function _fill!(node::BNode, - asmdata::CellwiseAssemblyData{Tv, Ti}, - ibnode, - ibface) where {Tv, Ti} +function _fill!( + node::BNode, + asmdata::CellwiseAssemblyData{Tv, Ti}, + ibnode, + ibface + ) where {Tv, Ti} node.ibface = ibface node.ibnode = ibnode node.region = node.bfaceregions[ibface] node.index = node.bfacenodes[ibnode, ibface] node.cellregions[1] = 0 node.cellregions[2] = 0 - for i = 1:num_targets(node.bfacecells, ibface) + for i in 1:num_targets(node.bfacecells, ibface) icell = node.bfacecells[i, ibface] node.cellregions[i] = node.allcellregions[icell] end - node.fac = asmdata.nodefactors[ibnode, ibface] + return node.fac = asmdata.nodefactors[ibnode, ibface] end """ @@ -160,10 +164,12 @@ end Fill edge with the help of assemblydata. """ -function _fill!(edge::Edge, - asmdata::CellwiseAssemblyData{Tv, Ti}, - iedge, - icell) where {Tv, Ti} +function _fill!( + edge::Edge, + asmdata::CellwiseAssemblyData{Tv, Ti}, + iedge, + icell + ) where {Tv, Ti} if edge.has_celledges # cellx==celledges, edgenodes==global_edgenodes # If we work with projections of fluxes onto edges, # we need to ensure that the edges are accessed with the @@ -179,7 +185,7 @@ function _fill!(edge::Edge, end edge.region = edge.cellregions[icell] edge.fac = asmdata.edgefactors[iedge, icell] - edge.icell = icell + return edge.icell = icell end """ @@ -187,16 +193,18 @@ end Fill boundary edge with the help of assemblydata. """ -function _fill!(bedge::BEdge, - asmdata::CellwiseAssemblyData{Tv, Ti}, - ibedge, - ibface) where {Tv, Ti} +function _fill!( + bedge::BEdge, + asmdata::CellwiseAssemblyData{Tv, Ti}, + ibedge, + ibface + ) where {Tv, Ti} bedge.index = bedge.bfaceedges[ibedge, ibface] bedge.node[1] = bedge.bedgenodes[1, bedge.index] bedge.node[2] = bedge.bedgenodes[2, bedge.index] bedge.region = bedge.bfaceregions[ibface] bedge.icell = ibface - bedge.fac = asmdata.edgefactors[ibedge, ibface] + return bedge.fac = asmdata.edgefactors[ibedge, ibface] end """ @@ -207,7 +215,7 @@ Fill node with the help of assemblydata. function _fill!(node::Node, asmdata::EdgewiseAssemblyData{Tv, Ti}, k, inode) where {Tv, Ti} node.index = inode node.region = asmdata.nodefactors.rowval[k] - node.fac = asmdata.nodefactors.nzval[k] + return node.fac = asmdata.nodefactors.nzval[k] end """ @@ -220,7 +228,7 @@ function _fill!(edge::Edge, asmdata::EdgewiseAssemblyData{Tv, Ti}, k, iedge) whe edge.node[1] = edge.edgenodes[1, edge.index] edge.node[2] = edge.edgenodes[2, edge.index] edge.region = asmdata.edgefactors.rowval[k] - edge.fac = asmdata.edgefactors.nzval[k] + return edge.fac = asmdata.edgefactors.nzval[k] end """ @@ -234,28 +242,31 @@ Assemble residual and jacobian for node functions. Parameters: - `asm_jac(idof,jdof,ispec,jspec)`: e.g. assemble entry `ispec,jspec` of local jacobian into entry `idof,jdof` of global matrix - `asm_param(idof,ispec,iparam)` shall assemble parameter derivatives """ -@inline function assemble_res_jac(node::Node, - system::AbstractSystem, - asm_res::R, - asm_jac::J, - asm_param::P) where {R, J, P} +@inline function assemble_res_jac( + node::Node, + system::AbstractSystem, + asm_res::R, + asm_jac::J, + asm_param::P + ) where {R, J, P} K = node.index ireg = node.region - for idof = firstnodedof(system, K):lastnodedof(system, K) + for idof in firstnodedof(system, K):lastnodedof(system, K) ispec = getspecies(system, idof) if isregionspecies(system, ispec, ireg) # it is not enough to know if the species are defined... asm_res(idof, ispec) - for jdof = firstnodedof(system, K):lastnodedof(system, K) + for jdof in firstnodedof(system, K):lastnodedof(system, K) jspec = getspecies(system, jdof) if isregionspecies(system, jspec, ireg) asm_jac(idof, jdof, ispec, jspec) end end - for iparam = 1:(system.num_parameters) + for iparam in 1:(system.num_parameters) asm_param(idof, ispec, iparam) end end end + return end """ @@ -264,27 +275,30 @@ $(SIGNATURES) Assemble residual and jacobian for boundary node functions. See [`assemble_res_jac`](@ref) for more explanations. """ -@inline function assemble_res_jac(bnode::BNode, - system::AbstractSystem, - asm_res::R, - asm_jac::J, - asm_param::P) where {R, J, P} +@inline function assemble_res_jac( + bnode::BNode, + system::AbstractSystem, + asm_res::R, + asm_jac::J, + asm_param::P + ) where {R, J, P} K = bnode.index - for idof = firstnodedof(system, K):lastnodedof(system, K) + for idof in firstnodedof(system, K):lastnodedof(system, K) ispec = getspecies(system, idof) if isnodespecies(system, ispec, K) asm_res(idof, ispec) - for jdof = firstnodedof(system, K):lastnodedof(system, K) + for jdof in firstnodedof(system, K):lastnodedof(system, K) jspec = getspecies(system, jdof) if isnodespecies(system, jspec, K) asm_jac(idof, jdof, ispec, jspec) end - for iparam = 1:(system.num_parameters) + for iparam in 1:(system.num_parameters) asm_param(idof, ispec, iparam) end end end end + return end """ @@ -296,12 +310,13 @@ See [`assemble_res_jac`](@ref) for more explanations. @inline function assemble_res(node::Node, system::AbstractSystem, asm_res::R) where {R} K = node.index ireg = node.region - for idof = firstnodedof(system, K):lastnodedof(system, K) + for idof in firstnodedof(system, K):lastnodedof(system, K) ispec = getspecies(system, idof) if isregionspecies(system, ispec, ireg) asm_res(idof, ispec) end end + return end """ @@ -312,12 +327,13 @@ See [`assemble_res_jac`](@ref) for more explanations. """ @inline function assemble_res(bnode::BNode, system::AbstractSystem, asm_res::R) where {R} K = bnode.index - for idof = firstnodedof(system, K):lastnodedof(system, K) + for idof in firstnodedof(system, K):lastnodedof(system, K) ispec = getspecies(system, idof) if isnodespecies(system, ispec, K) asm_res(idof, ispec) end end + return end """ @@ -331,21 +347,23 @@ Assemble residual and jacobian for edge (flux) functions. Parameters: - `asm_jac(idofK,jdofK,idofL,jdofL,ispec,jspec)`: e.g. assemble entry `ispec,jspec` of local jacobian into entry four entries defined by `idofK` and `idofL` of global matrix - `asm_param(idofK,idofL,ispec,iparam)` shall assemble parameter derivatives """ -@inline function assemble_res_jac(edge::Edge, - system::AbstractSystem, - asm_res::R, - asm_jac::J, - asm_param::P) where {R, J, P} +@inline function assemble_res_jac( + edge::Edge, + system::AbstractSystem, + asm_res::R, + asm_jac::J, + asm_param::P + ) where {R, J, P} K = edge.node[1] L = edge.node[2] ireg = edge.region - for idofK = firstnodedof(system, K):lastnodedof(system, K) + for idofK in firstnodedof(system, K):lastnodedof(system, K) ispec = getspecies(system, idofK) if isregionspecies(system, ispec, ireg) idofL = getnodedof(system, ispec, L) if idofL > 0 asm_res(idofK, idofL, ispec) - for jdofK = firstnodedof(system, K):lastnodedof(system, K) + for jdofK in firstnodedof(system, K):lastnodedof(system, K) jspec = getspecies(system, jdofK) if isregionspecies(system, jspec, ireg) jdofL = getnodedof(system, jspec, L) @@ -354,12 +372,13 @@ Assemble residual and jacobian for edge (flux) functions. Parameters: end end end - for iparam = 1:(system.num_parameters) + for iparam in 1:(system.num_parameters) asm_param(idofK, idofL, ispec, iparam) end end end end + return end """ @@ -373,7 +392,7 @@ See [`assemble_res_jac`](@ref) for more explanations. L = edge.node[2] ireg = edge.region - for idofK = firstnodedof(system, K):lastnodedof(system, K) + for idofK in firstnodedof(system, K):lastnodedof(system, K) ispec = getspecies(system, idofK) if isregionspecies(system, ispec, ireg) idofL = getnodedof(system, ispec, L) @@ -382,6 +401,7 @@ See [`assemble_res_jac`](@ref) for more explanations. end end end + return end """ @@ -390,21 +410,23 @@ $(SIGNATURES) Assemble residual and jacobian for boundary edge (flux) functions. See [`assemble_res_jac`](@ref) for more explanations. """ -@inline function assemble_res_jac(bedge::BEdge, - system::AbstractSystem, - asm_res::R, - asm_jac::J, - asm_param::P) where {R, J, P} +@inline function assemble_res_jac( + bedge::BEdge, + system::AbstractSystem, + asm_res::R, + asm_jac::J, + asm_param::P + ) where {R, J, P} K = bedge.node[1] L = bedge.node[2] - for idofK = firstnodedof(system, K):lastnodedof(system, K) + for idofK in firstnodedof(system, K):lastnodedof(system, K) ispec = getspecies(system, idofK) if isnodespecies(system, ispec, K) idofL = getnodedof(system, ispec, L) if idofL > 0 asm_res(idofK, idofL, ispec) - for jdofK = firstnodedof(system, K):lastnodedof(system, K) + for jdofK in firstnodedof(system, K):lastnodedof(system, K) jspec = getspecies(system, jdofK) if isnodespecies(system, jspec, K) jdofL = getnodedof(system, jspec, L) @@ -413,12 +435,13 @@ See [`assemble_res_jac`](@ref) for more explanations. end end end - for iparam = 1:(system.num_parameters) + for iparam in 1:(system.num_parameters) asm_param(idofK, idofL, ispec, iparam) end end end end + return end """ @@ -430,7 +453,7 @@ See [`assemble_res_jac`](@ref) for more explanations. @inline function assemble_res(bedge::BEdge, system::AbstractSystem, asm_res::R) where {R} K = bedge.node[1] L = bedge.node[2] - for idofK = firstnodedof(system, K):lastnodedof(system, K) + for idofK in firstnodedof(system, K):lastnodedof(system, K) ispec = getspecies(system, idofK) if isnodespecies(system, ispec, K) idofL = dof(F, ispec, L) @@ -439,4 +462,5 @@ See [`assemble_res_jac`](@ref) for more explanations. end end end + return end diff --git a/src/vfvm_densesolution.jl b/src/vfvm_densesolution.jl index b5368b3c7..aeeb1610f 100644 --- a/src/vfvm_densesolution.jl +++ b/src/vfvm_densesolution.jl @@ -8,8 +8,8 @@ Fields: $(TYPEDFIELDS) """ -mutable struct DenseSolutionArray{T, N} <: AbstractSolutionArray{T,N} - u::Array{T,N} +mutable struct DenseSolutionArray{T, N} <: AbstractSolutionArray{T, N} + u::Array{T, N} history::Union{NewtonSolverHistory, Nothing} end @@ -19,27 +19,27 @@ end `DenseSolutionArray` constructor. """ -DenseSolutionArray(u::Matrix{T}) where {T} =DenseSolutionArray{T,2}(u,nothing) +DenseSolutionArray(u::Matrix{T}) where {T} = DenseSolutionArray{T, 2}(u, nothing) """ solutionarray(a::Matrix) """ -solutionarray(u::Matrix{T}) where {T} =DenseSolutionArray{T,2}(u,nothing) +solutionarray(u::Matrix{T}) where {T} = DenseSolutionArray{T, 2}(u, nothing) """ $(TYPEDSIGNATURES) `DenseSolutionArray` constructor. """ -DenseSolutionArray{T,2}(nspec::Int, nnodes::Int) where {T} =DenseSolutionArray{T,2}(Matrix{T}(nspec,nnodes),nothing) +DenseSolutionArray{T, 2}(nspec::Int, nnodes::Int) where {T} = DenseSolutionArray{T, 2}(Matrix{T}(nspec, nnodes), nothing) """ $(TYPEDSIGNATURES) `DenseSolutionArray` constructor. """ -DenseSolutionArray{T,2}(::UndefInitializer,nspec::Int, nnodes::Int) where {T} =DenseSolutionArray{T,2}(Matrix{T}(undef,nspec,nnodes),nothing) - +DenseSolutionArray{T, 2}(::UndefInitializer, nspec::Int, nnodes::Int) where {T} = DenseSolutionArray{T, 2}(Matrix{T}(undef, nspec, nnodes), nothing) + """ $(SIGNATURES) @@ -66,7 +66,7 @@ $(SIGNATURES) Vector of degrees of freedom in solution array. """ dofs(a::DenseSolutionArray) = vec(a.u) -dofs(a::Array)=vec(a) +dofs(a::Array) = vec(a) """ $(TYPEDSIGNATURES) diff --git a/src/vfvm_diffeq_interface.jl b/src/vfvm_diffeq_interface.jl index 60e774490..4fa7dc34e 100644 --- a/src/vfvm_diffeq_interface.jl +++ b/src/vfvm_diffeq_interface.jl @@ -1,4 +1,3 @@ - """ $(SIGNATURES) @@ -7,7 +6,7 @@ See https://github.com/SciML/DifferentialEquations.jl/issues/521 for discussion """ function _eval_res_jac!(state, u, t) uhash = hash(u) - if uhash != state.uhash + return if uhash != state.uhash ur = reshape(u, state.system) eval_and_assemble(state.system, ur, ur, state.residual, state.matrix, state.dudp, value(t), Inf, 0.0, state.system.physics.data, state.params) state.uhash = uhash @@ -25,7 +24,7 @@ function eval_rhs!(du, u, state, t) _eval_res_jac!(state, u, t) du .= -dofs(state.residual) state.history.nf += 1 - nothing + return nothing end """ @@ -39,7 +38,7 @@ function eval_jacobian!(J, u, state, t) # Need to implement broadcast for ExtendableSparse. J .= -state.matrix.cscmatrix state.history.njac += 1 - nothing + return nothing end """ @@ -55,8 +54,8 @@ function mass_matrix(state::SystemState{Tv, TMatrix, TSolArray, TData}) where {T bnode = BNode(state.system) nspecies = num_species(state.system) ndof = num_dof(state.system) - data=state.system.physics.data - + data = state.system.physics.data + stor_eval = ResJacEvaluator(physics, data, :storage, zeros(Tv, nspecies), node, nspecies) bstor_eval = ResJacEvaluator(physics, data, :bstorage, zeros(Tv, nspecies), node, nspecies) @@ -89,7 +88,7 @@ function mass_matrix(state::SystemState{Tv, TMatrix, TSolArray, TData}) where {T end end Mcsc = SparseMatrixCSC(M) - isdiag(Mcsc) ? Diagonal([Mcsc[i, i] for i = 1:ndof]) : Mcsc + return isdiag(Mcsc) ? Diagonal([Mcsc[i, i] for i in 1:ndof]) : Mcsc end """ @@ -106,7 +105,7 @@ function prepare_diffeq!(state, jacval, tjac) _complete!(state.system) _eval_res_jac!(state, jacval, tjac) flush!(state.matrix) - state.matrix.cscmatrix + return state.matrix.cscmatrix end ################################################################################################### @@ -119,10 +118,12 @@ Create an [ODEFunction](https://diffeq.sciml.ai/stable/basics/overview/#Defining For more documentation, see [`SciMLBase.ODEFunction(state::VoronoiFVM.SystemState; kwargs...)`](@ref) """ function SciMLBase.ODEFunction(state::VoronoiFVM.SystemState; jacval = unknowns(sys, 0), tjac = 0) - SciMLBase.ODEFunction(eval_rhs!; - jac = eval_jacobian!, - jac_prototype = prepare_diffeq!(state, dofs(jacval), tjac), - mass_matrix = mass_matrix(state)) + return SciMLBase.ODEFunction( + eval_rhs!; + jac = eval_jacobian!, + jac_prototype = prepare_diffeq!(state, dofs(jacval), tjac), + mass_matrix = mass_matrix(state) + ) end """ @@ -140,7 +141,7 @@ Parameters: The `jacval` and `tjac` are passed for a first evaluation of the Jacobian, allowing to detect the sparsity pattern which is passed to the solver. """ -SciMLBase.ODEFunction(sys::VoronoiFVM.System; kwargs...)=SciMLBase.ODEFunction(SystemState(sys); kwargs...) +SciMLBase.ODEFunction(sys::VoronoiFVM.System; kwargs...) = SciMLBase.ODEFunction(SystemState(sys); kwargs...) """ ODEProblem(state,inival,tspan,callback=SciMLBase.CallbackSet()) @@ -151,11 +152,13 @@ for more documentation. Defined in VoronoiFVM.jl. """ -function SciMLBase.ODEProblem(state::VoronoiFVM.SystemState, inival, tspan; - params=state.params, callback = SciMLBase.CallbackSet()) - state.params.=params +function SciMLBase.ODEProblem( + state::VoronoiFVM.SystemState, inival, tspan; + params = state.params, callback = SciMLBase.CallbackSet() + ) + state.params .= params odefunction = SciMLBase.ODEFunction(state; jacval = dofs(inival), tjac = tspan[1]) - SciMLBase.ODEProblem(odefunction, dofs(inival), tspan, state, callback) + return SciMLBase.ODEProblem(odefunction, dofs(inival), tspan, state, callback) end """ @@ -176,9 +179,11 @@ by [solve()](https://diffeq.sciml.ai/stable/basics/common_solver_opts/). Defined in VoronoiFVM.jl. """ -function SciMLBase.ODEProblem(sys::VoronoiFVM.System, inival, tspan; - params=zeros(sys.num_parameters), kwargs...) - SciMLBase.ODEProblem(SystemState(sys), inival, tspan; params, kwargs...) +function SciMLBase.ODEProblem( + sys::VoronoiFVM.System, inival, tspan; + params = zeros(sys.num_parameters), kwargs... + ) + return SciMLBase.ODEProblem(SystemState(sys), inival, tspan; params, kwargs...) end """ @@ -192,15 +197,15 @@ If `times` is specified, the (possibly higher order) interpolated solution at th Defined in VoronoiFVM.jl. """ -function Base.reshape(sol::AbstractDiffEqArray, sys::VoronoiFVM.AbstractSystem; times = nothing, state=nothing) +function Base.reshape(sol::AbstractDiffEqArray, sys::VoronoiFVM.AbstractSystem; times = nothing, state = nothing) if isnothing(times) - tsol=TransientSolution([reshape(sol.u[i], sys) for i = 1:length(sol.u)], sol.t) + tsol = TransientSolution([reshape(sol.u[i], sys) for i in 1:length(sol.u)], sol.t) else isol = sol(times) - tsol=TransientSolution([reshape(isol[i], sys) for t = 1:length(times)], times) + tsol = TransientSolution([reshape(isol[i], sys) for t in 1:length(times)], times) end if !isnothing(state) - tsol.history=state.history + tsol.history = state.history end - tsol + return tsol end diff --git a/src/vfvm_exceptions.jl b/src/vfvm_exceptions.jl index e79998edf..a9a06fdab 100644 --- a/src/vfvm_exceptions.jl +++ b/src/vfvm_exceptions.jl @@ -36,7 +36,7 @@ function _print_error(err, st) println(io) println(io, err) nlines = 5 - for i = 1:min(nlines, length(st)) + for i in 1:min(nlines, length(st)) line = @sprintf("%s", st[i]) L = length(line) if L < 80 @@ -51,5 +51,5 @@ function _print_error(err, st) println(io, "...") end println(io) - @warn String(take!(io)) + return @warn String(take!(io)) end diff --git a/src/vfvm_formfactors.jl b/src/vfvm_formfactors.jl index 6610c5437..acda1695f 100644 --- a/src/vfvm_formfactors.jl +++ b/src/vfvm_formfactors.jl @@ -19,7 +19,7 @@ function cellfactors!(T::Type{Edge1D}, ::Type{Cartesian1D}, coord, cellnodes, ic nodefac[1] = d / 2 nodefac[2] = d / 2 edgefac[1] = 1 / d - nothing + return nothing end function cellfactors!(T::Type{Edge1D}, ::Type{<:Polar1D}, coord, cellnodes, icell, nodefac, edgefac) @@ -39,7 +39,7 @@ function cellfactors!(T::Type{Edge1D}, ::Type{<:Polar1D}, coord, cellnodes, icel nodefac[1] = π * (rhalf * rhalf - r0 * r0) # circular volume between midline and boundary nodefac[2] = π * (r1 * r1 - rhalf * rhalf) # circular volume between midline and boundary edgefac[1] = 2.0 * π * rhalf / (r1 - r0) # circular surface / width - nothing + return nothing end function cellfactors!(T::Type{Edge1D}, ::Type{<:Spherical1D}, coord, cellnodes, icell, nodefac, edgefac) @@ -58,7 +58,7 @@ function cellfactors!(T::Type{Edge1D}, ::Type{<:Spherical1D}, coord, cellnodes, nodefac[1] = π * (rhalf^3 - r0^3) * 4.0 / 3.0 # sphere volume between midline and boundary nodefac[2] = π * (r1^3 - rhalf^3) * 4.0 / 3.0 # sphere volume between midline and boundary edgefac[1] = 4.0 * π * rhalf^2 / (r1 - r0) # circular surface / width - nothing + return nothing end function cellfactors!(T::Type{Triangle2D}, ::Type{Cartesian2D}, coord, cellnodes, icell, npar, epar) @@ -66,18 +66,22 @@ function cellfactors!(T::Type{Triangle2D}, ::Type{Cartesian2D}, coord, cellnodes @views n = cellnodes[:, icell] # Fill matrix of edge vectors - V = @SMatrix[coord[1, n[en[1, 1]]]-coord[1, n[en[2, 1]]] coord[1, n[en[1, 2]]]-coord[1, n[en[2, 2]]] coord[1, n[en[1, 3]]]-coord[1, n[en[2, 3]]]; - coord[2, n[en[1, 1]]]-coord[2, n[en[2, 1]]] coord[2, n[en[1, 2]]]-coord[2, n[en[2, 2]]] coord[2, n[en[1, 3]]]-coord[2, n[en[2, 3]]]] + V = @SMatrix[ + coord[1, n[en[1, 1]]] - coord[1, n[en[2, 1]]] coord[1, n[en[1, 2]]] - coord[1, n[en[2, 2]]] coord[1, n[en[1, 3]]] - coord[1, n[en[2, 3]]]; + coord[2, n[en[1, 1]]] - coord[2, n[en[2, 1]]] coord[2, n[en[1, 2]]] - coord[2, n[en[2, 2]]] coord[2, n[en[1, 3]]] - coord[2, n[en[2, 3]]] + ] - # Compute determinant + # Compute determinant det = V[1, 3] * V[2, 2] - V[1, 2] * V[2, 3] vol = abs(0.5 * det) ivol = 1.0 / vol # squares of edge lengths - dd = (V[1, 1] * V[1, 1] + V[2, 1] * V[2, 1], - V[1, 2] * V[1, 2] + V[2, 2] * V[2, 2], - V[1, 3] * V[1, 3] + V[2, 3] * V[2, 3]) + dd = ( + V[1, 1] * V[1, 1] + V[2, 1] * V[2, 1], + V[1, 2] * V[1, 2] + V[2, 2] * V[2, 2], + V[1, 3] * V[1, 3] + V[2, 3] * V[2, 3], + ) # contributions to \sigma_kl/h_kl epar[1] = (dd[2] + dd[3] - dd[1]) * 0.125 * ivol @@ -87,12 +91,12 @@ function cellfactors!(T::Type{Triangle2D}, ::Type{Cartesian2D}, coord, cellnodes # contributions to \omega_k npar .= 0.0 - for i = 1:3 + for i in 1:3 npar[en[1, i]] += epar[i] * dd[i] * 0.25 npar[en[2, i]] += epar[i] * dd[i] * 0.25 end - nothing + return nothing end function cellfactors!(T::Type{Triangle2D}, ::Type{Cylindrical2D}, coord, cellnodes, icell, npar, epar) @@ -100,22 +104,28 @@ function cellfactors!(T::Type{Triangle2D}, ::Type{Cylindrical2D}, coord, cellnod @views n = cellnodes[:, icell] # Fill matrix of edge vectors - V = @SMatrix[coord[1, n[en[1, 1]]]-coord[1, n[en[2, 1]]] coord[1, n[en[1, 2]]]-coord[1, n[en[2, 2]]] coord[1, n[en[1, 3]]]-coord[1, n[en[2, 3]]]; - coord[2, n[en[1, 1]]]-coord[2, n[en[2, 1]]] coord[2, n[en[1, 2]]]-coord[2, n[en[2, 2]]] coord[2, n[en[1, 3]]]-coord[2, n[en[2, 3]]]] + V = @SMatrix[ + coord[1, n[en[1, 1]]] - coord[1, n[en[2, 1]]] coord[1, n[en[1, 2]]] - coord[1, n[en[2, 2]]] coord[1, n[en[1, 3]]] - coord[1, n[en[2, 3]]]; + coord[2, n[en[1, 1]]] - coord[2, n[en[2, 1]]] coord[2, n[en[1, 2]]] - coord[2, n[en[2, 2]]] coord[2, n[en[1, 3]]] - coord[2, n[en[2, 3]]] + ] - # Compute determinant + # Compute determinant det = V[1, 3] * V[2, 2] - V[1, 2] * V[2, 3] vol = abs(0.5 * det) ivol = 1.0 / vol # squares of edge lengths - dd = (V[1, 1] * V[1, 1] + V[2, 1] * V[2, 1], - V[1, 2] * V[1, 2] + V[2, 2] * V[2, 2], - V[1, 3] * V[1, 3] + V[2, 3] * V[2, 3]) + dd = ( + V[1, 1] * V[1, 1] + V[2, 1] * V[2, 1], + V[1, 2] * V[1, 2] + V[2, 2] * V[2, 2], + V[1, 3] * V[1, 3] + V[2, 3] * V[2, 3], + ) # Edge midpoints - emid = @SArray[0.5*(coord[1, n[en[1, 1]]] + coord[1, n[en[2, 1]]]) 0.5*(coord[1, n[en[1, 2]]] + coord[1, n[en[2, 2]]]) 0.5*(coord[1, n[en[1, 3]]] + coord[1, n[en[2, 3]]]); - 0.5*(coord[2, n[en[1, 1]]] + coord[2, n[en[2, 1]]]) 0.5*(coord[2, n[en[1, 2]]] + coord[2, n[en[2, 2]]]) 0.5*(coord[2, n[en[1, 3]]] + coord[2, n[en[2, 3]]])] + emid = @SArray[ + 0.5 * (coord[1, n[en[1, 1]]] + coord[1, n[en[2, 1]]]) 0.5 * (coord[1, n[en[1, 2]]] + coord[1, n[en[2, 2]]]) 0.5 * (coord[1, n[en[1, 3]]] + coord[1, n[en[2, 3]]]); + 0.5 * (coord[2, n[en[1, 1]]] + coord[2, n[en[2, 1]]]) 0.5 * (coord[2, n[en[1, 2]]] + coord[2, n[en[2, 2]]]) 0.5 * (coord[2, n[en[1, 3]]] + coord[2, n[en[2, 3]]]) + ] # Circumcenter; use epar as temp storage @views tricircumcenter!(epar, coord[:, n[1]], coord[:, n[2]], coord[:, n[3]]) @@ -129,7 +139,7 @@ function cellfactors!(T::Type{Triangle2D}, ::Type{Cylindrical2D}, coord, cellnod # contributions to \omega_k # for integration we multiply cartesian areas with 2\pi the average radius npar .= 0.0 - for i = 1:3 + for i in 1:3 @views r1 = coord[1, n[en[1, i]]] @views r2 = coord[1, n[en[2, i]]] @@ -142,12 +152,12 @@ function cellfactors!(T::Type{Triangle2D}, ::Type{Cylindrical2D}, coord, cellnod # for angular integration we multiply interface lengths with 2\pi the average radius of the interface # need to do this after angular integrating volume contributions - for i = 1:3 + for i in 1:3 rmid = (rcc + emid[1, i]) / 2 epar[i] *= 2π * rmid end - nothing + return nothing end function cellfactors!(T::Type{Tetrahedron3D}, ::Type{Cartesian3D}, coord, cellnodes, icell, npar, epar) @@ -166,7 +176,7 @@ function cellfactors!(T::Type{Tetrahedron3D}, ::Type{Cartesian3D}, coord, cellno po3 = (3, 5, 4, 5) # use epar as intermediate memory - for i = 1:6 + for i in 1:6 p1 = cellnodes[pp1[i], icell] p2 = cellnodes[pp2[i], icell] dx = coord[1, p1] - coord[1, p2] @@ -199,7 +209,7 @@ function cellfactors!(T::Type{Tetrahedron3D}, ::Type{Cartesian3D}, coord, cellno vol = det / 6 vv = 96 * 6 * vol - for i = 1:4 + for i in 1:4 npar[i] = 0.0 i1 = pi1[i] i2 = pi2[i] @@ -216,12 +226,12 @@ function cellfactors!(T::Type{Tetrahedron3D}, ::Type{Cartesian3D}, coord, cellno epar[i3] += h3 * vf end - for i = 1:6 + for i in 1:6 npar[pp1[i]] += epar[i] npar[pp2[i]] += epar[i] epar[i] = 6 * epar[i] / dd[i] end - nothing + return nothing end ################################################ @@ -233,21 +243,21 @@ Calculate node volume contributions for boundary face. function bfacefactors!(T::Type{Vertex0D}, ::Type{Cartesian1D}, coord, bfacenodes, ibface, nodefac, edgefac) nodefac[1] = 1.0 - nothing + return nothing end function bfacefactors!(T::Type{Vertex0D}, ::Type{<:Polar1D}, coord, bfacenodes, ibface, nodefac, edgefac) inode = bfacenodes[1, ibface] r = coord[1, inode] nodefac[1] = 2 * π * r - nothing + return nothing end function bfacefactors!(T::Type{Vertex0D}, ::Type{<:Spherical1D}, coord, bfacenodes, ibface, nodefac, edgefac) inode = bfacenodes[1, ibface] r = coord[1, inode] nodefac[1] = 4 * π * r^2 - nothing + return nothing end function bfacefactors!(T::Type{Edge1D}, ::Type{Cartesian2D}, coord, bfacenodes, ibface, nodefac, edgefac) @@ -260,7 +270,7 @@ function bfacefactors!(T::Type{Edge1D}, ::Type{Cartesian2D}, coord, bfacenodes, nodefac[1] = d / 2 nodefac[2] = d / 2 edgefac[1] = 1 / d - nothing + return nothing end function bfacefactors!(T::Type{Edge1D}, ::Type{<:Cylindrical2D}, coord, bfacenodes, ibface, nodefac, edgefac) @@ -277,7 +287,7 @@ function bfacefactors!(T::Type{Edge1D}, ::Type{<:Cylindrical2D}, coord, bfacenod l = sqrt(dr * dr + dz * dz) nodefac[1] = π * (r1 + rmid) * l / 2 nodefac[2] = π * (r2 + rmid) * l / 2 - nothing + return nothing end function bfacefactors!(T::Type{Triangle2D}, ::Type{<:Cartesian3D}, coord, bfacenodes, ibface, npar, epar) @@ -287,7 +297,7 @@ function bfacefactors!(T::Type{Triangle2D}, ::Type{<:Cartesian3D}, coord, bfacen @views n = bfacenodes[:, ibface] epar .= 0 - for j = 1:3 + for j in 1:3 d = coord[j, n[en[1, 1]]] - coord[j, n[en[2, 1]]] epar[1] += d * d d = coord[j, n[en[1, 2]]] - coord[j, n[en[2, 2]]] @@ -308,7 +318,7 @@ function bfacefactors!(T::Type{Triangle2D}, ::Type{<:Cartesian3D}, coord, bfacen # Knoten-Flaechenanteile (ohne Abschneiden) npar .= 0.0 - for i = 1:3 + for i in 1:3 npar[en[1, i]] += epar[i] * d * 0.25 npar[en[2, i]] += epar[i] * d * 0.25 end @@ -318,7 +328,7 @@ function bfacefactors!(T::Type{Triangle2D}, ::Type{<:Cartesian3D}, coord, bfacen epar[2] = epar[2] * d / dd[2] epar[3] = epar[3] * d / dd[3] - nothing + return nothing end ################################################################## @@ -338,7 +348,7 @@ function integrate(::Type{<:Cartesian2D}, coordl, coordr, hnormal, velofunc; kwa wl = 1.0 / 6.0 wm = 2.0 / 3.0 wr = 1.0 / 6.0 - coordm=( 0.5*(coordl[1]+coordr[1]), 0.5*(coordl[2]+coordr[2]) ) + coordm = (0.5 * (coordl[1] + coordr[1]), 0.5 * (coordl[2] + coordr[2])) (vxl, vyl) = velofunc(coordl[1], coordl[2]) (vxm, vym) = velofunc(coordm[1], coordm[2]) (vxr, vyr) = velofunc(coordr[1], coordr[2]) @@ -356,7 +366,7 @@ function integrate(::Type{<:Cylindrical2D}, coordl, coordr, hnormal, velofunc; k wl = 1.0 / 6.0 wm = 2.0 / 3.0 wr = 1.0 / 6.0 - coordm=( 0.5*(coordl[1]+coordr[1]), 0.5*(coordl[2]+coordr[2]) ) + coordm = (0.5 * (coordl[1] + coordr[1]), 0.5 * (coordl[2] + coordr[2])) rl = coordl[1] rm = coordm[1] @@ -384,7 +394,7 @@ Project velocity onto grid edges. That is, we compute the path integrals of the given `velofunc` along the Voronoi cell edges as provided by [`integrate`](@ref). """ -function edgevelocities(grid, velofunc::F ; kwargs...) where F +function edgevelocities(grid, velofunc::F; kwargs...) where {F} @assert dim_space(grid) < 3 cn = grid[CellNodes] @@ -395,7 +405,7 @@ function edgevelocities(grid, velofunc::F ; kwargs...) where F velovec = zeros(Float64, num_edges(grid)) if dim_space(grid) == 1 - for iedge = 1:num_edges(grid) + for iedge in 1:num_edges(grid) K = en[1, iedge] L = en[2, iedge] elen = coord[1, L] - coord[1, K] @@ -403,25 +413,29 @@ function edgevelocities(grid, velofunc::F ; kwargs...) where F velovec[iedge] = -elen * vx end else - hnormal=zeros(2) + hnormal = zeros(2) p1 = zeros(2) p2 = zeros(2) - for iedge = 1:num_edges(grid) + for iedge in 1:num_edges(grid) K = en[1, iedge] L = en[2, iedge] - @views tricircumcenter!(p1, - coord[:, cn[1, ec[1, iedge]]], - coord[:, cn[2, ec[1, iedge]]], - coord[:, cn[3, ec[1, iedge]]]) + @views tricircumcenter!( + p1, + coord[:, cn[1, ec[1, iedge]]], + coord[:, cn[2, ec[1, iedge]]], + coord[:, cn[3, ec[1, iedge]]] + ) if ec[2, iedge] > 0 - @views tricircumcenter!(p2, - coord[:, cn[1, ec[2, iedge]]], - coord[:, cn[2, ec[2, iedge]]], - coord[:, cn[3, ec[2, iedge]]]) + @views tricircumcenter!( + p2, + coord[:, cn[1, ec[2, iedge]]], + coord[:, cn[2, ec[2, iedge]]], + coord[:, cn[3, ec[2, iedge]]] + ) else @views @. p2 = 0.5 * (coord[:, K] + coord[:, L]) end - @views @. hnormal.= coord[:, K] - coord[:, L] + @views @. hnormal .= coord[:, K] - coord[:, L] velovec[iedge] = integrate(coord_system, p1, p2, hnormal, velofunc; kwargs...) end end @@ -433,7 +447,7 @@ $(SIGNATURES) Similar to [`edgevelocities`](@ref), but for boundary faces. """ -function bfacevelocities(grid::ExtendableGrid{Tc,Ti}, velofunc::F ; kwargs...) where {Tc, Ti, F} +function bfacevelocities(grid::ExtendableGrid{Tc, Ti}, velofunc::F; kwargs...) where {Tc, Ti, F} @assert dim_space(grid) < 3 bfacenodes = grid[BFaceNodes] coord = grid[Coordinates] @@ -443,15 +457,15 @@ function bfacevelocities(grid::ExtendableGrid{Tc,Ti}, velofunc::F ; kwargs...) w bfr = grid[BFaceRegions] velovec = zeros(Float64, 2, num_bfaces(grid)) if dim_space(grid) == 1 - for ibface = 1:num_bfaces(grid) + for ibface in 1:num_bfaces(grid) vx, vy = velofunc(coord[1, bfacenodes[1, ibface]]) velovec[ibface] = vx * bfacenormals[1, ibface] end else - p1=zeros(2) - p2=zeros(2) - pm=zeros(2) - for ibface = 1:num_bfaces(grid) + p1 = zeros(2) + p2 = zeros(2) + pm = zeros(2) + for ibface in 1:num_bfaces(grid) @views @. p1 = coord[:, bfacenodes[1, ibface]] @views @. p2 = coord[:, bfacenodes[2, ibface]] @views @. pm = 0.5 * (p1 + p2) @@ -504,7 +518,7 @@ function calc_divergences(sys, evelo, bfvelo) bfacenodes = grid[BFaceNodes] boundarynodefactors = boundary_assem_data.nodefactors - for ibface = 1:num_bfaces(grid) + for ibface in 1:num_bfaces(grid) node1 = bfacenodes[1, ibface] node2 = bfacenodes[2, ibface] div4nodes[node1] += boundarynodefactors[1, ibface] * bfvelo[1, ibface] diff --git a/src/vfvm_functions.jl b/src/vfvm_functions.jl index 357327e54..57583c359 100644 --- a/src/vfvm_functions.jl +++ b/src/vfvm_functions.jl @@ -1,5 +1,5 @@ ############################################################## -const c1 = 1/ 47_900_160 +const c1 = 1 / 47_900_160 const c2 = -1 / 1_209_600 const c3 = 1 / 30_240 const c4 = -1 / 720 @@ -23,7 +23,7 @@ function bernoulli_horner(x) y = x * y y = x * (c5 + y) y = x * (c6 + y) - y = 1 + y + return y = 1 + y end # Bernoulli thresholds optimized for Float64 @@ -47,7 +47,7 @@ interval `(-bernoulli_small_threshold, bernoulli_small_threshold)`. Also, see the discussion in [#117](https://github.com/WIAS-PDELib/VoronoiFVM.jl/issues/117). """ function fbernoulli(x) - if x < -bernoulli_large_threshold + return if x < -bernoulli_large_threshold -x elseif x > bernoulli_large_threshold zero(x) @@ -76,7 +76,7 @@ Returns two real numbers containing the result for argument For the general approach to the implementation, see the discussion in [`fbernoulli`](@ref). """ function fbernoulli_pm(x) - if x < -bernoulli_large_threshold + return if x < -bernoulli_large_threshold -x, zero(x) elseif x > bernoulli_large_threshold zero(x), x @@ -84,7 +84,7 @@ function fbernoulli_pm(x) @inline y = bernoulli_horner(x) y, x + y else - y=x / expm1(x) + y = x / expm1(x) y, x + y end end @@ -97,20 +97,20 @@ Adapted from https://en.wikipedia.org/wiki/LU_decomposition#MATLAB_code_example. """ @inline function doolittle_ludecomp!(LU) n = size(LU, 1) - @inbounds for i = 1:n - for j = 1:(i - 1) - for k = 1:(j - 1) + @inbounds for i in 1:n + for j in 1:(i - 1) + for k in 1:(j - 1) LU[i, j] -= LU[i, k] * LU[k, j] end LU[i, j] /= LU[j, j] end - for j = i:n - for k = 1:(i - 1) + for j in i:n + for k in 1:(i - 1) LU[i, j] -= LU[i, k] * LU[k, j] end end end - LU + return LU end """ @@ -124,19 +124,19 @@ Adapted from https://en.wikipedia.org/wiki/LU_decomposition#MATLAB_code_example. n = length(b) # LU= L+U-I # find solution of Ly = b and store it in b - @inbounds for i = 1:n - for k = 1:(i - 1) + @inbounds for i in 1:n + for k in 1:(i - 1) b[i] -= LU[i, k] * b[k] end end # find solution of Ux = b and store it in b - @inbounds for i = n:-1:1 - for k = (i + 1):n + @inbounds for i in n:-1:1 + for k in (i + 1):n b[i] -= LU[i, k] * b[k] end b[i] /= LU[i, i] end - b + return b end """ @@ -151,7 +151,7 @@ A pivoting version is available with Julia v1.9. """ @inline function inplace_linsolve!(A, b) doolittle_ludecomp!(A) - doolittle_lusolve!(A, b) + return doolittle_lusolve!(A, b) end """ @@ -164,5 +164,5 @@ After solution, `A` will contain the LU factorization, and `b` the result. `ipiv` must be an Int64 vector of the same length as `b`. """ @inline function inplace_linsolve!(A, b, ipiv) - LinearAlgebra.ldiv!(RecursiveFactorization.lu!(A, ipiv, Val(true), Val(false)), b) + return LinearAlgebra.ldiv!(RecursiveFactorization.lu!(A, ipiv, Val(true), Val(false)), b) end diff --git a/src/vfvm_geometryitems.jl b/src/vfvm_geometryitems.jl index e26d73d01..5515f47ea 100644 --- a/src/vfvm_geometryitems.jl +++ b/src/vfvm_geometryitems.jl @@ -56,7 +56,7 @@ Return abstract vector of parameters passed via vector of unknowns. This allows differentiation with respect to these parameters. """ function parameters(u::AbstractNodeData) - DParameters(u.val, u.nspec) + return DParameters(u.val, u.nspec) end """ @@ -81,7 +81,7 @@ Base.size(u::AbstractEdgeData) = (u.n1, 2) Base.getindex(u::AbstractEdgeData, i, j) = @inbounds u.val[(j - 1) * u.n1 + i] function parameters(u::AbstractEdgeData) - DParameters(u.val, u.n1 + u.n1) + return DParameters(u.val, u.n1 + u.n1) end ################################################################## @@ -154,17 +154,19 @@ mutable struct Node{Tc, Tp, Ti} <: AbstractNode{Tc, Tp, Ti} _idx::Ti function Node{Tc, Tp, Ti}(sys::AbstractSystem{Tv, Tc, Ti, Tm}, time, embedparam, params::Vector{Tp}) where {Tv, Tc, Tp, Ti, Tm} - new(zero(Ti), 0, + return new( + zero(Ti), 0, num_species(sys), 0, coordinates(sys.grid), sys.grid[CellNodes], sys.grid[CellRegions], - time, embedparam, params, 0.0, 0) + time, embedparam, params, 0.0, 0 + ) end end function Node(sys::AbstractSystem{Tv, Tc, Ti, Tm}, time, embedparam, params::Vector{Tp}) where {Tv, Tc, Tp, Ti, Tm} - Node{Tc, Tp, Ti}(sys, time, embedparam, params) + return Node{Tc, Tp, Ti}(sys, time, embedparam, params) end Node(sys) = Node(sys, 0, 0, zeros(0)) @@ -181,7 +183,7 @@ struct NodeUnknowns{Tv, Tc, Tp, Ti} <: AbstractNodeData{Tv} end @inline function unknowns(node::Node{Tc, Tp, Ti}, u::AbstractVector{Tv}) where {Tv, Tc, Tp, Ti} - NodeUnknowns{Tv, Tc, Tp, Ti}(u, node.nspec, node) + return NodeUnknowns{Tv, Tc, Tp, Ti}(u, node.nspec, node) end """ @@ -267,9 +269,12 @@ mutable struct BNode{Tv, Tc, Tp, Ti} <: AbstractNode{Tc, Tp, Ti} fac::Float64 - function BNode{Tv, Tc, Tp, Ti}(sys::AbstractSystem{Tv, Tc, Ti, Tm}, time, embedparam, - params::Vector{Tp}) where {Tv, Tc, Tp, Ti, Tm} - new(0, 0, 0, 0, zeros(Ti, 2), + function BNode{Tv, Tc, Tp, Ti}( + sys::AbstractSystem{Tv, Tc, Ti, Tm}, time, embedparam, + params::Vector{Tp} + ) where {Tv, Tc, Tp, Ti, Tm} + return new( + 0, 0, 0, 0, zeros(Ti, 2), num_species(sys), coordinates(sys.grid), sys.grid[BFaceNodes], @@ -277,11 +282,12 @@ mutable struct BNode{Tv, Tc, Tp, Ti} <: AbstractNode{Tc, Tp, Ti} sys.grid[CellRegions], sys.grid[BFaceCells], Dirichlet(Tv), time, embedparam, params, - zeros(Tv, num_species(sys)), 0.0) + zeros(Tv, num_species(sys)), 0.0 + ) end end function BNode(sys::AbstractSystem{Tv, Tc, Ti, Tm}, time, embedparam, params::Vector{Tp}) where {Tv, Tc, Tp, Ti, Tm} - BNode{Tv, Tc, Tp, Ti}(sys, time, embedparam, params) + return BNode{Tv, Tc, Tp, Ti}(sys, time, embedparam, params) end BNode(sys) = BNode(sys, 0, 0, zeros(0)) @@ -292,7 +298,7 @@ struct BNodeUnknowns{Tval, Tv, Tc, Tp, Ti} <: AbstractNodeData{Tv} end @inline function unknowns(bnode::BNode{Tv, Tc, Tp, Ti}, u::AbstractVector{Tval}) where {Tval, Tv, Tc, Tp, Ti} - BNodeUnknowns{Tval, Tv, Tc, Tp, Ti}(u, bnode.nspec, bnode) + return BNodeUnknowns{Tval, Tv, Tc, Tp, Ti}(u, bnode.nspec, bnode) end struct BNodeRHS{Tval, Tv, Tc, Tp, Ti} <: AbstractNodeData{Tv} @@ -302,7 +308,7 @@ struct BNodeRHS{Tval, Tv, Tc, Tp, Ti} <: AbstractNodeData{Tv} end @inline function rhs(bnode::BNode{Tv, Tc, Tp, Ti}, f::AbstractVector{Tval}) where {Tval, Tv, Tc, Tp, Ti} - BNodeRHS{Tval, Tv, Tc, Tp, Ti}(f, bnode.nspec, bnode) + return BNodeRHS{Tval, Tv, Tc, Tp, Ti}(f, bnode.nspec, bnode) end ################################################################## @@ -370,8 +376,8 @@ mutable struct Edge{Tc, Tp, Ti} <: AbstractEdge{Tc, Tp, Ti} fac::Float64 """ - Local loop index - """ + Local loop index + """ _idx::Ti outflownoderegions::Union{Nothing, SparseMatrixCSC{Bool, Int}} @@ -413,7 +419,7 @@ function Edge(sys::AbstractSystem{Tv, Tc, Ti, Tm}, time, embedparam, params::Vec edge.outflownode = 0 edge._idx = 0 edge.outflownoderegions = sys.outflownoderegions - edge + return edge end struct EdgeUnknowns{Tv, Tc, Tp, Ti} <: AbstractEdgeData{Tv} @@ -423,7 +429,7 @@ struct EdgeUnknowns{Tv, Tc, Tp, Ti} <: AbstractEdgeData{Tv} end @inline function unknowns(edge::Edge{Tc, Tp, Ti}, u::AbstractVector{Tv}) where {Tv, Tc, Tp, Ti} - EdgeUnknowns{Tv, Tc, Tp, Ti}(u, edge.nspec, edge) + return EdgeUnknowns{Tv, Tc, Tp, Ti}(u, edge.nspec, edge) end struct EdgeRHS{Tv, Tc, Tp, Ti} <: AbstractNodeData{Tv} @@ -469,7 +475,7 @@ Set `edge.outflownode` entry. """ function outflownode!(edge) isoutflownode(edge, 1) ? edge.outflownode = 1 : true - isoutflownode(edge, 2) ? edge.outflownode = 2 : true + return isoutflownode(edge, 2) ? edge.outflownode = 2 : true end ################################################################## @@ -553,7 +559,7 @@ function BEdge(sys::AbstractSystem{Tv, Tc, Ti, Tm}, time, embedparam, params::Ve bedge.embedparam = embedparam bedge.params = params bedge.fac = 0.0 - bedge + return bedge end struct BEdgeUnknowns{Tv, Tc, Tp, Ti} <: AbstractEdgeData{Tv} @@ -563,7 +569,7 @@ struct BEdgeUnknowns{Tv, Tc, Tp, Ti} <: AbstractEdgeData{Tv} end @inline function unknowns(edge::BEdge{Tc, Tp, Ti}, u::AbstractVector{Tv}) where {Tv, Tc, Tp, Ti} - BEdgeUnknowns{Tv, Tc, Tp, Ti}(u, edge.nspec, edge) + return BEdgeUnknowns{Tv, Tc, Tp, Ti}(u, edge.nspec, edge) end struct BEdgeRHS{Tv, Tc, Tp, Ti} <: AbstractNodeData{Tv} @@ -590,7 +596,7 @@ Calculate the length of an edge. """ function meas(edge::AbstractEdge) l = 0.0 - for i = 1:size(edge.coord)[1] + for i in 1:size(edge.coord)[1] d = edge.coord[i, edge.node[1]] - edge.coord[i, edge.node[2]] l = l + d * d end @@ -612,7 +618,7 @@ of `vector` with the difference of the edge end coordinates. """ function project(edge::Edge, vec) vh = zero(eltype(vec)) - for i = 1:size(edge.coord)[1] + for i in 1:size(edge.coord)[1] vh += (edge.coord[i, edge.node[2]] - edge.coord[i, edge.node[1]]) * vec[i] end return vh diff --git a/src/vfvm_history.jl b/src/vfvm_history.jl index b38189429..5b7836080 100644 --- a/src/vfvm_history.jl +++ b/src/vfvm_history.jl @@ -39,15 +39,17 @@ Base.size(h::NewtonSolverHistory) = size(h.updatenorm) Return named tuple summarizing history. """ function Base.summary(h::NewtonSolverHistory) - (seconds = round(h.time; sigdigits = 3), - tasm = round(h.tasm; sigdigits = 3), - tlinsolve = round(h.tlinsolve; sigdigits = 3), - iters = length(h.updatenorm), - absnorm = round(h.updatenorm[end]; sigdigits = 3), - relnorm = round(h.updatenorm[end] / h.updatenorm[1]; sigdigits = 3), - roundoff = round(h.l1normdiff[end]; sigdigits = 3), - factorizations = h.nlu, - liniters = h.nlin) + return ( + seconds = round(h.time; sigdigits = 3), + tasm = round(h.tasm; sigdigits = 3), + tlinsolve = round(h.tlinsolve; sigdigits = 3), + iters = length(h.updatenorm), + absnorm = round(h.updatenorm[end]; sigdigits = 3), + relnorm = round(h.updatenorm[end] / h.updatenorm[1]; sigdigits = 3), + roundoff = round(h.l1normdiff[end]; sigdigits = 3), + factorizations = h.nlu, + liniters = h.nlin, + ) end """ @@ -57,12 +59,16 @@ Return array of named tuples with info on each iteration step """ function details(h::NewtonSolverHistory) a = [] - for i = 1:length(h) - push!(a, - (update = round(h[i]; sigdigits = 3), contraction = round(i > 1 ? h[i] / h[i - 1] : 1.0; sigdigits = 3), - round = round(h.l1normdiff[i]; sigdigits = 3))) + for i in 1:length(h) + push!( + a, + ( + update = round(h[i]; sigdigits = 3), contraction = round(i > 1 ? h[i] / h[i - 1] : 1.0; sigdigits = 3), + round = round(h.l1normdiff[i]; sigdigits = 3), + ) + ) end - a + return a end ################################################################################# @@ -100,17 +106,19 @@ Return named tuple summarizing history. """ function Base.summary(hh::TransientSolverHistory) hx = view(hh, 2:length(hh)) - (seconds = round(sum(h -> h.time, hx); sigdigits = 3), - tasm = round(sum(h -> h.tasm, hx); sigdigits = 3), - tlinsolve = round(sum(h -> h.tlinsolve, hx); sigdigits = 3), - steps = length(hh.histories), - iters = sum(h -> length(h.updatenorm), hx), - maxabsnorm = round(maximum(h -> h.updatenorm[end], hx); sigdigits = 3), - maxrelnorm = round(maximum(h -> h.updatenorm[end] / h.updatenorm[1], hx); sigdigits = 3), - maxroundoff = round(maximum(h -> h.l1normdiff[end], hx); sigdigits = 3), - iters_per_step = round(mean(h -> length(h.updatenorm), hx); sigdigits = 3), - facts_per_step = round(mean(h -> h.nlu, hx); sigdigits = 3), - liniters_per_step = round(mean(h -> h.nlin, hx); sigdigits = 3)) + return ( + seconds = round(sum(h -> h.time, hx); sigdigits = 3), + tasm = round(sum(h -> h.tasm, hx); sigdigits = 3), + tlinsolve = round(sum(h -> h.tlinsolve, hx); sigdigits = 3), + steps = length(hh.histories), + iters = sum(h -> length(h.updatenorm), hx), + maxabsnorm = round(maximum(h -> h.updatenorm[end], hx); sigdigits = 3), + maxrelnorm = round(maximum(h -> h.updatenorm[end] / h.updatenorm[1], hx); sigdigits = 3), + maxroundoff = round(maximum(h -> h.l1normdiff[end], hx); sigdigits = 3), + iters_per_step = round(mean(h -> length(h.updatenorm), hx); sigdigits = 3), + facts_per_step = round(mean(h -> h.nlu, hx); sigdigits = 3), + liniters_per_step = round(mean(h -> h.nlin, hx); sigdigits = 3), + ) end """ @@ -120,12 +128,16 @@ Return array of details of each solver step """ function details(hh::TransientSolverHistory) a = [] - for i = 1:length(hh) - push!(a, - (t = round(hh.times[i]; sigdigits = 3), Δu = round(hh.updates[i]; sigdigits = 3), summary = summary(hh[i]), - detail = details(hh[i]))) + for i in 1:length(hh) + push!( + a, + ( + t = round(hh.times[i]; sigdigits = 3), Δu = round(hh.updates[i]; sigdigits = 3), summary = summary(hh[i]), + detail = details(hh[i]), + ) + ) end - a + return a end diff --git a/src/vfvm_impedance.jl b/src/vfvm_impedance.jl index a05edfcc7..4f4b6dcfd 100644 --- a/src/vfvm_impedance.jl +++ b/src/vfvm_impedance.jl @@ -47,7 +47,7 @@ $(SIGNATURES) Construct impedance system from time domain system `sys` and steady state solution `U0` """ function ImpedanceSystem(system::AbstractSystem{Tv, Tc, Ti}, U0::AbstractMatrix; λ0 = 0.0) where {Tv, Tc, Ti} - U0=solutionarray(U0) + U0 = solutionarray(U0) residual = copy(U0) if system.num_parameters > 0 @@ -55,7 +55,7 @@ function ImpedanceSystem(system::AbstractSystem{Tv, Tc, Ti}, U0::AbstractMatrix; else params = zeros(0) end - state=SystemState(system) + state = SystemState(system) # Ensure that matrix contains the jacobian at U0 # Moreover, here we use the fact that for large time step sizes, # the contribution from the time derivative (which should not belong to the @@ -75,10 +75,12 @@ function ImpedanceSystem(system::AbstractSystem{Tv, Tc, Ti}, U0::AbstractMatrix; impedance_system.storderiv = spzeros(Tv, m, n) # create sparse matrix with the same nonzero pattern of original matrix - impedance_system.matrix = SparseMatrixCSC(m, n, - SparseArrays.getcolptr(state.matrix), - SparseArrays.getrowval(state.matrix), - copy(impedance_system.sysnzval)) + impedance_system.matrix = SparseMatrixCSC( + m, n, + SparseArrays.getcolptr(state.matrix), + SparseArrays.getrowval(state.matrix), + copy(impedance_system.sysnzval) + ) impedance_system.U0 = U0 # Initialize right hand side of impedance system @@ -118,7 +120,7 @@ function ImpedanceSystem(system::AbstractSystem{Tv, Tc, Ti}, U0::AbstractMatrix; jac_stor = jac(stor_eval) # Sort it into storderiv matrix. function asm_jac(idof, jdof, ispec, jspec) - updateindex!(storderiv, +, jac_stor[ispec, jspec] * node.fac, idof, jdof) + return updateindex!(storderiv, +, jac_stor[ispec, jspec] * node.fac, idof, jdof) end assemble_res_jac(node, system, asm_res, asm_jac, asm_param) end @@ -136,7 +138,7 @@ function ImpedanceSystem(system::AbstractSystem{Tv, Tc, Ti}, U0::AbstractMatrix; jac_bstor = jac(bstor_eval) K = bnode.index function asm_jac(idof, jdof, ispec, jspec) - updateindex!(storderiv, +, jac_bstor[ispec, jspec] * bnode.fac, idof, jdof) + return updateindex!(storderiv, +, jac_bstor[ispec, jspec] * bnode.fac, idof, jdof) end assemble_res_jac(bnode, system, asm_res, asm_jac, asm_param) end @@ -166,7 +168,7 @@ function ImpedanceSystem(system::AbstractSystem{Tv, Tc, Ti}, U0::AbstractMatrix, # We don't need to put the penalty term to storderiv # as it is already in the main part of the matrix if bnode.region == excited_bc - for ispec = 1:nspecies + for ispec in 1:nspecies if ispec != excited_spec continue end @@ -214,15 +216,15 @@ function CommonSolve.solve!(UZ::AbstractMatrix{Complex{Tv}}, impedance_system::I colptr = storderiv.colptr inzval = storderiv.nzval - for i = 1:(length(colptr) - 1) - for k = colptr[i]:(colptr[i + 1] - 1) + for i in 1:(length(colptr) - 1) + for k in colptr[i]:(colptr[i + 1] - 1) j = rowval[k] updateindex!(matrix, +, inzval[k] * iω, i, j) end end lufact = LinearAlgebra.lu(matrix) - ldiv!(dofs(UZ), lufact, dofs(impedance_system.F)) + return ldiv!(dofs(UZ), lufact, dofs(impedance_system.F)) end """ @@ -238,9 +240,9 @@ function measurement_derivative(system::AbstractSystem, measurement_functional, # Create a sparse 1×ndof matrix assuming that the functional # depends on all unknowns in the system ndof = num_dof(system) - colptr = [i for i = 1:(ndof + 1)] - rowval = [1 for i = 1:ndof] - nzval = [1.0 for in = 1:ndof] + colptr = [i for i in 1:(ndof + 1)] + rowval = [1 for i in 1:ndof] + nzval = [1.0 for in in 1:ndof] jac = SparseMatrixCSC(1, ndof, colptr, rowval, nzval) # See https://github.com/JuliaDiff/SparseDiffTools.jl @@ -251,7 +253,7 @@ function measurement_derivative(system::AbstractSystem, measurement_functional, # Use Julia automatic differentiation for the calculation of the Jacobian forwarddiff_color_jacobian!(jac, measurement_functional, dofs(U0); colorvec = colors) - # Drop any zero entries + # Drop any zero entries dropzeros!(jac) return jac @@ -275,11 +277,13 @@ Calculate impedance. - dmeas_tran Derivative of transient part of the measurement functional """ -function impedance(impedance_system::ImpedanceSystem, # frequency domain system - ω, # frequency - U0, # steady state slution - dmeas_stdy, # Derivative of steady state part of measurement functional - dmeas_tran) +function impedance( + impedance_system::ImpedanceSystem, # frequency domain system + ω, # frequency + U0, # steady state slution + dmeas_stdy, # Derivative of steady state part of measurement functional + dmeas_tran + ) iω = 1im * ω # solve impedance system UZ = unknowns(impedance_system) @@ -289,7 +293,7 @@ function impedance(impedance_system::ImpedanceSystem, # frequency domain system m_stdy = dmeas_stdy * dofs(UZ) m_tran = dmeas_tran * dofs(UZ) - # Calculate complex measurement + # Calculate complex measurement z = m_stdy[1] + iω * m_tran[1] return 1 / z @@ -304,12 +308,14 @@ Calculate reciprocal value of impedance. !!! warning This is deprecated: use [`impedance`](@ref). """ -function freqdomain_impedance(impedance_system::ImpedanceSystem, # frequency domain system - ω, # frequency - U0, # steady state slution - excited_spec, excited_bc, excited_bcval, - dmeas_stdy, # Derivative of steady state part of measurement functional - dmeas_tran) +function freqdomain_impedance( + impedance_system::ImpedanceSystem, # frequency domain system + ω, # frequency + U0, # steady state slution + excited_spec, excited_bc, excited_bcval, + dmeas_stdy, # Derivative of steady state part of measurement functional + dmeas_tran + ) z = impedance(impedance_system, ω, U0, dmeas_stdy, dmeas_tran) - 1 / z + return 1 / z end diff --git a/src/vfvm_linsolve.jl b/src/vfvm_linsolve.jl index 0297cba84..601b03e43 100644 --- a/src/vfvm_linsolve.jl +++ b/src/vfvm_linsolve.jl @@ -1,11 +1,12 @@ - ################################################################ # 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} - ForwardDiff.Dual{T, V, N}(rand(rng, V)) +function Random.rand( + rng::AbstractRNG, + ::Random.SamplerType{ForwardDiff.Dual{T, V, N}} + ) where {T, V, N} + return ForwardDiff.Dual{T, V, N}(rand(rng, V)) end # TODO: these may be not anymore needed @@ -14,29 +15,31 @@ canonical_matrix(A::AbstractExtendableSparseMatrixCSC) = SparseMatrixCSC(A) function _solve_linear!(u, state, nlhistory, control, method_linear, A, b) if isnothing(state.linear_cache) - if !isa(method_linear, LinearSolve.SciMLLinearSolveAlgorithm) + if !isa(method_linear, LinearSolve.SciMLLinearSolveAlgorithm) @warn "use of $(typeof(method_linear)) is deprecated, use an algorithm from LinearSolve" end if hasproperty(method_linear, :precs) && !isnothing(method_linear.precs) - Pl=nothing + Pl = nothing else Pl = control.precon_linear(canonical_matrix(A)) - if !isa(Pl, Identity) && isa(method_linear, LinearSolve.AbstractKrylovSubspaceMethod) + if !isa(Pl, Identity) && isa(method_linear, LinearSolve.AbstractKrylovSubspaceMethod) @warn "Use of control.precon_linear is deprecated. Use the `precs` API of LinearSolve" end end nlhistory.nlu += 1 p = LinearProblem(canonical_matrix(A), b) - state.linear_cache = init(p, - method_linear; - abstol = control.abstol_linear, - reltol = control.reltol_linear, - maxiters = control.maxiters_linear, - verbose = doprint(control, 'l'), - Pl,) + state.linear_cache = init( + p, + method_linear; + abstol = control.abstol_linear, + reltol = control.reltol_linear, + maxiters = control.maxiters_linear, + verbose = doprint(control, 'l'), + Pl, + ) else if hasproperty(method_linear, :precs) && !isnothing(method_linear.precs) - reinit!(state.linear_cache; A=canonical_matrix(A), b, reuse_precs=!control.keepcurrent_linear) + reinit!(state.linear_cache; A = canonical_matrix(A), b, reuse_precs = !control.keepcurrent_linear) if control.keepcurrent_linear nlhistory.nlu += 1 end @@ -50,7 +53,7 @@ function _solve_linear!(u, state, nlhistory, control, method_linear, A, b) end end - try + return try sol = LinearSolve.solve!(state.linear_cache) u .= sol.u nliniter = sol.iters diff --git a/src/vfvm_linsolve_deprecated.jl b/src/vfvm_linsolve_deprecated.jl index 01364eaad..b5eff4c2c 100644 --- a/src/vfvm_linsolve_deprecated.jl +++ b/src/vfvm_linsolve_deprecated.jl @@ -107,7 +107,7 @@ end DirectSolver(factorization::FactorizationStrategy; kwargs...) = DirectSolver(; factorization, kwargs...) function VoronoiFVM.SolverControl(strat::DirectSolver, sys; kwargs...) - SolverControl(; method_linear = strat.factorization, kwargs...) + return SolverControl(; method_linear = strat.factorization, kwargs...) end """ @@ -124,15 +124,18 @@ Base.@kwdef struct GMRESIteration <: LinearSolverStrategy end function GMRESIteration(factorization::FactorizationStrategy, blocking = NoBlock(); kwargs...) - GMRESIteration(; factorization, blocking, kwargs...) + return GMRESIteration(; factorization, blocking, kwargs...) end function VoronoiFVM.SolverControl(strat::GMRESIteration, sys; kwargs...) - SolverControl(; - method_linear = KrylovJL_GMRES(; gmres_restart = strat.memory, - restart = strat.restart), - precon_linear = factorizationstrategy(strat.factorization, strat.blocking, sys), - kwargs...,) + return SolverControl(; + method_linear = KrylovJL_GMRES(; + gmres_restart = strat.memory, + restart = strat.restart + ), + precon_linear = factorizationstrategy(strat.factorization, strat.blocking, sys), + kwargs..., + ) end """ @@ -147,14 +150,15 @@ Base.@kwdef struct CGIteration <: LinearSolverStrategy end function CGIteration(factorization::FactorizationStrategy, blocking = NoBlock(); kwargs...) - CGIteration(; factorization, blocking, kwargs...) + return CGIteration(; factorization, blocking, kwargs...) end function VoronoiFVM.SolverControl(strat::CGIteration, sys; kwargs...) - SolverControl(; - method_linear = KrylovJL_CG(), - precon_linear = factorizationstrategy(strat.factorization, strat.blocking, sys), - kwargs...,) + return SolverControl(; + method_linear = KrylovJL_CG(), + precon_linear = factorizationstrategy(strat.factorization, strat.blocking, sys), + kwargs..., + ) end """ @@ -169,14 +173,15 @@ Base.@kwdef struct BICGstabIteration <: LinearSolverStrategy end function BICGstabIteration(factorization::FactorizationStrategy, blocking = NoBlock(); kwargs...) - BICGstabIteration(; factorization, blocking, kwargs...) + return BICGstabIteration(; factorization, blocking, kwargs...) end function VoronoiFVM.SolverControl(strat::BICGstabIteration, sys; kwargs...) - SolverControl(; - method_linear = KrylovJL_BICGSTAB(), - precon_linear = factorizationstrategy(strat.factorization, strat.blocking, sys), - kwargs...,) + return SolverControl(; + method_linear = KrylovJL_BICGSTAB(), + precon_linear = factorizationstrategy(strat.factorization, strat.blocking, sys), + kwargs..., + ) end """ @@ -187,15 +192,16 @@ Create a factorizations strategy from preconditioner and block information factorizationstrategy(p::FactorizationStrategy, ::NoBlock, sys) = p function factorizationstrategy(strat::FactorizationStrategy, ::EquationBlock, sys) - BlockPreconditioner(; - partitioning = partitioning(sys, Equationwise()), - factorization = factorizationstrategy(strat, NoBlock(), sys),) + return BlockPreconditioner(; + partitioning = partitioning(sys, Equationwise()), + factorization = factorizationstrategy(strat, NoBlock(), sys), + ) end function factorizationstrategy(::ExtendableSparse.ILUZeroPreconditioner, ::PointBlock, sys) !isdensesystem(sys) ? - error("Point block preconditioner needs dense system") : nothing - PointBlockILUZeroPreconditioner(; blocksize = num_species(sys)) + error("Point block preconditioner needs dense system") : nothing + return PointBlockILUZeroPreconditioner(; blocksize = num_species(sys)) end VoronoiFVM.SolverControl(::AbstractStrategy, sys; kwargs...) = SolverControl(; kwargs...) @@ -207,20 +213,20 @@ VoronoiFVM.SolverControl(::Nothing, sys; kwargs...) = SolverControl(; kwargs...) function (method::LinearSolve.AbstractFactorization)(A) pr = LinearProblem(A, zeros(eltype(A), size(A, 1))) - init(pr, method) + return init(pr, method) end function (method::LinearSolve.SciMLLinearSolveAlgorithm)(A) pr = LinearProblem(SparseMatrixCSC(A), zeros(eltype(A), size(A, 1))) - init(pr, method) + return init(pr, method) end function (f::ExtendableSparse.AbstractFactorization)(A) - factorize!(f, A) + return factorize!(f, A) end function LinearAlgebra.ldiv!(u, cache::LinearSolve.LinearCache, b) cache.b = b sol = solve!(cache) - copyto!(u, sol.u) + return copyto!(u, sol.u) end diff --git a/src/vfvm_physics.jl b/src/vfvm_physics.jl index c95e9d59c..3fba9e0f3 100644 --- a/src/vfvm_physics.jl +++ b/src/vfvm_physics.jl @@ -24,8 +24,9 @@ function _showstruct(io::IO, this::AbstractData) myround(b::Bool; kwargs...) = b println(typeof(this)) for name in fieldnames(typeof(this)) - println(io, "$(lpad(name,20)) = $(myround.(getfield(this,name),sigdigits=5))") + println(io, "$(lpad(name, 20)) = $(myround.(getfield(this, name), sigdigits = 5))") end + return end """ @@ -39,7 +40,7 @@ function Base.copy!(vdata::AbstractData{Tv}, udata::AbstractData{Tu}) where {Tv, for name in fieldnames(typeof(udata)) setproperty!(vdata, name, vval(getproperty(udata, name))) end - vdata + return vdata end """ @@ -63,7 +64,7 @@ function nofunc(args...) end function default_storage(f, u, node, data) - f .= u + return f .= u end @@ -77,19 +78,21 @@ Physics data record with the following fields: $(TYPEDFIELDS) """ -mutable struct Physics{Flux <: Function, - Reaction <: Function, - EdgeReaction <: Function, - Storage <: Function, - Source <: Function, - BFlux <: Function, - BReaction <: Function, - BSource <: Function, - BStorage <: Function, - BOutflow <: Function, - GenericOperator <: Function, - GenericOperatorSparsity <: Function, - Data} <: AbstractPhysics +mutable struct Physics{ + Flux <: Function, + Reaction <: Function, + EdgeReaction <: Function, + Storage <: Function, + Source <: Function, + BFlux <: Function, + BReaction <: Function, + BSource <: Function, + BStorage <: Function, + BOutflow <: Function, + GenericOperator <: Function, + GenericOperatorSparsity <: Function, + Data, + } <: AbstractPhysics """ Flux between neighboring control volumes: `flux(f,u,edge,data)` should return in `f[i]` the flux of species i along the edge joining circumcenters @@ -221,55 +224,61 @@ Physics(;num_species=0, Constructor for physics data. For the meaning of the optional keyword arguments, see [`VoronoiFVM.System(grid::ExtendableGrid; kwargs...)`](@ref). """ -function Physics(; num_species = 0, - data = nothing, - flux::Function = nofunc, - reaction::Function = nofunc, - edgereaction::Function = nofunc, - storage::Function = default_storage, - source::Function = nofunc, - bflux::Function = nofunc, - breaction::Function = nofunc, - bsource::Function = nofunc, - bstorage::Function = nofunc, - boutflow::Function = nofunc, - outflowboundaries::Vector{Int} = Int[], - generic::Function = nofunc, - generic_sparsity::Function = nofunc, - kwargs...) - return Physics(flux, - storage, - reaction, - edgereaction, - source, - bflux, - breaction, - bsource, - bstorage, - boutflow, - outflowboundaries, - generic, - generic_sparsity, - data, - Int8(num_species)) +function Physics(; + num_species = 0, + data = nothing, + flux::Function = nofunc, + reaction::Function = nofunc, + edgereaction::Function = nofunc, + storage::Function = default_storage, + source::Function = nofunc, + bflux::Function = nofunc, + breaction::Function = nofunc, + bsource::Function = nofunc, + bstorage::Function = nofunc, + boutflow::Function = nofunc, + outflowboundaries::Vector{Int} = Int[], + generic::Function = nofunc, + generic_sparsity::Function = nofunc, + kwargs... + ) + return Physics( + flux, + storage, + reaction, + edgereaction, + source, + bflux, + breaction, + bsource, + bstorage, + boutflow, + outflowboundaries, + generic, + generic_sparsity, + data, + Int8(num_species) + ) end function Physics(physics::Physics, data) - Physics(physics.flux, - physics.storage, - physics.reaction, - physics.edgereaction, - physics.source, - physics.bflux, - physics.breaction, - physics.bsource, - physics.bstorage, - physics.boutflow, - physics.outflowboundaries, - physics.generic, - physics.generic_sparsity, - data, - physics.num_species) + return Physics( + physics.flux, + physics.storage, + physics.reaction, + physics.edgereaction, + physics.source, + physics.bflux, + physics.breaction, + physics.bsource, + physics.bstorage, + physics.boutflow, + physics.outflowboundaries, + physics.generic, + physics.generic_sparsity, + data, + physics.num_species + ) end """ @@ -291,23 +300,23 @@ function Base.show(io::IO, physics::AbstractPhysics) if isdata(physics.data) str = str * "data=$(typeof(physics.data)), " end - + # function addfunc(func, name) # if func != nofunc # str = str * ", $(name)=$(nameof(func))" # end # end - + for name in fieldnames(typeof(physics)) if (name != :num_species) && (name != :data) && (name != :outflowboundaries) && getfield(physics, name) != nofunc - str = str * "$(name)=$(nameof(getfield(physics,name))), " + str = str * "$(name)=$(nameof(getfield(physics, name))), " end end - if length(physics.outflowboundaries)>0 - str=str * "outflowboundaries=$(physics.outflowboundaries)" + if length(physics.outflowboundaries) > 0 + str = str * "outflowboundaries=$(physics.outflowboundaries)" end str = str * ")" - print(io, str) + return print(io, str) end """ @@ -357,20 +366,20 @@ function ResEvaluator(physics, data, symb::Symbol, uproto::Vector{Tv}, geom, nsp fwrap = function (y) y .= 0 func(rhs(geom, y), geom, data) - nothing + return nothing end - else # Normal functions wihth u as parameter + else # Normal functions wihth u as parameter fwrap = function (y, u) y .= 0 ## for ii in .. uu[geom.speclist[ii]]=u[ii] func(rhs(geom, y), unknowns(geom, u), geom, data) ## for ii in .. y[ii]=y[geom.speclist[ii]] - nothing + return nothing end end isnontrivial = (func != nofunc) y = zeros(Tv, nspec) - ResEvaluator(fwrap, y, geom, nspec, isnontrivial) + return ResEvaluator(fwrap, y, geom, nspec, isnontrivial) end """ @@ -380,7 +389,7 @@ Call function in evaluator, store result in predefined memory. """ function evaluate!(e::ResEvaluator, u) e.isnontrivial ? e.fwrap(e.y, u) : nothing - nothing + return nothing end """ @@ -390,7 +399,7 @@ Call function in evaluator, store result in predefined memory. """ function evaluate!(e::ResEvaluator) e.isnontrivial ? e.fwrap(e.y) : nothing - nothing + return nothing end """ @@ -443,7 +452,7 @@ function ResJacEvaluator(physics, data, symb::Symbol, uproto::Vector{Tv}, geom, ## for ii in .. uu[geom.speclist[ii]]=u[ii] func(rhs(geom, y), unknowns(geom, u), geom, data) ## for ii in .. y[ii]=y[geom.speclist[ii]] - nothing + return nothing end isnontrivial = (func != nofunc) @@ -453,7 +462,7 @@ function ResJacEvaluator(physics, data, symb::Symbol, uproto::Vector{Tv}, geom, jac = zeros(Tv, nspec, length(u)) result = DiffResults.DiffResult(u, jac) config = ForwardDiff.JacobianConfig(fwrap, y, u, ForwardDiff.Chunk(u, length(u))) - ResJacEvaluator(fwrap, config, result, y, geom, nspec, isnontrivial) + return ResJacEvaluator(fwrap, config, result, y, geom, nspec, isnontrivial) end """ @@ -463,7 +472,7 @@ Call function in evaluator, store result and jacobian in predefined memory. """ function evaluate!(e::ResJacEvaluator, u) e.isnontrivial ? ForwardDiff.jacobian!(e.result, e.fwrap, e.y, u, e.config) : nothing - nothing + return nothing end """ @@ -491,7 +500,7 @@ isnontrivial(e::AbstractEvaluator) = e.isnontrivial # "Generate" a flux function function diffusion_flux(D::T) where {T} - (y, u, args...) -> y[1] = D(u[1, 1] + u[1, 2]) * (u[1, 1] - u[1, 2]) + return (y, u, args...) -> y[1] = D(u[1, 1] + u[1, 2]) * (u[1, 1] - u[1, 2]) end """ @@ -505,7 +514,7 @@ function boundary_dirichlet!(y, u, bnode::AbstractGeometryItem, ispec, ireg, val # just for call during initialization, so we can convert from dual number bnode.dirichlet_value[ispec] = value(val) end - nothing + return nothing end """ @@ -517,7 +526,7 @@ Keyword argument version: - `value`: value """ function boundary_dirichlet!(y, u, bnode::AbstractGeometryItem; species = 1, region = bnode.region, value = 0, penalty = bnode.Dirichlet) - boundary_dirichlet!(y, u, bnode, species, region, value; penalty) + return boundary_dirichlet!(y, u, bnode, species, region, value; penalty) end """ @@ -555,7 +564,7 @@ Keyword argument version: - `value`: value """ function boundary_neumann!(y, u, bnode::AbstractGeometryItem; species = 1, region = bnode.region, value = 0) - boundary_neumann!(y, u, bnode, species, region, value) + return boundary_neumann!(y, u, bnode, species, region, value) end @@ -575,5 +584,5 @@ Keyword argument version: - `value`: value """ function boundary_robin!(y, u, bnode::AbstractGeometryItem; species = 1, region = bnode.region, factor = 0, value = 0) - boundary_robin!(y, u, bnode, species, region, factor, value) + return boundary_robin!(y, u, bnode, species, region, factor, value) end diff --git a/src/vfvm_quantities.jl b/src/vfvm_quantities.jl index d5bc972b5..ac16dd7ec 100644 --- a/src/vfvm_quantities.jl +++ b/src/vfvm_quantities.jl @@ -50,7 +50,7 @@ function ContinuousQuantity(sys::AbstractSystem{Tv, Tc, Ti, Tm}, regions; ispec id = sys.num_quantities end enable_species!(sys, nspec, regions) - ContinuousQuantity{Ti}(nspec, id) + return ContinuousQuantity{Ti}(nspec, id) end ########################################################## @@ -102,7 +102,7 @@ function InterfaceQuantity(sys::AbstractSystem{Tv, Tc, Ti, Tm}, bregions::Abstra if id == 0 id = sys.num_quantities end - InterfaceQuantity{Ti}(nspec, bregions, id) + return InterfaceQuantity{Ti}(nspec, bregions, id) end ########################################################### @@ -138,18 +138,20 @@ are generated automatically. Unless specified by `id`, the quantity ID is generated automatically. """ -function DiscontinuousQuantity(sys::AbstractSystem{Tv, Tc, Ti, Tm}, regions::AbstractVector; regionspec = nothing, - id = 0) where {Tv, Tc, Ti, Tm} +function DiscontinuousQuantity( + sys::AbstractSystem{Tv, Tc, Ti, Tm}, regions::AbstractVector; regionspec = nothing, + id = 0 + ) where {Tv, Tc, Ti, Tm} rspec = zeros(Ti, num_cellregions(sys.grid)) if regionspec == nothing nspec = num_species(sys) - for ireg ∈ regions + for ireg in regions nspec = nspec + 1 enable_species!(sys, nspec, [ireg]) rspec[ireg] = nspec end else - for ireg ∈ regions + for ireg in regions enable_species!(sys, regionspec[ireg], [ireg]) rspec[ireg] = regionspec[ireg] end @@ -159,7 +161,7 @@ function DiscontinuousQuantity(sys::AbstractSystem{Tv, Tc, Ti, Tm}, regions::Abs id = sys.num_quantities end quantity = DiscontinuousQuantity{Ti}(rspec, id) - quantity + return quantity end """ @@ -178,13 +180,13 @@ region where discontinuous quantity is defined. function subgrids(quantity::DiscontinuousQuantity, sys) grid = sys.grid subgrids = Vector{typeof(sys.grid)}(undef, 0) - for ireg = 1:num_cellregions(grid) + for ireg in 1:num_cellregions(grid) ispec = quantity.regionspec[ireg] if ispec > 0 push!(subgrids, subgrid(grid, [ireg])) end end - subgrids + return subgrids end """ @@ -194,7 +196,7 @@ Return the subgrid where interface quantity is defined. """ function subgrids(quantity::InterfaceQuantity, sys) grid = sys.grid - bgrid = subgrid(grid, quantity.bregspec; boundary = true) + return bgrid = subgrid(grid, quantity.bregspec; boundary = true) end """ @@ -207,29 +209,29 @@ function views(U, quantity::DiscontinuousQuantity, subgrids, sys) grid = sys.grid projections = Vector[] j = 1 - for ireg = 1:num_cellregions(grid) + for ireg in 1:num_cellregions(grid) ispec = quantity.regionspec[ireg] if ispec > 0 push!(projections, view(U[ispec, :], subgrids[j])) j = j + 1 end end - projections + return projections end function views(U, quantity::ContinuousQuantity, subgrids, sys) grid = sys.grid projections = Vector[] j = 1 - for ireg = 1:num_cellregions(grid) + for ireg in 1:num_cellregions(grid) push!(projections, view(U[quantity.ispec, :], subgrids[j])) j = j + 1 end - projections + return projections end function views(U, quantity::InterfaceQuantity, bgrid, sys) - view(U[quantity.ispec, :], bgrid) + return view(U[quantity.ispec, :], bgrid) end # just return the first which comes into mind. @@ -239,7 +241,7 @@ function get_cellregion(sys, ibc) grid = sys.grid bfregions = grid[BFaceRegions] cregions = grid[CellRegions] - for ibface = 1:num_bfaces(sys.grid) + for ibface in 1:num_bfaces(sys.grid) if bfregions[ibface] == ibc bfcells = grid[BFaceCells] return cregions[bfcells[ibface, 1]] @@ -254,47 +256,59 @@ end Set Dirichlet boundary `value` for `quantity` at boundary `ibc`. """ function boundary_dirichlet!(sys::AbstractSystem, q::DiscontinuousQuantity, ibc, v) - boundary_dirichlet!(sys, - q.regionspec[get_cellregion(sys, ibc)], - ibc, - v) + return boundary_dirichlet!( + sys, + q.regionspec[get_cellregion(sys, ibc)], + ibc, + v + ) end function boundary_dirichlet!(sys::AbstractSystem, q::ContinuousQuantity, ibc, v) - boundary_dirichlet!(sys, - q.ispec, - ibc, - v) + return boundary_dirichlet!( + sys, + q.ispec, + ibc, + v + ) end function boundary_neumann!(sys::AbstractSystem, q::DiscontinuousQuantity, ibc, v) - boundary_neumann!(sys, - q.regionspec[get_cellregion(sys, ibc)], - ibc, - v) + return boundary_neumann!( + sys, + q.regionspec[get_cellregion(sys, ibc)], + ibc, + v + ) end function boundary_neumann!(sys::AbstractSystem, q::ContinuousQuantity, ibc, v) - boundary_neumann!(sys, - q.ispec, - ibc, - v) + return boundary_neumann!( + sys, + q.ispec, + ibc, + v + ) end function boundary_robin!(sys::AbstractSystem, q::DiscontinuousQuantity, ibc, α, v) - boundary_robin!(sys, - q.regionspec[get_cellregion(sys, ibc)], - ibc, - α, - v) + return boundary_robin!( + sys, + q.regionspec[get_cellregion(sys, ibc)], + ibc, + α, + v + ) end function boundary_robin!(sys::AbstractSystem, q::ContinuousQuantity, ibc, α, v) - boundary_robin!(sys, - q.ispec, - ibc, - α, - v) + return boundary_robin!( + sys, + q.ispec, + ibc, + α, + v + ) end """ @@ -390,5 +404,5 @@ Base.setindex!(A::AbstractArray, v, q::AbstractQuantity) = A[q.id] = v Base.getindex(I::SolutionIntegral, cspec::ContinuousQuantity, ireg) = I[cspec.id, ireg] Base.getindex(I::SolutionIntegral, dspec::DiscontinuousQuantity, ireg) = I[dspec.regionspec[ireg], ireg] function Base.getindex(I::SolutionIntegral, dspec::DiscontinuousQuantity, ::Colon) - [I[dspec.regionspec[ireg], ireg] for ireg = 1:size(I, 2)] + return [I[dspec.regionspec[ireg], ireg] for ireg in 1:size(I, 2)] end diff --git a/src/vfvm_solver.jl b/src/vfvm_solver.jl index 62035e4c0..b2ff20e60 100644 --- a/src/vfvm_solver.jl +++ b/src/vfvm_solver.jl @@ -10,14 +10,16 @@ $(SIGNATURES) Solve time step problem. This is the core routine for implicit Euler and stationary solve. """ -function solve_step!(state, - solution, # old time step solution resp. initial value - oldsol, # old time step solution resp. initial value - control, - time, - tstep, - embedparam, - params) +function solve_step!( + state, + solution, # old time step solution resp. initial value + oldsol, # old time step solution resp. initial value + control, + time, + tstep, + embedparam, + params + ) nlhistory = NewtonSolverHistory() tasm = 0.0 tlinsolve = 0.0 @@ -26,8 +28,8 @@ function solve_step!(state, residual = state.residual update = state.update _initialize!(solution, state.system; time, λ = embedparam, params) - - Tv=eltype(solution) + + Tv = eltype(solution) method_linear = state.system.matrixtype == :sparse ? control.method_linear : nothing if isnothing(method_linear) && state.system.matrixtype == :sparse if Tv != Float64 @@ -36,7 +38,7 @@ function solve_step!(state, method_linear = UMFPACKFactorization() # seems to do the best pivoting end end - + oldnorm = 1.0 converged = false damp = 1.0 @@ -47,7 +49,7 @@ function solve_step!(state, damp = control.damp_initial rnorm = control.rnorm(solution) end - + nlu_reuse = 0 nround = 0 tolx = 0.0 @@ -55,22 +57,24 @@ function solve_step!(state, nballoc = 0 neval = 0 niter = 1 - + while niter <= control.maxiters # Create Jacobi matrix and RHS for Newton iteration try - tasm += @elapsed nca, nba, nev = eval_and_assemble(state.system, - solution, - oldsol, - residual, - state.matrix, - state.dudp, - time, - tstep, - embedparam, - state.data, - params; - edge_cutoff = control.edge_cutoff,) + tasm += @elapsed nca, nba, nev = eval_and_assemble( + state.system, + solution, + oldsol, + residual, + state.matrix, + state.dudp, + time, + tstep, + embedparam, + state.data, + params; + edge_cutoff = control.edge_cutoff, + ) ncalloc += nca nballoc += nba neval += nev @@ -82,22 +86,24 @@ function solve_step!(state, rethrow(err) end end - - tlinsolve += @elapsed _solve_linear!(dofs(update), - state, - nlhistory, - control, - method_linear, - state.matrix, - dofs(residual)) + + tlinsolve += @elapsed _solve_linear!( + dofs(update), + state, + nlhistory, + control, + method_linear, + state.matrix, + dofs(residual) + ) dofs(solution) .-= damp * dofs(update) - + if state.system.is_linear converged = true break end - + damp = min(damp * control.damp_growth, 1.0) norm = control.unorm(update) if tolx == 0.0 @@ -108,13 +114,13 @@ function solve_step!(state, if rnorm > 1.0e-50 dnorm = abs((rnorm - rnorm_new) / rnorm) end - + if dnorm < control.tol_round nround = nround + 1 else nround = 0 end - + if control.log push!(nlhistory.l1normdiff, dnorm) push!(nlhistory.updatenorm, norm) @@ -126,28 +132,30 @@ function solve_step!(state, itstring = @sprintf("it=% 3d", niter) end if control.max_round > 0 - @printf("%s %.3e %.3e %.3e % 2d\n", - itstring, - norm, - norm/oldnorm, - dnorm, - nround) + @printf( + "%s %.3e %.3e %.3e % 2d\n", + itstring, + norm, + norm / oldnorm, + dnorm, + nround + ) else - @printf("%s %.3e %.3e\n", itstring, norm, norm/oldnorm) + @printf("%s %.3e %.3e\n", itstring, norm, norm / oldnorm) end end if niter > 1 && norm / oldnorm > 1.0 / control.tol_mono converged = false break end - + if norm < control.abstol || norm < tolx converged = true break end oldnorm = norm rnorm = rnorm_new - + if nround > control.max_round converged = true break @@ -155,7 +163,7 @@ function solve_step!(state, niter = niter + 1 end if !converged - throw(ConvergenceError()) + throw(ConvergenceError()) end end if control.log @@ -166,37 +174,38 @@ function solve_step!(state, if neval > 0 if ncalloc ÷ neval + nballoc ÷ neval > 0 && doprint(control, 'a') && !is_precompiling() - @warn "[a]llocations in assembly loop: cells: $(ncalloc÷neval), bfaces: $(nballoc÷neval)" + @warn "[a]llocations in assembly loop: cells: $(ncalloc ÷ neval), bfaces: $(nballoc ÷ neval)" end end if doprint(control, 'n') && !state.system.is_linear - println(" [n]ewton: $(round(t,sigdigits=3)) seconds asm: $(round(100*tasm/t,sigdigits=3))%, linsolve: $(round(100*tlinsolve/t,sigdigits=3))%") + println(" [n]ewton: $(round(t, sigdigits = 3)) seconds asm: $(round(100 * tasm / t, sigdigits = 3))%, linsolve: $(round(100 * tlinsolve / t, sigdigits = 3))%") end if doprint(control, 'l') && state.system.is_linear - println(" [l]inear($(nameof(typeof(method_linear)))): $(round(t,sigdigits=3)) seconds") + println(" [l]inear($(nameof(typeof(method_linear)))): $(round(t, sigdigits = 3)) seconds") end - solution.history=nlhistory - solution + solution.history = nlhistory + return solution end -function evaluate_residual_and_jacobian!(state,u; params=Float64[], t = 0.0, tstep = Inf, embed = 0.0) +function evaluate_residual_and_jacobian!(state, u; params = Float64[], t = 0.0, tstep = Inf, embed = 0.0) _initialize_dirichlet!(u, state.system) - eval_and_assemble(state.system, - u, - u, - state.residual, - state.matrix, - state.dudp, - t, - tstep, - embed, - state.data, - params - ) - flush!(state.matrix) + eval_and_assemble( + state.system, + u, + u, + state.residual, + state.matrix, + state.dudp, + t, + tstep, + embed, + state.data, + params + ) + return flush!(state.matrix) end @@ -210,9 +219,9 @@ containing a copy of the linearization at u. """ function evaluate_residual_and_jacobian(sys, u; kwargs...) - state=SystemState(sys) + state = SystemState(sys) eval_and_linearize!(state, u; kwargs...) - copy(state.residual), copy(state.matrix) + return copy(state.residual), copy(state.matrix) end @@ -220,14 +229,16 @@ end solve_transient(inival, system, times; kwargs...) Solve transient or embedding problem. """ -function solve_transient!(state, - inival, - lambdas; - control = SolverControl(), - transient = true, # choose between transient and stationary (embedding) case - time = 0.0, - params = zeros(0), - kwargs...,) +function solve_transient!( + state, + inival, + lambdas; + control = SolverControl(), + transient = true, # choose between transient and stationary (embedding) case + time = 0.0, + params = zeros(0), + kwargs..., + ) # rounding in output rd(x) = round(x; sigdigits = 5) @@ -266,17 +277,19 @@ function solve_transient!(state, # If not transient, solve for first embedding lambdas[1] _initialize_dirichlet!(solution, state.system; time, λ = Float64(lambdas[1]), params) control.pre(solution, Float64(lambdas[1])) - t0 = @elapsed solution = solve_step!(state, - solution, - oldsolution, - control, - time, - Inf, - Float64(lambdas[1]), - params) - + t0 = @elapsed solution = solve_step!( + state, + solution, + oldsolution, + control, + time, + Inf, + Float64(lambdas[1]), + params + ) + control.post(solution, oldsolution, lambdas[1], 0) - + if control.log push!(allhistory, solution.history) push!(allhistory.times, lambdas[1]) @@ -297,7 +310,7 @@ function solve_transient!(state, istep = 0 solved = false # Outer loop over embedding params/ time values - t1 = @elapsed for i = 1:(length(lambdas) - 1) + t1 = @elapsed for i in 1:(length(lambdas) - 1) Δλ = max(Δλ, Δλ_min) λstart = lambdas[i] λend = lambdas[i + 1] @@ -327,16 +340,18 @@ function solve_transient!(state, _tstep = Inf _embedparam = λ end - solution = solve_step!(state, - solution, - oldsolution, - control, - _time, - _tstep, - _embedparam, - params) + solution = solve_step!( + state, + solution, + oldsolution, + control, + _time, + _tstep, + _embedparam, + params + ) catch err - err = "Problem at $(λstr)=$(λ|>rd), Δ$(λstr)=$(Δλ|>rd):\n$(err)" + err = "Problem at $(λstr)=$(λ |> rd), Δ$(λstr)=$(Δλ |> rd):\n$(err)" if (control.handle_exceptions) _print_error(err, stacktrace(catch_backtrace())) else @@ -355,9 +370,9 @@ function solve_transient!(state, if Δλ ≈ Δλ_min if !(control.force_first_step && istep == 0) err = """ - At $(λstr)=$(λ|>rd): Δ$(λstr)_min=$(Δλ_min|>rd) reached while Δu/Δu_opt=$(Δu/Δu_opt|>rd). - Returning prematurely before $(λstr)[end]=$(lambdas[end]|>rd) - """ + At $(λstr)=$(λ |> rd): Δ$(λstr)_min=$(Δλ_min |> rd) reached while Δu/Δu_opt=$(Δu / Δu_opt |> rd). + Returning prematurely before $(λstr)[end]=$(lambdas[end] |> rd) + """ if control.handle_exceptions @warn err else @@ -366,7 +381,7 @@ function solve_transient!(state, break # give up lowering stepsize, break out if "while !solved" loop elseif !errored if doprint(control, 'e') - println("[e]volution: forced first timestep: Δu/Δu_opt=$(Δu/Δu_opt|>rd)") + println("[e]volution: forced first timestep: Δu/Δu_opt=$(Δu / Δu_opt |> rd)") end forced = true solved = true @@ -381,10 +396,10 @@ function solve_transient!(state, break end else - # reduce time step + # reduce time step Δλ = max(Δλ_min, Δλ * Δλ_decrease) if doprint(control, 'e') - @printf("[e]volution: Δu/Δu_opt=%.3e => retry: Δ%s=%.3e\n", Δu/Δu_opt, λstr, Δλ) + @printf("[e]volution: Δu/Δu_opt=%.3e => retry: Δ%s=%.3e\n", Δu / Δu_opt, λstr, Δλ) end end end @@ -394,13 +409,15 @@ function solve_transient!(state, if solved istep = istep + 1 if doprint(control, 'e') - @printf("[e]volution: step=%d %s=%.3e Δ%s=%.3e Δu=%.3e\n", - istep, - λstr, - λ, - λstr, - Δλ, - Δu) + @printf( + "[e]volution: step=%d %s=%.3e Δ%s=%.3e Δu=%.3e\n", + istep, + λstr, + λ, + λstr, + Δλ, + Δu + ) end if control.log push!(allhistory, solution.history) @@ -428,21 +445,23 @@ function solve_transient!(state, if λ < λend # ### account for close last timestep - Δλ = min(Δλ_max, - Δλ * Δλ_grow, - Δλ * Δu_opt / (Δu + 1.0e-14), - λ_predict, - λend - λ) + Δλ = min( + Δλ_max, + Δλ * Δλ_grow, + Δλ * Δu_opt / (Δu + 1.0e-14), + λ_predict, + λend - λ + ) # adjust for roundoff error, so there will be no accidental # very tiny timestep - if isapprox(λ+Δλ, λend; atol=1.0e-15, rtol=1.0e-15) - Δλ=λend-λ + if isapprox(λ + Δλ, λend; atol = 1.0e-15, rtol = 1.0e-15) + Δλ = λend - λ end end else break # break out of inner loop over timestep - end # if solved + end # if solved end # while λ<λ_end if !control.store_all # store last solution obtained @@ -453,7 +472,7 @@ function solve_transient!(state, if solved if !(λ ≈ lambdas[i + 1]) # check end of interval has been reached in inner loop - @warn "λ=$(λ), lambdas[i+1]=$(lambdas[i+1])" + @warn "λ=$(λ), lambdas[i+1]=$(lambdas[i + 1])" end else break # emergency exit @@ -461,7 +480,7 @@ function solve_transient!(state, end # for i = 1:(length(lambdas)-1), end outer loop if doprint(control, 'e') - println("[e]volution: $(round(t0+t1,sigdigits=3)) seconds") + println("[e]volution: $(round(t0 + t1, sigdigits = 3)) seconds") end tsol.history = allhistory @@ -469,7 +488,6 @@ function solve_transient!(state, end - ##################################################################### """ solve!(state; kwargs...) @@ -481,62 +499,70 @@ Mutates the state and returns the solution. For the keyword argumentsm see [`VoronoiFVM.solve`](@ref). """ -function CommonSolve.solve!(state::VoronoiFVM.SystemState; - inival = 0, - data = nothing, - params = zeros(0), - control = VoronoiFVM.SolverControl(), - time = 0.0, - tstep = Inf, - kwargs...,) +function CommonSolve.solve!( + state::VoronoiFVM.SystemState; + inival = 0, + data = nothing, + params = zeros(0), + control = VoronoiFVM.SolverControl(), + time = 0.0, + tstep = Inf, + kwargs..., + ) fix_deprecations!(control) - if isa(inival, Number) || isa(inival, Matrix) + if isa(inival, Number) || isa(inival, Matrix) inival = unknowns(state.system; inival = inival) elseif !isdensesystem(state.system) && isa(inival, SparseMatrixCSC) inival = SparseSolutionArray(inival) elseif !VoronoiFVM.isunknownsof(inival, state.system) @error "wrong type of inival: $(typeof(inival))" end - + for pair in kwargs if first(pair) != :times && - first(pair) != :embed && - hasfield(SolverControl, first(pair)) + first(pair) != :embed && + hasfield(SolverControl, first(pair)) setproperty!(control, first(pair), last(pair)) end end if !isnothing(data) - state.data=data + state.data = data end - state.params.=params - - - if haskey(kwargs, :times) && !isnothing(kwargs[:times]) - solve_transient!(state, - inival, - kwargs[:times]; - control, - transient = true, - params, - time = kwargs[:times][1]) + state.params .= params + + + return if haskey(kwargs, :times) && !isnothing(kwargs[:times]) + solve_transient!( + state, + inival, + kwargs[:times]; + control, + transient = true, + params, + time = kwargs[:times][1] + ) elseif haskey(kwargs, :embed) && !isnothing(kwargs[:embed]) - solve_transient!(state, - inival, - kwargs[:embed]; - transient = false, - control, - params, - time,) + solve_transient!( + state, + inival, + kwargs[:embed]; + transient = false, + control, + params, + time, + ) else - solve_step!(state, - unknowns(state.system), - inival, - control, - time, - tstep, - 0.0, - params) + solve_step!( + state, + unknowns(state.system), + inival, + control, + time, + tstep, + 0.0, + params + ) end end @@ -584,7 +610,7 @@ Keyword arguments: - `tstep`: time step Returns a [`DenseSolutionArray`](@ref) or [`SparseSolutionArray`](@ref) """ -function CommonSolve.solve(sys::VoronoiFVM.AbstractSystem; data=sys.physics.data, kwargs...) - state=SystemState(sys;data) - solve!(state; kwargs...) +function CommonSolve.solve(sys::VoronoiFVM.AbstractSystem; data = sys.physics.data, kwargs...) + state = SystemState(sys; data) + return solve!(state; kwargs...) end diff --git a/src/vfvm_solvercontrol.jl b/src/vfvm_solvercontrol.jl index ba8ebb72c..2e51e5b80 100644 --- a/src/vfvm_solvercontrol.jl +++ b/src/vfvm_solvercontrol.jl @@ -1,7 +1,8 @@ - # Deprecated. TODO: remove with v3.0 -const FactorizationStrategy = Union{Nothing, Function, Type, ExtendableSparse.AbstractFactorization, - LinearSolve.AbstractFactorization, LinearSolve.SciMLLinearSolveAlgorithm} +const FactorizationStrategy = Union{ + Nothing, Function, Type, ExtendableSparse.AbstractFactorization, + LinearSolve.AbstractFactorization, LinearSolve.SciMLLinearSolveAlgorithm, +} ## Deprecated. TODO: remove with v3.0 struct Identity end @@ -286,19 +287,21 @@ const false_verbosity = "da" doprint(b::Bool, a::Char) = b ? doprint(true_verbosity, a) : doprint(false_verbosity, a) doprint(c::SolverControl, a::Char) = doprint(c.verbose, a) -const key_replacements = Dict(:tol_absolute => :abstol, - :tol_relative => :reltol, - :damp => :damp_initial, - :damp_grow => :damp_growth, - :max_iterations => :maxiters, - :tol_linear => :reltol_linear, - :mynorm => :unorm, - :myrnorm => :rnorm, - :max_lureuse => nothing) +const key_replacements = Dict( + :tol_absolute => :abstol, + :tol_relative => :reltol, + :damp => :damp_initial, + :damp_grow => :damp_growth, + :max_iterations => :maxiters, + :tol_linear => :reltol_linear, + :mynorm => :unorm, + :myrnorm => :rnorm, + :max_lureuse => nothing +) function fix_deprecations!(control) # compatibility to names in SolverControl which cannot be deprecated. - for key ∈ keys(key_replacements) + for key in keys(key_replacements) value = getproperty(control, key) if !isnothing(value) if !isnothing(key_replacements[key]) @@ -314,6 +317,7 @@ function fix_deprecations!(control) setproperty!(control, key, nothing) end end + return end """ @@ -330,7 +334,7 @@ function fixed_timesteps!(control, Δt; grow = 1.0) control.Δt_min = Δt control.Δt_grow = grow control.Δu_opt = floatmax() - control + return control end # function Base.show(io::IO, this::SolverControl) diff --git a/src/vfvm_sparsesolution.jl b/src/vfvm_sparsesolution.jl index df8df6136..d500f294c 100644 --- a/src/vfvm_sparsesolution.jl +++ b/src/vfvm_sparsesolution.jl @@ -1,4 +1,3 @@ - ################################################################# """ $(TYPEDEF) @@ -12,13 +11,13 @@ Fields: $(TYPEDFIELDS) """ -mutable struct SparseSolutionArray{T, N, Ti} <: AbstractSolutionArray{T,N} +mutable struct SparseSolutionArray{T, N, Ti} <: AbstractSolutionArray{T, N} """ Sparse matrix holding actual data. """ u::SparseMatrixCSC{T, Ti} - history::Union{NewtonSolverHistory,Nothing} + history::Union{NewtonSolverHistory, Nothing} end """ @@ -26,12 +25,12 @@ end `SparseSolutionArray` constructor """ -SparseSolutionArray(a::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti}=SparseSolutionArray{Tv,2,Ti}(a,nothing) +SparseSolutionArray(a::SparseMatrixCSC{Tv, Ti}) where {Tv, Ti} = SparseSolutionArray{Tv, 2, Ti}(a, nothing) """ solutionarray(a::SparseMatrixCSC) """ -solutionarray(a::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti}=SparseSolutionArray{Tv,2,Ti}(a,nothing) +solutionarray(a::SparseMatrixCSC{Tv, Ti}) where {Tv, Ti} = SparseSolutionArray{Tv, 2, Ti}(a, nothing) """ $(TYPEDEF) @@ -60,19 +59,23 @@ Vector of degrees of freedom in sparse solution array. dofs(a::SparseSolutionArray) = a.u.nzval dofs(a::SparseMatrixCSC) = a.nzval -Base.size(a::SparseSolutionArray)=size(a.u) +Base.size(a::SparseSolutionArray) = size(a.u) ################################################################## """ $(SIGNATURES) Create a copy of sparse solution array """ -function Base.copy(this::SparseSolutionArray{T,N, Ti}) where {T,N, Ti} - SparseSolutionArray{T,N,Ti}(SparseMatrixCSC(this.u.m, - this.u.n, - this.u.colptr, - this.u.rowval, - Base.copy(this.u.nzval)),this.history) +function Base.copy(this::SparseSolutionArray{T, N, Ti}) where {T, N, Ti} + return SparseSolutionArray{T, N, Ti}( + SparseMatrixCSC( + this.u.m, + this.u.n, + this.u.colptr, + this.u.rowval, + Base.copy(this.u.nzval) + ), this.history + ) end @@ -81,12 +84,16 @@ $(SIGNATURES) Create a similar uninitialized sparse solution array """ -function Base.similar(this::SparseSolutionArray{T,N, Ti}) where {T,N, Ti} - SparseSolutionArray{T,N, Ti}(SparseMatrixCSC(this.u.m, - this.u.n, - this.u.colptr, - this.u.rowval, - Base.similar(this.u.nzval)),nothing) +function Base.similar(this::SparseSolutionArray{T, N, Ti}) where {T, N, Ti} + return SparseSolutionArray{T, N, Ti}( + SparseMatrixCSC( + this.u.m, + this.u.n, + this.u.colptr, + this.u.rowval, + Base.similar(this.u.nzval) + ), nothing + ) end ################################################################## """ @@ -94,7 +101,7 @@ $(SIGNATURES) Get number of degree of freedom. Return 0 if species is not defined in node. """ -function dof(a::SparseSolutionArray, i,j) +function dof(a::SparseSolutionArray, i, j) A = a.u coljfirstk = Int(A.colptr[j]) coljlastk = Int(A.colptr[j + 1] - 1) @@ -112,7 +119,7 @@ $(SIGNATURES) Set value for degree of freedom. """ function setdof!(a::SparseSolutionArray, v, i::Integer) - a.u.nzval[i] = v + return a.u.nzval[i] = v end ################################################################## diff --git a/src/vfvm_state.jl b/src/vfvm_state.jl index 08285194d..df8ab98ef 100644 --- a/src/vfvm_state.jl +++ b/src/vfvm_state.jl @@ -13,7 +13,7 @@ Type parameters: Type fields: $(TYPEDFIELDS) """ -mutable struct SystemState{Tv, Tp, TMatrix<:AbstractMatrix{Tv}, TSolArray<:AbstractMatrix{Tv}, TData} +mutable struct SystemState{Tv, Tp, TMatrix <: AbstractMatrix{Tv}, TSolArray <: AbstractMatrix{Tv}, TData} """ Related finite volume system @@ -39,7 +39,7 @@ mutable struct SystemState{Tv, Tp, TMatrix<:AbstractMatrix{Tv}, TSolArray<:Abstr Parameter derivative (vector of solution arrays) """ dudp::Vector{TSolArray} - + """ Vector holding Newton update """ @@ -59,7 +59,7 @@ mutable struct SystemState{Tv, Tp, TMatrix<:AbstractMatrix{Tv}, TSolArray<:Abstr Parameter vector """ params::Vector{Tp} - + """ Hash value of latest unknowns vector the assembly was called with (used by differential equation interface) @@ -88,23 +88,25 @@ Keyword arguments: - `data`: User data. Default: `data(system)` - `matrixtype`. Default: `system.matrixtype` """ -function SystemState(::Type{Tu}, system::AbstractSystem{Tv, Tc, Ti, Tm}; - data=system.physics.data, - params=zeros(system.num_parameters), - matrixtype=system.matrixtype) where {Tu,Tv,Tc, Ti, Tm} +function SystemState( + ::Type{Tu}, system::AbstractSystem{Tv, Tc, Ti, Tm}; + data = system.physics.data, + params = zeros(system.num_parameters), + matrixtype = system.matrixtype + ) where {Tu, Tv, Tc, Ti, Tm} _complete!(system) - - if (length(params)!=system.num_parameters) + + if (length(params) != system.num_parameters) error("length(params)!=system.num_parameters") end - + nspec = size(system.node_dof, 1) n = num_dof(system) matrixtype = system.matrixtype if matrixtype == :auto - if !isdensesystem(system) || dim_grid(system.grid)>1 + if !isdensesystem(system) || dim_grid(system.grid) > 1 matrixtype = :sparse else if nspec == 1 @@ -132,8 +134,8 @@ function SystemState(::Type{Tu}, system::AbstractSystem{Tv, Tc, Ti, Tm}; solution = unknowns(Tu, system) residual = unknowns(Tu, system) update = unknowns(Tu, system) - dudp = [unknowns(Tu, system) for i = 1:(system.num_parameters)] - SystemState(system, data, solution, matrix, dudp, residual, update, nothing, params, zero(UInt64), nothing) + dudp = [unknowns(Tu, system) for i in 1:(system.num_parameters)] + return SystemState(system, data, solution, matrix, dudp, residual, update, nothing, params, zero(UInt64), nothing) end @@ -142,7 +144,7 @@ end Shortcut for creating state with value type defined by `Tv` type parameter of system """ -SystemState(system::AbstractSystem{Tv,Tc,Ti,Tm}; kwargs...) where {Tv,Tc,Ti,Tm} =SystemState(Tv, system; kwargs...) +SystemState(system::AbstractSystem{Tv, Tc, Ti, Tm}; kwargs...) where {Tv, Tc, Ti, Tm} = SystemState(Tv, system; kwargs...) """ similar(state; data=state.data) @@ -150,22 +152,22 @@ SystemState(system::AbstractSystem{Tv,Tc,Ti,Tm}; kwargs...) where {Tv,Tc,Ti,Tm} Create a new state of with the same system, different work arrays, and possibly different data. The matrix of the new state initially shares the sparsity structure with `state`. """ -function Base.similar(state::SystemState; data=state.data) - system=state.system - solution=similar(state.solution) +function Base.similar(state::SystemState; data = state.data) + system = state.system + solution = similar(state.solution) if issparse(state.matrix) - csc=SparseMatrixCSC(state.matrix) - cscnew=SparseMatrixCSC(csc.m, csc.n, csc.colptr, csc.rowval, similar(csc.nzval)) - matrix=ExtendableSparseMatrix(cscnew) + csc = SparseMatrixCSC(state.matrix) + cscnew = SparseMatrixCSC(csc.m, csc.n, csc.colptr, csc.rowval, similar(csc.nzval)) + matrix = ExtendableSparseMatrix(cscnew) else - matrix=similar(state.matrix) + matrix = similar(state.matrix) end - dudp=similar(state.dudp) - residual=similar(state.residual) - update=similar(state.update) - linear_cache=nothing - params=similar(state.params) - uhash=zero(UInt64) - history=nothing - SystemState(system, data, solution, matrix, dudp, residual, update, linear_cache, params, uhash, history) + dudp = similar(state.dudp) + residual = similar(state.residual) + update = similar(state.update) + linear_cache = nothing + params = similar(state.params) + uhash = zero(UInt64) + history = nothing + return SystemState(system, data, solution, matrix, dudp, residual, update, linear_cache, params, uhash, history) end diff --git a/src/vfvm_system.jl b/src/vfvm_system.jl index 9668650b7..27821e85b 100644 --- a/src/vfvm_system.jl +++ b/src/vfvm_system.jl @@ -91,7 +91,7 @@ mutable struct System{Tv, Tc, Ti, Tm, TSpecMat <: AbstractMatrix} <: AbstractSys Is the system linear ? """ is_linear::Bool - + """ Outflow nodes with their region numbers. """ @@ -208,17 +208,19 @@ Physics keyword arguments: solution storage depending on space dimension and number of species. """ -function System(grid::ExtendableGrid; - valuetype = coord_type(grid), - indextype = index_type(grid), - species = Int[], - assembly = :cellwise, - unknown_storage = :dense, - matrixindextype = Int64, - matrixtype = :sparse, - is_linear = false, - nparams = 0, - kwargs...) +function System( + grid::ExtendableGrid; + valuetype = coord_type(grid), + indextype = index_type(grid), + species = Int[], + assembly = :cellwise, + unknown_storage = :dense, + matrixindextype = Int64, + matrixtype = :sparse, + is_linear = false, + nparams = 0, + kwargs... + ) Tv = valuetype Tc = coord_type(grid) Ti = indextype @@ -284,7 +286,7 @@ Replace System's physics data """ function physics!(system, physics) system.physics = physics - system + return system end """ @@ -312,18 +314,18 @@ function physics!(system; kwargs...) end end - physics!(system, Physics(; kwdict...)) + return physics!(system, Physics(; kwdict...)) end ################################################################## -# Constant to be used as boundary condition factor -# to mark Dirichlet boundary conditions. -Dirichlet(::Type{Tv}) where {Tv} = 1.0e30 +# Constant to be used as boundary condition factor +# to mark Dirichlet boundary conditions. +Dirichlet(::Type{Tv}) where {Tv} = 1.0e30 -Dirichlet(::Type{Rational{Ti}}) where Ti = 1//10000 +Dirichlet(::Type{Rational{Ti}}) where {Ti} = 1 // 10000 -Dirichlet(::Type{Rational{BigInt}}) = 1//10000000000 +Dirichlet(::Type{Rational{BigInt}}) = 1 // 10000000000 ################################################################# @@ -339,12 +341,12 @@ function addzrows(matrix::Matrix, maxrow) return matrix end newmatrix = zeros(eltype(matrix), maxrow, ncol) - for icol = 1:ncol - for irow = 1:nrow + for icol in 1:ncol + for irow in 1:nrow newmatrix[irow, icol] = matrix[irow, icol] end end - newmatrix + return newmatrix end function addzrows(matrix::SparseMatrixCSC, maxrow) @@ -352,7 +354,7 @@ function addzrows(matrix::SparseMatrixCSC, maxrow) if maxrow <= nrow return matrix end - SparseMatrixCSC(maxrow, matrix.n, matrix.colptr, matrix.rowval, matrix.nzval) + return SparseMatrixCSC(maxrow, matrix.n, matrix.colptr, matrix.rowval, matrix.nzval) end """ @@ -374,7 +376,7 @@ function increase_num_species!(system, maxspec) system.bregion_species = addzrows(system.bregion_species, maxspec) system.node_dof = addzrows(system.node_dof, maxspec) system.boundary_values = addzrows(system.boundary_values, maxspec) - system.boundary_factors = addzrows(system.boundary_factors, maxspec) + return system.boundary_factors = addzrows(system.boundary_factors, maxspec) end ################################################################## @@ -387,7 +389,7 @@ Check if species number corresponds to a boundary species. """ function is_boundary_species(system::AbstractSystem, ispec) isbspec = false - for ibreg = 1:num_bfaceregions(system.grid) + for ibreg in 1:num_bfaceregions(system.grid) if system.bregion_species[ispec, ibreg] > 0 isbspec = true end @@ -405,7 +407,7 @@ Check if species number corresponds to a bulk species. """ function is_bulk_species(system::AbstractSystem, ispec) isrspec = false - for ixreg = 1:num_cellregions(system.grid) + for ixreg in 1:num_cellregions(system.grid) if system.region_species[ispec, ixreg] > 0 isrspec = true end @@ -434,15 +436,16 @@ function enable_species!(system::AbstractSystem, ispec::Integer, regions::Abstra for i in eachindex(regions) ireg = regions[i] system.region_species[ispec, ireg] = ispec - for icell = 1:num_cells(system.grid) + for icell in 1:num_cells(system.grid) if _cellregions[icell] == ireg - for iloc = 1:num_targets(_cellnodes, icell) + for iloc in 1:num_targets(_cellnodes, icell) iglob = _cellnodes[iloc, icell] system.node_dof[ispec, iglob] = ispec end end end end + return end """ @@ -464,10 +467,10 @@ function enable_species!(sys::AbstractSystem; species = nothing, regions = nothi species = [species] end - for ispec ∈ species + for ispec in species enable_species!(sys, ispec, regions) end - sys + return sys end ################################################################## @@ -492,15 +495,16 @@ function enable_boundary_species!(system::AbstractSystem, ispec::Integer, bregio for i in eachindex(bregions) ireg = bregions[i] system.bregion_species[ispec, ireg] = ispec - for ibface = 1:num_bfaces(system.grid) + for ibface in 1:num_bfaces(system.grid) if _bfaceregions[ibface] == ireg - for iloc = 1:size(_bfacenodes, 1) + for iloc in 1:size(_bfacenodes, 1) iglob = _bfacenodes[iloc, ibface] system.node_dof[ispec, iglob] = ispec end end end end + return end """ @@ -508,7 +512,7 @@ end Reentrant lock to safeguard mutating methods [`_complete!`](@ref) and [`update_grid!`](@ref). """ -const sysmutatelock=ReentrantLock() +const sysmutatelock = ReentrantLock() """ _complete!(system) @@ -527,8 +531,8 @@ function _complete!(system::AbstractSystem{Tv, Tc, Ti, Tm}) where {Tv, Tc, Ti, T try system.species_homogeneous = true species_added = false - for inode = 1:size(system.node_dof, 2) - for ispec = 1:size(system.node_dof, 1) + for inode in 1:size(system.node_dof, 2) + for ispec in 1:size(system.node_dof, 1) if system.node_dof[ispec, inode] == ispec species_added = true else @@ -536,14 +540,14 @@ function _complete!(system::AbstractSystem{Tv, Tc, Ti, Tm}) where {Tv, Tc, Ti, T end end end - + if (!species_added) error("No species enabled.\n Call enable_species(system,species_number, list_of_regions) at least once.") end - + nspec = size(system.node_dof, 1) n = num_dof(system) - + if has_generic_operator(system) if has_generic_operator_sparsity(system) system.generic_matrix = system.physics.generic_operator_sparsity(system) @@ -568,7 +572,7 @@ function _complete!(system::AbstractSystem{Tv, Tc, Ti, Tm}) where {Tv, Tc, Ti, T finally unlock(sysmutatelock) end - system.is_complete=true + return system.is_complete = true end """ @@ -577,7 +581,7 @@ Set generic operator sparsity, in the case where a generic operator has been defined in physics. """ function generic_operator_sparsity!(system::AbstractSystem, sparsematrix::SparseMatrixCSC) - system.generic_matrix = sparsematrix + return system.generic_matrix = sparsematrix end """ @@ -590,16 +594,18 @@ Uses a lock to ensure parallel access. """ function update_grid!(system::AbstractSystem; grid = system.grid) lock(sysmutatelock) - try + return try system.assembly_type == :cellwise ? update_grid_cellwise!(system, grid) : update_grid_edgewise!(system, grid) - + if length(system.physics.outflowboundaries) > 0 bfacenodes = system.grid[BFaceNodes] bfaceregions = system.grid[BFaceRegions] - outflownoderegions = ExtendableSparseMatrix{Bool, Int}(num_bfaceregions(system.grid), - num_nodes(system.grid)) - for ibface = 1:num_bfaces(system.grid) - for ibn = 1:dim_space(system.grid) + outflownoderegions = ExtendableSparseMatrix{Bool, Int}( + num_bfaceregions(system.grid), + num_nodes(system.grid) + ) + for ibface in 1:num_bfaces(system.grid) + for ibn in 1:dim_space(system.grid) if bfaceregions[ibface] ∈ system.physics.outflowboundaries outflownoderegions[bfaceregions[ibface], bfacenodes[ibn, ibface]] = true end @@ -634,27 +640,35 @@ function update_grid_cellwise!(system::AbstractSystem{Tv, Tc, Ti, Tm}, grid) whe bfaceedgefactors = zeros(Tv, num_edges(bgeom), nbfaces) function cellwise_factors!(csys::Type{T}) where {T} - nalloc = @allocations for icell = 1:ncells - @views cellfactors!(geom, csys, coord, cellnodes, icell, - cellnodefactors[:, icell], celledgefactors[:, icell]) + nalloc = @allocations for icell in 1:ncells + @views cellfactors!( + geom, csys, coord, cellnodes, icell, + cellnodefactors[:, icell], celledgefactors[:, icell] + ) end nalloc > 0 && @warn "$nalloc allocations in cell factor calculation" - nalloc = @allocations for ibface = 1:nbfaces - @views bfacefactors!(bgeom, csys, coord, bfacenodes, ibface, - bfacenodefactors[:, ibface], bfaceedgefactors[:, ibface]) + nalloc = @allocations for ibface in 1:nbfaces + @views bfacefactors!( + bgeom, csys, coord, bfacenodes, ibface, + bfacenodefactors[:, ibface], bfaceedgefactors[:, ibface] + ) end - nalloc > 0 && @warn "$nalloc allocations in bface factor calculation" + return nalloc > 0 && @warn "$nalloc allocations in bface factor calculation" end cellwise_factors!(csys) - system.assembly_data = CellwiseAssemblyData{Tc, Ti}(cellnodefactors, - celledgefactors, - grid[PColorPartitions], - grid[PartitionCells]) - system.boundary_assembly_data = CellwiseAssemblyData{Tc, Ti}(bfacenodefactors, bfaceedgefactors, grid[PColorPartitions], - grid[PartitionBFaces]) + system.assembly_data = CellwiseAssemblyData{Tc, Ti}( + cellnodefactors, + celledgefactors, + grid[PColorPartitions], + grid[PartitionCells] + ) + return system.boundary_assembly_data = CellwiseAssemblyData{Tc, Ti}( + bfacenodefactors, bfaceedgefactors, grid[PColorPartitions], + grid[PartitionBFaces] + ) end """ @@ -688,39 +702,45 @@ function update_grid_edgewise!(system::AbstractSystem{Tv, Tc, Ti, Tm}, grid) whe cellnodefactors = zeros(Tv, nn) celledgefactors = zeros(Tv, ne) - for icell = 1:ncells + for icell in 1:ncells @views cellfactors!(geom, csys, coord, cellnodes, icell, cellnodefactors, celledgefactors) ireg = cellregions[icell] - for inode = 1:nn + for inode in 1:nn cnf[ireg, cellnodes[inode, icell]] += cellnodefactors[inode] end - for iedge = 1:ne + for iedge in 1:ne cef[ireg, celledges[iedge, icell]] += celledgefactors[iedge] end end # nalloc > 0 && @warn "$nalloc allocations in cell factor calculation" - nalloc = @allocations for ibface = 1:nbfaces - @views bfacefactors!(bgeom, csys, coord, bfacenodes, ibface, - bfacenodefactors[:, ibface], bfaceedgefactors[:, ibface]) + nalloc = @allocations for ibface in 1:nbfaces + @views bfacefactors!( + bgeom, csys, coord, bfacenodes, ibface, + bfacenodefactors[:, ibface], bfaceedgefactors[:, ibface] + ) end - nalloc > 0 && @warn "$nalloc allocations in bface factor calculation" + return nalloc > 0 && @warn "$nalloc allocations in bface factor calculation" end edgewise_factors!(csys) partition_nodes = grid[PartitionNodes] partition_edges = grid[PartitionEdges] - system.assembly_data = EdgewiseAssemblyData{Tc, Ti}(SparseMatrixCSC(cnf), - SparseMatrixCSC(cef), - grid[PColorPartitions], - partition_nodes, - partition_edges) - - system.boundary_assembly_data = CellwiseAssemblyData{Tc, Ti}(bfacenodefactors, bfaceedgefactors, [1, 2], - [1, num_bfaces(grid) + 1]) + system.assembly_data = EdgewiseAssemblyData{Tc, Ti}( + SparseMatrixCSC(cnf), + SparseMatrixCSC(cef), + grid[PColorPartitions], + partition_nodes, + partition_edges + ) + + return system.boundary_assembly_data = CellwiseAssemblyData{Tc, Ti}( + bfacenodefactors, bfaceedgefactors, [1, 2], + [1, num_bfaces(grid) + 1] + ) end ################################################################################################ @@ -823,7 +843,7 @@ Set Dirichlet boundary condition for species ispec at boundary ibc: function boundary_dirichlet!(system::AbstractSystem{Tv}, ispec, ibc, v) where {Tv} increase_num_species!(system, ispec) system.boundary_factors[ispec, ibc] = Dirichlet(Tv) - system.boundary_values[ispec, ibc] = v + return system.boundary_values[ispec, ibc] = v end """ @@ -838,7 +858,7 @@ Keyword argument version: Starting with version 0.14, it is preferable to define boundary conditions within the `bcondition` physics callback """ function boundary_dirichlet!(system::AbstractSystem; species = 1, region = 1, value = 0) - boundary_dirichlet!(system, species, region, value) + return boundary_dirichlet!(system, species, region, value) end @@ -855,7 +875,7 @@ Set Neumann boundary condition for species ispec at boundary ibc: function boundary_neumann!(system::AbstractSystem, ispec, ibc, v) increase_num_species!(system, ispec) system.boundary_factors[ispec, ibc] = 0.0 - system.boundary_values[ispec, ibc] = v + return system.boundary_values[ispec, ibc] = v end """ @@ -884,7 +904,7 @@ Set Robin boundary condition for species ispec at boundary ibc: function boundary_robin!(system::AbstractSystem, ispec, ibc, α, v) increase_num_species!(system, ispec) system.boundary_factors[ispec, ibc] = α - system.boundary_values[ispec, ibc] = v + return system.boundary_values[ispec, ibc] = v end """ @@ -898,7 +918,7 @@ Keyword argument version: Starting with version 0.14, it is preferable to define boundary conditions within the `bcondition` physics callback """ function boundary_robin!(system::AbstractSystem; species = 0, region = 0, factor = 0, value = 0) - boundary_robin!(system, species, region, factor, value) + return boundary_robin!(system, species, region, factor, value) end @@ -913,8 +933,10 @@ num_species(a::AbstractArray) = size(a, 1) # # Initialize Dirichlet BC # -function _initialize_dirichlet!(U::AbstractMatrix, system::AbstractSystem{Tv, Tc, Ti, Tm}; time = 0.0, λ = 0.0, - params::Vector{Tp} = Float64[]) where {Tv, Tp, Tc, Ti, Tm} +function _initialize_dirichlet!( + U::AbstractMatrix, system::AbstractSystem{Tv, Tc, Ti, Tm}; time = 0.0, λ = 0.0, + params::Vector{Tp} = Float64[] + ) where {Tv, Tp, Tc, Ti, Tm} _complete!(system) nspecies = num_species(system) @@ -924,7 +946,7 @@ function _initialize_dirichlet!(U::AbstractMatrix, system::AbstractSystem{Tv, Tc # setup unknowns to be passed UK = zeros(Tv, num_species(system) + length(params)) - for iparm = 1:length(params) + for iparm in 1:length(params) UK[nspecies + iparm] = params[iparm] end u = unknowns(bnode, UK) @@ -943,7 +965,7 @@ function _initialize_dirichlet!(U::AbstractMatrix, system::AbstractSystem{Tv, Tc system.physics.breaction(y, u, bnode, data) # Check for Dirichlet bc - for ispec = 1:nspecies + for ispec in 1:nspecies # Dirichlet bc given in breaction if !isinf(bnode.dirichlet_value[ispec]) U[ispec, bnode.index] = bnode.dirichlet_value[ispec] @@ -956,11 +978,12 @@ function _initialize_dirichlet!(U::AbstractMatrix, system::AbstractSystem{Tv, Tc end end end + return end function _initialize!(U::AbstractMatrix, system::AbstractSystem; time = 0.0, λ = 0.0, params = Number[]) _initialize_dirichlet!(U, system; time, λ, params) - _initialize_inactive_dof!(U, system) + return _initialize_inactive_dof!(U, system) end function _eval_and_assemble_inactive_species(system::AbstractSystem, matrix, U, Uold, F) end @@ -969,8 +992,8 @@ function _eval_and_assemble_inactive_species(system::DenseSystem, matrix, U, Uol if system.species_homogeneous return end - for inode = 1:size(system.node_dof, 2) - for ispec = 1:size(system.node_dof, 1) + for inode in 1:size(system.node_dof, 2) + for ispec in 1:size(system.node_dof, 1) if !isnodespecies(system, ispec, inode) F[ispec, inode] += U[ispec, inode] - Uold[ispec, inode] idof = dof(F, ispec, inode) @@ -978,6 +1001,7 @@ function _eval_and_assemble_inactive_species(system::DenseSystem, matrix, U, Uol end end end + return end function _initialize_inactive_dof!(U::AbstractMatrix, system::AbstractSystem) end @@ -986,19 +1010,20 @@ function _initialize_inactive_dof!(U::DenseSolutionArray, system::DenseSystem) if system.species_homogeneous return end - for inode = 1:size(system.node_dof, 2) - for ispec = 1:size(system.node_dof, 1) + for inode in 1:size(system.node_dof, 2) + for ispec in 1:size(system.node_dof, 1) if !isnodespecies(system, ispec, inode) U[ispec, inode] = 0 end end end + return end function Base.show(io::IO, sys::AbstractSystem) str = "$(typeof(sys))(\n grid = $(sys.grid),\n physics = $(sys.physics),\n num_species = $(num_species(sys)))" - sz=displaysize(io) - print_wrapped(io, str; replace_whitespace=false, subsequent_indent=" ", width=sz[2]) + sz = displaysize(io) + return print_wrapped(io, str; replace_whitespace = false, subsequent_indent = " ", width = sz[2]) end ##################################################### @@ -1051,15 +1076,19 @@ function unknowns(Tu::Type, system::SparseSystem; inival = undef, inifunc = noth if inival != undef fill!(a0, inival) end - Ti=eltype(system.node_dof.colptr) - - u = SparseSolutionArray(SparseMatrixCSC(system.node_dof.m, - system.node_dof.n, - system.node_dof.colptr, - system.node_dof.rowval, - a0)) + Ti = eltype(system.node_dof.colptr) + + u = SparseSolutionArray( + SparseMatrixCSC( + system.node_dof.m, + system.node_dof.n, + system.node_dof.colptr, + system.node_dof.rowval, + a0 + ) + ) isa(inifunc, Function) && map!(inifunc, u, system) - u + return u end @@ -1080,7 +1109,7 @@ Possible modes: function partitioning(system::DenseSystem, ::Equationwise) len = length(system.node_dof) nspec = size(system.node_dof, 1) - [i:nspec:len for i = 1:nspec] + return [i:nspec:len for i in 1:nspec] end function partitioning(system::SparseSystem, ::Equationwise) @@ -1094,8 +1123,8 @@ function partitioning(system::SparseSystem, ::Equationwise) # how many unknowns are there for each species ? # to make things fast we want to avoid push! - for i = 1:nnodes - for j = colptr[i]:(colptr[i + 1] - 1) + for i in 1:nnodes + for j in colptr[i]:(colptr[i + 1] - 1) ispec = rowval[j] @assert ispec == nzval[j] if ispec == nzval[j] @@ -1114,8 +1143,8 @@ function partitioning(system::SparseSystem, ::Equationwise) # # Sort unknown numbers into partitions # - for i = 1:nnodes - for j = colptr[i]:(colptr[i + 1] - 1) + for i in 1:nnodes + for j in colptr[i]:(colptr[i + 1] - 1) ispec = rowval[j] @assert ispec == nzval[j] if ispec == nzval[j] @@ -1124,15 +1153,15 @@ function partitioning(system::SparseSystem, ::Equationwise) end end end - parts + return parts end function unknowns(Tu::Type, system::DenseSystem; inival = undef, inifunc = nothing) - a = DenseSolutionArray(Array{Tu,2}(undef, size(system.node_dof)...)) + a = DenseSolutionArray(Array{Tu, 2}(undef, size(system.node_dof)...)) if isa(inival, Number) fill!(a, inival) elseif isa(inival, Matrix) - a.=inival + a .= inival end isa(inifunc, Function) && map!(inifunc, a, system) return a @@ -1144,8 +1173,8 @@ $(SIGNATURES) Create a solution vector for system using the callback `inifunc` which has the same signature as a source term. """ -function Base.map(inifunc::TF,sys::System) where {TF <: Function} - unknowns(sys; inifunc) +function Base.map(inifunc::TF, sys::System) where {TF <: Function} + return unknowns(sys; inifunc) end """ @@ -1154,7 +1183,7 @@ $(SIGNATURES) Create a solution vector for system using a constant initial value """ function Base.map(inival::TI, sys::System) where {TI <: Number} - unknowns(sys; inival) + return unknowns(sys; inival) end """ @@ -1162,9 +1191,11 @@ $(SIGNATURES) Map `inifunc` onto solution array `U` """ -function Base.map!(inifunc::TF, - U::AbstractMatrix{Tu}, - system::System{Tv, Tc, Ti, Tm, TSpecMat}) where {Tu, Tv, Tc, Ti, Tm, TSpecMat, TF} +function Base.map!( + inifunc::TF, + U::AbstractMatrix{Tu}, + system::System{Tv, Tc, Ti, Tm, TSpecMat} + ) where {Tu, Tv, Tc, Ti, Tm, TSpecMat, TF} isunknownsof(U, system) || error("U is not unknowns of system") _complete!(system) grid = system.grid @@ -1179,7 +1210,7 @@ function Base.map!(inifunc::TF, inifunc(unknowns(node, UK), node) K = node.index ireg = node.region - for idof = firstnodedof(system, K):lastnodedof(system, K) + for idof in firstnodedof(system, K):lastnodedof(system, K) ispec = getspecies(system, idof) if isregionspecies(system, ispec, ireg) _set(U, idof, UK[ispec]) @@ -1187,7 +1218,7 @@ function Base.map!(inifunc::TF, end end end - U + return U end """ @@ -1204,16 +1235,20 @@ Base.reshape(v::SparseSolutionArray, sys::SparseSystem) = v function Base.reshape(v::AbstractVector, sys::DenseSystem) @assert length(v) == num_dof(sys) nspec = num_species(sys) - DenseSolutionArray(reshape(v, Int64(nspec), Int64(length(v) / nspec))) + return DenseSolutionArray(reshape(v, Int64(nspec), Int64(length(v) / nspec))) end function Base.reshape(v::AbstractVector, system::SparseSystem) @assert length(v) == num_dof(system) - SparseSolutionArray(SparseMatrixCSC(system.node_dof.m, - system.node_dof.n, - system.node_dof.colptr, - system.node_dof.rowval, - Vector(v))) + return SparseSolutionArray( + SparseMatrixCSC( + system.node_dof.m, + system.node_dof.n, + system.node_dof.colptr, + system.node_dof.rowval, + Vector(v) + ) + ) end @@ -1228,14 +1263,16 @@ Create system with physics record. !!! info Starting with version 0.14, all physics data can be passed directly to the system constructor """ -function System(grid::ExtendableGrid, physics::Physics; - valuetype = coord_type(grid), - indextype = index_type(grid), - unknown_storage = :dense, - matrixindextype = Int64, - kwargs...) +function System( + grid::ExtendableGrid, physics::Physics; + valuetype = coord_type(grid), + indextype = index_type(grid), + unknown_storage = :dense, + matrixindextype = Int64, + kwargs... + ) system = System(grid; valuetype, indextype, unknown_storage, matrixindextype, kwargs...) - physics!(system, physics) + return physics!(system, physics) end """ @@ -1246,7 +1283,7 @@ Constructor for DenseSystem. Will be removed in future versions """ function DenseSystem(grid, physics::Physics; matrixindextype = Int64) - System(grid, physics; matrixindextype = matrixindextype, unknown_storage = :dense) + return System(grid, physics; matrixindextype = matrixindextype, unknown_storage = :dense) end """ @@ -1257,5 +1294,5 @@ Constructor for SparseSystem. Will be removed in future versions """ function SparseSystem(grid, physics::Physics; matrixindextype = Int64) - System(grid, physics; matrixindextype = matrixindextype, unknown_storage = :sparse) + return System(grid, physics; matrixindextype = matrixindextype, unknown_storage = :sparse) end diff --git a/src/vfvm_testfunctions.jl b/src/vfvm_testfunctions.jl index 8bbecdd60..f9a502352 100644 --- a/src/vfvm_testfunctions.jl +++ b/src/vfvm_testfunctions.jl @@ -34,15 +34,17 @@ $(TYPEDSIGNATURES) Constructor for TestFunctionFactory from System """ function TestFunctionFactory(system::AbstractSystem{Tv}; control = SolverControl()) where {Tv} - physics = Physics(; flux = function (f, u, edge, data) - f[1] = u[1] - u[2] - end, - storage = function (f, u, node, data) - f[1] = u[1] - end) + physics = Physics(; + flux = function (f, u, edge, data) + return f[1] = u[1] - u[2] + end, + storage = function (f, u, node, data) + return f[1] = u[1] + end + ) tfsystem = System(system.grid, physics; unknown_storage = :dense) - enable_species!(tfsystem, 1, [i for i = 1:num_cellregions(system.grid)]) - state=SystemState(tfsystem) + enable_species!(tfsystem, 1, [i for i in 1:num_cellregions(system.grid)]) + state = SystemState(tfsystem) return TestFunctionFactory(system, state, control) end @@ -63,17 +65,17 @@ function testfunction(factory::TestFunctionFactory{Tv}, bc0, bc1) where {Tv} factory.state.system.boundary_factors .= 0 factory.state.system.boundary_values .= 0 - for i = 1:length(bc1) + for i in 1:length(bc1) factory.state.system.boundary_factors[1, bc1[i]] = Dirichlet(Tv) factory.state.system.boundary_values[1, bc1[i]] = -1 end - for i = 1:length(bc0) + for i in 1:length(bc0) factory.state.system.boundary_factors[1, bc0[i]] = Dirichlet(Tv) factory.state.system.boundary_values[1, bc0[i]] = 0 end - eval_and_assemble(factory.state.system, u, u, f, factory.state.matrix, factory.state.dudp, Inf, Inf, 0.0, nothing, zeros(0)) + eval_and_assemble(factory.state.system, u, u, f, factory.state.matrix, factory.state.dudp, Inf, Inf, 0.0, nothing, zeros(0)) _initialize!(u, factory.state.system) @@ -84,7 +86,7 @@ function testfunction(factory::TestFunctionFactory{Tv}, bc0, bc1) where {Tv} p = LinearProblem(SparseMatrixCSC(factory.state.matrix), dofs(f)) sol = solve(p, method_linear) - sol.u + return sol.u end ############################################################################ @@ -94,8 +96,10 @@ $(SIGNATURES) Calculate test function integral for transient solution. """ -function integrate(system::AbstractSystem, tf, U::AbstractMatrix{Tv}, - Uold::AbstractMatrix{Tv}, tstep; params = Tv[], data=system.physics.data) where {Tv} +function integrate( + system::AbstractSystem, tf, U::AbstractMatrix{Tv}, + Uold::AbstractMatrix{Tv}, tstep; params = Tv[], data = system.physics.data + ) where {Tv} grid = system.grid nspecies = num_species(system) integral = zeros(Tv, nspecies) @@ -131,7 +135,7 @@ function integrate(system::AbstractSystem, tf, U::AbstractMatrix{Tv}, for item in nodebatch(system.assembly_data) for inode in noderange(system.assembly_data, item) _fill!(node, system.assembly_data, inode, item) - for ispec = 1:nspecies + for ispec in 1:nspecies UK[ispec] = U[ispec, node.index] UKold[ispec] = Uold[ispec, node.index] end @@ -146,8 +150,8 @@ function integrate(system::AbstractSystem, tf, U::AbstractMatrix{Tv}, src = res(src_eval) function asm_res(idof, ispec) - integral[ispec] += node.fac * - (rea[ispec] - src[ispec] + (stor[ispec] - storold[ispec]) * tstepinv) * tf[node.index] + return integral[ispec] += node.fac * + (rea[ispec] - src[ispec] + (stor[ispec] - storold[ispec]) * tstepinv) * tf[node.index] end assemble_res(node, system, asm_res) end @@ -163,7 +167,7 @@ function integrate(system::AbstractSystem, tf, U::AbstractMatrix{Tv}, flux = res(flux_eval) function asm_res(idofK, idofL, ispec) - integral[ispec] += edge.fac * flux[ispec] * (tf[edge.node[1]] - tf[edge.node[2]]) + return integral[ispec] += edge.fac * flux[ispec] * (tf[edge.node[1]] - tf[edge.node[2]]) end assemble_res(edge, system, asm_res) @@ -172,7 +176,7 @@ function integrate(system::AbstractSystem, tf, U::AbstractMatrix{Tv}, erea = res(erea_eval) function easm_res(idofK, idofL, ispec) - integral[ispec] += edge.fac * erea[ispec] * (tf[edge.node[1]] + tf[edge.node[2]]) + return integral[ispec] += edge.fac * erea[ispec] * (tf[edge.node[1]] + tf[edge.node[2]]) end assemble_res(edge, system, easm_res) end @@ -189,7 +193,7 @@ $(SIGNATURES) Calculate test function integral for steady state solution. """ function integrate(system::AbstractSystem, tf::Vector{Tv}, U::AbstractMatrix{Tu}; kwargs...) where {Tu, Tv} - integrate(system, tf, U, U, Inf; kwargs...) + return integrate(system, tf, U, U, Inf; kwargs...) end ############################################################################ @@ -198,7 +202,7 @@ $(SIGNATURES) Steady state part of test function integral. """ -function integrate_stdy(system::AbstractSystem, tf::Vector{Tv}, U::AbstractArray{Tu, 2}; data=system.physics.data) where {Tu, Tv} +function integrate_stdy(system::AbstractSystem, tf::Vector{Tv}, U::AbstractArray{Tu, 2}; data = system.physics.data) where {Tu, Tv} grid = system.grid nspecies = num_species(system) integral = zeros(Tu, nspecies) @@ -229,7 +233,7 @@ function integrate_stdy(system::AbstractSystem, tf::Vector{Tv}, U::AbstractArray src = res(src_eval) function asm_res(idof, ispec) - integral[ispec] += node.fac * (rea[ispec] - src[ispec]) * tf[node.index] + return integral[ispec] += node.fac * (rea[ispec] - src[ispec]) * tf[node.index] end assemble_res(node, system, asm_res) end @@ -244,7 +248,7 @@ function integrate_stdy(system::AbstractSystem, tf::Vector{Tv}, U::AbstractArray flux = res(flux_eval) function asm_res(idofK, idofL, ispec) - integral[ispec] += edge.fac * flux[ispec] * (tf[edge.node[1]] - tf[edge.node[2]]) + return integral[ispec] += edge.fac * flux[ispec] * (tf[edge.node[1]] - tf[edge.node[2]]) end assemble_res(edge, system, asm_res) @@ -253,7 +257,7 @@ function integrate_stdy(system::AbstractSystem, tf::Vector{Tv}, U::AbstractArray erea = res(erea_eval) function easm_res(idofK, idofL, ispec) - integral[ispec] += edge.fac * erea[ispec] * (tf[edge.node[1]] + tf[edge.node[2]]) + return integral[ispec] += edge.fac * erea[ispec] * (tf[edge.node[1]] + tf[edge.node[2]]) end assemble_res(edge, system, easm_res) end @@ -269,7 +273,7 @@ $(SIGNATURES) Calculate transient part of test function integral. """ -function integrate_tran(system::AbstractSystem, tf::Vector{Tv}, U::AbstractArray{Tu, 2}; data=system.physics.data) where {Tu, Tv} +function integrate_tran(system::AbstractSystem, tf::Vector{Tv}, U::AbstractArray{Tu, 2}; data = system.physics.data) where {Tu, Tv} grid = system.grid nspecies = num_species(system) integral = zeros(Tu, nspecies) diff --git a/src/vfvm_transientsolution.jl b/src/vfvm_transientsolution.jl index 271ff4d0e..ad006f390 100644 --- a/src/vfvm_transientsolution.jl +++ b/src/vfvm_transientsolution.jl @@ -47,7 +47,7 @@ end function TransientSolution(vec::AbstractVector{T}, ts, ::NTuple{N}) where {T, N} - TransientSolution{eltype(T), N, typeof(vec), typeof(ts)}(vec, ts, TransientSolverHistory()) + return TransientSolution{eltype(T), N, typeof(vec), typeof(ts)}(vec, ts, TransientSolverHistory()) end TransientSolution(vec::AbstractVector, ts::AbstractVector) = TransientSolution(vec, ts, (size(vec[1])..., length(vec))) @@ -61,11 +61,11 @@ If during a time steping process it is the same vector, a `copy` should appended Defined in VoronoiFVM.jl. """ -Base.append! +Base.append! Base.append!(s::AbstractTransientSolution, t::Real, sol::AbstractArray) = push!(s.t, t), push!(s.u, sol) -Base.append!(s::AbstractTransientSolution, t::Real, sol::AbstractSolutionArray) = append!(s,t,sol.u) +Base.append!(s::AbstractTransientSolution, t::Real, sol::AbstractSolutionArray) = append!(s, t, sol.u) (sol::AbstractTransientSolution)(t) = _interpolate(sol, t) @@ -96,7 +96,7 @@ end function Base.push!(v::VectorOfDiskArrays, obj) v.n += 1 - if isnothing(v.file) + return if isnothing(v.file) jldopen(v.fname, "a+") do file file[string(v.n)] = obj end @@ -109,7 +109,7 @@ Base.size(v::VectorOfDiskArrays) = (v.n,) Base.length(v::VectorOfDiskArrays) = v.n Base.eltype(v::VectorOfDiskArrays{T}) where {T} = T function Base.getindex(v::VectorOfDiskArrays, i) - if isnothing(v.file) + return if isnothing(v.file) jldopen(v.fname, "r") do file file[string(i)] end @@ -143,11 +143,11 @@ function VectorOfDiskArrays(obj::AbstractArray{T}; keep_open = true, fname = _te end v = VectorOfDiskArrays{T}(fname, file, 1) finalizer(v -> (isnothing(v.file) ? nothing : close(v.file); rm(v.fname; force = true)), v) - v + return v end function Base.append!(s::AbstractTransientSolution{T, N, VectorOfDiskArrays{T}, B}, t::Real, sol::AbstractArray) where {T, N, B} - push!(s.t, t), push!(s.u, sol) + return push!(s.t, t), push!(s.u, sol) end """ @@ -163,16 +163,18 @@ Constructor of transient solution with initial value and initial time. - `keep_open`: if true, disk file is not closed during the existence of the object - `fname`: file name for the disk file """ -function TransientSolution(t0::Number, - inival::AbstractArray{T}; - in_memory = true, - keep_open = true, - fname = _tempname()) where {T} - if !in_memory && !isa(inival, SparseSolutionArray) +function TransientSolution( + t0::Number, + inival::AbstractArray{T}; + in_memory = true, + keep_open = true, + fname = _tempname() + ) where {T} + return if !in_memory && !isa(inival, SparseSolutionArray) TransientSolution(VectorOfDiskArrays(inival; keep_open = keep_open, fname = fname), [t0]) else TransientSolution([inival], [t0]) end end -TransientSolution(t0::Number,inival::AbstractSolutionArray{T,N};kwargs...) where{T,N} = TransientSolution(t0,inival.u; kwargs...) +TransientSolution(t0::Number, inival::AbstractSolutionArray{T, N}; kwargs...) where {T, N} = TransientSolution(t0, inival.u; kwargs...) diff --git a/test/runtests.jl b/test/runtests.jl index 230cd8c4d..fef9488f8 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -14,6 +14,7 @@ function run_tests_from_directory(testdir, prefix) examples = filter(ex -> length(ex) >= length(prefix) && ex[1:length(prefix)] == prefix, basename.(readdir(testdir))) @info examples @testmodules(testdir, examples) + return nothing end function run_all_tests(; run_notebooks = false, notebooksonly = false) @@ -21,7 +22,7 @@ function run_all_tests(; run_notebooks = false, notebooksonly = false) @testset "basictest" begin run_tests_from_directory(@__DIR__, "test_") end - + @testset "Development Examples" begin run_tests_from_directory(joinpath(@__DIR__, "..", "examples"), "Example0") end @@ -45,7 +46,7 @@ function run_all_tests(; run_notebooks = false, notebooksonly = false) end if run_notebooks - ENV["VORONOIFVM_RUNTESTS"]="1" + ENV["VORONOIFVM_RUNTESTS"] = "1" notebooks = [ "nbproto.jl", "ode-diffusion1d.jl", @@ -59,7 +60,7 @@ function run_all_tests(; run_notebooks = false, notebooksonly = false) "nonlinear-solvers.jl", "api-update.jl", "heterogeneous-catalysis.jl", - ] + ] @testset "Notebooks" begin @testscripts(joinpath(@__DIR__, "..", "pluto-examples"), notebooks) end @@ -71,28 +72,29 @@ function run_all_tests(; run_notebooks = false, notebooksonly = false) end @testset "Aqua" begin - Aqua.test_ambiguities(VoronoiFVM, broken=true) + Aqua.test_ambiguities(VoronoiFVM, broken = true) Aqua.test_unbound_args(VoronoiFVM) Aqua.test_undefined_exports(VoronoiFVM) Aqua.test_project_extras(VoronoiFVM) Aqua.test_stale_deps(VoronoiFVM) Aqua.test_deps_compat(VoronoiFVM) - Aqua.test_piracies(VoronoiFVM, broken=true) + Aqua.test_piracies(VoronoiFVM, broken = true) Aqua.test_persistent_tasks(VoronoiFVM) end - - if isdefined(Docs,:undocumented_names) # >=1.11 + + if isdefined(Docs, :undocumented_names) # >=1.11 @testset "UndocumentedNames" begin @test isempty(Docs.undocumented_names(VoronoiFVM)) end end + return nothing end # Don't run notebooks on 1.12: https://github.com/fonsp/Pluto.jl/issues/2939 -if haskey(ENV,"EXAMPLES_ONLY") +if haskey(ENV, "EXAMPLES_ONLY") run_all_tests(; run_notebooks = false, notebooksonly = false) -elseif haskey(ENV,"NOTEBOOKS_ONLY") - run_all_tests(; run_notebooks=true, notebooksonly = true) +elseif haskey(ENV, "NOTEBOOKS_ONLY") + run_all_tests(; run_notebooks = true, notebooksonly = true) else - run_all_tests(; run_notebooks = VERSION < v"1.12.0-DEV.0" , notebooksonly = false) + run_all_tests(; run_notebooks = VERSION < v"1.12.0-DEV.0", notebooksonly = false) end diff --git a/test/test_bernoulli.jl b/test/test_bernoulli.jl index 4885a5a8b..cba6b6220 100644 --- a/test/test_bernoulli.jl +++ b/test/test_bernoulli.jl @@ -5,7 +5,7 @@ using Test function runtests() function B_Big(x) bx = BigFloat(x) - Float64(bx / (exp(bx) - one(bx))) + return Float64(bx / (exp(bx) - one(bx))) end smallrange = -1:1.00001e-5:1 largerange = -100:1.00001e-3:100 @@ -19,7 +19,7 @@ function runtests() @test maxerror(smallrange, x -> B_Big(-x), (x) -> fbernoulli_pm(x)[2]) < 1.0e-14 @test maxerror(largerange, x -> B_Big(-x), (x) -> fbernoulli_pm(x)[2]) < 1.0e-14 - true + return true end end diff --git a/test/test_checkdelaunay.jl b/test/test_checkdelaunay.jl index f3ae618b8..3ae9a7efb 100644 --- a/test/test_checkdelaunay.jl +++ b/test/test_checkdelaunay.jl @@ -4,18 +4,19 @@ using ExtendableGrids: Coordinates, simplexgrid using VoronoiFVM: nondelaunay function runtests() - X=0:0.1:10 - g=simplexgrid(X,X) + X = 0:0.1:10 + g = simplexgrid(X, X) @test length(nondelaunay(g)) == 0 - - coord=g[Coordinates] - for i=1:size(coord,2) - coord[1,i]+=0.01*(rand()-0.5) - coord[2,i]+=0.01*(rand()-0.5) + + coord = g[Coordinates] + for i in 1:size(coord, 2) + coord[1, i] += 0.01 * (rand() - 0.5) + coord[2, i] += 0.01 * (rand() - 0.5) end - @test length(nondelaunay(g))>0 + @test length(nondelaunay(g)) > 0 + return nothing end end diff --git a/test/test_diffeq.jl b/test/test_diffeq.jl index 6a01b3ff6..dcd94b54a 100644 --- a/test/test_diffeq.jl +++ b/test/test_diffeq.jl @@ -8,30 +8,32 @@ using Test function test_matrices(nspec) grid = simplexgrid(0:1.0:5) function flux(y, u, edge, data) - for i = 1:length(y) + for i in 1:length(y) y[i] = u[i, 1] - u[i, 2] end + return nothing end function storage(y, u, node, data) - for i = 1:length(y) + for i in 1:length(y) y[i] = i * u[i] end + return nothing end sys = VoronoiFVM.System(grid; flux, storage, species = collect(1:nspec)) - state=SystemState(sys) + state = SystemState(sys) jac_proto = prepare_diffeq!(state, unknowns(sys), 0) nd = num_nodes(grid) * nspec d = zeros(nd) j = 1 - for i = 1:num_nodes(grid) + for i in 1:num_nodes(grid) fac = 1.0 if i == 1 || i == num_nodes(grid) fac = 0.5 end - for id = 1:nspec + for id in 1:nspec d[j] = fac * id j = j + 1 end @@ -41,12 +43,13 @@ function test_matrices(nspec) J = similar(jac_proto) eval_jacobian!(J, u, state, 0.0) @test jac_proto == -J + return nothing end function runtests() test_matrices(1) test_matrices(2) - true + return true end end diff --git a/test/test_formfactors.jl b/test/test_formfactors.jl index 5af9f0614..2d91aefc9 100644 --- a/test/test_formfactors.jl +++ b/test/test_formfactors.jl @@ -3,24 +3,25 @@ using Test using ExtendableGrids using VoronoiFVM: cellfactors!, bfacefactors! -randpoint=rand(-10:0.01:10,2) -function ttri(;ntest=100) - cellnodes=[1 2 3;]' - icell=1 - epar2d=zeros(3) - npar2d=zeros(3) - epar3d=zeros(3) - npar3d=zeros(3) - for i=1:100 - coord2d=rand(-10:0.01:10,2,3) - coord3d=vcat(coord2d,[0.0,0,0]') +randpoint = rand(-10:0.01:10, 2) +function ttri(; ntest = 100) + cellnodes = [1 2 3;]' + icell = 1 + epar2d = zeros(3) + npar2d = zeros(3) + epar3d = zeros(3) + npar3d = zeros(3) + for i in 1:100 + coord2d = rand(-10:0.01:10, 2, 3) + coord3d = vcat(coord2d, [0.0, 0, 0]') - cellfactors!(Triangle2D,Cartesian2D,coord2d,cellnodes,1,npar2d,epar2d) - bfacefactors!(Triangle2D,Cartesian3D,coord3d,cellnodes,1,npar3d,epar3d) + cellfactors!(Triangle2D, Cartesian2D, coord2d, cellnodes, 1, npar2d, epar2d) + bfacefactors!(Triangle2D, Cartesian3D, coord3d, cellnodes, 1, npar3d, epar3d) @test npar3d ≈ npar2d @test epar3d ≈ epar2d end + return nothing end diff --git a/test/test_linsolve.jl b/test/test_linsolve.jl index b1d3c000d..b91d00836 100644 --- a/test/test_linsolve.jl +++ b/test/test_linsolve.jl @@ -13,8 +13,8 @@ function checklux0(::Type{Val{N}}, ::Type{T}) where {N, T} x = StrideArray{T}(undef, StaticInt(N)) b = StrideArray{T}(undef, StaticInt(N)) - for i = 1:N - for j = 1:N + for i in 1:N + for j in 1:N A[i, j] = -rand() end A[i, i] += 100 @@ -25,11 +25,11 @@ function checklux0(::Type{Val{N}}, ::Type{T}) where {N, T} @gc_preserve inplace_linsolve!(A, b) nm = 0 - for i = 1:N + for i in 1:N nm += (b[i] - x[i])^2 end @assert sqrt(nm) / N < 100.0 * eps(Float64) - nothing + return nothing end checklux(n, T) = checklux0(Val{n}, T) @@ -39,8 +39,8 @@ function checklum0(::Type{Val{N}}, ::Type{T}) where {N, T} x = MVector{N, Float64}(undef) b = MVector{N, Float64}(undef) - for i = 1:N - for j = 1:N + for i in 1:N + for j in 1:N A[i, j] = -rand() end A[i, i] += 100 @@ -51,12 +51,12 @@ function checklum0(::Type{Val{N}}, ::Type{T}) where {N, T} @gc_preserve inplace_linsolve!(A, b) nm = 0 - for i = 1:N + for i in 1:N nm += (b[i] - x[i])^2 end @assert sqrt(nm) / N < 100.0 * eps(Float64) - nothing + return nothing end checklum(n, T) = checklum0(Val{n}, T) @@ -67,23 +67,23 @@ function checklurx0(::Type{Val{N}}, ::Type{T}) where {N, T} x = StrideArray{T}(undef, StaticInt(N)) b = StrideArray{T}(undef, StaticInt(N)) ipiv = StrideArray{Int64}(undef, StaticInt(N)) - for i = 1:N - for j = 1:N + for i in 1:N + for j in 1:N A[i, j] = -rand() - end + end A[i, i] += 100 x[i] = 1 end @gc_preserve mul!(b, A, x) @gc_preserve inplace_linsolve!(A, b, ipiv) - nm = 0 - for i = 1:N + nm = 0 + for i in 1:N nm += (b[i] - x[i])^2 end @assert sqrt(nm) / N < 100.0 * eps(Float64) - nothing + return nothing end checklurx(n, T) = checklurx0(Val{n}, T) @@ -93,8 +93,8 @@ function checklurm0(::Type{Val{N}}, ::Type{T}) where {N, T} x = MVector{N, Float64}(undef) b = MVector{N, Float64}(undef) ipiv = MVector{N, Int64}(undef) - for i = 1:N - for j = 1:N + for i in 1:N + for j in 1:N A[i, j] = -rand() end A[i, i] += 100 @@ -104,12 +104,12 @@ function checklurm0(::Type{Val{N}}, ::Type{T}) where {N, T} @gc_preserve inplace_linsolve!(A, b, ipiv) nm = 0 - for i = 1:N + for i in 1:N nm += (b[i] - x[i])^2 end @assert sqrt(nm) / N < 100.0 * eps(Float64) - nothing + return nothing end checklurm(n, T) = checklurm0(Val{n}, T) @@ -146,7 +146,7 @@ function runtests() @test rn3 == 0 rn4 = @allocated checklurm(10, Dual64) @test rn4 == 0 - true + return true end end diff --git a/test/test_norms.jl b/test/test_norms.jl index c8f03ab79..ed16346b3 100644 --- a/test/test_norms.jl +++ b/test/test_norms.jl @@ -6,12 +6,13 @@ using LinearAlgebra function grid(X, dim) if dim == 1 - simplexgrid(X) + return simplexgrid(X) elseif dim == 2 - simplexgrid(X, X) + return simplexgrid(X, X) else - simplexgrid(X, X, X) + return simplexgrid(X, X, X) end + return nothing end function test_solint(; dim = 2, c = 1.0, assembly = :edgewise, h = 0.1) @@ -20,7 +21,7 @@ function test_solint(; dim = 2, c = 1.0, assembly = :edgewise, h = 0.1) sys = VoronoiFVM.System(g; species = [1], assembly) VoronoiFVM._complete!(sys) u = map(c, sys) - VoronoiFVM.integrate(sys, u)[1, 1] + return VoronoiFVM.integrate(sys, u)[1, 1] end @@ -30,10 +31,11 @@ function test_edgeint(; dim = 2, c = 1.0, assembly = :edgewise, h = 0.1) sys = VoronoiFVM.System(g; species = [1], assembly) VoronoiFVM._complete!(sys) u = map(c, sys) - function f(y, u, edge, data=nothing) + function f(y, u, edge, data = nothing) y[1] = 0.5 * (u[1, 1] + u[2, 1]) + return nothing end - VoronoiFVM.edgeintegrate(sys, f, u)[1, 1] + return VoronoiFVM.edgeintegrate(sys, f, u)[1, 1] end function test_const(; dim = 2, c = 1.0, nrm = l2norm, assembly = :edgewise, h = 0.1) @@ -42,7 +44,7 @@ function test_const(; dim = 2, c = 1.0, nrm = l2norm, assembly = :edgewise, h = sys = VoronoiFVM.System(g; species = [1], assembly) VoronoiFVM._complete!(sys) F = map(c, sys) - nrm(sys, F) + return nrm(sys, F) end function test_lin(; dim = 2, c = 1.0, nrm = h1seminorm, assembly = :edgewise, h = 0.1) @@ -52,15 +54,16 @@ function test_lin(; dim = 2, c = 1.0, nrm = h1seminorm, assembly = :edgewise, h VoronoiFVM._complete!(sys) F = unknowns(sys) F[1, :] .= map((x...) -> (c * sum(x) / sqrt(dim)), g) - nrm(sys, F) + return nrm(sys, F) end function test_transient(; - dim = 2, - c = 1.0, - nrm = l2h1seminorm, - assembly = :edgewise, - h = 0.1,) + dim = 2, + c = 1.0, + nrm = l2h1seminorm, + assembly = :edgewise, + h = 0.1, + ) X = 0:h:1 g = grid(X, dim) sys = VoronoiFVM.System(g; species = [1], assembly) @@ -68,20 +71,21 @@ function test_transient(; F = unknowns(sys) F[1, :] .= map((x...) -> (c * sum(x) / sqrt(dim)), g) U = TransientSolution(X[1], F) - for i = 2:length(X) + for i in 2:length(X) append!(U, X[i], F) end - nrm(sys, U) + return nrm(sys, U) end function test_transient_exp(; - dim = 2, - c = 1.0, - nrm = l2h1seminorm, - time_dep = t -> 1, - assembly = :edgewise, - h = 0.1,) + dim = 2, + c = 1.0, + nrm = l2h1seminorm, + time_dep = t -> 1, + assembly = :edgewise, + h = 0.1, + ) X = 0:h:1 g = grid(X, dim) sys = VoronoiFVM.System(g; species = [1], assembly) @@ -89,23 +93,23 @@ function test_transient_exp(; F = unknowns(sys) F[1, :] .= map((x...) -> c * sum(x) / sqrt(dim), g) U = TransientSolution(X[1], F) - for i = 2:length(X) + for i in 2:length(X) append!(U, X[i], time_dep(X[i]) * F) end - nrm(sys, U) + return nrm(sys, U) end function test_nodevol(; dim = 1, h = 0.1, assembly = :edgewise) X = 0:h:1 g = grid(X, dim) sys = VoronoiFVM.System(g; species = [1], assembly) - sum(nodevolumes(sys)) + return sum(nodevolumes(sys)) end function runtests() for assembly in (:edgewise, :cellwise) - for dim = 1:3 + for dim in 1:3 for c in [0.5, 1, 2.0] @test test_solint(; dim, c, assembly) ≈ c @test test_edgeint(; dim, c, assembly) ≈ c @@ -125,7 +129,7 @@ function runtests() @test test_nodevol(; dim, assembly) ≈ 1.0 end end - true + return true end end diff --git a/test/test_spec.jl b/test/test_spec.jl index 761d94105..405e89ec2 100644 --- a/test/test_spec.jl +++ b/test/test_spec.jl @@ -7,7 +7,7 @@ function test_addrows(m, n, mx) sa = sprand(m, n, 0.5) da = Matrix(sa) SparseMatrixCSC(VoronoiFVM.addzrows(da, mx)) == VoronoiFVM.addzrows(sa, mx) - sa == da + return sa == da end function runtests() @@ -17,7 +17,7 @@ function runtests() @test test_addrows(1, 100, 4) @test test_addrows(10, 100, 11) @test test_addrows(10, 100, 1) - true + return true end end diff --git a/test/test_state.jl b/test/test_state.jl index 17665a334..cecbbd8ed 100644 --- a/test/test_state.jl +++ b/test/test_state.jl @@ -5,47 +5,47 @@ using ExtendableGrids using LinearAlgebra using Test -flux(y,u,edge, data)= y[1]=u[1,1]-u[1,2] +flux(y, u, edge, data) = y[1] = u[1, 1] - u[1, 2] -function bcondition(y,u,bnode,data) - boundary_robin!(y,u,bnode,region=1, value=0.0, factor=0.1) - boundary_robin!(y,u,bnode,region=2, value=1.0, factor=0.1) +function bcondition(y, u, bnode, data) + boundary_robin!(y, u, bnode, region = 1, value = 0.0, factor = 0.1) + boundary_robin!(y, u, bnode, region = 2, value = 1.0, factor = 0.1) + return nothing end -function main(; unknown_storage=:dense) - g=simplexgrid(0:0.1:1) - sys=VoronoiFVM.System(g; flux, bcondition, species=[1], unknown_storage) - sol1=solve(sys) +function main(; unknown_storage = :dense) + g = simplexgrid(0:0.1:1) + sys = VoronoiFVM.System(g; flux, bcondition, species = [1], unknown_storage) + sol1 = solve(sys) # Solution and solution with state shall be the same - state=VoronoiFVM.SystemState(sys) - sol2=solve!(state) - @test sol1≈sol2 + state = VoronoiFVM.SystemState(sys) + sol2 = solve!(state) + @test sol1 ≈ sol2 - control=SolverControl() - fixed_timesteps!(control,0.025) + control = SolverControl() + fixed_timesteps!(control, 0.025) # Allow initial values as result of previous time evolution - tsol1=solve(sys; inival=0.0, times=(0,0.1), control) - tsol2=solve(sys; inival=tsol1.u[end], times=(0.1,0.2), control) - tsol3=solve(sys; inival=0.0, times=[0.0,0.1,0.2], control) - @test tsol3.u[end]≈tsol2.u[end] + tsol1 = solve(sys; inival = 0.0, times = (0, 0.1), control) + tsol2 = solve(sys; inival = tsol1.u[end], times = (0.1, 0.2), control) + tsol3 = solve(sys; inival = 0.0, times = [0.0, 0.1, 0.2], control) + @test tsol3.u[end] ≈ tsol2.u[end] # Solution and solution with state shall be the same - xsol1=solve!(state; inival=0.0, times=(0,0.1), control) - xsol2=solve!(state; inival=tsol1.u[end], times=(0.1,0.2), control) - xsol3=solve!(state; inival=0.0, times=[0.0,0.1,0.2], control) - @test xsol3.u[end]≈xsol2.u[end] - @test xsol3.u[end]≈tsol3.u[end] - - + xsol1 = solve!(state; inival = 0.0, times = (0, 0.1), control) + xsol2 = solve!(state; inival = tsol1.u[end], times = (0.1, 0.2), control) + xsol3 = solve!(state; inival = 0.0, times = [0.0, 0.1, 0.2], control) + @test xsol3.u[end] ≈ xsol2.u[end] + @test xsol3.u[end] ≈ tsol3.u[end] + return nothing end function runtests() - main(;unknown_storage=:dense) - main(;unknown_storage=:sparse) - + main(; unknown_storage = :dense) + main(; unknown_storage = :sparse) + return nothing end end diff --git a/test/test_transientsol.jl b/test/test_transientsol.jl index 12ad58573..67b498b6f 100644 --- a/test/test_transientsol.jl +++ b/test/test_transientsol.jl @@ -2,12 +2,12 @@ module test_transientsol using VoronoiFVM using Test function make_transientsol(; n = 10, M = 5, N = 100, in_memory = true) - makevec(k) = [k + i * j for i = 1:M, j = 1:N] + makevec(k) = [k + i * j for i in 1:M, j in 1:N] sol = TransientSolution(0, makevec(0); in_memory = in_memory) - for k = 1:n + for k in 1:n append!(sol, k, makevec(k)) end - sol + return sol end function runtests() @@ -16,7 +16,7 @@ function runtests() @test msol == dsol @test length(msol[2, :, 1]) == 100 @test length(dsol[2, :, 2]) == 100 - true + return true end end