Skip to content

Commit 22aa40e

Browse files
committed
Added metric, metric_shape, matrix_element_metric
1 parent 511fbc6 commit 22aa40e

File tree

4 files changed

+49
-2
lines changed

4 files changed

+49
-2
lines changed

src/CompactBases.jl

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,47 @@ is simply [`locs`](@ref), i.e. the location of the quadrature nodes.
6969
"""
7070
centers(B::BasisOrRestricted) = locs(B)
7171

72+
"""
73+
metric(B)
74+
75+
Returns the metric or mass matrix of the basis `B`, equivalent to
76+
`S=B'B`.
77+
"""
78+
metric(B::BasisOrRestricted) = B'B
79+
80+
"""
81+
metric_shape(B)
82+
83+
Returns the shape of the metric or mass matrix of the basis `B`,
84+
i.e. `Diagonal`, `BandedMatrix`, etc.
85+
"""
86+
metric_shape(B::BasisOrRestricted) = typeof(metric(B))
87+
88+
function matrix_element_metric(B::BasisOrRestricted)
89+
# For non-orthogonal bases, we need to apply the metric inverse,
90+
# after computing the action of a matrix representation of a
91+
# linear operator on a ket. However, when computing the inner
92+
# product with the bra afterwards, we again use the metric. Here,
93+
# we short-circuit this by combining them into them identity
94+
# operator I, if the operator metric equals the metric. For
95+
# orthogonal bases, with the integration weights not built into the
96+
# coefficients, and an identity matrix operator metric, we /do/
97+
# need to use the metric for the inner product.
98+
S = metric(B)
99+
oS = operator_metric(B)
100+
oS == S ? I : (oS \ S)
101+
end
102+
72103
export AbstractFiniteDifferences,
73104
FiniteDifferences, StaggeredFiniteDifferences, ImplicitFiniteDifferences,
74105
Derivative, dot, QuasiDiagonal, Inclusion, .., distribution,
75106
FEDVR, Derivative, @elem, dot,
76107
BSpline,
77108
ArbitraryKnotSet, LinearKnotSet, ExpKnotSet,
78109
order, numintervals, numfunctions, nonempty_intervals,
79-
centers, vandermonde, FunctionProduct, Density,
110+
centers, vandermonde,
111+
metric, metric_shape, matrix_element_metric,
112+
FunctionProduct, Density,
80113
LinearOperator, DiagonalOperator, ShiftAndInvert
81114

82115
end # module

src/bsplines.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ end
288288
end
289289
end
290290

291+
metric(B::BSpline) = B.S
292+
291293
# * Diagonal operators
292294

293295
@materialize function *(Ac::AdjointBSplineOrRestricted,

src/fedvr.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ inverse_weight(B::FEDVR, j) = B.n[j]
201201
inverse_weights(B::FEDVR) = B.n
202202

203203
vandermonde(B::FEDVR) = BandedMatrix(0 => B.n)
204+
metric(B::FEDVROrRestricted{T}) where T = Diagonal(Ones{T}(size(B,2)))
205+
metric_shape(B::FEDVROrRestricted) = Diagonal
204206

205207
# * Basis functions
206208

test/inner_products.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@
44
N = ceil(Int, rmax/ρ)
55
k = 7
66

7-
@testset "$(grid_type)" for grid_type = [:fd, :sfd, :implicit_fd, :fedvr, :bsplines]
7+
@testset "$(grid_type)" for (grid_type,MS,MatElMetric) = [
8+
(:fd, Diagonal, ρ*I),
9+
(:sfd, Diagonal, ρ*I),
10+
(:implicit_fd, Diagonal, ρ*I),
11+
(:fedvr, Diagonal, I),
12+
(:bsplines, BandedMatrix, I)
13+
]
814
R = if grid_type == :fd
915
FiniteDifferences(N, ρ)
1016
elseif grid_type == :sfd
@@ -51,6 +57,10 @@
5157
@test isapprox(f'g, 0.0, atol=1e-14)
5258
@test g'g isa Real
5359
@test isapprox(g'g, 0.5, rtol=1e-3)
60+
61+
@test metric(R) == S
62+
@test metric_shape(R) <: MS
63+
@test matrix_element_metric(R) == MatElMetric
5464
end
5565

5666
@warn "Need to test inner products with restricted bases as well"

0 commit comments

Comments
 (0)