Skip to content

Commit 67fae56

Browse files
authored
Merge pull request #185 from Da-Be-Ru/test/cachesolve
Add cache-based solve test for multiple right-hand sides
2 parents dcc520c + ea325e6 commit 67fae56

File tree

6 files changed

+77
-10
lines changed

6 files changed

+77
-10
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
- Try to remove type piracies
77
- Remove `params` from edge, node structs (apparently never used)
88

9+
## v2.9 April 3, 2025
10+
- Fixed bug in `evaluate_residual_and_jacobian`
11+
- Added `init_dirichlet` flag to `evaluate_residual_and_jacobian!` to suppress initialization of Dirichlet values in argument vector `u`
12+
913
## v2.8 February 23, 2025
1014
- Add `integrate` methods for transient solutions returning instances of `DiffEqArray`
1115

Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "VoronoiFVM"
22
uuid = "82b139dc-5afc-11e9-35da-9b9bdfd336f3"
33
authors = ["Jürgen Fuhrmann <juergen.fuhrmann@wias-berlin.de>", "Patrick Jaap", "Daniel Runge", "Dilara Abdel", "Jan Weidner", "Alexander Seiler", "Patricio Farrell", "Matthias Liero"]
4-
version = "2.8.0"
4+
version = "2.9.0"
55

66
[deps]
77
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"

src/VoronoiFVM.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ solutionarray(a::AbstractSolutionArray) = a
7777
export AbstractSolutionArray
7878

7979
include("vfvm_physics.jl")
80-
# see https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/34m
80+
# see https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/34
8181
VERSION >= v"1.11.0-DEV.469" && eval(Meta.parse("public Physics, AbstractPhysics, AbstractData"))
8282

8383
include("vfvm_functions.jl")
@@ -91,6 +91,7 @@ export NewtonSolverHistory, TransientSolverHistory, details
9191

9292
include("vfvm_densesolution.jl")
9393
include("vfvm_sparsesolution.jl")
94+
VERSION >= v"1.11.0-DEV.469" && eval(Meta.parse("public dofs"))
9495
export num_dof
9596
export dof
9697
export getdof

src/vfvm_solver.jl

+8-5
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,10 @@ function solve_step!(
192192
return solution
193193
end
194194

195-
function evaluate_residual_and_jacobian!(state, u; params = Float64[], t = 0.0, tstep = Inf, embed = 0.0)
196-
_initialize_dirichlet!(u, state.system, state.data)
195+
function evaluate_residual_and_jacobian!(state, u; params = Float64[], t = 0.0, tstep = Inf, embed = 0.0, init_dirichlet = false)
196+
if init_dirichlet
197+
_initialize_dirichlet!(u, state.system, state.data)
198+
end
197199
eval_and_assemble(
198200
state.system,
199201
u,
@@ -213,16 +215,17 @@ end
213215

214216
"""
215217
evaluate_residual_and_jacobian(system,u;
216-
t=0.0, tstep=Inf,embed=0.0)
218+
t=0.0, tstep=Inf, embed=0.0, init_dirichlet=false)
217219
218220
Evaluate residual and jacobian at solution value u.
219221
Returns a solution vector containing a copy of residual, and an ExendableSparseMatrix
220-
containing a copy of the linearization at u.
222+
containing a copy of the linearization at u. The flag `init_dirichlet` controls whether
223+
u should be adjusted to satisfy the Dirichlet boundary conditions specified by the system.
221224
222225
"""
223226
function evaluate_residual_and_jacobian(sys, u; kwargs...)
224227
state = SystemState(sys)
225-
eval_and_linearize!(state, u; kwargs...)
228+
evaluate_residual_and_jacobian!(state, u; kwargs...)
226229
return copy(state.residual), copy(state.matrix)
227230
end
228231

test/alltests.jl

+9-3
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,17 @@ ExampleJuggler.verbose!(true)
77
# Include all Julia files in `testdir` whose name starts with `prefix`,
88
# Each file `prefixModName.jl` must contain a module named
99
# `prefixModName` which has a method test() returning true
10-
# or false depending on success.
10+
# or false depending on success. All files with filenames contained in
11+
# the `ignore` list will not be included.
1112
#
12-
function run_tests_from_directory(testdir, prefix)
13+
function run_tests_from_directory(testdir, prefix; ignore = [])
1314
@info "Directory $(testdir):"
14-
examples = filter(ex -> length(ex) >= length(prefix) && ex[1:length(prefix)] == prefix, basename.(readdir(testdir)))
15+
examples = filter(
16+
filename -> length(filename) >= length(prefix) &&
17+
filename[1:length(prefix)] == prefix &&
18+
filename ignore,
19+
basename.(readdir(testdir))
20+
)
1521
@info examples
1622
@testmodules(testdir, examples)
1723
return nothing

test/test_cachesol.jl

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
module test_cachesol
2+
using ExtendableGrids
3+
using VoronoiFVM
4+
using LinearSolve
5+
using ExtendableSparse
6+
using LinearAlgebra
7+
using SparseArrays
8+
using Test
9+
10+
function flux!(f, u, edge, data)
11+
f[1] = u[1, 1] - u[1, 2]
12+
return nothing
13+
end
14+
15+
function bcondition!(f, u, bnode, data)
16+
boundary_dirichlet!(f, u, bnode; species = 1, region = 1, value = 0.0)
17+
boundary_dirichlet!(f, u, bnode; species = 1, region = 2, value = 1.0)
18+
return nothing
19+
end
20+
21+
function setup_linear_solve(n)
22+
# define system, initialize system matrix
23+
X = linspace(0.0, 1.0, n)
24+
system = VoronoiFVM.System(X; flux = flux!, bcondition = bcondition!, species = [1])
25+
F = unknowns(system; inival = 0.0)
26+
# assemble system matrix A and the residual F of A*U=RHS in U=0, i.e.
27+
# F = A*0 - RHS = -RHS
28+
F, A = VoronoiFVM.evaluate_residual_and_jacobian(system, F)
29+
30+
p = LinearProblem(A, -VoronoiFVM.dofs(F))
31+
linear_cache = init(p, LinearSolve.UMFPACKFactorization())
32+
33+
return X, linear_cache
34+
end
35+
36+
function solve_problem(cache)
37+
sol = LinearSolve.solve!(cache)
38+
return sol
39+
end
40+
41+
function main(; n = 10)
42+
X, cache = setup_linear_solve(n)
43+
approx_sol = solve_problem(cache)
44+
true_sol = map((x) -> (x), X)
45+
@test norm(approx_sol .- true_sol, Inf) 3.0e-16
46+
return nothing
47+
end
48+
49+
function runtests()
50+
main()
51+
return nothing
52+
end
53+
end

0 commit comments

Comments
 (0)