Mercurial > repos > public > sbplib_julia
changeset 873:9929c99754fb laplace_benchmarks
Add some benchmarks using the Laplace Operator Set
author | Vidar Stiernström <vidar.stiernstrom@it.uu.se> |
---|---|
date | Wed, 19 Jan 2022 13:15:45 +0100 |
parents | 545a6c1a0a0e |
children | 7e9ebd572deb |
files | laplace_benchmark.jl laplace_benchmark.m src/SbpOperators/volumeops/laplace/laplace.jl wave.gif |
diffstat | 4 files changed, 114 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/laplace_benchmark.jl Wed Jan 19 13:15:45 2022 +0100 @@ -0,0 +1,42 @@ +using Sbplib.Grids, Sbplib.SbpOperators, Sbplib.LazyTensors, Sbplib.RegionIndices +using Profile, BenchmarkTools + +function apply_laplace!(f, u, L, inds) + for I in inds + f[I] = (L*u)[I] + end +end + +apply_laplace!(f, u, L) = apply_laplace!(f, u, L, eachindex(u)) + +region_indices(L, N, ::Lower) = map(x->Index{Lower}(x),1:closure_size(L)) +region_indices(L, N, ::Interior) = map(x->Index{Interior}(x),closure_size(L)+1:N-closure_size(L)) +region_indices(L, N, ::Upper) = map(x->Index{Upper}(x),N-closure_size(L)+1:N) + +function get_region_indices(L,N) + ind_lower = region_indices(L, N, Lower()) + ind_interior = region_indices(L, N, Interior()) + ind_upper = region_indices(L, N, Upper()) + return (ind_lower, ind_interior, ind_upper) +end + +function apply_laplace_regions!(f, u, L, region_inds) + apply_laplace!(f, u, L, region_inds[1]) + apply_laplace!(f, u, L, region_inds[2]) + apply_laplace!(f, u, L, region_inds[3]) +end + +# Domain +N = 4001 +g = EquidistantGrid(N,0.,1.) + +# Operators +L = Laplace(g,sbp_operators_path()*"standard_diagonal.toml"; order=4) +u = evalOn(g,x->x^2) +f = similar(u) + +apply_laplace!(f,u,L) #ensure compilation +@btime apply_laplace!(f,u,L) +rinds = get_region_indices(L,N) +apply_laplace_regions!(f,u,L,rinds) #ensure compilation +@btime apply_laplace_regions!(f,u,L,rinds)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/laplace_benchmark.m Wed Jan 19 13:15:45 2022 +0100 @@ -0,0 +1,14 @@ +m = 4001; +ops = sbp.D2Standard(m,{0,1},4); +D2 = ops.D2; +u = linspace(0,1,m)'; +f = zeros(size(u)); + +nsample = 10000; +ts = zeros(nsample,1); + +for i = 1:nsample + tic; f = D2*u; t = toc; + ts(i) = t; +end +min(ts) \ No newline at end of file
--- a/src/SbpOperators/volumeops/laplace/laplace.jl Fri Jul 02 14:23:33 2021 +0200 +++ b/src/SbpOperators/volumeops/laplace/laplace.jl Wed Jan 19 13:15:45 2022 +0100 @@ -22,6 +22,7 @@ e::StaticDict{<:BoundaryIdentifier,<:TensorMapping} # Boundary restriction operators. d::StaticDict{<:BoundaryIdentifier,<:TensorMapping} # Normal derivative operators H_boundary::StaticDict{<:BoundaryIdentifier,<:TensorMapping} # Boundary quadrature operators # TODO: Boundary inner product? + order::Int end export Laplace @@ -48,7 +49,7 @@ d_pairs = ntuple(i -> ids[i] => normal_derivative(grid,d_closure_stencil,ids[i]),n_ids) Hᵧ_pairs = ntuple(i -> ids[i] => inner_product(boundary_grid(grid,ids[i]),H_closure_stencils),n_ids) - return Laplace(Δ, H, H⁻¹, StaticDict(e_pairs), StaticDict(d_pairs), StaticDict(Hᵧ_pairs)) + return Laplace(Δ, H, H⁻¹, StaticDict(e_pairs), StaticDict(d_pairs), StaticDict(Hᵧ_pairs), order) end # TODO: Consider pretty printing of the following form @@ -58,6 +59,14 @@ LazyTensors.domain_size(L::Laplace) = LazyTensors.domain_size(L.D) LazyTensors.apply(L::Laplace, v::AbstractArray, I...) = LazyTensors.apply(L.D,v,I...) +""" + closure_size(L::Lapalace) + +Returns the inner product operator associated with `L` + +""" +closure_size(L::Laplace) = closure_size(L.D) +export closure_size """ inner_product(L::Lapalace) @@ -124,6 +133,54 @@ boundary_quadrature(L::Laplace,ids::Vararg{BoundaryIdentifier,N}) where N = ntuple(i->L.H_boundary[ids[i]],N) export boundary_quadrature +abstract type BoundaryConditionType end +struct NeumannBC <: BoundaryConditionType end +struct DirichletBC <: BoundaryConditionType end +export NeumannBC + +boundary_condition(L, id, ::NeumannBC) = neumann_bc(L, id) +boundary_condition(L, id, ::DirichletBC) = dirichlet_bc(L, id) +export boundary_condition + +function neumann_bc(L::Laplace, id::BoundaryIdentifier) + H_inv = inverse_inner_product(L) + e = boundary_restriction(L,id) + d = normal_derivative(L,id) + H_b = boundary_quadrature(L,id) + tau = H_inv∘e'∘H_b + closure = tau∘d + # TODO: Return penalty once we have implemented scalar scaling of the operators. + return closure +end + +function dirichlet_bc(L::Laplace, id::BoundaryIdentifier) + error("Not implemented") + # H_inv = inverse_inner_product(L) + # e = boundary_restriction(L,id) + # d = normal_derivative(L,id) + # H_b = boundary_quadrature(L,id) + # gamma = borrowing_parameter(L) + # tuning = 1.2 + # S = ScalingOperator(tuning * -1.0/gamma) + # tau = H_inv∘(S∘e' + d')∘H_b + # closure = tau∘e + # penalty = ScalingOperator(-1)∘tau + # return (closure, penalty) +end + +# function borrowing_parameter(L) +# if L.order == 2 +# return 0.4 +# elseif L.order == 4 +# return 0.2508 +# elseif L.order == 6 +# return 0.1878 +# elseif L.order == 8 +# return 0.0015 +# elseif L.order == 10 +# return 0.0351 +# end +# end """ laplace(grid, inner_stencil, closure_stencils)