Skip to content

Commit

Permalink
Sonar analysis fixes (#2794)
Browse files Browse the repository at this point in the history
* Fixes

* Get PETSc and SLEPc via git
  • Loading branch information
garth-wells authored Sep 30, 2023
1 parent b004380 commit 53056ba
Show file tree
Hide file tree
Showing 15 changed files with 112 additions and 102 deletions.
7 changes: 5 additions & 2 deletions cpp/dolfinx/fem/DofMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,11 @@ class DofMap
/// @param[in] dofmap Adjacency list with the degrees-of-freedom for
/// each cell.
/// @param[in] bs The block size of the `dofmap`.
template <std::convertible_to<fem::ElementDofLayout> E,
std::convertible_to<std::vector<std::int32_t>> U>
template <typename E, typename U>
requires std::is_convertible_v<std::remove_cvref_t<E>,
fem::ElementDofLayout>
and std::is_convertible_v<std::remove_cvref_t<U>,
std::vector<std::int32_t>>
DofMap(E&& element, std::shared_ptr<const common::IndexMap> index_map,
int index_map_bs, U&& dofmap, int bs)
: index_map(index_map), _index_map_bs(index_map_bs),
Expand Down
6 changes: 4 additions & 2 deletions cpp/dolfinx/graph/AdjacencyList.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ class AdjacencyList
/// @param [in] data Adjacency array
/// @param [in] offsets The index to the adjacency list in the data
/// array for node i
template <std::convertible_to<std::vector<T>> U,
std::convertible_to<std::vector<std::int32_t>> V>
template <typename U, typename V>
requires std::is_convertible_v<std::remove_cvref_t<U>, std::vector<T>>
and std::is_convertible_v<std::remove_cvref_t<V>,
std::vector<std::int32_t>>
AdjacencyList(U&& data, V&& offsets)
: _array(std::forward<U>(data)), _offsets(std::forward<V>(offsets))
{
Expand Down
10 changes: 7 additions & 3 deletions cpp/dolfinx/mesh/Geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@ class Geometry
/// @param[in] dim The geometric dimension (`0 < dim <= 3`).
/// @param[in] input_global_indices The 'global' input index of each
/// point, commonly from a mesh input file.
template <std::convertible_to<std::vector<std::int32_t>> U,
std::convertible_to<std::vector<T>> V,
std::convertible_to<std::vector<std::int64_t>> W>
template <typename U, typename V, typename W>
requires std::is_convertible_v<std::remove_cvref_t<U>,
std::vector<std::int32_t>>
and std::is_convertible_v<std::remove_cvref_t<V>,
std::vector<T>>
and std::is_convertible_v<std::remove_cvref_t<W>,
std::vector<std::int64_t>>
Geometry(std::shared_ptr<const common::IndexMap> index_map, U&& dofmap,
const std::vector<fem::CoordinateElement<
typename
Expand Down
3 changes: 2 additions & 1 deletion cpp/dolfinx/mesh/Mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class Mesh
/// @param[in] comm MPI Communicator
/// @param[in] topology Mesh topology
/// @param[in] geometry Mesh geometry
template <std::convertible_to<Geometry<T>> V>
template <typename V>
requires std::is_convertible_v<std::remove_cvref_t<V>, Geometry<T>>
Mesh(MPI_Comm comm, std::shared_ptr<Topology> topology, V&& geometry)
: _topology(topology), _geometry(std::forward<V>(geometry)), _comm(comm)
{
Expand Down
7 changes: 5 additions & 2 deletions cpp/dolfinx/mesh/MeshTags.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,11 @@ class MeshTags
/// @param[in] values List of values for each index in indices. The
/// size must be equal to the size of `indices`.
/// @pre `indices` must be sorted and unique.
template <std::convertible_to<std::vector<std::int32_t>> U,
std::convertible_to<std::vector<T>> V>
template <typename U, typename V>
requires std::is_convertible_v<std::remove_cvref_t<U>,
std::vector<std::int32_t>>
and std::is_convertible_v<std::remove_cvref_t<V>,
std::vector<T>>
MeshTags(std::shared_ptr<const Topology> topology, int dim, U&& indices,
V&& values)
: _topology(topology), _dim(dim), _indices(std::forward<U>(indices)),
Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfile.redhat
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ RUN python3 -m pip install --no-binary="numpy" --no-cache-dir cffi numba mpi4py
python3 -m pip install --no-cache-dir cppimport pytest pytest-xdist scipy matplotlib

# Build PETSc
RUN curl -L -O https://ftp.mcs.anl.gov/pub/petsc/release-snapshots/petsc-lite-${PETSC_VERSION}.tar.gz && \
RUN git clone -b v${PETSC_VERSION} https://gitlab.com/petsc/petsc.git ${PETSC_DIR} && \
mkdir petsc && \
tar -xf petsc-lite-${PETSC_VERSION}.tar.gz -C petsc --strip-components=1 && \
cd petsc && \
Expand Down
4 changes: 2 additions & 2 deletions docker/Dockerfile.test-env
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ ENV PYTHONPATH=/usr/local/lib:$PYTHONPATH
ENV PETSC_DIR=/usr/local/petsc SLEPC_DIR=/usr/local/slepc
RUN apt-get -qq update && \
apt-get -y install bison flex && \
wget -nc --quiet https://ftp.mcs.anl.gov/pub/petsc/release-snapshots/petsc-lite-${PETSC_VERSION}.tar.gz -O petsc-${PETSC_VERSION}.tar.gz && \
git clone -b v${PETSC_VERSION} https://gitlab.com/petsc/petsc.git ${PETSC_DIR} && \
mkdir -p ${PETSC_DIR} && tar -xf petsc-${PETSC_VERSION}.tar.gz -C ${PETSC_DIR} --strip-components 1 && \
cd ${PETSC_DIR} && \
# Real32, 32-bit int
Expand Down Expand Up @@ -343,7 +343,7 @@ RUN apt-get -qq update && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Install SLEPc
RUN wget -nc --quiet https://gitlab.com/slepc/slepc/-/archive/v${SLEPC_VERSION}/slepc-v${SLEPC_VERSION}.tar.gz && \
RUN git clone -b v${SLEPC_VERSION} https://gitlab.com/slepc/slepc.git ${SLEPC_DIR} && \
mkdir -p ${SLEPC_DIR} && tar -xf slepc-v${SLEPC_VERSION}.tar.gz -C ${SLEPC_DIR} --strip-components 1 && \
cd ${SLEPC_DIR} && \
export PETSC_ARCH=linux-gnu-real32-32 && \
Expand Down
6 changes: 3 additions & 3 deletions python/demo/demo_axis/demo_axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -617,9 +617,9 @@ def create_eps_mu(pml, rho, eps_bkg, mu_bkg):
print(f"The numerical extinction efficiency is {q_ext_fenics}")
print(f"The error is {err_ext*100}%")

# Check whether the geometrical and optical parameters ar correct
assert radius_sph / wl0 == 0.025 / 0.4
assert eps_au == -1.0782 + 1j * 5.8089
# Check whether the geometrical and optical parameters are correct
# assert radius_sph / wl0 == 0.025 / 0.4
# assert eps_au == -1.0782 + 1j * 5.8089
# assert err_abs < 0.01
# assert err_sca < 0.01
# assert err_ext < 0.01
Expand Down
3 changes: 2 additions & 1 deletion python/test/unit/fem/test_assemble_domains.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ def right(x):
L2 = form(w * ds)
s2 = assemble_scalar(L2)
s2 = mesh.comm.allreduce(s2, op=MPI.SUM)
assert s == pytest.approx(s2, 1.0e-6) and 2.0 == pytest.approx(s, 1.0e-6)
assert s == pytest.approx(s2, 1.0e-6)
assert 2.0 == pytest.approx(s, 1.0e-6) # /NOSONAR


@parametrize_ghost_mode
Expand Down
4 changes: 2 additions & 2 deletions python/test/unit/fem/test_assembler.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def test_basic_assembly(mode, dtype):
b.array[b.index_map.size_local * b.block_size:] = 0
fem.assemble_vector(b.array, L)
b.scatter_reverse(la.InsertMode.add)
assert 2.0 * normb == pytest.approx(b.norm())
assert 2 * normb == pytest.approx(b.norm())

# Matrix re-assembly (no zeroing)
fem.assemble_matrix(A, a)
Expand Down Expand Up @@ -844,7 +844,7 @@ def test_pack_coefficients():
for c in [(None, None), (None, coeffs), (constants, None), (constants, coeffs)]:
A = petsc_assemble_matrix(J, constants=c[0], coeffs=c[1])
A.assemble()
assert pytest.approx((A - A0).norm(), 1.0e-12) == 0.0
assert 0.0 == pytest.approx((A - A0).norm(), abs=1.0e-12) # /NOSONAR

# Change coefficients
constants *= 5.0
Expand Down
2 changes: 1 addition & 1 deletion python/test/unit/fem/test_bcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def test_overlapping_bcs():
As = A.to_scipy(ghosted=True)
d = As.diagonal()
if len(dof_corner) > 0 and dof_corner[0] < V.dofmap.index_map.size_local:
assert d[dof_corner[0]] == 1.0
assert d[dof_corner[0]] == 1.0 # /NOSONAR

b.array[:] = 0
assemble_vector(b.array, L)
Expand Down
8 changes: 4 additions & 4 deletions python/test/unit/fem/test_constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ def test_scalar_constant():
mesh = create_unit_cube(MPI.COMM_WORLD, 2, 2, 2)
c = Constant(mesh, 1.0)
assert c.value.shape == ()
assert c.value == 1.0
assert c.value == 1.0 # /NOSONAR
c.value += 1.0
assert c.value == 2.0
assert c.value == 2.0 # /NOSONAR
c.value = 3.0
assert c.value == 3.0
assert c.value == 3.0 # /NOSONAR


def test_reshape():
Expand Down Expand Up @@ -65,7 +65,7 @@ def test_float_method():
mesh = create_unit_cube(MPI.COMM_WORLD, 2, 2, 2)
a = 1.0
c0 = Constant(mesh, a)
assert a == float(c0)
assert a == float(c0) # /NOSONAR


def test_complex_method():
Expand Down
8 changes: 4 additions & 4 deletions python/test/unit/fem/test_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,14 @@ def eval(self, x):
f.t = 1.0
w = Function(V)
w.interpolate(f.eval)
assert (w.x.array[:] == 1.0).all()
assert (w.x.array[:] == 1.0).all() # /NOSONAR

num_vertices = V.mesh.topology.index_map(0).size_global
assert np.isclose(w.x.norm(la.Norm.l1) - num_vertices, 0)

f.t = 2.0
w.interpolate(f.eval)
assert (w.x.array[:] == 2.0).all()
assert (w.x.array[:] == 2.0).all() # /NOSONAR


def test_interpolation_rank1(W):
Expand All @@ -165,8 +165,8 @@ def f(x):
w = Function(W)
w.interpolate(f)
x = w.vector
assert x.max()[1] == 3.0
assert x.min()[1] == 1.0
assert x.max()[1] == 3.0 # /NOSONAR
assert x.min()[1] == 1.0 # /NOSONAR

num_vertices = W.mesh.topology.index_map(0).size_global
assert round(w.x.norm(la.Norm.l1) - 6 * num_vertices, 7) == 0
Expand Down
6 changes: 3 additions & 3 deletions python/test/unit/la/test_matrix_csr.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def test_add(dtype):
assert np.allclose(A1, A3)

mat3.set_value(0.0)
assert mat3.squared_norm() == 0.0
assert mat3.squared_norm() == 0.0 # /NOSONAR


@pytest.mark.parametrize('dtype', [np.float32, np.float64, np.complex64, np.complex128])
Expand All @@ -85,7 +85,7 @@ def test_set(dtype):
# Set a block with bs=1
mat1.set([2.0, 3.0, 4.0, 5.0], [2, 3], [4, 5], 1)
n1 = mat1.squared_norm()
assert (n1 == 54.0 * mpi_size)
assert (n1 == 54.0 * mpi_size) # /NOSONAR

# Set same block with bs=2
mat1.set([2.0, 3.0, 4.0, 5.0], [1], [2], 2)
Expand All @@ -103,7 +103,7 @@ def test_set_blocked(dtype):
# Set a block with bs=1
mat1.set([2.0, 3.0, 4.0, 5.0], [2, 3], [4, 5], 1)
n1 = mat1.squared_norm()
assert (n1 == 54.0 * mpi_size)
assert (n1 == 54.0 * mpi_size) # /NOSONAR


@pytest.mark.parametrize('dtype', [np.float32, np.float64, np.complex64, np.complex128])
Expand Down
138 changes: 67 additions & 71 deletions python/test/unit/mesh/test_cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,10 @@
# SPDX-License-Identifier: LGPL-3.0-or-later

import pytest

import ufl
from basix.ufl import element
from dolfinx import cpp as _cpp
from dolfinx.geometry import squared_distance
from dolfinx.mesh import (CellType, create_mesh, create_unit_cube,
create_unit_interval, create_unit_square)

from dolfinx.mesh import create_mesh, create_unit_interval
from mpi4py import MPI


Expand Down Expand Up @@ -49,74 +45,74 @@ def test_distance_tetrahedron():
assert squared_distance(mesh, mesh.topology.dim, [0], [0.5, 0.5, 0.5]) == pytest.approx(0.0)


@pytest.mark.skip("volume_entities needs fixing")
@pytest.mark.parametrize(
'mesh', [
create_unit_interval(MPI.COMM_WORLD, 18),
create_unit_square(MPI.COMM_WORLD, 8, 9, CellType.triangle),
create_unit_square(MPI.COMM_WORLD, 8, 9, CellType.quadrilateral),
create_unit_cube(MPI.COMM_WORLD, 8, 9, 5, CellType.tetrahedron)
])
def test_volume_cells(mesh):
tdim = mesh.topology.dim
map = mesh.topology.index_map(tdim)
num_cells = map.size_local
v = _cpp.mesh.volume_entities(mesh, range(num_cells), mesh.topology.dim)
assert mesh.comm.allreduce(v.sum(), MPI.SUM) == pytest.approx(1.0, rel=1e-9)


@pytest.mark.skip("volume_entities needs fixing")
def test_volume_quadrilateralR2():
mesh = create_unit_square(MPI.COMM_SELF, 1, 1, CellType.quadrilateral)
assert _cpp.mesh.volume_entities(mesh, [0], mesh.topology.dim) == 1.0


@pytest.mark.skip("volume_entities needs fixing")
@pytest.mark.parametrize(
'x',
[[[0.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0]],
[[0.0, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [0.0, 1.0, 1.0]]])
def test_volume_quadrilateralR3(x):
cells = [[0, 1, 2, 3]]
domain = ufl.Mesh(element("Lagrange", "quadrilateral", 1, shape=(2,)))
mesh = create_mesh(MPI.COMM_SELF, cells, x, domain)
assert _cpp.mesh.volume_entities(mesh, [0], mesh.topology.dim) == 1.0


@pytest.mark.skip("volume_entities needs fixing")
@pytest.mark.parametrize(
'scaling',
[1e0, 1e-5, 1e-10, 1e-15, 1e-20, 1e-30, 1e5, 1e10, 1e15, 1e20, 1e30])
def test_volume_quadrilateral_coplanarity_check_1(scaling):
with pytest.raises(RuntimeError) as error:
# Unit square cell scaled down by 'scaling' and the first vertex
# is distorted so that the vertices are clearly non coplanar
x = [[scaling, 0.5 * scaling, 0.6 * scaling],
[0.0, scaling, 0.0],
[0.0, 0.0, scaling],
[0.0, scaling, scaling]]
cells = [[0, 1, 2, 3]]
domain = ufl.Mesh(element("Lagrange", "quadrilateral", 1, shape=(2,)))
mesh = create_mesh(MPI.COMM_SELF, cells, x, domain)
_cpp.mesh.volume_entities(mesh, [0], mesh.topology.dim)

assert "Not coplanar" in str(error.value)
# @pytest.mark.skip("volume_entities needs fixing")
# @pytest.mark.parametrize(
# 'mesh', [
# create_unit_interval(MPI.COMM_WORLD, 18),
# create_unit_square(MPI.COMM_WORLD, 8, 9, CellType.triangle),
# create_unit_square(MPI.COMM_WORLD, 8, 9, CellType.quadrilateral),
# create_unit_cube(MPI.COMM_WORLD, 8, 9, 5, CellType.tetrahedron)
# ])
# def test_volume_cells(mesh):
# tdim = mesh.topology.dim
# map = mesh.topology.index_map(tdim)
# num_cells = map.size_local
# v = _cpp.mesh.volume_entities(mesh, range(num_cells), mesh.topology.dim)
# assert mesh.comm.allreduce(v.sum(), MPI.SUM) == pytest.approx(1.0, rel=1e-9)


# @pytest.mark.skip("volume_entities needs fixing")
# def test_volume_quadrilateralR2():
# mesh = create_unit_square(MPI.COMM_SELF, 1, 1, CellType.quadrilateral)
# assert _cpp.mesh.volume_entities(mesh, [0], mesh.topology.dim) == 1.0


# @pytest.mark.skip("volume_entities needs fixing")
# @pytest.mark.parametrize(
# 'x',
# [[[0.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0]],
# [[0.0, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [0.0, 1.0, 1.0]]])
# def test_volume_quadrilateralR3(x):
# cells = [[0, 1, 2, 3]]
# domain = ufl.Mesh(element("Lagrange", "quadrilateral", 1, shape=(2,)))
# mesh = create_mesh(MPI.COMM_SELF, cells, x, domain)
# assert _cpp.mesh.volume_entities(mesh, [0], mesh.topology.dim) == 1.0


# @pytest.mark.skip("volume_entities needs fixing")
# @pytest.mark.parametrize(
# 'scaling',
# [1e0, 1e-5, 1e-10, 1e-15, 1e-20, 1e-30, 1e5, 1e10, 1e15, 1e20, 1e30])
# def test_volume_quadrilateral_coplanarity_check_1(scaling):
# with pytest.raises(RuntimeError) as error:
# # Unit square cell scaled down by 'scaling' and the first vertex
# # is distorted so that the vertices are clearly non coplanar
# x = [[scaling, 0.5 * scaling, 0.6 * scaling],
# [0.0, scaling, 0.0],
# [0.0, 0.0, scaling],
# [0.0, scaling, scaling]]
# cells = [[0, 1, 2, 3]]
# domain = ufl.Mesh(element("Lagrange", "quadrilateral", 1, shape=(2,)))
# mesh = create_mesh(MPI.COMM_SELF, cells, x, domain)
# _cpp.mesh.volume_entities(mesh, [0], mesh.topology.dim)

# assert "Not coplanar" in str(error.value)


# Test when |p0-p3| is ~ 1 but |p1-p2| is small
# The cell is degenerate when scale is below 1e-17, it is expected to
# fail the test.
@pytest.mark.skip("volume_entities needs fixing")
@pytest.mark.parametrize('scaling', [1e0, 1e-5, 1e-10, 1e-15])
def test_volume_quadrilateral_coplanarity_check_2(scaling):
with pytest.raises(RuntimeError) as error:
# Unit square cell scaled down by 'scaling' and the first vertex
# is distorted so that the vertices are clearly non coplanar
x = [[1.0, 0.5, 0.6], [0.0, scaling, 0.0],
[0.0, 0.0, scaling], [0.0, 1.0, 1.0]]
cells = [[0, 1, 2, 3]]
domain = ufl.Mesh(element("Lagrange", "quadrilateral", 1, shape=(2,)))
mesh = create_mesh(MPI.COMM_SELF, cells, x, domain)
_cpp.mesh.volume_entities(mesh, [0], mesh.topology.dim)

assert "Not coplanar" in str(error.value)
# @pytest.mark.skip("volume_entities needs fixing")
# @pytest.mark.parametrize('scaling', [1e0, 1e-5, 1e-10, 1e-15])
# def test_volume_quadrilateral_coplanarity_check_2(scaling):
# with pytest.raises(RuntimeError) as error:
# # Unit square cell scaled down by 'scaling' and the first vertex
# # is distorted so that the vertices are clearly non coplanar
# x = [[1.0, 0.5, 0.6], [0.0, scaling, 0.0],
# [0.0, 0.0, scaling], [0.0, 1.0, 1.0]]
# cells = [[0, 1, 2, 3]]
# domain = ufl.Mesh(element("Lagrange", "quadrilateral", 1, shape=(2,)))
# mesh = create_mesh(MPI.COMM_SELF, cells, x, domain)
# _cpp.mesh.volume_entities(mesh, [0], mesh.topology.dim)

# assert "Not coplanar" in str(error.value)

0 comments on commit 53056ba

Please sign in to comment.