import pytest
import numpy as np
from ndelement.reference_cell import ReferenceCellType
from bempp.assembly.boundary import OperatorType, create_laplace_assembler
from bempp.function_space import function_space
from ndgrid.shapes import regular_sphere
from ndelement.ciarlet import create_family, Family, Continuity
@pytest.mark.parametrize(
"otype",
[
OperatorType.SingleLayer,
OperatorType.DoubleLayer,
OperatorType.AdjointDoubleLayer,
OperatorType.Hypersingular,
],
)
def test_create_assembler(otype):
a = create_laplace_assembler(otype)
assert a.quadrature_degree(ReferenceCellType.Triangle) != 3
a.set_quadrature_degree(ReferenceCellType.Triangle, 3)
assert a.quadrature_degree(ReferenceCellType.Triangle) == 3
with pytest.raises(ValueError):
a.set_quadrature_degree(ReferenceCellType.Interval, 3)
with pytest.raises(ValueError):
a.quadrature_degree(ReferenceCellType.Interval)
assert a.singular_quadrature_degree(ReferenceCellType.Triangle, ReferenceCellType.Triangle) != 3
a.set_singular_quadrature_degree(ReferenceCellType.Triangle, ReferenceCellType.Triangle, 3)
assert a.singular_quadrature_degree(ReferenceCellType.Triangle, ReferenceCellType.Triangle) == 3
with pytest.raises(ValueError):
a.set_singular_quadrature_degree(ReferenceCellType.Interval, ReferenceCellType.Interval, 3)
assert a.batch_size != 4
a.set_batch_size(4)
assert a.batch_size == 4
assert a.dtype == np.float64
@pytest.mark.parametrize(
"operator",
[
OperatorType.SingleLayer,
OperatorType.DoubleLayer,
OperatorType.AdjointDoubleLayer,
OperatorType.Hypersingular,
],
)
@pytest.mark.parametrize("test_degree", range(3))
@pytest.mark.parametrize("trial_degree", range(3))
def test_assemble_singular(operator, test_degree, trial_degree):
grid = regular_sphere(0)
test_element = create_family(Family.Lagrange, test_degree, Continuity.Discontinuous)
test_space = function_space(grid, test_element)
trial_element = create_family(Family.Lagrange, trial_degree, Continuity.Discontinuous)
trial_space = function_space(grid, trial_element)
a = create_laplace_assembler(operator)
mat = a.assemble_singular(trial_space, test_space)
dense = a.assemble_into_dense(trial_space, test_space)
for i, j, value in zip(mat.row, mat.col, mat.data):
assert np.isclose(dense[i, j], value)
@pytest.mark.parametrize(
"operator",
[
OperatorType.SingleLayer,
OperatorType.DoubleLayer,
OperatorType.AdjointDoubleLayer,
OperatorType.Hypersingular,
],
)
@pytest.mark.parametrize(
"test_degree, test_continuity",
[
(0, Continuity.Discontinuous),
(1, Continuity.Discontinuous),
(1, Continuity.Standard),
(2, Continuity.Standard),
],
)
@pytest.mark.parametrize(
"trial_degree, trial_continuity",
[
(0, Continuity.Discontinuous),
(1, Continuity.Discontinuous),
(1, Continuity.Standard),
(2, Continuity.Standard),
],
)
def test_assemble_singular_sparse_vs_dense(
operator, test_degree, test_continuity, trial_degree, trial_continuity
):
grid = regular_sphere(0)
test_element = create_family(Family.Lagrange, test_degree, test_continuity)
test_space = function_space(grid, test_element)
trial_element = create_family(Family.Lagrange, trial_degree, trial_continuity)
trial_space = function_space(grid, trial_element)
a = create_laplace_assembler(operator)
mat = a.assemble_singular(trial_space, test_space)
dense = a.assemble_singular_into_dense(trial_space, test_space)
assert np.allclose(dense, mat.todense())
@pytest.mark.parametrize(
"operator",
[
OperatorType.SingleLayer,
OperatorType.DoubleLayer,
OperatorType.AdjointDoubleLayer,
OperatorType.Hypersingular,
],
)
@pytest.mark.parametrize("test_degree", range(3))
@pytest.mark.parametrize("trial_degree", range(3))
def test_assemble_singular_correction(operator, test_degree, trial_degree):
grid = regular_sphere(0)
test_element = create_family(Family.Lagrange, test_degree, Continuity.Discontinuous)
test_space = function_space(grid, test_element)
trial_element = create_family(Family.Lagrange, trial_degree, Continuity.Discontinuous)
trial_space = function_space(grid, trial_element)
a = create_laplace_assembler(operator)
a.assemble_singular_correction(trial_space, test_space)
@pytest.mark.parametrize(
"operator",
[
OperatorType.SingleLayer,
OperatorType.DoubleLayer,
OperatorType.AdjointDoubleLayer,
OperatorType.Hypersingular,
],
)
@pytest.mark.parametrize(
"test_degree, test_continuity",
[
(0, Continuity.Discontinuous),
(1, Continuity.Discontinuous),
(1, Continuity.Standard),
(2, Continuity.Standard),
],
)
@pytest.mark.parametrize(
"trial_degree, trial_continuity",
[
(0, Continuity.Discontinuous),
(1, Continuity.Discontinuous),
(1, Continuity.Standard),
(2, Continuity.Standard),
],
)
def test_assemble_singular_and_nonsingular(
operator, test_degree, test_continuity, trial_degree, trial_continuity
):
grid = regular_sphere(0)
test_element = create_family(Family.Lagrange, test_degree, test_continuity)
test_space = function_space(grid, test_element)
trial_element = create_family(Family.Lagrange, trial_degree, trial_continuity)
trial_space = function_space(grid, trial_element)
a = create_laplace_assembler(operator)
mat = a.assemble_singular_into_dense(trial_space, test_space)
mat += a.assemble_nonsingular_into_dense(trial_space, test_space)
mat2 = a.assemble_into_dense(trial_space, test_space)
assert np.allclose(mat, mat2)
def test_single_layer_sphere0_dp0():
grid = regular_sphere(0)
element = create_family(Family.Lagrange, 0, Continuity.Discontinuous)
space = function_space(grid, element)
a = create_laplace_assembler(OperatorType.SingleLayer)
mat = a.assemble_into_dense(space, space)
from_cl = np.array(
[
[
0.1854538822982487,
0.08755414595678074,
0.05963897421514472,
0.08755414595678074,
0.08755414595678074,
0.05963897421514473,
0.04670742127454548,
0.05963897421514472,
],
[
0.08755414595678074,
0.1854538822982487,
0.08755414595678074,
0.05963897421514472,
0.05963897421514472,
0.08755414595678074,
0.05963897421514473,
0.04670742127454548,
],
[
0.05963897421514472,
0.08755414595678074,
0.1854538822982487,
0.08755414595678074,
0.04670742127454548,
0.05963897421514472,
0.08755414595678074,
0.05963897421514473,
],
[
0.08755414595678074,
0.05963897421514472,
0.08755414595678074,
0.1854538822982487,
0.05963897421514473,
0.04670742127454548,
0.05963897421514472,
0.08755414595678074,
],
[
0.08755414595678074,
0.05963897421514472,
0.046707421274545476,
0.05963897421514473,
0.1854538822982487,
0.08755414595678074,
0.05963897421514472,
0.08755414595678074,
],
[
0.05963897421514473,
0.08755414595678074,
0.05963897421514472,
0.046707421274545476,
0.08755414595678074,
0.1854538822982487,
0.08755414595678074,
0.05963897421514472,
],
[
0.046707421274545476,
0.05963897421514473,
0.08755414595678074,
0.05963897421514472,
0.05963897421514472,
0.08755414595678074,
0.1854538822982487,
0.08755414595678074,
],
[
0.05963897421514472,
0.046707421274545476,
0.05963897421514473,
0.08755414595678074,
0.08755414595678074,
0.05963897421514472,
0.08755414595678074,
0.1854538822982487,
],
]
)
assert np.allclose(mat, from_cl, rtol=1e-4)