Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
3b2d94a
WIP on local bdim
maltezfaria Jun 7, 2024
62dd139
begin working towards `local_bdim`
maltezfaria Jun 7, 2024
cb315c6
small changes
maltezfaria Jun 7, 2024
814bfd1
sketch of a function returning boundary
HDC427 Jun 10, 2024
4934db5
tweak `topological_neighbors` to work on `AbstractMesh`
maltezfaria Jun 11, 2024
78b74d9
implement `k` topological neighbors
maltezfaria Jun 11, 2024
942af12
sketch implement of local dim
HDC427 Jun 12, 2024
621fd0a
Merge branch 'local-bdim' of https://github.com/IntegralEquations/Int…
HDC427 Jun 12, 2024
6c88ace
Implemented k neighbor ldim
HDC427 Jun 13, 2024
e283394
function connected_components
HDC427 Jun 14, 2024
12a0bd6
function etype_to_near_elements and test
HDC427 Jun 19, 2024
328d717
etype_to_near_elements correct version
HDC427 Jun 20, 2024
56a6a59
(etype_to_)near_elements takes different types of elements into account
HDC427 Jun 24, 2024
e609f93
near_components
HDC427 Jun 24, 2024
d9ea012
Initial Local VDIM work.
tanderson92 Aug 17, 2024
e999092
Working Local VDIM
tanderson92 Aug 18, 2024
44695b6
Tweak boundary quadratures in local VDIM
tanderson92 Aug 18, 2024
aaa3514
lvdim: possible performance tweak
tanderson92 Aug 20, 2024
ef6ef7d
LVDIM: Use least-squares approximating polynomial.
tanderson92 Aug 23, 2024
d880f12
LVDIM: Expose differing quad/interp order ability
tanderson92 Aug 23, 2024
fd98810
LVDIM: cleanup
tanderson92 Aug 23, 2024
830ab77
lvdim: initial 3d work
tanderson92 Aug 27, 2024
275c27f
minor doc fixes
maltezfaria Aug 28, 2024
756ec1c
cleanup dependencies
maltezfaria Aug 28, 2024
8522621
Merge branch 'main' into local-vdim
maltezfaria Aug 28, 2024
2006455
perf improvement
maltezfaria Aug 28, 2024
117b52d
lvdim: Initial work towards shifting/scaling every local computation …
tanderson92 Aug 30, 2024
cdb5018
Fix breakage
tanderson92 Aug 30, 2024
8877785
lvdim: perf improvement for `boundarynd()`
tanderson92 Aug 31, 2024
fd49860
lvdim: perf improvements
tanderson92 Aug 31, 2024
9ea2b6e
lvdim: various performance improvements
tanderson92 Aug 31, 2024
58b8f85
lvdim: fix 3D regression from perf tuning
tanderson92 Sep 1, 2024
21727be
lvdim: fix type instability for 3D
tanderson92 Sep 1, 2024
f5df86d
lvdim: only use VR if we are doing volume stuff, not boundary quadrature
tanderson92 Sep 1, 2024
8471cdb
lvdim Polynomial evaluator test
tanderson92 Sep 2, 2024
78d6b04
cleanup
tanderson92 Sep 2, 2024
ca342a3
Use `Fastpolynomials.jl` extension in `ElementaryPDESolutions.jl` for…
tanderson92 Sep 6, 2024
1657ff2
tweak problematic bits to comprehensions
tanderson92 Sep 6, 2024
801e2c5
perf tweaks
tanderson92 Sep 8, 2024
49fb913
Fix blooper
tanderson92 Sep 8, 2024
7e99158
`Bessels.jl` provides faster routines than `SpecialFunctions.jl`
tanderson92 Sep 10, 2024
354d71a
lvdim: perf tweaks
tanderson92 Sep 11, 2024
2dde674
Fix bug in triangle center/scale calculation
tanderson92 Sep 21, 2024
9a2eb15
lvdim: temporary switch to scaling polynomials
tanderson92 Sep 21, 2024
7772ca1
add more methods to work on `EntityKey`
maltezfaria Oct 17, 2024
0090520
Use lightweight Quadrature objects (no mesh) for local vdim
tanderson92 Oct 20, 2024
8cda596
Merge branch 'main' into local-vdim
tanderson92 Oct 20, 2024
e45bc1f
Remove ldim code from local-vdim branch
tanderson92 Oct 20, 2024
2c993a8
format
tanderson92 Oct 20, 2024
1d65331
Update lvdim for changes in main
tanderson92 Oct 21, 2024
4ec3450
lvdim: [WIP] Stabilize Helmholtz.
tanderson92 Oct 21, 2024
4028967
lvdim: Refactor to prepare for low freq. stabilization
tanderson92 Oct 22, 2024
2c5026e
lvdim: WIP low-freq stabilization
tanderson92 Nov 25, 2024
d5985f5
simplify stab-lvdim
tanderson92 Jan 14, 2025
a703b05
some more scaled quadrature tests
tanderson92 Jan 22, 2025
fd66abe
tmp
tanderson92 Mar 7, 2025
1dfe7c4
Merge branch 'main' into local-vdim
tanderson92 Jul 11, 2025
c114e7c
lvdim: fix merge from main
tanderson92 Jul 11, 2025
fdf0410
Merge branch 'main' into local-vdim
tanderson92 Jul 13, 2025
345c1d7
lvdim: fix lvdim after merge
tanderson92 Jul 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 43 additions & 2 deletions ext/IntiMakieExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@
end

function Meshes.viz(els::AbstractVector{<:Inti.ReferenceInterpolant}, args...; kwargs...)
return viz([to_meshes(el) for el in els])
return viz([to_meshes(el) for el in els], args...; kwargs...)
end
function Meshes.viz!(els::AbstractVector{<:Inti.ReferenceInterpolant}, args...; kwargs...)
return viz!([to_meshes(el) for el in els])
return viz!([to_meshes(el) for el in els], args...; kwargs...)

Check warning on line 82 in ext/IntiMakieExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/IntiMakieExt.jl#L82

Added line #L82 was not covered by tests
end

function Meshes.viz(msh::Inti.AbstractMesh, args...; kwargs...)
Expand All @@ -89,4 +89,45 @@
return viz!(to_meshes(msh), args...; kwargs...)
end

function Inti.viz_elements(els, msh)
E = first(Inti.element_types(msh))
Els = [Inti.elements(msh, E)[i] for (E, i) in els]
fig, _, _ = viz(Els)
viz!(msh; color = 0, showsegments = true, alpha = 0.3)
return display(fig)

Check warning on line 97 in ext/IntiMakieExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/IntiMakieExt.jl#L92-L97

Added lines #L92 - L97 were not covered by tests
end

function Inti.viz_elements_bords(Ei, els, ell, bords, msh; quad = nothing)
E = first(Inti.element_types(msh))

Check warning on line 101 in ext/IntiMakieExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/IntiMakieExt.jl#L100-L101

Added lines #L100 - L101 were not covered by tests
#ell = collect(Ei[(E, 1)])[1]
el = Inti.elements(msh, ell[1])[ell[2]]
fig, _, _ = viz(msh; color = 0, showsegments = true, alpha = 0.3)
viz!(el; color = 0, showsegments = true, alpha = 0.5)
for (E, i) in els
el = Inti.elements(msh, E)[i]
viz!(el; showsegments = true, alpha = 0.7)
end
viz!(bords; color = 4, showsegments = false, segmentsize = 5, segmentcolor = 4)

Check warning on line 110 in ext/IntiMakieExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/IntiMakieExt.jl#L103-L110

Added lines #L103 - L110 were not covered by tests
# if !isnothing(quad)
# xs = [qnode.coords[1] for qnode in quad.qnodes]
# ys = [qnode.coords[2] for qnode in quad.qnodes]
# zs = [qnode.coords[3] for qnode in quad.qnodes]
# nx = [Inti.normal(qnode)[1] for qnode in quad.qnodes]
# ny = [Inti.normal(qnode)[2] for qnode in quad.qnodes]
# nz = [Inti.normal(qnode)[3] for qnode in quad.qnodes]
# Mke.arrows!(
# xs,
# ys,
# zs,
# nx,
# ny,
# nz;
# lengthscale = 0.05,
# linewidth = 0.01,
# arrowsize = 0.01,
# )
# end
return display(fig)

Check warning on line 130 in ext/IntiMakieExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/IntiMakieExt.jl#L130

Added line #L130 was not covered by tests
end

end # module
19 changes: 19 additions & 0 deletions src/api.jl
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,25 @@
correction.maxdist,
interpolation_order,
)
elseif correction.method == :ldim
loc = target === source ? :inside : correction.target_location
μ = _green_multiplier(loc)
green_multiplier = fill(μ, length(target))
shift = Val(true)
δV = local_vdim_correction(

Check warning on line 347 in src/api.jl

View check run for this annotation

Codecov / codecov/patch

src/api.jl#L342-L347

Added lines #L342 - L347 were not covered by tests
op,
eltype(V),
target,
source,
correction.mesh,
correction.bdry_nodes;
green_multiplier,
correction.maxdist,
correction.interpolation_order,
correction.quadrature_order,
correction.meshsize,
shift,
)
else
error("Unknown correction method. Available options: $CORRECTION_METHODS")
end
Expand Down
76 changes: 68 additions & 8 deletions src/mesh.jl
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@
function elements end

"""
element_types(msh::AbstractMesh)
elements(msh::AbstractMesh,E::DataType)

Return the element types present in the `msh`.
Return an iterator for all elements of type `E` on a mesh `msh`.
"""
function element_types end
elements(msh::AbstractMesh, E::DataType) = ElementIterator{E,typeof(msh)}(msh)

Check warning on line 58 in src/mesh.jl

View check run for this annotation

Codecov / codecov/patch

src/mesh.jl#L58

Added line #L58 was not covered by tests

"""
struct Mesh{N,T} <: AbstractMesh{N,T}
Expand Down Expand Up @@ -607,6 +607,69 @@
return map(t -> g2l[t], view(msh.parent.etype2mat[E], :, eltags))
end

"""
Domain(f::Function, msh::AbstractMesh)

Call `Domain(f, ents)` on `ents = entities(msh).`
"""
Domain(f::Function, msh::AbstractMesh) = Domain(f, entities(msh))

"""
topological_neighbors(msh::LagrangeMesh, k=1)

Return the `k` neighbors of each element in `msh`. The one-neighbors are the
elements that share a common vertex with the element, `k` neighbors are the
one-neighbors of the `k-1` neighbors.

This function returns a dictionary where the key is an `(Eᵢ,i)` tuple denoting
the element `i` of type `E` in the mesh, and the value is a set of tuples
`(Eⱼ,j)` where `Eⱼ` is the type of the element and `j` its index.
"""
function topological_neighbors(msh::AbstractMesh, k = 1)

Check warning on line 628 in src/mesh.jl

View check run for this annotation

Codecov / codecov/patch

src/mesh.jl#L628

Added line #L628 was not covered by tests
# dictionary mapping a node index to all elements containing it. Note
# that the elements are stored as a tuple (type, index)
T = Tuple{DataType,Int}
node2els = Dict{Int,Vector{T}}()
for E in element_types(msh)
mat = connectivity(msh, E)::Matrix{Int} # connectivity matrix
np, Nel = size(mat)
for n in 1:Nel
for i in 1:np
idx = mat[i, n]
els = get!(node2els, idx, Vector{T}())
push!(els, (E, n))
end
end
end

Check warning on line 643 in src/mesh.jl

View check run for this annotation

Codecov / codecov/patch

src/mesh.jl#L631-L643

Added lines #L631 - L643 were not covered by tests
# now revert the map to get the neighbors
one_neighbors = Dict{T,Set{T}}()
for (_, els) in node2els
for el in els
nei = get!(one_neighbors, el, Set{T}())
for el′ in els
push!(nei, el′)
end
end
end

Check warning on line 653 in src/mesh.jl

View check run for this annotation

Codecov / codecov/patch

src/mesh.jl#L645-L653

Added lines #L645 - L653 were not covered by tests
# Recursively compute the neighbors from the one-neighbors
if k > 1
k_neighbors = deepcopy(one_neighbors)

Check warning on line 656 in src/mesh.jl

View check run for this annotation

Codecov / codecov/patch

src/mesh.jl#L655-L656

Added lines #L655 - L656 were not covered by tests
else
k_neighbors = one_neighbors

Check warning on line 658 in src/mesh.jl

View check run for this annotation

Codecov / codecov/patch

src/mesh.jl#L658

Added line #L658 was not covered by tests
end
while k > 1

Check warning on line 660 in src/mesh.jl

View check run for this annotation

Codecov / codecov/patch

src/mesh.jl#L660

Added line #L660 was not covered by tests
# update neighborhood of each element
for el in keys(one_neighbors)
knn = k_neighbors[el]
for el′ in copy(knn)
union!(knn, one_neighbors[el′])
end
end
k -= 1
end
return k_neighbors

Check warning on line 670 in src/mesh.jl

View check run for this annotation

Codecov / codecov/patch

src/mesh.jl#L662-L670

Added lines #L662 - L670 were not covered by tests
end

"""
near_interaction_list(X,Y::AbstractMesh; tol)

Expand Down Expand Up @@ -642,12 +705,9 @@
return inrange(balltree, centers, tol)
end

"""
Domain(f::Function, msh::AbstractMesh)
function viz_elements(args...; kwargs...) end

Check warning on line 708 in src/mesh.jl

View check run for this annotation

Codecov / codecov/patch

src/mesh.jl#L708

Added line #L708 was not covered by tests

Call `Domain(f, ents)` on `ents = entities(msh).`
"""
Domain(f::Function, msh::AbstractMesh) = Domain(f, entities(msh))
function viz_elements_bords(args...; kwargs...) end

Check warning on line 710 in src/mesh.jl

View check run for this annotation

Codecov / codecov/patch

src/mesh.jl#L710

Added line #L710 was not covered by tests

function node2etags(msh)
# dictionary mapping a node index to all elements containing it. Note
Expand Down
19 changes: 11 additions & 8 deletions src/nystrom.jl
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ I[u](x) = \\int_{\\Gamma\\_s} K(x,y)u(y) ds_y, x \\in \\Gamma_{t}
```
where ``\\Gamma_s`` and ``\\Gamma_t`` are the source and target domains, respectively.
"""
struct IntegralOperator{V,K,T,S<:Quadrature} <: AbstractMatrix{V}
struct IntegralOperator{V,K,T,S} <: AbstractMatrix{V}
kernel::K
# since the target can be as simple as a vector of points, leave it untyped
target::T
Expand All @@ -76,15 +76,18 @@ kernel(iop::IntegralOperator) = iop.kernel
target(iop::IntegralOperator) = iop.target
source(iop::IntegralOperator) = iop.source

function IntegralOperator(k, X, Y::Quadrature = X)
function IntegralOperator(k, X, Y = X)
# check that all entities in the quadrature are of the same dimension
if !allequal(geometric_dimension(ent) for ent in entities(Y))
msg = "entities in the target quadrature have different geometric dimensions"
throw(ArgumentError(msg))
if Y isa Quadrature && !isnothing(Y.mesh)
if !allequal(geometric_dimension(ent) for ent in entities(Y))
msg = "entities in the target quadrature have different geometric dimensions"
throw(ArgumentError(msg))
end
end
T = return_type(k, eltype(X), eltype(Y))
msg = """IntegralOperator of nonbits being created: $T"""
isbitstype(T) || (@warn msg)
# FIXME This cripples performance for local VDIM
#msg = """IntegralOperator of nonbits being created: $T"""
#isbitstype(T) || (@warn msg)
return IntegralOperator{T,typeof(k),typeof(X),typeof(Y)}(k, X, Y)
end

Expand Down Expand Up @@ -117,7 +120,7 @@ end
@noinline function _assemble_matrix!(out, K, X, Y::Quadrature, threads)
@usethreads threads for j in 1:length(Y)
for i in 1:length(X)
out[i, j] = K(X[i], Y[j]) * weight(Y[j])
@inbounds out[i, j] = K(X[i], Y[j]) * weight(Y[j])
end
end
return out
Expand Down
53 changes: 48 additions & 5 deletions src/quadrature.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,16 @@
return print(io, "-- weight: $(q.weight)")
end

const Maybe{T} = Union{T,Nothing}

"""
struct Quadrature{N,T} <: AbstractVector{QuadratureNode{N,T}}

A collection of [`QuadratureNode`](@ref)s used to integrate over an
[`AbstractMesh`](@ref).
"""
struct Quadrature{N,T} <: AbstractVector{QuadratureNode{N,T}}
mesh::AbstractMesh{N,T}
mesh::Maybe{AbstractMesh{N,T}}
etype2qrule::Dict{DataType,ReferenceQuadrature}
qnodes::Vector{QuadratureNode{N,T}}
etype2qtags::Dict{DataType,Matrix{Int}}
Expand All @@ -75,7 +77,10 @@
Base.setindex!(quad::Quadrature, q, i) = (quad.qnodes[i] = q)

qnodes(quad::Quadrature) = quad.qnodes
mesh(quad::Quadrature) = quad.mesh
function mesh(quad::Quadrature)
isnothing(quad.mesh) && error("The Quadrature has no mesh!")
return quad.mesh
end
etype2qtags(quad::Quadrature, E) = quad.etype2qtags[E]

quadrature_rule(quad::Quadrature, E) = quad.etype2qrule[E]
Expand Down Expand Up @@ -119,6 +124,40 @@
return quad
end

# Quadrature constructor for list of volume elements for local vdim
function Quadrature(

Check warning on line 128 in src/quadrature.jl

View check run for this annotation

Codecov / codecov/patch

src/quadrature.jl#L128

Added line #L128 was not covered by tests
::Type{T},
elementlist::AbstractVector{E},
etype2qrule::Dict{DataType,Q},
qrule::Q;
center::SVector{N,Float64} = zero(SVector{N,Float64}),
scale::Float64 = 1.0,
) where {N,T,E,Q}
# initialize mesh with empty fields
quad = Quadrature{N,T}(

Check warning on line 137 in src/quadrature.jl

View check run for this annotation

Codecov / codecov/patch

src/quadrature.jl#L137

Added line #L137 was not covered by tests
nothing,
etype2qrule,
QuadratureNode{N,T}[],
Dict{DataType,Matrix{Int}}(),
)
ori = ones(Int64, length(elementlist))

Check warning on line 143 in src/quadrature.jl

View check run for this annotation

Codecov / codecov/patch

src/quadrature.jl#L143

Added line #L143 was not covered by tests
# loop element types and generate quadrature for each
_build_quadrature!(quad, elementlist, ori, qrule; center, scale)

Check warning on line 145 in src/quadrature.jl

View check run for this annotation

Codecov / codecov/patch

src/quadrature.jl#L145

Added line #L145 was not covered by tests

# check for entities with negative orientation and flip normal vectors if
# present
#for ent in entities(msh)
# if (sign(tag(ent)) < 0) && (N - geometric_dimension(ent) == 1)
# @debug "Flipping normals of $ent"
# tags = dom2qtags(quad, Domain(ent))
# for i in tags
# quad[i] = flip_normal(quad[i])
# end
# end
#end
return quad

Check warning on line 158 in src/quadrature.jl

View check run for this annotation

Codecov / codecov/patch

src/quadrature.jl#L158

Added line #L158 was not covered by tests
end

function Quadrature(msh::AbstractMesh{N,T}, qrule::ReferenceQuadrature) where {N,T}
etype2qrule = Dict(E => qrule for E in element_types(msh))
return Quadrature(msh, etype2qrule)
Expand All @@ -134,14 +173,18 @@
quad::Quadrature{N,T},
els::AbstractVector{E},
orientation::Vector{Int},
qrule::ReferenceQuadrature,
) where {N,T,E}
qrule::ReferenceQuadrature;
center::SVector{N,Float64} = zero(SVector{N,Float64}),
scale::Float64 = 1.0,
) where {E,N,T}
x̂, ŵ = qrule() # nodes and weights on reference element
x̂ = map(x̂ -> T.(x̂), qcoords(qrule))
ŵ = map(ŵ -> T.(ŵ), qweights(qrule))
num_nodes = length(ŵ)
M = geometric_dimension(domain(E))
codim = N - M
istart = length(quad.qnodes) + 1
sizehint!(quad.qnodes, length(els) * length(x̂))
@assert length(els) == length(orientation)
for (s, el) in zip(orientation, els)
# and all qnodes for that element
Expand All @@ -151,7 +194,7 @@
μ = _integration_measure(jac)
w = μ * ŵi
ν = codim == 1 ? T.(s * _normal(jac)) : nothing
qnode = QuadratureNode(T.(x), T.(w), ν)
qnode = QuadratureNode(T.((x - center) / scale), T.(w / scale^M), ν)
push!(quad.qnodes, qnode)
end
end
Expand Down
25 changes: 17 additions & 8 deletions src/reference_integration.jl
Original file line number Diff line number Diff line change
Expand Up @@ -170,16 +170,19 @@
domain == :segment && (domain = ReferenceLine())
domain == :triangle && (domain = ReferenceTriangle())
domain == :tetrehedron && (domain = ReferenceTetrahedron())
msg = "quadrature of order $order not available for $domain"
if domain isa ReferenceLine
# TODO: support Gauss-Legendre quadratures of arbitrary order
order == 13 || error(msg)
order == 13 || error("quadrature of order $order not available for $domain")

Check warning on line 175 in src/reference_integration.jl

View check run for this annotation

Codecov / codecov/patch

src/reference_integration.jl#L175

Added line #L175 was not covered by tests
n = 7
elseif domain isa ReferenceTriangle
haskey(TRIANGLE_GAUSS_ORDER_TO_NPTS, order) || error(msg)
if !haskey(TRIANGLE_GAUSS_ORDER_TO_NPTS, order)
error("quadrature of order $order not available for $domain")

Check warning on line 179 in src/reference_integration.jl

View check run for this annotation

Codecov / codecov/patch

src/reference_integration.jl#L179

Added line #L179 was not covered by tests
end
n = TRIANGLE_GAUSS_ORDER_TO_NPTS[order]
elseif domain isa ReferenceTetrahedron
haskey(TETRAHEDRON_GAUSS_ORDER_TO_NPTS, order) || error(msg)
if !haskey(TETRAHEDRON_GAUSS_ORDER_TO_NPTS, order)
error("quadrature of order $order not available for $domain")

Check warning on line 184 in src/reference_integration.jl

View check run for this annotation

Codecov / codecov/patch

src/reference_integration.jl#L184

Added line #L184 was not covered by tests
end
n = TETRAHEDRON_GAUSS_ORDER_TO_NPTS[order]
else
error(
Expand Down Expand Up @@ -272,12 +275,18 @@
domain == :triangle && (domain = ReferenceTriangle())
domain == :tetrahedron && (domain = ReferenceTetrahedron())
if domain isa ReferenceTriangle
msg = "VioreanuRokhlin quadrature of order $order not available for ReferenceTriangle"
haskey(TRIANGLE_VR_ORDER_TO_NPTS, order) || error(msg)
if !haskey(TRIANGLE_VR_ORDER_TO_NPTS, order)
error(

Check warning on line 279 in src/reference_integration.jl

View check run for this annotation

Codecov / codecov/patch

src/reference_integration.jl#L279

Added line #L279 was not covered by tests
"VioreanuRokhlin quadrature of order $order not available for ReferenceTriangle",
)
end
n = TRIANGLE_VR_ORDER_TO_NPTS[order]
elseif domain isa ReferenceTetrahedron
msg = "VioreanuRokhlin quadrature of order $order not available for ReferenceTetrahedron"
haskey(TETRAHEDRON_VR_ORDER_TO_NPTS, order) || error(msg)
if !haskey(TETRAHEDRON_VR_ORDER_TO_NPTS, order)
error(

Check warning on line 286 in src/reference_integration.jl

View check run for this annotation

Codecov / codecov/patch

src/reference_integration.jl#L286

Added line #L286 was not covered by tests
"VioreanuRokhlin quadrature of order $order not available for ReferenceTetrahedron",
)
end
n = TETRAHEDRON_VR_ORDER_TO_NPTS[order]
else
error(
Expand Down
Loading
Loading