From 3467092d0818804a79b85a630bb98436a61424f7 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Sun, 4 May 2025 16:21:40 +0200 Subject: [PATCH 01/15] Add clang-tidy performance config --- .clang-tidy | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .clang-tidy diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000000..15985ed0ef --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,6 @@ +WarningsAsErrors: "*" +UseColor: true +HeaderFilterRegex: '.*' +Checks: > + -*, + performance* \ No newline at end of file From 2a4312610cf8c57777a0e195cd5c6b79f98eccf1 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Sun, 4 May 2025 16:22:16 +0200 Subject: [PATCH 02/15] Add clang tidy support to cmake --- cpp/CMakeLists.txt | 4 ++++ cpp/dolfinx/CMakeLists.txt | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index b7049cc553..0a97ee0ea3 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -108,6 +108,10 @@ add_feature_info( "Ask Python FFCx module where to find ufcx.h header using MODULE mode. Otherwise use CONFIG mode." ) +# clang-tidy +option(ENABLE_CLANG_TIDY "Run clang-tidy while building" OFF) +add_feature_info(ENABLE_CLANG_TIDY ENABLE_CLANG_TIDY "Run clang-tidy while building") + # ------------------------------------------------------------------------------ # Enable or disable optional packages diff --git a/cpp/dolfinx/CMakeLists.txt b/cpp/dolfinx/CMakeLists.txt index 7adaaeb73c..ce4f02d000 100644 --- a/cpp/dolfinx/CMakeLists.txt +++ b/cpp/dolfinx/CMakeLists.txt @@ -48,6 +48,11 @@ set_target_properties( SOVERSION ${DOLFINX_VERSION_MAJOR}.${DOLFINX_VERSION_MINOR} ) +if(ENABLE_CLANG_TIDY) + find_program(CLANG_TIDY NAMES clang-tidy REQUIRED) + set_target_properties(dolfinx PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY};--config-file=${CMAKE_CURRENT_SOURCE_DIR}/../../.clang-tidy") +endif() + # Add git revision flag to the one affected file set_source_files_properties( common/defines.cpp From d633df6b989ee78f104b4c393685c77ad16466d3 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Sun, 4 May 2025 16:22:33 +0200 Subject: [PATCH 03/15] Add clang-tidy CI for C++ build --- .github/workflows/clang-tidy.yml | 58 ++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 .github/workflows/clang-tidy.yml diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml new file mode 100644 index 0000000000..be200b2be0 --- /dev/null +++ b/.github/workflows/clang-tidy.yml @@ -0,0 +1,58 @@ +name: clang-tidy + +on: + schedule: + # daily at 1am + - cron: "0 1 * * *" + pull_request: + branches: + - main + push: + branches: + - "**" + tags: + - "v*" + merge_group: + branches: + - main + workflow_dispatch: + +jobs: + clang-tidy: + runs-on: ubuntu-latest + container: "ghcr.io/fenics/test-env:current-openmpi" + env: + PETSC_ARCH: linux-gnu-real64-32 + OMPI_ALLOW_RUN_AS_ROOT: 1 + OMPI_ALLOW_RUN_AS_ROOT_CONFIRM: 1 + PRTE_MCA_rmaps_default_mapping_policy: :oversubscribe + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: | + apt-get update + apt-get install -y clang-tidy + + - name: Load environment variables + run: cat .github/workflows/fenicsx-refs.env >> $GITHUB_ENV + + - name: Install FEniCS Python components (default branches/tags) + if: github.event_name != 'workflow_dispatch' + run: | + pip install git+https://github.com/FEniCS/ufl.git@${{ env.ufl_ref }} + pip install git+https://github.com/FEniCS/basix.git@${{ env.basix_ref }} + pip install git+https://github.com/FEniCS/ffcx.git@${{ env.ffcx_ref }} + + - name: Install FEniCS Python components + if: github.event_name == 'workflow_dispatch' + run: | + pip install git+https://github.com/FEniCS/ufl.git@${{ env.ufl_ref }} + pip install git+https://github.com/FEniCS/basix.git@${{ env.basix_ref }} + pip install git+https://github.com/FEniCS/ffcx.git@${{ env.ffcx_ref }} + + - name: Configure, build and install C++ library + run: | + cmake -G Ninja -DCMAKE_BUILD_TYPE=Developer -DDOLFINX_ENABLE_ADIOS2=true -DDOLFINX_ENABLE_KAHIP=true -DDOLFINX_ENABLE_PARMETIS=false -DDOLFINX_ENABLE_PETSC=true -DDOLFINX_ENABLE_SCOTCH=true -DDOLFINX_ENABLE_SLEPC=true -DENABLE_CLANG_TIDY=ON -B build -S cpp/ + cmake --build build + cmake --install build \ No newline at end of file From 9b7c2b276316ef43947c0febc258d48c64fc504a Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Sun, 4 May 2025 17:17:18 +0200 Subject: [PATCH 04/15] Apply clang-tidy performance fixes --- cpp/dolfinx/common/IndexMap.cpp | 1 + cpp/dolfinx/common/MPI.cpp | 2 +- cpp/dolfinx/common/MPI.h | 2 +- cpp/dolfinx/common/Scatterer.h | 2 +- cpp/dolfinx/common/Table.cpp | 10 ++--- cpp/dolfinx/common/Table.h | 9 ++-- cpp/dolfinx/common/TimeLogger.cpp | 6 +-- cpp/dolfinx/common/TimeLogger.h | 4 +- cpp/dolfinx/common/Timer.h | 4 +- cpp/dolfinx/common/timing.cpp | 2 +- cpp/dolfinx/common/timing.h | 2 +- cpp/dolfinx/fem/CoordinateElement.cpp | 2 +- cpp/dolfinx/fem/DirichletBC.cpp | 3 ++ cpp/dolfinx/fem/DofMap.h | 2 +- cpp/dolfinx/fem/ElementDofLayout.h | 3 +- cpp/dolfinx/fem/FiniteElement.cpp | 6 +-- cpp/dolfinx/fem/FiniteElement.h | 4 +- cpp/dolfinx/fem/FunctionSpace.h | 6 +-- cpp/dolfinx/fem/dofmapbuilder.cpp | 8 ++-- cpp/dolfinx/fem/petsc.h | 8 ++-- cpp/dolfinx/fem/utils.cpp | 15 ++++--- cpp/dolfinx/fem/utils.h | 21 +++++---- cpp/dolfinx/graph/AdjacencyList.h | 2 +- cpp/dolfinx/graph/partitioners.cpp | 1 + cpp/dolfinx/graph/partitioners.h | 2 +- cpp/dolfinx/io/ADIOS2Writers.cpp | 5 ++- cpp/dolfinx/io/ADIOS2Writers.h | 2 +- cpp/dolfinx/io/XDMFFile.cpp | 45 +++++++++++--------- cpp/dolfinx/io/XDMFFile.h | 47 +++++++++++---------- cpp/dolfinx/io/utils.h | 4 +- cpp/dolfinx/io/vtk_utils.h | 2 +- cpp/dolfinx/io/xdmf_function.cpp | 4 +- cpp/dolfinx/io/xdmf_mesh.cpp | 8 ++-- cpp/dolfinx/io/xdmf_mesh.h | 5 ++- cpp/dolfinx/io/xdmf_utils.cpp | 2 +- cpp/dolfinx/la/Vector.h | 5 +-- cpp/dolfinx/la/petsc.cpp | 29 +++++++------ cpp/dolfinx/la/petsc.h | 25 +++++------ cpp/dolfinx/la/slepc.cpp | 7 +-- cpp/dolfinx/la/slepc.h | 6 +-- cpp/dolfinx/la/utils.h | 2 +- cpp/dolfinx/mesh/Geometry.h | 23 +++++----- cpp/dolfinx/mesh/Mesh.h | 3 +- cpp/dolfinx/mesh/MeshTags.h | 7 +-- cpp/dolfinx/mesh/Topology.cpp | 11 +++-- cpp/dolfinx/mesh/Topology.h | 4 +- cpp/dolfinx/mesh/cell_types.cpp | 2 +- cpp/dolfinx/mesh/cell_types.h | 2 +- cpp/dolfinx/mesh/graphbuild.h | 2 +- cpp/dolfinx/mesh/permutationcomputation.cpp | 4 +- cpp/dolfinx/mesh/utils.cpp | 2 +- cpp/dolfinx/mesh/utils.h | 9 ++-- cpp/dolfinx/nls/NewtonSolver.cpp | 13 +++--- cpp/dolfinx/refinement/plaza.cpp | 2 +- cpp/dolfinx/refinement/utils.h | 3 +- 55 files changed, 229 insertions(+), 183 deletions(-) diff --git a/cpp/dolfinx/common/IndexMap.cpp b/cpp/dolfinx/common/IndexMap.cpp index e4eb98fc53..1844497b56 100644 --- a/cpp/dolfinx/common/IndexMap.cpp +++ b/cpp/dolfinx/common/IndexMap.cpp @@ -1183,6 +1183,7 @@ graph::AdjacencyList IndexMap::index_to_dest_ranks(int tag) const // Build list of (ghost index, ghost position) pairs for indices // ghosted by this rank, and sort std::vector> idx_to_pos; + idx_to_pos.reserve(2 * _ghosts.size()); for (auto idx : _ghosts) idx_to_pos.push_back({idx, idx_to_pos.size()}); std::ranges::sort(idx_to_pos); diff --git a/cpp/dolfinx/common/MPI.cpp b/cpp/dolfinx/common/MPI.cpp index 8b81d9a4bc..5aa91f4fba 100644 --- a/cpp/dolfinx/common/MPI.cpp +++ b/cpp/dolfinx/common/MPI.cpp @@ -85,7 +85,7 @@ void dolfinx::MPI::check_error(MPI_Comm comm, int code) std::string error_string(MPI_MAX_ERROR_STRING, ' '); MPI_Error_string(code, error_string.data(), &len); error_string.resize(len); - std::cerr << error_string << std::endl; + std::cerr << error_string << '\n'; MPI_Abort(comm, code); std::abort(); } diff --git a/cpp/dolfinx/common/MPI.h b/cpp/dolfinx/common/MPI.h index 196484098c..c5eeeed9d1 100644 --- a/cpp/dolfinx/common/MPI.h +++ b/cpp/dolfinx/common/MPI.h @@ -30,7 +30,7 @@ namespace dolfinx::MPI { /// MPI communication tags -enum class tag : int +enum class tag : std::uint16_t { consensus_pcx = 1200, consensus_pex = 1201, diff --git a/cpp/dolfinx/common/Scatterer.h b/cpp/dolfinx/common/Scatterer.h index 9425f8d254..b1ec339e77 100644 --- a/cpp/dolfinx/common/Scatterer.h +++ b/cpp/dolfinx/common/Scatterer.h @@ -34,7 +34,7 @@ class Scatterer using allocator_type = Allocator; /// Types of MPI communication pattern used by the Scatterer. - enum class type + enum class type : std::uint8_t { neighbor, // use MPI neighborhood collectives p2p // use MPI Isend/Irecv for communication diff --git a/cpp/dolfinx/common/Table.cpp b/cpp/dolfinx/common/Table.cpp index 241cebd853..5527335ac2 100644 --- a/cpp/dolfinx/common/Table.cpp +++ b/cpp/dolfinx/common/Table.cpp @@ -31,12 +31,12 @@ using namespace dolfinx; //----------------------------------------------------------------------------- Table::Table(std::string title, bool right_justify) - : name(title), _right_justify(right_justify) + : name(std::move(title)), _right_justify(right_justify) { // Do nothing } //----------------------------------------------------------------------------- -void Table::set(std::string row, std::string col, +void Table::set(const std::string& row, const std::string& col, std::variant value) { // Add row @@ -49,11 +49,11 @@ void Table::set(std::string row, std::string col, // Store value std::pair key(row, col); - _values[key] = value; + _values[key] = std::move(value); } //----------------------------------------------------------------------------- -std::variant Table::get(std::string row, - std::string col) const +std::variant Table::get(const std::string& row, + const std::string& col) const { std::pair key(row, col); auto it = _values.find(key); diff --git a/cpp/dolfinx/common/Table.h b/cpp/dolfinx/common/Table.h index 4e39d72881..41b2905398 100644 --- a/cpp/dolfinx/common/Table.h +++ b/cpp/dolfinx/common/Table.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include #include @@ -29,7 +30,7 @@ class Table public: /// Types of MPI reduction available for Table, to get the max, min or /// average values over an MPI_Comm - enum class Reduction + enum class Reduction : std::uint8_t { average, max, @@ -58,15 +59,15 @@ class Table /// @param[in] row Row name /// @param[in] col Column name /// @param[in] value The value to set - void set(std::string row, std::string col, + void set(const std::string& row, const std::string& col, std::variant value); /// Get value of table entry /// @param[in] row Row name /// @param[in] col Column name /// @returns Returns the entry for requested row and columns - std::variant get(std::string row, - std::string col) const; + std::variant get(const std::string& row, + const std::string& col) const; /// Do MPI reduction on Table /// @param[in] comm MPI communicator diff --git a/cpp/dolfinx/common/TimeLogger.cpp b/cpp/dolfinx/common/TimeLogger.cpp index eb356f9b3a..de214712ac 100644 --- a/cpp/dolfinx/common/TimeLogger.cpp +++ b/cpp/dolfinx/common/TimeLogger.cpp @@ -21,7 +21,7 @@ TimeLogger& TimeLogger::instance() //----------------------------------------------------------------------------- void TimeLogger::register_timing( - std::string task, std::chrono::duration> time) + const std::string& task, std::chrono::duration> time) { // Print a message std::string line @@ -47,7 +47,7 @@ void TimeLogger::list_timings(MPI_Comm comm, Table::Reduction reduction) const // Print just on rank 0 if (dolfinx::MPI::rank(comm) == 0) - std::cout << str << std::endl; + std::cout << str << '\n'; } //----------------------------------------------------------------------------- Table TimeLogger::timing_table() const @@ -67,7 +67,7 @@ Table TimeLogger::timing_table() const } //----------------------------------------------------------------------------- std::pair>> -TimeLogger::timing(std::string task) const +TimeLogger::timing(const std::string& task) const { // Find timing auto it = _timings.find(task); diff --git a/cpp/dolfinx/common/TimeLogger.h b/cpp/dolfinx/common/TimeLogger.h index cad8de5f2a..f9b6236250 100644 --- a/cpp/dolfinx/common/TimeLogger.h +++ b/cpp/dolfinx/common/TimeLogger.h @@ -28,7 +28,7 @@ class TimeLogger static TimeLogger& instance(); /// Register timing (for later summary) - void register_timing(std::string task, + void register_timing(const std::string& task, std::chrono::duration> wall); /// Return a summary of timings and tasks in a Table @@ -44,7 +44,7 @@ class TimeLogger /// @param[in] task The task name to retrieve the timing for /// @return Values (count, total wall time) for given task. std::pair>> - timing(std::string task) const; + timing(const std::string& task) const; /// @brief Logged elapsed times. /// @return Elapsed [task id: (count, total wall time)]. diff --git a/cpp/dolfinx/common/Timer.h b/cpp/dolfinx/common/Timer.h index 8f792a2e1c..5717ec1650 100644 --- a/cpp/dolfinx/common/Timer.h +++ b/cpp/dolfinx/common/Timer.h @@ -48,7 +48,9 @@ class Timer /// @param[in] task Name used to registered the elapsed time in the /// logger. If no name is set, the elapsed time is not registered in /// the logger. - Timer(std::optional task = std::nullopt) : _task(task) {} + Timer(std::optional task = std::nullopt) : _task(std::move(task)) + { + } /// If timer is still running, it is stopped. Elapsed time is /// registered in the logger. diff --git a/cpp/dolfinx/common/timing.cpp b/cpp/dolfinx/common/timing.cpp index f48ac44c03..0820d20a74 100644 --- a/cpp/dolfinx/common/timing.cpp +++ b/cpp/dolfinx/common/timing.cpp @@ -21,7 +21,7 @@ void dolfinx::list_timings(MPI_Comm comm, Table::Reduction reduction) } //----------------------------------------------------------------------------- std::pair>> -dolfinx::timing(std::string task) +dolfinx::timing(const std::string& task) { return dolfinx::common::TimeLogger::instance().timing(task); } diff --git a/cpp/dolfinx/common/timing.h b/cpp/dolfinx/common/timing.h index 20bc1d1f50..5441041d2d 100644 --- a/cpp/dolfinx/common/timing.h +++ b/cpp/dolfinx/common/timing.h @@ -32,7 +32,7 @@ void list_timings(MPI_Comm comm, /// @param[in] task Name of a task /// @return The (count, total wall time) for the task. std::pair>> -timing(std::string task); +timing(const std::string& task); /// @brief Logged elapsed times. /// @return Elapsed [task id: (count, total wall time)]. diff --git a/cpp/dolfinx/fem/CoordinateElement.cpp b/cpp/dolfinx/fem/CoordinateElement.cpp index 6b990fccd6..07a5647e8e 100644 --- a/cpp/dolfinx/fem/CoordinateElement.cpp +++ b/cpp/dolfinx/fem/CoordinateElement.cpp @@ -18,7 +18,7 @@ using namespace dolfinx::fem; template CoordinateElement::CoordinateElement( std::shared_ptr> element) - : _element(element) + : _element(std::move(element)) { int degree = _element->degree(); mesh::CellType cell = this->cell_shape(); diff --git a/cpp/dolfinx/fem/DirichletBC.cpp b/cpp/dolfinx/fem/DirichletBC.cpp index 97d9b0689d..eb9afbcef7 100644 --- a/cpp/dolfinx/fem/DirichletBC.cpp +++ b/cpp/dolfinx/fem/DirichletBC.cpp @@ -154,6 +154,7 @@ get_remote_dofs(MPI_Comm comm, const common::IndexMap& map, int bs_map, // NOTE: Should we use map here or just one vector with ghosts and // std::distance? std::vector> global_local_ghosts; + global_local_ghosts.reserve(ghosts.size()); const std::int32_t local_size = range[1] - range[0]; for (std::size_t i = 0; i < ghosts.size(); ++i) global_local_ghosts.emplace_back(ghosts[i], i + local_size); @@ -194,6 +195,7 @@ std::vector fem::locate_dofs_topological( // entity_dim const int num_cell_entities = mesh::cell_num_entities(cell_type, dim); std::vector> entity_dofs; + entity_dofs.reserve(num_cell_entities); for (int i = 0; i < num_cell_entities; ++i) { entity_dofs.push_back( @@ -310,6 +312,7 @@ std::array, 2> fem::locate_dofs_topological( // Build vector of local dofs for each cell entity const int num_cell_entities = mesh::cell_num_entities(cell_type, dim); std::vector> entity_dofs; + entity_dofs.reserve(num_cell_entities); for (int i = 0; i < num_cell_entities; ++i) { entity_dofs.push_back( diff --git a/cpp/dolfinx/fem/DofMap.h b/cpp/dolfinx/fem/DofMap.h index 4f3de84177..85efae6b41 100644 --- a/cpp/dolfinx/fem/DofMap.h +++ b/cpp/dolfinx/fem/DofMap.h @@ -92,7 +92,7 @@ class DofMap std::vector> DofMap(E&& element, std::shared_ptr index_map, int index_map_bs, U&& dofmap, int bs) - : index_map(index_map), _index_map_bs(index_map_bs), + : index_map(std::move(index_map)), _index_map_bs(index_map_bs), _element_dof_layout(std::forward(element)), _dofmap(std::forward(dofmap)), _bs(bs), _shape1(_element_dof_layout.num_dofs() diff --git a/cpp/dolfinx/fem/ElementDofLayout.h b/cpp/dolfinx/fem/ElementDofLayout.h index 2564e58749..0d102df783 100644 --- a/cpp/dolfinx/fem/ElementDofLayout.h +++ b/cpp/dolfinx/fem/ElementDofLayout.h @@ -7,12 +7,13 @@ #pragma once #include +#include #include #include namespace dolfinx::mesh { -enum class CellType; +enum class CellType : std::int8_t; } namespace dolfinx::fem diff --git a/cpp/dolfinx/fem/FiniteElement.cpp b/cpp/dolfinx/fem/FiniteElement.cpp index 176f2ec043..21a4be9090 100644 --- a/cpp/dolfinx/fem/FiniteElement.cpp +++ b/cpp/dolfinx/fem/FiniteElement.cpp @@ -32,7 +32,7 @@ _build_element_list(std::vector> elements) { std::vector>> _e; std::ranges::transform(elements, std::back_inserter(_e), - [](auto data) + [](const auto& data) { auto& [e, bs, symm] = data; return std::make_shared>(e, bs, @@ -110,7 +110,7 @@ int _compute_block_size(std::optional> value_shape, template FiniteElement::FiniteElement( const basix::FiniteElement& element, - std::optional> value_shape, bool symmetric) + const std::optional>& value_shape, bool symmetric) : _value_shape(value_shape.value_or(element.value_shape())), _bs(_compute_block_size(value_shape, symmetric)), _cell_type(mesh::cell_type_from_basix_type(element.cell_type())), @@ -161,7 +161,7 @@ FiniteElement::FiniteElement( //----------------------------------------------------------------------------- template FiniteElement::FiniteElement(std::vector> elements) - : FiniteElement(_build_element_list(elements)) + : FiniteElement(_build_element_list(std::move(elements))) { } //----------------------------------------------------------------------------- diff --git a/cpp/dolfinx/fem/FiniteElement.h b/cpp/dolfinx/fem/FiniteElement.h index d11d15c0dc..34e31b389d 100644 --- a/cpp/dolfinx/fem/FiniteElement.h +++ b/cpp/dolfinx/fem/FiniteElement.h @@ -22,7 +22,7 @@ namespace dolfinx::fem { /// DOF transformation type -enum class doftransform +enum class doftransform : std::uint8_t { standard = 0, ///< Standard transpose = 1, ///< Transpose @@ -68,7 +68,7 @@ class FiniteElement /// @param[in] symmetric Is the element a symmetric tensor? Should /// only set for 2nd-order tensor blocked elements. FiniteElement(const basix::FiniteElement& element, - std::optional> value_shape + const std::optional>& value_shape = std::nullopt, bool symmetric = false); diff --git a/cpp/dolfinx/fem/FunctionSpace.h b/cpp/dolfinx/fem/FunctionSpace.h index 74cff05a7d..201f846e0d 100644 --- a/cpp/dolfinx/fem/FunctionSpace.h +++ b/cpp/dolfinx/fem/FunctionSpace.h @@ -44,7 +44,7 @@ class FunctionSpace FunctionSpace(std::shared_ptr> mesh, std::shared_ptr> element, std::shared_ptr dofmap) - : _mesh(mesh), _elements{element}, _dofmaps{dofmap}, + : _mesh(mesh), _elements{element}, _dofmaps{std::move(dofmap)}, _id(boost::uuids::random_generator()()), _root_space_id(_id) { // Do nothing @@ -62,7 +62,7 @@ class FunctionSpace std::shared_ptr> mesh, std::vector>> elements, std::vector> dofmaps) - : _mesh(mesh), _elements(elements), _dofmaps(dofmaps), + : _mesh(mesh), _elements(elements), _dofmaps(std::move(dofmaps)), _id(boost::uuids::random_generator()()), _root_space_id(_id) { std::vector cell_types = mesh->topology()->cell_types(); @@ -72,7 +72,7 @@ class FunctionSpace throw std::runtime_error( "Number of elements must match number of cell types"); } - if (dofmaps.size() != num_cell_types) + if (_dofmaps.size() != num_cell_types) { throw std::runtime_error( "Number of dofmaps must match number of cell types"); diff --git a/cpp/dolfinx/fem/dofmapbuilder.cpp b/cpp/dolfinx/fem/dofmapbuilder.cpp index fd7113a60e..4081578994 100644 --- a/cpp/dolfinx/fem/dofmapbuilder.cpp +++ b/cpp/dolfinx/fem/dofmapbuilder.cpp @@ -344,7 +344,7 @@ build_basic_dofmaps( for (std::size_t k = 0; k < required_dim_et.size(); ++k) { const int num_entity_dofs = num_entity_dofs_et[k]; - auto map = topo_index_maps[k]; + const auto& map = topo_index_maps[k]; assert(map); std::vector global_indices = map->global_indices(); @@ -413,7 +413,7 @@ std::pair, std::int32_t> compute_reordering_map( // owned dofs. Set to -1 for unowned dofs. std::vector original_to_contiguous(dof_entity.size(), -1); std::int32_t counter_owned(0), counter_unowned(owned_size); - for (auto dofmap : dofmaps) + for (const auto& dofmap : dofmaps) { for (std::int32_t dof : dofmap.array) { @@ -487,7 +487,7 @@ std::pair, std::vector> get_global_indices( std::vector> shared_entity(index_maps.size()); for (std::size_t d = 0; d < index_maps.size(); ++d) { - auto map = index_maps[d]; + const auto& map = index_maps[d]; assert(map); shared_entity[d] = std::vector(map->size_local(), false); @@ -524,7 +524,7 @@ std::pair, std::vector> get_global_indices( std::vector> disp_recv(index_maps.size()); for (std::size_t d = 0; d < index_maps.size(); ++d) { - auto map = index_maps[d]; + const auto& map = index_maps[d]; assert(map); std::span src = map->src(); diff --git a/cpp/dolfinx/fem/petsc.h b/cpp/dolfinx/fem/petsc.h index 38f668a94d..16523a1dcf 100644 --- a/cpp/dolfinx/fem/petsc.h +++ b/cpp/dolfinx/fem/petsc.h @@ -44,7 +44,7 @@ namespace petsc /// object. template Mat create_matrix(const Form& a, - std::optional type = std::nullopt) + const std::optional& type = std::nullopt) { la::SparsityPattern pattern = fem::create_sparsity_pattern(a); pattern.finalize(); @@ -64,7 +64,7 @@ Mat create_matrix(const Form& a, template Mat create_matrix_block( const std::vector*>>& a, - std::optional type = std::nullopt) + const std::optional& type = std::nullopt) { // Extract and check row/column ranges std::array>>, 2> V @@ -404,8 +404,8 @@ void apply_lifting( template void apply_lifting( Vec b, - std::vector< - std::optional>>> + const std::vector< + std::optional>>>& a, const std::vector>>>& bcs1, diff --git a/cpp/dolfinx/fem/utils.cpp b/cpp/dolfinx/fem/utils.cpp index d0f7c60a05..c3099306a6 100644 --- a/cpp/dolfinx/fem/utils.cpp +++ b/cpp/dolfinx/fem/utils.cpp @@ -30,9 +30,10 @@ using namespace dolfinx; //----------------------------------------------------------------------------- fem::DofMap fem::create_dofmap( MPI_Comm comm, const ElementDofLayout& layout, mesh::Topology& topology, - std::function, std::uint32_t)> permute_inv, - std::function(const graph::AdjacencyList&)> - reorder_fn) + const std::function, std::uint32_t)>& + permute_inv, + const std::function( + const graph::AdjacencyList&)>& reorder_fn) { // Create required mesh entities const int D = topology.dim(); @@ -68,9 +69,10 @@ fem::DofMap fem::create_dofmap( std::vector fem::create_dofmaps( MPI_Comm comm, const std::vector& layouts, mesh::Topology& topology, - std::function, std::uint32_t)> permute_inv, - std::function(const graph::AdjacencyList&)> - reorder_fn) + const std::function, std::uint32_t)>& + permute_inv, + const std::function( + const graph::AdjacencyList&)>& reorder_fn) { std::int32_t D = topology.dim(); assert(layouts.size() == topology.entity_types(D).size()); @@ -108,6 +110,7 @@ std::vector fem::create_dofmaps( } std::vector dms; + dms.reserve(dofmaps.size()); for (std::size_t i = 0; i < dofmaps.size(); ++i) dms.emplace_back(layouts[i], index_map, bs, std::move(dofmaps[i]), bs); diff --git a/cpp/dolfinx/fem/utils.h b/cpp/dolfinx/fem/utils.h index 8ba38ef74c..7108d1eb43 100644 --- a/cpp/dolfinx/fem/utils.h +++ b/cpp/dolfinx/fem/utils.h @@ -309,11 +309,13 @@ ElementDofLayout create_element_dof_layout(const fem::FiniteElement& element, /// when transformation is not required. /// @param[in] reorder_fn Graph reordering function called on the dofmap /// @return A new dof map -DofMap create_dofmap( - MPI_Comm comm, const ElementDofLayout& layout, mesh::Topology& topology, - std::function, std::uint32_t)> permute_inv, - std::function(const graph::AdjacencyList&)> - reorder_fn); +DofMap +create_dofmap(MPI_Comm comm, const ElementDofLayout& layout, + mesh::Topology& topology, + const std::function, std::uint32_t)>& + permute_inv, + const std::function( + const graph::AdjacencyList&)>& reorder_fn); /// @brief Create a set of dofmaps on a given topology /// @param[in] comm MPI communicator @@ -328,9 +330,10 @@ DofMap create_dofmap( std::vector create_dofmaps( MPI_Comm comm, const std::vector& layouts, mesh::Topology& topology, - std::function, std::uint32_t)> permute_inv, - std::function(const graph::AdjacencyList&)> - reorder_fn); + const std::function, std::uint32_t)>& + permute_inv, + const std::function( + const graph::AdjacencyList&)>& reorder_fn); /// Get the name of each coefficient in a UFC form /// @param[in] ufcx_form The UFC form @@ -967,6 +970,7 @@ Expression create_expression( // Place coefficients in appropriate order std::vector>> coeff_map; std::vector coefficient_names; + coefficient_names.reserve(e.num_coefficients); for (int i = 0; i < e.num_coefficients; ++i) coefficient_names.push_back(e.coefficient_names[i]); @@ -984,6 +988,7 @@ Expression create_expression( // Place constants in appropriate order std::vector>> const_map; std::vector constant_names; + constant_names.reserve(e.num_constants); for (int i = 0; i < e.num_constants; ++i) constant_names.push_back(e.constant_names[i]); diff --git a/cpp/dolfinx/graph/AdjacencyList.h b/cpp/dolfinx/graph/AdjacencyList.h index b66a1450ea..f4923e008c 100644 --- a/cpp/dolfinx/graph/AdjacencyList.h +++ b/cpp/dolfinx/graph/AdjacencyList.h @@ -148,7 +148,7 @@ class AdjacencyList s << " " << e << ": ["; for (auto link : this->links(e)) s << link << " "; - s << "]" << std::endl; + s << "]" << '\n'; } return s.str(); } diff --git a/cpp/dolfinx/graph/partitioners.cpp b/cpp/dolfinx/graph/partitioners.cpp index fade5e160c..0d0427dd09 100644 --- a/cpp/dolfinx/graph/partitioners.cpp +++ b/cpp/dolfinx/graph/partitioners.cpp @@ -152,6 +152,7 @@ graph::AdjacencyList compute_destination_ranks( // Prepare (local node index, destination rank) array. Add local data, // then add the received data, and the make unique. std::vector> local_node_to_dest; + local_node_to_dest.reserve(2 * part.size() + 2 * recv_buffer.size()); for (auto d : part) { local_node_to_dest.push_back( diff --git a/cpp/dolfinx/graph/partitioners.h b/cpp/dolfinx/graph/partitioners.h index aba51a8430..2e166f1eed 100644 --- a/cpp/dolfinx/graph/partitioners.h +++ b/cpp/dolfinx/graph/partitioners.h @@ -17,7 +17,7 @@ namespace scotch /// @brief PT-SCOTCH partitioning strategies. /// /// See PT-SCOTCH documentation for details. -enum class strategy +enum class strategy : std::uint8_t { ///< SCOTCH default strategy none, diff --git a/cpp/dolfinx/io/ADIOS2Writers.cpp b/cpp/dolfinx/io/ADIOS2Writers.cpp index f77a209598..b454be1519 100644 --- a/cpp/dolfinx/io/ADIOS2Writers.cpp +++ b/cpp/dolfinx/io/ADIOS2Writers.cpp @@ -10,6 +10,7 @@ #include "cells.h" #include #include +#include #include using namespace dolfinx; @@ -19,9 +20,9 @@ using namespace dolfinx::io; ADIOS2Writer::ADIOS2Writer(MPI_Comm comm, const std::filesystem::path& filename, std::string tag, std::string engine) : _adios(std::make_unique(comm)), - _io(std::make_unique(_adios->DeclareIO(tag))) + _io(std::make_unique(_adios->DeclareIO(std::move(tag)))) { - _io->SetEngine(engine); + _io->SetEngine(std::move(engine)); _engine = std::make_unique( _io->Open(filename, adios2::Mode::Write)); } diff --git a/cpp/dolfinx/io/ADIOS2Writers.h b/cpp/dolfinx/io/ADIOS2Writers.h index 05dbb899e7..889ac9a418 100644 --- a/cpp/dolfinx/io/ADIOS2Writers.h +++ b/cpp/dolfinx/io/ADIOS2Writers.h @@ -405,7 +405,7 @@ vtx_write_mesh_from_space(adios2::IO& io, adios2::Engine& engine, } // namespace impl_vtx /// Mesh reuse policy -enum class VTXMeshPolicy +enum class VTXMeshPolicy : std::int8_t { update, ///< Re-write the mesh to file upon every write of a fem::Function reuse ///< Write the mesh to file only the first time a fem::Function is diff --git a/cpp/dolfinx/io/XDMFFile.cpp b/cpp/dolfinx/io/XDMFFile.cpp index b30bfb1429..de3ebe7368 100644 --- a/cpp/dolfinx/io/XDMFFile.cpp +++ b/cpp/dolfinx/io/XDMFFile.cpp @@ -26,7 +26,7 @@ using namespace dolfinx::io; //----------------------------------------------------------------------------- XDMFFile::XDMFFile(MPI_Comm comm, const std::filesystem::path& filename, - std::string file_mode, Encoding encoding) + const std::string& file_mode, Encoding encoding) : _comm(comm), _filename(filename), _file_mode(file_mode), _xml_doc(new pugi::xml_document), _encoding(encoding) { @@ -140,7 +140,7 @@ void XDMFFile::close() } //----------------------------------------------------------------------------- template -void XDMFFile::write_mesh(const mesh::Mesh& mesh, std::string xpath) +void XDMFFile::write_mesh(const mesh::Mesh& mesh, const std::string& xpath) { pugi::xml_node node = _xml_doc->select_node(xpath.c_str()).node(); if (!node) @@ -154,12 +154,14 @@ void XDMFFile::write_mesh(const mesh::Mesh& mesh, std::string xpath) _xml_doc->save_file(_filename.c_str(), " "); } /// @cond -template void XDMFFile::write_mesh(const mesh::Mesh&, std::string); -template void XDMFFile::write_mesh(const mesh::Mesh&, std::string); +template void XDMFFile::write_mesh(const mesh::Mesh&, + const std::string&); +template void XDMFFile::write_mesh(const mesh::Mesh&, + const std::string&); /// @endcond //----------------------------------------------------------------------------- void XDMFFile::write_geometry(const mesh::Geometry& geometry, - std::string name, std::string xpath) + const std::string& name, const std::string& xpath) { pugi::xml_node node = _xml_doc->select_node(xpath.c_str()).node(); if (!node) @@ -182,8 +184,8 @@ void XDMFFile::write_geometry(const mesh::Geometry& geometry, //----------------------------------------------------------------------------- mesh::Mesh XDMFFile::read_mesh(const fem::CoordinateElement& element, - mesh::GhostMode mode, std::string name, - std::string xpath) const + mesh::GhostMode mode, const std::string& name, + const std::string& xpath) const { // Read mesh data auto [cells, cshape] = XDMFFile::read_topology_data(name, xpath); @@ -198,7 +200,8 @@ XDMFFile::read_mesh(const fem::CoordinateElement& element, } //----------------------------------------------------------------------------- std::pair, std::array> -XDMFFile::read_topology_data(std::string name, std::string xpath) const +XDMFFile::read_topology_data(const std::string& name, + const std::string& xpath) const { pugi::xml_node node = _xml_doc->select_node(xpath.c_str()).node(); if (!node) @@ -215,7 +218,8 @@ XDMFFile::read_topology_data(std::string name, std::string xpath) const //----------------------------------------------------------------------------- std::pair, std::vector>, std::array> -XDMFFile::read_geometry_data(std::string name, std::string xpath) const +XDMFFile::read_geometry_data(const std::string& name, + const std::string& xpath) const { pugi::xml_node node = _xml_doc->select_node(xpath.c_str()).node(); if (!node) @@ -301,7 +305,8 @@ XDMFFile::write_function(const fem::Function, double>&, template void XDMFFile::write_meshtags(const mesh::MeshTags& meshtags, const mesh::Geometry& x, - std::string geometry_xpath, std::string xpath) + const std::string& geometry_xpath, + const std::string& xpath) { pugi::xml_node node = _xml_doc->select_node(xpath.c_str()).node(); if (!node) @@ -328,16 +333,16 @@ void XDMFFile::write_meshtags(const mesh::MeshTags& meshtags, /// @cond template void XDMFFile::write_meshtags(const mesh::MeshTags&, const mesh::Geometry& x, - std::string, std::string); + const std::string&, const std::string&); template void XDMFFile::write_meshtags(const mesh::MeshTags&, const mesh::Geometry& x, - std::string, std::string); + const std::string&, const std::string&); /// @endcond //----------------------------------------------------------------------------- mesh::MeshTags -XDMFFile::read_meshtags(const mesh::Mesh& mesh, std::string name, +XDMFFile::read_meshtags(const mesh::Mesh& mesh, const std::string& name, std::optional attribute_name, - std::string xpath) + const std::string& xpath) { spdlog::info("XDMF read meshtags ({})", name); pugi::xml_node node = _xml_doc->select_node(xpath.c_str()).node(); @@ -402,8 +407,8 @@ XDMFFile::read_meshtags(const mesh::Mesh& mesh, std::string name, return meshtags; } //----------------------------------------------------------------------------- -std::pair XDMFFile::read_cell_type(std::string grid_name, - std::string xpath) +std::pair +XDMFFile::read_cell_type(const std::string& grid_name, const std::string& xpath) { pugi::xml_node node = _xml_doc->select_node(xpath.c_str()).node(); if (!node) @@ -427,8 +432,9 @@ std::pair XDMFFile::read_cell_type(std::string grid_name, return {cell_type, cell_type_str.second}; } //----------------------------------------------------------------------------- -void XDMFFile::write_information(std::string name, std::string value, - std::string xpath) +void XDMFFile::write_information(const std::string& name, + const std::string& value, + const std::string& xpath) { pugi::xml_node node = _xml_doc->select_node(xpath.c_str()).node(); if (!node) @@ -444,7 +450,8 @@ void XDMFFile::write_information(std::string name, std::string value, _xml_doc->save_file(_filename.c_str(), " "); } //----------------------------------------------------------------------------- -std::string XDMFFile::read_information(std::string name, std::string xpath) +std::string XDMFFile::read_information(const std::string& name, + const std::string& xpath) { pugi::xml_node node = _xml_doc->select_node(xpath.c_str()).node(); if (!node) diff --git a/cpp/dolfinx/io/XDMFFile.h b/cpp/dolfinx/io/XDMFFile.h index de0dc1ffa8..8628c0b147 100644 --- a/cpp/dolfinx/io/XDMFFile.h +++ b/cpp/dolfinx/io/XDMFFile.h @@ -35,7 +35,7 @@ namespace dolfinx::mesh { template class Geometry; -enum class GhostMode : int; +enum class GhostMode : std::uint8_t; template class Mesh; template @@ -59,7 +59,7 @@ class XDMFFile { public: /// File encoding type - enum class Encoding + enum class Encoding : std::int8_t { HDF5, ASCII @@ -67,7 +67,7 @@ class XDMFFile /// Constructor XDMFFile(MPI_Comm comm, const std::filesystem::path& filename, - std::string file_mode, Encoding encoding = Encoding::HDF5); + const std::string& file_mode, Encoding encoding = Encoding::HDF5); /// Move constructor XDMFFile(XDMFFile&&) = default; @@ -87,14 +87,15 @@ class XDMFFile /// @param[in] xpath XPath where Mesh Grid will be written template void write_mesh(const mesh::Mesh& mesh, - std::string xpath = "/Xdmf/Domain"); + const std::string& xpath = "/Xdmf/Domain"); /// Save Geometry /// @param[in] geometry /// @param[in] name /// @param[in] xpath XPath of a node where Geometry will be inserted - void write_geometry(const mesh::Geometry& geometry, std::string name, - std::string xpath = "/Xdmf/Domain"); + void write_geometry(const mesh::Geometry& geometry, + const std::string& name, + const std::string& xpath = "/Xdmf/Domain"); /// Read Mesh /// @param[in] element Element that describes the geometry of a cell @@ -105,16 +106,16 @@ class XDMFFile /// @return A Mesh distributed on the same communicator as the /// XDMFFile mesh::Mesh read_mesh(const fem::CoordinateElement& element, - mesh::GhostMode mode, std::string name, - std::string xpath = "/Xdmf/Domain") const; + mesh::GhostMode mode, const std::string& name, + const std::string& xpath = "/Xdmf/Domain") const; /// Read Topology data for Mesh /// @param[in] name Name of the mesh (Grid) /// @param[in] xpath XPath where Mesh Grid data is located /// @return (Cell type, degree), and cells topology (global node indexing) std::pair, std::array> - read_topology_data(std::string name, - std::string xpath = "/Xdmf/Domain") const; + read_topology_data(const std::string& name, + const std::string& xpath = "/Xdmf/Domain") const; /// Read Geometry data for Mesh /// @param[in] name Name of the mesh (Grid) @@ -122,14 +123,15 @@ class XDMFFile /// @return points on each process std::pair, std::vector>, std::array> - read_geometry_data(std::string name, - std::string xpath = "/Xdmf/Domain") const; + read_geometry_data(const std::string& name, + const std::string& xpath = "/Xdmf/Domain") const; /// Read information about cell type /// @param[in] grid_name Name of Grid for which cell type is needed /// @param[in] xpath XPath where Grid is stored - std::pair - read_cell_type(std::string grid_name, std::string xpath = "/Xdmf/Domain"); + std::pair read_cell_type(const std::string& grid_name, + const std::string& xpath + = "/Xdmf/Domain"); /// @brief Write a fem::Function to file. /// @@ -160,8 +162,9 @@ class XDMFFile /// @param[in] xpath XPath where MeshTags Grid will be inserted template void write_meshtags(const mesh::MeshTags& meshtags, - const mesh::Geometry& x, std::string geometry_xpath, - std::string xpath = "/Xdmf/Domain"); + const mesh::Geometry& x, + const std::string& geometry_xpath, + const std::string& xpath = "/Xdmf/Domain"); /// Read MeshTags /// @param[in] mesh Mesh that the input data is defined on @@ -171,22 +174,22 @@ class XDMFFile /// @param[in] attribute_name Name of the attribute to read /// @param[in] xpath XPath where MeshTags Grid is stored in file mesh::MeshTags - read_meshtags(const mesh::Mesh& mesh, std::string name, + read_meshtags(const mesh::Mesh& mesh, const std::string& name, std::optional attribute_name, - std::string xpath = "/Xdmf/Domain"); + const std::string& xpath = "/Xdmf/Domain"); /// Write Information /// @param[in] name /// @param[in] value String to store into Information tag /// @param[in] xpath XPath where Information will be inserted - void write_information(std::string name, std::string value, - std::string xpath = "/Xdmf/Domain/"); + void write_information(const std::string& name, const std::string& value, + const std::string& xpath = "/Xdmf/Domain/"); /// Read Information /// @param[in] name /// @param[in] xpath XPath where Information is stored in file - std::string read_information(std::string name, - std::string xpath = "/Xdmf/Domain/"); + std::string read_information(const std::string& name, + const std::string& xpath = "/Xdmf/Domain/"); /// Get the MPI communicator /// @return The MPI communicator for the file object diff --git a/cpp/dolfinx/io/utils.h b/cpp/dolfinx/io/utils.h index 00d8b33172..51e3a386a8 100644 --- a/cpp/dolfinx/io/utils.h +++ b/cpp/dolfinx/io/utils.h @@ -89,7 +89,7 @@ std::pair, std::vector> distribute_entity_data( // Use ElementDofLayout of the cell to get vertex dof indices (local // to a cell), i.e. build a map from local vertex index to associated // local dof index - const std::vector entity_layout + const std::vector& entity_layout = cmap_dof_layout.entity_closure_dofs(entity_dim, 0); std::vector entity_vertex_dofs; for (std::size_t i = 0; i < cell_vertex_dofs.size(); ++i) @@ -136,6 +136,7 @@ std::pair, std::vector> distribute_entity_data( // Determine destination by index of first vertex std::vector dest0; + dest0.reserve(entities.extent(0)); for (std::size_t e = 0; e < entities.extent(0); ++e) { dest0.push_back( @@ -353,6 +354,7 @@ std::pair, std::vector> distribute_entity_data( dolfinx::MPI::check_error(comm, err); std::vector num_items_send; + num_items_send.reserve(send_data.size()); for (auto& x : send_data) num_items_send.push_back(x.size() / entities.extent(1)); diff --git a/cpp/dolfinx/io/vtk_utils.h b/cpp/dolfinx/io/vtk_utils.h index 4d2a2648d3..4964ba3438 100644 --- a/cpp/dolfinx/io/vtk_utils.h +++ b/cpp/dolfinx/io/vtk_utils.h @@ -34,7 +34,7 @@ class FunctionSpace; namespace mesh { -enum class CellType; +enum class CellType : std::int8_t; template class Geometry; } // namespace mesh diff --git a/cpp/dolfinx/io/xdmf_function.cpp b/cpp/dolfinx/io/xdmf_function.cpp index 33c78f3177..8b1f69c4ce 100644 --- a/cpp/dolfinx/io/xdmf_function.cpp +++ b/cpp/dolfinx/io/xdmf_function.cpp @@ -169,11 +169,11 @@ void xdmf_function::add_function(MPI_Comm comm, const fem::Function& u, components = {"real_", "imag_"}; std::string t_str = boost::lexical_cast(t); std::replace(t_str.begin(), t_str.end(), '.', '_'); - for (auto component : components) + for (const auto& component : components) { std::string attr_name = component + u.name; std::string dataset_name - = std::string("/Function/") + attr_name + std::string("/") + t_str; + = "/Function/" + attr_name.append("/").append(t_str); // Add attribute node pugi::xml_node attr_node = xml_node.append_child("Attribute"); diff --git a/cpp/dolfinx/io/xdmf_mesh.cpp b/cpp/dolfinx/io/xdmf_mesh.cpp index e221a940bd..d0177ada24 100644 --- a/cpp/dolfinx/io/xdmf_mesh.cpp +++ b/cpp/dolfinx/io/xdmf_mesh.cpp @@ -21,7 +21,7 @@ using namespace dolfinx::io; //----------------------------------------------------------------------------- template void xdmf_mesh::add_topology_data(MPI_Comm comm, pugi::xml_node& xml_node, - hid_t h5_id, std::string path_prefix, + hid_t h5_id, const std::string& path_prefix, const mesh::Topology& topology, const mesh::Geometry& geometry, int dim, std::span entities) @@ -98,7 +98,9 @@ void xdmf_mesh::add_topology_data(MPI_Comm comm, pugi::xml_node& xml_node, // Tabulate geometry dofs for local entities std::vector> entity_dofs; - for (int e = 0; e < mesh::cell_num_entities(cell_type, dim); ++e) + int cellc_count = mesh::cell_num_entities(cell_type, dim); + entity_dofs.reserve(cellc_count); + for (int e = 0; e < cellc_count; ++e) entity_dofs.push_back(cmap_dof_layout.entity_closure_dofs(dim, e)); for (std::int32_t e : entities) @@ -156,7 +158,7 @@ void xdmf_mesh::add_topology_data(MPI_Comm comm, pugi::xml_node& xml_node, //----------------------------------------------------------------------------- template void xdmf_mesh::add_geometry_data(MPI_Comm comm, pugi::xml_node& xml_node, - hid_t h5_id, std::string path_prefix, + hid_t h5_id, const std::string& path_prefix, const mesh::Geometry& geometry) { spdlog::info("Adding geometry data to node \"{}\"", xml_node.path('/')); diff --git a/cpp/dolfinx/io/xdmf_mesh.h b/cpp/dolfinx/io/xdmf_mesh.h index 768cd846f3..a2a4a3b070 100644 --- a/cpp/dolfinx/io/xdmf_mesh.h +++ b/cpp/dolfinx/io/xdmf_mesh.h @@ -60,14 +60,15 @@ void add_mesh(MPI_Comm comm, pugi::xml_node& xml_node, hid_t h5_id, /// whose topology will be saved. This is used to save subsets of Mesh. template void add_topology_data(MPI_Comm comm, pugi::xml_node& xml_node, hid_t h5_id, - std::string path_prefix, const mesh::Topology& topology, + const std::string& path_prefix, + const mesh::Topology& topology, const mesh::Geometry& geometry, int cell_dim, std::span entities); /// Add Geometry xml node template void add_geometry_data(MPI_Comm comm, pugi::xml_node& xml_node, hid_t h5_id, - std::string path_prefix, + const std::string& path_prefix, const mesh::Geometry& geometry); /// @brief Read geometry (coordinate) data. diff --git a/cpp/dolfinx/io/xdmf_utils.cpp b/cpp/dolfinx/io/xdmf_utils.cpp index be2d9472b9..b6a10c9414 100644 --- a/cpp/dolfinx/io/xdmf_utils.cpp +++ b/cpp/dolfinx/io/xdmf_utils.cpp @@ -130,7 +130,7 @@ xdmf_utils::get_dataset_shape(const pugi::xml_node& dataset_node) boost::split(dims_list, dims_str, boost::is_any_of(" ")); // Cast dims to integers - for (auto d : dims_list) + for (const auto& d : dims_list) dims.push_back(boost::lexical_cast(d)); } diff --git a/cpp/dolfinx/la/Vector.h b/cpp/dolfinx/la/Vector.h index e5592fb9a1..41525d7896 100644 --- a/cpp/dolfinx/la/Vector.h +++ b/cpp/dolfinx/la/Vector.h @@ -62,10 +62,9 @@ class Vector } /// Move constructor - Vector(Vector&& x) + Vector(Vector&& x) noexcept : _map(std::move(x._map)), _scatterer(std::move(x._scatterer)), - _bs(std::move(x._bs)), - _request(std::exchange(x._request, {MPI_REQUEST_NULL})), + _bs(x._bs), _request(std::exchange(x._request, {MPI_REQUEST_NULL})), _buffer_local(std::move(x._buffer_local)), _buffer_remote(std::move(x._buffer_remote)), _x(std::move(x._x)) { diff --git a/cpp/dolfinx/la/petsc.cpp b/cpp/dolfinx/la/petsc.cpp index ea59afd447..acf3d6018a 100644 --- a/cpp/dolfinx/la/petsc.cpp +++ b/cpp/dolfinx/la/petsc.cpp @@ -18,6 +18,7 @@ #include #include #include +#include using namespace dolfinx; using namespace dolfinx::la; @@ -31,8 +32,8 @@ using namespace dolfinx::la; } while (0) //----------------------------------------------------------------------------- -void la::petsc::error(int error_code, std::string filename, - std::string petsc_function) +void la::petsc::error(int error_code, const std::string& filename, + const std::string& petsc_function) { // Fetch PETSc error description const char* desc; @@ -371,7 +372,7 @@ MatNullSpace la::petsc::create_nullspace(MPI_Comm comm, //----------------------------------------------------------------------------- void petsc::options::set(std::string option) { - petsc::options::set(option, ""); + petsc::options::set(std::move(option), ""); } //----------------------------------------------------------------------------- void petsc::options::clear(std::string option) @@ -406,7 +407,7 @@ petsc::Vector::Vector(Vec x, bool inc_ref_count) : _x(x) PetscObjectReference((PetscObject)_x); } //----------------------------------------------------------------------------- -petsc::Vector::Vector(Vector&& v) : _x(std::exchange(v._x, nullptr)) {} +petsc::Vector::Vector(Vector&& v) noexcept : _x(std::exchange(v._x, nullptr)) {} //----------------------------------------------------------------------------- petsc::Vector::~Vector() { @@ -414,7 +415,7 @@ petsc::Vector::~Vector() VecDestroy(&_x); } //----------------------------------------------------------------------------- -petsc::Vector& petsc::Vector::operator=(Vector&& v) +petsc::Vector& petsc::Vector::operator=(Vector&& v) noexcept { std::swap(_x, v._x); return *this; @@ -467,7 +468,7 @@ MPI_Comm petsc::Vector::comm() const return mpi_comm; } //----------------------------------------------------------------------------- -void petsc::Vector::set_options_prefix(std::string options_prefix) +void petsc::Vector::set_options_prefix(const std::string& options_prefix) { assert(_x); PetscErrorCode ierr = VecSetOptionsPrefix(_x, options_prefix.c_str()); @@ -500,7 +501,8 @@ petsc::Operator::Operator(Mat A, bool inc_ref_count) : _matA(A) PetscObjectReference((PetscObject)_matA); } //----------------------------------------------------------------------------- -petsc::Operator::Operator(Operator&& A) : _matA(std::exchange(A._matA, nullptr)) +petsc::Operator::Operator(Operator&& A) noexcept + : _matA(std::exchange(A._matA, nullptr)) { } //----------------------------------------------------------------------------- @@ -512,7 +514,7 @@ petsc::Operator::~Operator() MatDestroy(&_matA); } //----------------------------------------------------------------------------- -petsc::Operator& petsc::Operator::operator=(Operator&& A) +petsc::Operator& petsc::Operator::operator=(Operator&& A) noexcept { std::swap(_matA, A._matA); return *this; @@ -562,7 +564,7 @@ Mat petsc::Operator::mat() const { return _matA; } //----------------------------------------------------------------------------- petsc::Matrix::Matrix(MPI_Comm comm, const SparsityPattern& sp, std::optional type) - : Operator(petsc::create_matrix(comm, sp, type), false) + : Operator(petsc::create_matrix(comm, sp, std::move(type)), false) { // Do nothing } @@ -614,7 +616,7 @@ void petsc::Matrix::apply(AssemblyType type) petsc::error(ierr, __FILE__, "MatAssemblyEnd"); } //----------------------------------------------------------------------------- -void petsc::Matrix::set_options_prefix(std::string options_prefix) +void petsc::Matrix::set_options_prefix(const std::string& options_prefix) { assert(_matA); MatSetOptionsPrefix(_matA, options_prefix.c_str()); @@ -654,7 +656,7 @@ petsc::KrylovSolver::KrylovSolver(KSP ksp, bool inc_ref_count) : _ksp(ksp) } } //----------------------------------------------------------------------------- -petsc::KrylovSolver::KrylovSolver(KrylovSolver&& solver) +petsc::KrylovSolver::KrylovSolver(KrylovSolver&& solver) noexcept : _ksp(std::exchange(solver._ksp, nullptr)) { // Do nothing @@ -666,7 +668,8 @@ petsc::KrylovSolver::~KrylovSolver() KSPDestroy(&_ksp); } //----------------------------------------------------------------------------- -petsc::KrylovSolver& petsc::KrylovSolver::operator=(KrylovSolver&& solver) +petsc::KrylovSolver& +petsc::KrylovSolver::operator=(KrylovSolver&& solver) noexcept { std::swap(_ksp, solver._ksp); return *this; @@ -761,7 +764,7 @@ int petsc::KrylovSolver::solve(Vec x, const Vec b, bool transpose) const return num_iterations; } //----------------------------------------------------------------------------- -void petsc::KrylovSolver::set_options_prefix(std::string options_prefix) +void petsc::KrylovSolver::set_options_prefix(const std::string& options_prefix) { // Set options prefix assert(_ksp); diff --git a/cpp/dolfinx/la/petsc.h b/cpp/dolfinx/la/petsc.h index 82a686ed5c..9b1443b8e1 100644 --- a/cpp/dolfinx/la/petsc.h +++ b/cpp/dolfinx/la/petsc.h @@ -35,7 +35,8 @@ class SparsityPattern; namespace petsc { /// Print error message for PETSc calls that return an error -void error(int error_code, std::string filename, std::string petsc_function); +void error(int error_code, const std::string& filename, + const std::string& petsc_function); /// Create PETsc vectors from the local data. The data is copied into /// the PETSc vectors and is not shared. @@ -140,7 +141,7 @@ void set(std::string option); /// Generic function for setting PETSc option template -void set(std::string option, const T value) +void set(std::string option, const T& value) { if (option[0] != '-') option = '-' + option; @@ -177,7 +178,7 @@ class Vector Vector(const Vector& x) = delete; /// Move constructor - Vector(Vector&& x); + Vector(Vector&& x) noexcept; /// Create holder of a PETSc Vec object/pointer. The Vec x object /// should already be created. If inc_ref_count is true, the reference @@ -199,7 +200,7 @@ class Vector Vector& operator=(const Vector& x) = delete; /// Move Assignment operator - Vector& operator=(Vector&& x); + Vector& operator=(Vector&& x) noexcept; /// Create a copy of the vector /// @note Collective @@ -218,7 +219,7 @@ class Vector MPI_Comm comm() const; /// Sets the prefix used by PETSc when searching the options database - void set_options_prefix(std::string options_prefix); + void set_options_prefix(const std::string& options_prefix); /// Returns the prefix used by PETSc when searching the options /// database @@ -247,7 +248,7 @@ class Operator Operator(const Operator& A) = delete; /// Move constructor - Operator(Operator&& A); + Operator(Operator&& A) noexcept; /// Destructor virtual ~Operator(); @@ -256,7 +257,7 @@ class Operator Operator& operator=(const Operator& A) = delete; /// Move assignment operator - Operator& operator=(Operator&& A); + Operator& operator=(Operator&& A) noexcept; /// Return number of rows and columns (num_rows, num_cols). PETSc /// returns -1 if size has not been set. @@ -417,7 +418,7 @@ class Matrix : public Operator /// Assembly type /// FINAL - corresponds to PETSc MAT_FINAL_ASSEMBLY /// FLUSH - corresponds to PETSc MAT_FLUSH_ASSEMBLY - enum class AssemblyType : std::int32_t + enum class AssemblyType : std::int8_t { FINAL, FLUSH @@ -437,7 +438,7 @@ class Matrix : public Operator /// Sets the prefix used by PETSc when searching the options /// database - void set_options_prefix(std::string options_prefix); + void set_options_prefix(const std::string& options_prefix); /// Returns the prefix used by PETSc when searching the options /// database @@ -465,7 +466,7 @@ class KrylovSolver KrylovSolver(const KrylovSolver& solver) = delete; /// Move constructor - KrylovSolver(KrylovSolver&& solver); + KrylovSolver(KrylovSolver&& solver) noexcept; /// Destructor ~KrylovSolver(); @@ -474,7 +475,7 @@ class KrylovSolver KrylovSolver& operator=(const KrylovSolver&) = delete; /// Move assignment - KrylovSolver& operator=(KrylovSolver&& solver); + KrylovSolver& operator=(KrylovSolver&& solver) noexcept; /// Set operator (Mat) void set_operator(const Mat A); @@ -488,7 +489,7 @@ class KrylovSolver /// Sets the prefix used by PETSc when searching the PETSc options /// database - void set_options_prefix(std::string options_prefix); + void set_options_prefix(const std::string& options_prefix); /// Returns the prefix used by PETSc when searching the PETSc options /// database diff --git a/cpp/dolfinx/la/slepc.cpp b/cpp/dolfinx/la/slepc.cpp index 11ba6ea0be..e1f16e5fee 100644 --- a/cpp/dolfinx/la/slepc.cpp +++ b/cpp/dolfinx/la/slepc.cpp @@ -34,7 +34,7 @@ SLEPcEigenSolver::SLEPcEigenSolver(EPS eps, bool inc_ref_count) : _eps(eps) } } //----------------------------------------------------------------------------- -SLEPcEigenSolver::SLEPcEigenSolver(SLEPcEigenSolver&& solver) +SLEPcEigenSolver::SLEPcEigenSolver(SLEPcEigenSolver&& solver) noexcept : _eps(std::exchange(solver._eps, nullptr)) { // Do nothing @@ -46,7 +46,8 @@ SLEPcEigenSolver::~SLEPcEigenSolver() EPSDestroy(&_eps); } //----------------------------------------------------------------------------- -SLEPcEigenSolver& SLEPcEigenSolver::operator=(SLEPcEigenSolver&& solver) +SLEPcEigenSolver& +SLEPcEigenSolver::operator=(SLEPcEigenSolver&& solver) noexcept { std::swap(_eps, solver._eps); return *this; @@ -162,7 +163,7 @@ std::int64_t SLEPcEigenSolver::get_number_converged() const return num_conv; } //----------------------------------------------------------------------------- -void SLEPcEigenSolver::set_options_prefix(std::string options_prefix) +void SLEPcEigenSolver::set_options_prefix(const std::string& options_prefix) { assert(_eps); PetscErrorCode ierr = EPSSetOptionsPrefix(_eps, options_prefix.c_str()); diff --git a/cpp/dolfinx/la/slepc.h b/cpp/dolfinx/la/slepc.h index c59c24d696..58e0124fcc 100644 --- a/cpp/dolfinx/la/slepc.h +++ b/cpp/dolfinx/la/slepc.h @@ -33,7 +33,7 @@ class SLEPcEigenSolver SLEPcEigenSolver(const SLEPcEigenSolver&) = delete; /// Move constructor - SLEPcEigenSolver(SLEPcEigenSolver&& solver); + SLEPcEigenSolver(SLEPcEigenSolver&& solver) noexcept; /// Destructor ~SLEPcEigenSolver(); @@ -42,7 +42,7 @@ class SLEPcEigenSolver SLEPcEigenSolver& operator=(const SLEPcEigenSolver&) = delete; /// Move assignment - SLEPcEigenSolver& operator=(SLEPcEigenSolver&& solver); + SLEPcEigenSolver& operator=(SLEPcEigenSolver&& solver) noexcept; /// Set operators (B may be nullptr for regular eigenvalues /// problems) @@ -70,7 +70,7 @@ class SLEPcEigenSolver /// Sets the prefix used by PETSc when searching the PETSc options /// database - void set_options_prefix(std::string options_prefix); + void set_options_prefix(const std::string& options_prefix); /// Returns the prefix used by PETSc when searching the PETSc options /// database diff --git a/cpp/dolfinx/la/utils.h b/cpp/dolfinx/la/utils.h index c6d9fa74a8..f2a6846079 100644 --- a/cpp/dolfinx/la/utils.h +++ b/cpp/dolfinx/la/utils.h @@ -13,7 +13,7 @@ namespace dolfinx::la { /// Norm types -enum class Norm +enum class Norm : std::int8_t { l1, l2, diff --git a/cpp/dolfinx/mesh/Geometry.h b/cpp/dolfinx/mesh/Geometry.h index d631cb160c..6b9b5597a0 100644 --- a/cpp/dolfinx/mesh/Geometry.h +++ b/cpp/dolfinx/mesh/Geometry.h @@ -71,8 +71,9 @@ class Geometry const std::vector>>& elements, V&& x, int dim, W&& input_global_indices) - : _dim(dim), _dofmaps(std::forward(dofmaps)), _index_map(index_map), - _cmaps(elements), _x(std::forward(x)), + : _dim(dim), _dofmaps(std::forward(dofmaps)), + _index_map(std::move(index_map)), _cmaps(elements), + _x(std::forward(x)), _input_global_indices(std::forward(input_global_indices)) { assert(_x.size() % 3 == 0); @@ -233,15 +234,14 @@ Geometry(std::shared_ptr, U&&, /// @return A mesh geometry. template Geometry> -create_geometry( - const Topology& topology, - const std::vector>>& elements, - std::span nodes, std::span xdofs, - const U& x, int dim, - std::function(const graph::AdjacencyList&)> - reorder_fn - = nullptr) +create_geometry(const Topology& topology, + const std::vector>>& elements, + std::span nodes, + std::span xdofs, const U& x, int dim, + const std::function( + const graph::AdjacencyList&)>& reorder_fn + = nullptr) { spdlog::info("Create Geometry (multiple)"); @@ -255,6 +255,7 @@ create_geometry( throw std::runtime_error("Mismatch between topology and geometry."); std::vector dof_layouts; + dof_layouts.reserve(elements.size()); for (const auto& el : elements) dof_layouts.push_back(el.create_dof_layout()); diff --git a/cpp/dolfinx/mesh/Mesh.h b/cpp/dolfinx/mesh/Mesh.h index c43429969c..eca9d70017 100644 --- a/cpp/dolfinx/mesh/Mesh.h +++ b/cpp/dolfinx/mesh/Mesh.h @@ -36,7 +36,8 @@ class Mesh template requires std::is_convertible_v, Geometry> Mesh(MPI_Comm comm, std::shared_ptr topology, V&& geometry) - : _topology(topology), _geometry(std::forward(geometry)), _comm(comm) + : _topology(std::move(topology)), _geometry(std::forward(geometry)), + _comm(comm) { // Do nothing } diff --git a/cpp/dolfinx/mesh/MeshTags.h b/cpp/dolfinx/mesh/MeshTags.h index d871db35da..8fd242d108 100644 --- a/cpp/dolfinx/mesh/MeshTags.h +++ b/cpp/dolfinx/mesh/MeshTags.h @@ -49,8 +49,8 @@ class MeshTags std::vector> MeshTags(std::shared_ptr topology, int dim, U&& indices, V&& values) - : _topology(topology), _dim(dim), _indices(std::forward(indices)), - _values(std::forward(values)) + : _topology(std::move(topology)), _dim(dim), + _indices(std::forward(indices)), _values(std::forward(values)) { if (_indices.size() != _values.size()) { @@ -135,7 +135,8 @@ class MeshTags /// @note Entities that do not exist on this rank are ignored. /// @warning `entities` must not contain duplicate entities. template -MeshTags create_meshtags(std::shared_ptr topology, int dim, +MeshTags create_meshtags(const std::shared_ptr& topology, + int dim, const graph::AdjacencyList& entities, std::span values) { diff --git a/cpp/dolfinx/mesh/Topology.cpp b/cpp/dolfinx/mesh/Topology.cpp index c4249e7aa1..ecf54d7d60 100644 --- a/cpp/dolfinx/mesh/Topology.cpp +++ b/cpp/dolfinx/mesh/Topology.cpp @@ -740,7 +740,7 @@ build_entity_types(const std::vector& cell_types) //----------------------------------------------------------------------------- Topology::Topology( std::vector cell_types, - std::shared_ptr vertex_map, + const std::shared_ptr& vertex_map, std::vector> cell_maps, std::vector>> cells, const std::optional>>& original_index) @@ -1230,6 +1230,7 @@ Topology mesh::create_topology( std::ranges::sort(global_to_local_vertices); std::vector> _cells_local_idx; + _cells_local_idx.reserve(cells.size()); for (std::span c : cells) { _cells_local_idx.push_back( @@ -1272,6 +1273,7 @@ Topology mesh::create_topology( // Set cell index map and connectivity std::vector>> cells_c; + cells_c.reserve(cell_types.size()); for (std::size_t i = 0; i < cell_types.size(); ++i) { cells_c.push_back(std::make_shared>( @@ -1445,8 +1447,9 @@ mesh::compute_mixed_cell_pairs(const Topology& topology, mesh::CellType facet_type) { int tdim = topology.dim(); - std::vector cell_types = topology.entity_types(tdim); - std::vector facet_types = topology.entity_types(tdim - 1); + const std::vector& cell_types = topology.entity_types(tdim); + const std::vector& facet_types + = topology.entity_types(tdim - 1); int facet_index = -1; for (std::size_t i = 0; i < facet_types.size(); ++i) @@ -1470,7 +1473,7 @@ mesh::compute_mixed_cell_pairs(const Topology& topology, auto cfi = topology.connectivity({tdim, static_cast(i)}, {tdim - 1, facet_index}); - auto local_facet = [](auto cf, std::int32_t c, std::int32_t f) + auto local_facet = [](const auto& cf, std::int32_t c, std::int32_t f) { auto it = std::find(cf->links(c).begin(), cf->links(c).end(), f); if (it == cf->links(c).end()) diff --git a/cpp/dolfinx/mesh/Topology.h b/cpp/dolfinx/mesh/Topology.h index 47c4194a0a..5692712ac0 100644 --- a/cpp/dolfinx/mesh/Topology.h +++ b/cpp/dolfinx/mesh/Topology.h @@ -30,7 +30,7 @@ class AdjacencyList; namespace dolfinx::mesh { -enum class CellType; +enum class CellType : std::int8_t; /// @brief Topology stores the topology of a mesh, consisting of mesh /// entities and connectivity (incidence relations for the mesh @@ -64,7 +64,7 @@ class Topology /// `cells`. Topology( std::vector cell_types, - std::shared_ptr vertex_map, + const std::shared_ptr& vertex_map, std::vector> cell_maps, std::vector>> cells, const std::optional>>& diff --git a/cpp/dolfinx/mesh/cell_types.cpp b/cpp/dolfinx/mesh/cell_types.cpp index a1435c1ed0..1134655605 100644 --- a/cpp/dolfinx/mesh/cell_types.cpp +++ b/cpp/dolfinx/mesh/cell_types.cpp @@ -127,7 +127,7 @@ graph::AdjacencyList mesh::get_sub_entities(CellType type, int dim0, std::vector> subset; subset.reserve(connectivity.size()); for (auto& row : connectivity) - subset.emplace_back(std::move(row[dim1])); + subset.emplace_back(row[dim1]); return graph::AdjacencyList(subset); } //----------------------------------------------------------------------------- diff --git a/cpp/dolfinx/mesh/cell_types.h b/cpp/dolfinx/mesh/cell_types.h index c5d8fc7986..f2faf3935b 100644 --- a/cpp/dolfinx/mesh/cell_types.h +++ b/cpp/dolfinx/mesh/cell_types.h @@ -18,7 +18,7 @@ namespace dolfinx::mesh { /// Cell type identifier -enum class CellType : int +enum class CellType : std::int8_t { // NOTE: Simplex cells have index > 0, see mesh::is_simplex point = 1, diff --git a/cpp/dolfinx/mesh/graphbuild.h b/cpp/dolfinx/mesh/graphbuild.h index 2aab6bca6f..3fcd9bc647 100644 --- a/cpp/dolfinx/mesh/graphbuild.h +++ b/cpp/dolfinx/mesh/graphbuild.h @@ -20,7 +20,7 @@ class AdjacencyList; namespace dolfinx::mesh { -enum class CellType; +enum class CellType : std::int8_t; /// @brief Compute the local part of the dual graph (cell-cell /// connections via facets) and facets with only one attached cell. diff --git a/cpp/dolfinx/mesh/permutationcomputation.cpp b/cpp/dolfinx/mesh/permutationcomputation.cpp index e870140342..c64d4cc800 100644 --- a/cpp/dolfinx/mesh/permutationcomputation.cpp +++ b/cpp/dolfinx/mesh/permutationcomputation.cpp @@ -123,11 +123,11 @@ std::vector> compute_triangle_quad_face_permutations(const mesh::Topology& topology, int cell_index) { - std::vector cell_types = topology.entity_types(3); + const std::vector& cell_types = topology.entity_types(3); mesh::CellType cell_type = cell_types.at(cell_index); // Get face types of the cell and mesh - std::vector mesh_face_types = topology.entity_types(2); + const std::vector& mesh_face_types = topology.entity_types(2); std::vector cell_face_types( mesh::cell_num_entities(cell_type, 2)); for (std::size_t i = 0; i < cell_face_types.size(); ++i) diff --git a/cpp/dolfinx/mesh/utils.cpp b/cpp/dolfinx/mesh/utils.cpp index 3491e36712..0dcc76e52b 100644 --- a/cpp/dolfinx/mesh/utils.cpp +++ b/cpp/dolfinx/mesh/utils.cpp @@ -35,7 +35,7 @@ mesh::extract_topology(CellType cell_type, const fem::ElementDofLayout& layout, std::vector local_vertices(num_vertices_per_cell); for (int i = 0; i < num_vertices_per_cell; ++i) { - const std::vector local_index = layout.entity_dofs(0, i); + const std::vector& local_index = layout.entity_dofs(0, i); assert(local_index.size() == 1); local_vertices[i] = local_index[0]; } diff --git a/cpp/dolfinx/mesh/utils.h b/cpp/dolfinx/mesh/utils.h index 03d6b389d9..a38914c05a 100644 --- a/cpp/dolfinx/mesh/utils.h +++ b/cpp/dolfinx/mesh/utils.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -30,10 +31,10 @@ class ElementDofLayout; namespace dolfinx::mesh { -enum class CellType; +enum class CellType : std::int8_t; /// Enum for different partitioning ghost modes -enum class GhostMode : int +enum class GhostMode : std::uint8_t { none, shared_facet, @@ -857,10 +858,10 @@ Mesh> create_mesh( assert(cells.size() == elements.size()); std::vector celltypes; std::ranges::transform(elements, std::back_inserter(celltypes), - [](auto e) { return e.cell_shape(); }); + [](const auto& e) { return e.cell_shape(); }); std::vector doflayouts; std::ranges::transform(elements, std::back_inserter(doflayouts), - [](auto e) { return e.create_dof_layout(); }); + [](const auto& e) { return e.create_dof_layout(); }); // Note: `extract_topology` extracts topology data, i.e. just the // vertices. For P1 geometry this should just be the identity diff --git a/cpp/dolfinx/nls/NewtonSolver.cpp b/cpp/dolfinx/nls/NewtonSolver.cpp index 1c5d5e8939..a8ec0706eb 100644 --- a/cpp/dolfinx/nls/NewtonSolver.cpp +++ b/cpp/dolfinx/nls/NewtonSolver.cpp @@ -11,6 +11,7 @@ #include #include #include +#include using namespace dolfinx; @@ -93,7 +94,7 @@ nls::petsc::NewtonSolver::~NewtonSolver() void nls::petsc::NewtonSolver::setF(std::function F, Vec b) { - _fnF = F; + _fnF = std::move(F); _b = b; PetscObjectReference((PetscObject)_b); } @@ -101,7 +102,7 @@ void nls::petsc::NewtonSolver::setF(std::function F, void nls::petsc::NewtonSolver::setJ(std::function J, Mat Jmat) { - _fnJ = J; + _fnJ = std::move(J); _matJ = Jmat; PetscObjectReference((PetscObject)_matJ); } @@ -109,7 +110,7 @@ void nls::petsc::NewtonSolver::setJ(std::function J, void nls::petsc::NewtonSolver::setP(std::function P, Mat Pmat) { - _fnP = P; + _fnP = std::move(P); _matP = Pmat; PetscObjectReference((PetscObject)_matP); } @@ -127,19 +128,19 @@ la::petsc::KrylovSolver& nls::petsc::NewtonSolver::get_krylov_solver() //----------------------------------------------------------------------------- void nls::petsc::NewtonSolver::set_form(std::function form) { - _system = form; + _system = std::move(form); } //----------------------------------------------------------------------------- void nls::petsc::NewtonSolver::set_convergence_check( std::function(const NewtonSolver&, const Vec)> c) { - _converged = c; + _converged = std::move(c); } //----------------------------------------------------------------------------- void nls::petsc::NewtonSolver::set_update( std::function update) { - _update_solution = update; + _update_solution = std::move(update); } //----------------------------------------------------------------------------- std::pair nls::petsc::NewtonSolver::solve(Vec x) diff --git a/cpp/dolfinx/refinement/plaza.cpp b/cpp/dolfinx/refinement/plaza.cpp index 8dcd037e19..8189fe321a 100644 --- a/cpp/dolfinx/refinement/plaza.cpp +++ b/cpp/dolfinx/refinement/plaza.cpp @@ -177,7 +177,7 @@ get_tetrahedra(std::span indices, } } - return {std::move(tet_set), tet_set_size}; + return {tet_set, tet_set_size}; } //----------------------------------------------------------------------------- } // namespace diff --git a/cpp/dolfinx/refinement/utils.h b/cpp/dolfinx/refinement/utils.h index 4c47ce94a6..a51a972031 100644 --- a/cpp/dolfinx/refinement/utils.h +++ b/cpp/dolfinx/refinement/utils.h @@ -25,7 +25,7 @@ namespace dolfinx::mesh template class MeshTags; class Topology; -enum class GhostMode; +enum class GhostMode : std::uint8_t; } // namespace dolfinx::mesh namespace dolfinx::common @@ -245,6 +245,7 @@ create_new_vertices(MPI_Comm comm, // Add received remote global vertex indices to map std::vector recv_global_edge; + recv_global_edge.reserve(received_values.size() / 2); assert(received_values.size() % 2 == 0); for (std::size_t i = 0; i < received_values.size() / 2; ++i) recv_global_edge.push_back(received_values[i * 2]); From d7ba1ccbe93c21e54cefdcbdc07e44ed46c43fd5 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Sun, 4 May 2025 17:28:59 +0200 Subject: [PATCH 05/15] Add clang-tidy flag no-unknown-warning-option --- .clang-tidy | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.clang-tidy b/.clang-tidy index 15985ed0ef..4053b0f11d 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,6 +1,8 @@ WarningsAsErrors: "*" UseColor: true HeaderFilterRegex: '.*' +ExtraArgsBefore: + - '-Wno-unknown-warning-option' Checks: > -*, - performance* \ No newline at end of file + performance* From 81c0227db75ed79caebeb97592eefd4fc7bf9027 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:06:49 +0200 Subject: [PATCH 06/15] Tidy cmake command --- .github/workflows/clang-tidy.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index be200b2be0..fa060554ad 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -53,6 +53,16 @@ jobs: - name: Configure, build and install C++ library run: | - cmake -G Ninja -DCMAKE_BUILD_TYPE=Developer -DDOLFINX_ENABLE_ADIOS2=true -DDOLFINX_ENABLE_KAHIP=true -DDOLFINX_ENABLE_PARMETIS=false -DDOLFINX_ENABLE_PETSC=true -DDOLFINX_ENABLE_SCOTCH=true -DDOLFINX_ENABLE_SLEPC=true -DENABLE_CLANG_TIDY=ON -B build -S cpp/ + cmake -G Ninja \ + -B build \ + -S cpp/ \ + -DCMAKE_BUILD_TYPE=Developer \ + -DDOLFINX_ENABLE_ADIOS2=ON \ + -DDOLFINX_ENABLE_KAHIP=ON \ + -DDOLFINX_ENABLE_PARMETIS=OFF \ + -DDOLFINX_ENABLE_PETSC=ON \ + -DDOLFINX_ENABLE_SCOTCH=ON \ + -DDOLFINX_ENABLE_SLEPC=ON \ + -DENABLE_CLANG_TIDY=ON cmake --build build cmake --install build \ No newline at end of file From dce7402a9d112c8410cf4458ee84e4fa50a67306 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:12:16 +0200 Subject: [PATCH 07/15] More fine tuning --- .github/workflows/clang-tidy.yml | 40 ++++++++++++++------------------ 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index fa060554ad..67d7be2375 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -37,32 +37,28 @@ jobs: - name: Load environment variables run: cat .github/workflows/fenicsx-refs.env >> $GITHUB_ENV - - name: Install FEniCS Python components (default branches/tags) - if: github.event_name != 'workflow_dispatch' - run: | - pip install git+https://github.com/FEniCS/ufl.git@${{ env.ufl_ref }} - pip install git+https://github.com/FEniCS/basix.git@${{ env.basix_ref }} - pip install git+https://github.com/FEniCS/ffcx.git@${{ env.ffcx_ref }} - - name: Install FEniCS Python components - if: github.event_name == 'workflow_dispatch' run: | pip install git+https://github.com/FEniCS/ufl.git@${{ env.ufl_ref }} pip install git+https://github.com/FEniCS/basix.git@${{ env.basix_ref }} pip install git+https://github.com/FEniCS/ffcx.git@${{ env.ffcx_ref }} - - name: Configure, build and install C++ library - run: | - cmake -G Ninja \ - -B build \ - -S cpp/ \ - -DCMAKE_BUILD_TYPE=Developer \ - -DDOLFINX_ENABLE_ADIOS2=ON \ - -DDOLFINX_ENABLE_KAHIP=ON \ - -DDOLFINX_ENABLE_PARMETIS=OFF \ - -DDOLFINX_ENABLE_PETSC=ON \ - -DDOLFINX_ENABLE_SCOTCH=ON \ - -DDOLFINX_ENABLE_SLEPC=ON \ + - name: Configure (C++ lib) + run: > + cmake -G Ninja + -B build + -S cpp/ + -DCMAKE_BUILD_TYPE=Developer -DENABLE_CLANG_TIDY=ON - cmake --build build - cmake --install build \ No newline at end of file + -DDOLFINX_ENABLE_ADIOS2=ON + -DDOLFINX_ENABLE_KAHIP=ON + -DDOLFINX_ENABLE_PETSC=ON + -DDOLFINX_ENABLE_SCOTCH=ON + -DDOLFINX_ENABLE_SLEPC=ON + -DDOLFINX_ENABLE_PARMETIS=OFF + + - name: Build (C++ lib) + run: cmake --build build + + - name: Install (C++ lib) + run: cmake --install build From 5298a3e06eaac1759abf8840d5c28b4b0f68326c Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:19:53 +0200 Subject: [PATCH 08/15] Remove tab --- .github/workflows/clang-tidy.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index 67d7be2375..119a5b7556 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -46,16 +46,16 @@ jobs: - name: Configure (C++ lib) run: > cmake -G Ninja - -B build - -S cpp/ - -DCMAKE_BUILD_TYPE=Developer - -DENABLE_CLANG_TIDY=ON - -DDOLFINX_ENABLE_ADIOS2=ON - -DDOLFINX_ENABLE_KAHIP=ON - -DDOLFINX_ENABLE_PETSC=ON - -DDOLFINX_ENABLE_SCOTCH=ON - -DDOLFINX_ENABLE_SLEPC=ON - -DDOLFINX_ENABLE_PARMETIS=OFF + -B build + -S cpp/ + -DCMAKE_BUILD_TYPE=Developer + -DENABLE_CLANG_TIDY=ON + -DDOLFINX_ENABLE_ADIOS2=ON + -DDOLFINX_ENABLE_KAHIP=ON + -DDOLFINX_ENABLE_PETSC=ON + -DDOLFINX_ENABLE_SCOTCH=ON + -DDOLFINX_ENABLE_SLEPC=ON + -DDOLFINX_ENABLE_PARMETIS=OFF - name: Build (C++ lib) run: cmake --build build From f5687b6d1c1e4847b37fc61a75f503aee6606114 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:32:29 +0200 Subject: [PATCH 09/15] Add clang-tidy option to C++ tests --- .github/workflows/clang-tidy.yml | 10 ++++++++++ cpp/test/CMakeLists.txt | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index 119a5b7556..c71ea67ce7 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -62,3 +62,13 @@ jobs: - name: Install (C++ lib) run: cmake --install build + + - name: Configure (C++ test) + run: > + cmake -G Ninja + -B build-test + -S cpp/test/ + -DENABLE_CLANG_TIDY=ON + + - name: Build (C++ test) + run: cmake --build build-test diff --git a/cpp/test/CMakeLists.txt b/cpp/test/CMakeLists.txt index af258d1a07..bb40aaa977 100644 --- a/cpp/test/CMakeLists.txt +++ b/cpp/test/CMakeLists.txt @@ -9,11 +9,17 @@ set(CMAKE_CXX_EXTENSIONS OFF) # Find DOLFINx config file find_package(DOLFINX REQUIRED) +include(FeatureSummary) + # Add shared library paths so shared libs in non-system paths are found option(CMAKE_INSTALL_RPATH_USE_LINK_PATH "Add paths to linker search and installed rpath." ON ) +# clang-tidy +option(ENABLE_CLANG_TIDY "Run clang-tidy while building" OFF) +add_feature_info(ENABLE_CLANG_TIDY ENABLE_CLANG_TIDY "Run clang-tidy while building") + add_custom_command( OUTPUT expr.c COMMAND ffcx ${CMAKE_CURRENT_SOURCE_DIR}/fem/expr.py @@ -91,6 +97,11 @@ target_compile_options( $<$,$>:${DOLFINX_CXX_DEVELOPER_FLAGS}> ) +if(ENABLE_CLANG_TIDY) + find_program(CLANG_TIDY NAMES clang-tidy REQUIRED) + set_target_properties(unittests PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY};--config-file=${CMAKE_CURRENT_SOURCE_DIR}/../../.clang-tidy") +endif() + # Enable testing enable_testing() From fd319e5c496fabbe751a071cb6fe09e1a3c8f093 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:37:48 +0200 Subject: [PATCH 10/15] Remove catch2 clang-tidy lints by using system installed version --- .github/workflows/clang-tidy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index c71ea67ce7..b04c0029e6 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -32,7 +32,7 @@ jobs: - name: Install dependencies run: | apt-get update - apt-get install -y clang-tidy + apt-get install -y clang-tidy catch2 - name: Load environment variables run: cat .github/workflows/fenicsx-refs.env >> $GITHUB_ENV From 2503d8cc3cddaa6cf2ad8d4a615d86de26ae3bb4 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Mon, 23 Jun 2025 15:00:11 +0200 Subject: [PATCH 11/15] Fix tests --- cpp/test/fem/form.cpp | 4 ++-- cpp/test/mesh/distributed_mesh.cpp | 4 ++-- cpp/test/mesh/generation.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cpp/test/fem/form.cpp b/cpp/test/fem/form.cpp index cb4b56df05..348ae15c5e 100644 --- a/cpp/test/fem/form.cpp +++ b/cpp/test/fem/form.cpp @@ -19,13 +19,13 @@ using namespace dolfinx; namespace { -void test_form_cmap_compat(auto V) +void test_form_cmap_compat(const auto& V) { fem::create_form(*form_expr_L1, {V}, {}, {}, {}, {}); CHECK_THROWS(fem::create_form(*form_expr_L2, {V}, {}, {}, {}, {})); } -void test_expression_cmap_compat(auto V) +void test_expression_cmap_compat(const auto& V) { auto u = std::make_shared>(V); auto mesh = u->function_space()->mesh(); diff --git a/cpp/test/mesh/distributed_mesh.cpp b/cpp/test/mesh/distributed_mesh.cpp index 07e8f5a4b1..a9b240a279 100644 --- a/cpp/test/mesh/distributed_mesh.cpp +++ b/cpp/test/mesh/distributed_mesh.cpp @@ -37,7 +37,7 @@ constexpr int N = 8; file.write_mesh(*mesh); } -[[maybe_unused]] void test_create_box(mesh::CellPartitionFunction part) +[[maybe_unused]] void test_create_box(const mesh::CellPartitionFunction& part) { MPI_Comm comm; MPI_Comm_dup(MPI_COMM_WORLD, &comm); @@ -84,7 +84,7 @@ constexpr int N = 8; MPI_Comm_free(&comm); } -void test_distributed_mesh(mesh::CellPartitionFunction partitioner) +void test_distributed_mesh(const mesh::CellPartitionFunction& partitioner) { using T = double; diff --git a/cpp/test/mesh/generation.cpp b/cpp/test/mesh/generation.cpp index a860207c6d..e227a18a4e 100644 --- a/cpp/test/mesh/generation.cpp +++ b/cpp/test/mesh/generation.cpp @@ -114,7 +114,7 @@ TEMPLATE_TEST_CASE("Interval mesh (parallel)", "[mesh][interval]", float, else SKIP("Test only supports <= 3 processes"); - return graph::AdjacencyList(std::move(data)); + return graph::AdjacencyList(data); }; mesh::Mesh mesh = mesh::create_interval( From 452729eb91e9d5ee23aa7fd308a016bad3c2f99e Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Mon, 23 Jun 2025 16:01:18 +0200 Subject: [PATCH 12/15] Add clang-tidy cmake option to python module --- .github/workflows/clang-tidy.yml | 8 ++++++++ python/CMakeLists.txt | 13 +++++++++++++ 2 files changed, 21 insertions(+) diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index b04c0029e6..a1f86b2ceb 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -72,3 +72,11 @@ jobs: - name: Build (C++ test) run: cmake --build build-test + + - name: Build (Python) + working-directory: python + run: > + pip install . + --no-build-isolation + --verbose + --config-settings=cmake.define.ENABLE_CLANG_TIDY=ON diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 42a5b6ef04..5893048c3c 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -14,6 +14,14 @@ find_package( REQUIRED ) +# Options +include(FeatureSummary) + +option(ENABLE_CLANG_TIDY "Run clang-tidy while building" OFF) +add_feature_info(ENABLE_CLANG_TIDY ENABLE_CLANG_TIDY "Run clang-tidy while building") + +feature_summary(WHAT ALL) + # Detect the installed nanobind package and import it into CMake execute_process( COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir @@ -68,6 +76,11 @@ endif() set(CMAKE_CXX_EXTENSIONS OFF) target_compile_definitions(cpp PRIVATE cxx_std_20) +if(ENABLE_CLANG_TIDY) + find_program(CLANG_TIDY NAMES clang-tidy REQUIRED) + set_target_properties(cpp PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY};--config-file=${CMAKE_CURRENT_SOURCE_DIR}/../.clang-tidy") +endif() + # Add DOLFINx libraries target_link_libraries(cpp PRIVATE dolfinx) # UUID requires bcrypt to be linked on Windows, broken in vcpkg. From 47ab3be97235686ecb16bbd2cceac873a855d089 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Mon, 23 Jun 2025 16:13:23 +0200 Subject: [PATCH 13/15] Add build dependencies install --- .github/workflows/clang-tidy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index a1f86b2ceb..1dd47573bd 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -33,6 +33,7 @@ jobs: run: | apt-get update apt-get install -y clang-tidy catch2 + pip install -r python/build-requirements.txt - name: Load environment variables run: cat .github/workflows/fenicsx-refs.env >> $GITHUB_ENV From 3cea74c6d191bab1ec9839bf541ac8cc6e892d71 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Mon, 23 Jun 2025 17:42:03 +0200 Subject: [PATCH 14/15] Fix python module --- .clang-tidy | 1 + python/dolfinx/wrappers/assemble.cpp | 44 ++--- python/dolfinx/wrappers/common.cpp | 29 +-- .../dolfinx/wrappers/dolfinx_wrappers/mesh.h | 6 +- python/dolfinx/wrappers/fem.cpp | 170 ++++++++++-------- python/dolfinx/wrappers/geometry.cpp | 36 ++-- python/dolfinx/wrappers/graph.cpp | 13 +- python/dolfinx/wrappers/io.cpp | 55 +++--- python/dolfinx/wrappers/la.cpp | 17 +- python/dolfinx/wrappers/log.cpp | 8 +- python/dolfinx/wrappers/mesh.cpp | 112 ++++++------ python/dolfinx/wrappers/petsc.cpp | 38 ++-- python/dolfinx/wrappers/refinement.cpp | 14 +- 13 files changed, 306 insertions(+), 237 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 4053b0f11d..c7f809c375 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,6 +1,7 @@ WarningsAsErrors: "*" UseColor: true HeaderFilterRegex: '.*' +ExcludeHeaderFilterRegex: 'MPI_api.h|PETSc_api.h' # Pulled in from python packages and not classified as system headers ExtraArgsBefore: - '-Wno-unknown-warning-option' Checks: > diff --git a/python/dolfinx/wrappers/assemble.cpp b/python/dolfinx/wrappers/assemble.cpp index 99aaec789f..94211edbf7 100644 --- a/python/dolfinx/wrappers/assemble.cpp +++ b/python/dolfinx/wrappers/assemble.cpp @@ -212,7 +212,7 @@ void declare_assembly_functions(nb::module_& m) m.def( "pack_coefficients", [](const dolfinx::fem::Expression& e, - nb::ndarray entities) + const nb::ndarray& entities) { std::vector coffsets = e.coefficient_offsets(); const std::vector>>& @@ -222,9 +222,10 @@ void declare_assembly_functions(nb::module_& m) std::size_t cstride = coffsets.back(); std::vector>> c; - std::ranges::transform(coefficients, std::back_inserter(c), - [](auto c) -> const dolfinx::fem::Function& - { return *c; }); + std::ranges::transform( + coefficients, std::back_inserter(c), + [](const auto& c) -> const dolfinx::fem::Function& + { return *c; }); if (entities.ndim() == 1) { @@ -261,12 +262,12 @@ void declare_assembly_functions(nb::module_& m) // Expression m.def( "tabulate_expression", - [](nb::ndarray values, + [](const nb::ndarray& values, const dolfinx::fem::Expression& e, - nb::ndarray, nb::c_contig> constants, - nb::ndarray, nb::c_contig> coeffs, + const nb::ndarray, nb::c_contig>& constants, + const nb::ndarray, nb::c_contig>& coeffs, const dolfinx::mesh::Mesh& mesh, - nb::ndarray entities) + const nb::ndarray& entities) { std::optional>, @@ -313,7 +314,7 @@ void declare_assembly_functions(nb::module_& m) m.def( "assemble_scalar", [](const dolfinx::fem::Form& M, - nb::ndarray, nb::c_contig> constants, + const nb::ndarray, nb::c_contig>& constants, const std::map, nb::ndarray, nb::c_contig>>& coefficients) @@ -328,9 +329,9 @@ void declare_assembly_functions(nb::module_& m) // Vector m.def( "assemble_vector", - [](nb::ndarray, nb::c_contig> b, + [](const nb::ndarray, nb::c_contig>& b, const dolfinx::fem::Form& L, - nb::ndarray, nb::c_contig> constants, + const nb::ndarray, nb::c_contig>& constants, const std::map, nb::ndarray, nb::c_contig>>& coefficients) @@ -347,11 +348,11 @@ void declare_assembly_functions(nb::module_& m) m.def( "assemble_matrix", [](dolfinx::la::MatrixCSR& A, const dolfinx::fem::Form& a, - nb::ndarray, nb::c_contig> constants, + const nb::ndarray, nb::c_contig>& constants, const std::map, nb::ndarray, nb::c_contig>>& coefficients, - std::vector*> bcs) + const std::vector*>& bcs) { std::vector< std::reference_wrapper>> @@ -445,7 +446,8 @@ void declare_assembly_functions(nb::module_& m) m.def( "insert_diagonal", [](dolfinx::la::MatrixCSR& A, const dolfinx::fem::FunctionSpace& V, - std::vector*> bcs, T diagonal) + const std::vector*>& bcs, + T diagonal) { std::vector< std::reference_wrapper>> @@ -464,7 +466,7 @@ void declare_assembly_functions(nb::module_& m) m.def( "insert_diagonal", [](dolfinx::la::MatrixCSR& A, - nb::ndarray, nb::c_contig> rows, + const nb::ndarray, nb::c_contig>& rows, T diagonal) { dolfinx::fem::set_diagonal( @@ -481,7 +483,7 @@ void declare_assembly_functions(nb::module_& m) nb::ndarray, nb::c_contig, nb::numpy>)> fin, const dolfinx::fem::Form& form, - std::vector*> bcs) + const std::vector*>& bcs) { std::vector< std::reference_wrapper>> @@ -512,14 +514,15 @@ void declare_assembly_functions(nb::module_& m) // BC modifiers m.def( "apply_lifting", - [](nb::ndarray, nb::c_contig> b, - std::vector*> a, + [](const nb::ndarray, nb::c_contig>& b, + const std::vector*>& a, const std::vector, nb::c_contig>>& constants, const std::vector< std::map, nb::ndarray, nb::c_contig>>>& coeffs, - std::vector*>> bcs1, + const std::vector*>>& + bcs1, const std::vector, nb::c_contig>>& x0, T alpha) { @@ -548,7 +551,8 @@ void declare_assembly_functions(nb::module_& m) } std::vector> _x0; - for (auto x : x0) + _x0.reserve(x0.size()); + for (const auto& x : x0) _x0.emplace_back(x.data(), x.size()); std::vector> _constants; diff --git a/python/dolfinx/wrappers/common.cpp b/python/dolfinx/wrappers/common.cpp index a2e0f69186..a8152ae0d4 100644 --- a/python/dolfinx/wrappers/common.cpp +++ b/python/dolfinx/wrappers/common.cpp @@ -53,8 +53,8 @@ void add_scatter_functions(nb::class_>& sc) sc.def( "scatter_fwd", [](dolfinx::common::Scatterer<>& self, - nb::ndarray, nb::c_contig> local_data, - nb::ndarray, nb::c_contig> remote_data) + const nb::ndarray, nb::c_contig>& local_data, + const nb::ndarray, nb::c_contig>& remote_data) { self.scatter_fwd(std::span(local_data.data(), local_data.size()), std::span(remote_data.data(), remote_data.size())); @@ -64,8 +64,8 @@ void add_scatter_functions(nb::class_>& sc) sc.def( "scatter_rev", [](dolfinx::common::Scatterer<>& self, - nb::ndarray, nb::c_contig> local_data, - nb::ndarray, nb::c_contig> remote_data) + const nb::ndarray, nb::c_contig>& local_data, + const nb::ndarray, nb::c_contig>& remote_data) { self.scatter_rev(std::span(local_data.data(), local_data.size()), std::span(remote_data.data(), remote_data.size()), @@ -115,8 +115,10 @@ void common(nb::module_& m) "__init__", [](dolfinx::common::IndexMap* self, MPICommWrapper comm, std::int32_t local_size, - nb::ndarray, nb::c_contig> ghosts, - nb::ndarray, nb::c_contig> ghost_owners, + const nb::ndarray, nb::c_contig>& + ghosts, + const nb::ndarray, nb::c_contig>& + ghost_owners, int tag) { new (self) dolfinx::common::IndexMap( @@ -131,8 +133,10 @@ void common(nb::module_& m) std::int32_t local_size, std::array, nb::c_contig>, 2> dest_src, - nb::ndarray, nb::c_contig> ghosts, - nb::ndarray, nb::c_contig> ghost_owners) + const nb::ndarray, nb::c_contig>& + ghosts, + const nb::ndarray, nb::c_contig>& + ghost_owners) { std::array, 2> ranks; ranks[0].assign(dest_src[0].data(), @@ -179,7 +183,8 @@ void common(nb::module_& m) .def( "local_to_global", [](const dolfinx::common::IndexMap& self, - nb::ndarray, nb::c_contig> local) + const nb::ndarray, nb::c_contig>& + local) { std::vector global(local.size()); self.local_to_global(std::span(local.data(), local.size()), global); @@ -189,7 +194,8 @@ void common(nb::module_& m) .def( "global_to_local", [](const dolfinx::common::IndexMap& self, - nb::ndarray, nb::c_contig> global) + const nb::ndarray, nb::c_contig>& + global) { std::vector local(global.size()); self.global_to_local(std::span(global.data(), global.size()), @@ -242,7 +248,8 @@ void common(nb::module_& m) m.def( "create_sub_index_map", [](const dolfinx::common::IndexMap& imap, - nb::ndarray, nb::c_contig> indices, + const nb::ndarray, nb::c_contig>& + indices, bool allow_owner_change) { auto [map, submap_to_map] = dolfinx::common::create_sub_index_map( diff --git a/python/dolfinx/wrappers/dolfinx_wrappers/mesh.h b/python/dolfinx/wrappers/dolfinx_wrappers/mesh.h index 5471dc1ab2..76b38c96a6 100644 --- a/python/dolfinx/wrappers/dolfinx_wrappers/mesh.h +++ b/python/dolfinx/wrappers/dolfinx_wrappers/mesh.h @@ -15,7 +15,7 @@ namespace dolfinx_wrappers::part::impl { /// Wrap a Python graph partitioning function as a C++ function template -auto create_partitioner_cpp(Functor p) +auto create_partitioner_cpp(Functor&& p) { return [p](MPI_Comm comm, int nparts, const dolfinx::graph::AdjacencyList& local_graph, @@ -28,7 +28,7 @@ auto create_partitioner_cpp(Functor p) /// Wrap a C++ cell partitioning function as a Python function template -auto create_cell_partitioner_py(Functor p) +auto create_cell_partitioner_py(Functor&& p) { return [p](dolfinx_wrappers::MPICommWrapper comm, int n, const std::vector& cell_types, @@ -36,7 +36,7 @@ auto create_cell_partitioner_py(Functor p) { std::vector> cells; std::ranges::transform( - cells_nb, std::back_inserter(cells), [](auto c) + cells_nb, std::back_inserter(cells), [](const auto& c) { return std::span(c.data(), c.size()); }); return p(comm.get(), n, cell_types, cells); }; diff --git a/python/dolfinx/wrappers/fem.cpp b/python/dolfinx/wrappers/fem.cpp index 594624f86b..223c6bd4bb 100644 --- a/python/dolfinx/wrappers/fem.cpp +++ b/python/dolfinx/wrappers/fem.cpp @@ -67,7 +67,7 @@ struct geom_type> }; template -void declare_function_space(nb::module_& m, std::string type) +void declare_function_space(nb::module_& m, const std::string& type) { { std::string pyclass_name = "FunctionSpace_" + type; @@ -110,7 +110,7 @@ void declare_function_space(nb::module_& m, std::string type) "__init__", [](dolfinx::fem::FiniteElement* self, basix::FiniteElement& element, - std::optional> block_shape, + const std::optional>& block_shape, bool symmetric) { new (self) dolfinx::fem::FiniteElement(element, block_shape, @@ -121,17 +121,16 @@ void declare_function_space(nb::module_& m, std::string type) .def( "__init__", [](dolfinx::fem::FiniteElement* self, - std::vector< - std::shared_ptr>> - elements) + const std::vector>>& elements) { new (self) dolfinx::fem::FiniteElement(elements); }, nb::arg("elements"), "Mixed-element constructor.") .def( "__init__", [](dolfinx::fem::FiniteElement* self, dolfinx::mesh::CellType cell_type, - nb::ndarray, nb::c_contig> points, - std::vector block_shape, bool symmetry) + const nb::ndarray, nb::c_contig>& points, + const std::vector& block_shape, bool symmetry) { std::span pdata(points.data(), points.size()); new (self) dolfinx::fem::FiniteElement( @@ -170,9 +169,9 @@ void declare_function_space(nb::module_& m, std::string type) .def( "T_apply", [](const dolfinx::fem::FiniteElement& self, - nb::ndarray, nb::c_contig> x, - nb::ndarray, nb::c_contig> - cell_permutations, + const nb::ndarray, nb::c_contig>& x, + const nb::ndarray, + nb::c_contig>& cell_permutations, int dim) { const std::size_t data_per_cell @@ -190,9 +189,9 @@ void declare_function_space(nb::module_& m, std::string type) .def( "Tt_apply", [](const dolfinx::fem::FiniteElement& self, - nb::ndarray, nb::c_contig> x, - nb::ndarray, nb::c_contig> - cell_permutations, + const nb::ndarray, nb::c_contig>& x, + const nb::ndarray, + nb::c_contig>& cell_permutations, int dim) { const std::size_t data_per_cell @@ -210,9 +209,9 @@ void declare_function_space(nb::module_& m, std::string type) .def( "Tt_inv_apply", [](const dolfinx::fem::FiniteElement& self, - nb::ndarray, nb::c_contig> x, - nb::ndarray, nb::c_contig> - cell_permutations, + const nb::ndarray, nb::c_contig>& x, + const nb::ndarray, + nb::c_contig>& cell_permutations, int dim) { const std::size_t data_per_cell @@ -232,9 +231,9 @@ void declare_function_space(nb::module_& m, std::string type) .def( "T_apply", [](const dolfinx::fem::FiniteElement& self, - nb::ndarray, nb::ndim<1>, nb::c_contig> x, - nb::ndarray, nb::c_contig> - cell_permutations, + const nb::ndarray, nb::ndim<1>, nb::c_contig>& x, + const nb::ndarray, + nb::c_contig>& cell_permutations, int dim) { const std::size_t data_per_cell @@ -253,9 +252,9 @@ void declare_function_space(nb::module_& m, std::string type) .def( "Tt_apply", [](const dolfinx::fem::FiniteElement& self, - nb::ndarray, nb::ndim<1>, nb::c_contig> x, - nb::ndarray, nb::c_contig> - cell_permutations, + const nb::ndarray, nb::ndim<1>, nb::c_contig>& x, + const nb::ndarray, + nb::c_contig>& cell_permutations, int dim) { const std::size_t data_per_cell @@ -274,9 +273,9 @@ void declare_function_space(nb::module_& m, std::string type) .def( "Tt_inv_apply", [](const dolfinx::fem::FiniteElement& self, - nb::ndarray, nb::ndim<1>, nb::c_contig> x, - nb::ndarray, nb::c_contig> - cell_permutations, + const nb::ndarray, nb::ndim<1>, nb::c_contig>& x, + const nb::ndarray, + nb::c_contig>& cell_permutations, int dim) { const std::size_t data_per_cell @@ -316,9 +315,10 @@ void declare_objects(nb::module_& m, const std::string& type) .def( "__init__", [](dolfinx::fem::DirichletBC* bc, - nb::ndarray g, - nb::ndarray, nb::c_contig> dofs, - std::shared_ptr> V) + const nb::ndarray& g, + const nb::ndarray, nb::c_contig>& + dofs, + const std::shared_ptr>& V) { std::vector shape(g.shape_ptr(), g.shape_ptr() + g.ndim()); @@ -331,9 +331,10 @@ void declare_objects(nb::module_& m, const std::string& type) .def( "__init__", [](dolfinx::fem::DirichletBC* bc, - std::shared_ptr> g, - nb::ndarray, nb::c_contig> dofs, - std::shared_ptr> V) + const std::shared_ptr>& g, + const nb::ndarray, nb::c_contig>& + dofs, + const std::shared_ptr>& V) { new (bc) dolfinx::fem::DirichletBC( g, std::vector(dofs.data(), dofs.data() + dofs.size()), V); @@ -342,8 +343,9 @@ void declare_objects(nb::module_& m, const std::string& type) .def( "__init__", [](dolfinx::fem::DirichletBC* bc, - std::shared_ptr> g, - nb::ndarray, nb::c_contig> dofs) + const std::shared_ptr>& g, + const nb::ndarray, nb::c_contig>& + dofs) { new (bc) dolfinx::fem::DirichletBC( g, std::vector(dofs.data(), dofs.data() + dofs.size())); @@ -352,11 +354,11 @@ void declare_objects(nb::module_& m, const std::string& type) .def( "__init__", [](dolfinx::fem::DirichletBC* bc, - std::shared_ptr> g, + const std::shared_ptr>& g, std::array< nb::ndarray, nb::c_contig>, 2> V_g_dofs, - std::shared_ptr> V) + const std::shared_ptr>& V) { std::array dofs = {std::vector(V_g_dofs[0].data(), @@ -382,7 +384,7 @@ void declare_objects(nb::module_& m, const std::string& type) .def( "set", [](const dolfinx::fem::DirichletBC& self, - nb::ndarray, nb::c_contig> b, + const nb::ndarray, nb::c_contig>& b, std::optional, nb::c_contig>> x0, T alpha) { @@ -417,8 +419,9 @@ void declare_objects(nb::module_& m, const std::string& type) .def( "interpolate", [](dolfinx::fem::Function& self, - nb::ndarray, nb::c_contig> f, - nb::ndarray, nb::c_contig> cells) + const nb::ndarray, nb::c_contig>& f, + const nb::ndarray, nb::c_contig>& + cells) { dolfinx::fem::interpolate(self, std::span(f.data(), f.size()), {1, f.size()}, @@ -428,8 +431,9 @@ void declare_objects(nb::module_& m, const std::string& type) .def( "interpolate", [](dolfinx::fem::Function& self, - nb::ndarray, nb::c_contig> f, - nb::ndarray, nb::c_contig> cells) + const nb::ndarray, nb::c_contig>& f, + const nb::ndarray, nb::c_contig>& + cells) { dolfinx::fem::interpolate(self, std::span(f.data(), f.size()), {f.shape(0), f.shape(1)}, @@ -440,8 +444,10 @@ void declare_objects(nb::module_& m, const std::string& type) "interpolate", [](dolfinx::fem::Function& self, dolfinx::fem::Function& u0, - nb::ndarray, nb::c_contig> cells0, - nb::ndarray, nb::c_contig> cells1) + const nb::ndarray, nb::c_contig>& + cells0, + const nb::ndarray, nb::c_contig>& + cells1) { self.interpolate(u0, std::span(cells0.data(), cells0.size()), std::span(cells1.data(), cells1.size())); @@ -452,7 +458,8 @@ void declare_objects(nb::module_& m, const std::string& type) "interpolate", [](dolfinx::fem::Function& self, dolfinx::fem::Function& u, - nb::ndarray, nb::c_contig> cells, + const nb::ndarray, nb::c_contig>& + cells, const dolfinx::geometry::PointOwnershipData& interpolation_data) { self.interpolate(u, std::span(cells.data(), cells.size()), @@ -460,10 +467,12 @@ void declare_objects(nb::module_& m, const std::string& type) }, nb::arg("u"), nb::arg("cells"), nb::arg("interpolation_data"), "Interpolate a finite element function on non-matching meshes") + // NOLINTBEGIN(performance-no-int-to-ptr) .def( "interpolate_ptr", [](dolfinx::fem::Function& self, std::uintptr_t addr, - nb::ndarray, nb::c_contig> cells) + const nb::ndarray, nb::c_contig>& + cells) { assert(self.function_space()); auto element = self.function_space()->element(); @@ -494,8 +503,8 @@ void declare_objects(nb::module_& m, const std::string& type) "interpolate", [](dolfinx::fem::Function& self, const dolfinx::fem::Expression& e0, - nb::ndarray cells0, - nb::ndarray cells1) + const nb::ndarray& cells0, + const nb::ndarray& cells1) { self.interpolate(e0, std::span(cells0.data(), cells0.size()), std::span(cells1.data(), cells1.size())); @@ -508,9 +517,10 @@ void declare_objects(nb::module_& m, const std::string& type) .def( "eval", [](const dolfinx::fem::Function& self, - nb::ndarray, nb::c_contig> x, - nb::ndarray, nb::c_contig> cells, - nb::ndarray, nb::c_contig> u) + const nb::ndarray, nb::c_contig>& x, + const nb::ndarray, nb::c_contig>& + cells, + const nb::ndarray, nb::c_contig>& u) { // TODO: handle 1d case self.eval(std::span(x.data(), x.size()), {x.shape(0), x.shape(1)}, @@ -531,7 +541,7 @@ void declare_objects(nb::module_& m, const std::string& type) .def( "__init__", [](dolfinx::fem::Constant* cp, - nb::ndarray c) + const nb::ndarray& c) { std::vector shape(c.shape_ptr(), c.shape_ptr() + c.ndim()); @@ -539,7 +549,7 @@ void declare_objects(nb::module_& m, const std::string& type) dolfinx::fem::Constant(std::span(c.data(), c.size()), shape); }, nb::arg("c").noconvert(), "Create a constant from a value array") - .def_prop_ro("dtype", [](const dolfinx::fem::Constant) + .def_prop_ro("dtype", [](const dolfinx::fem::Constant&) { return dolfinx_wrappers::numpy_dtype(); }) .def_prop_ro( "value", @@ -561,10 +571,10 @@ void declare_objects(nb::module_& m, const std::string& type) const dolfinx::fem::Function>>& coefficients, const std::vector< std::shared_ptr>>& constants, - nb::ndarray, nb::c_contig> X, + const nb::ndarray, nb::c_contig>& X, std::uintptr_t fn_addr, const std::vector& value_shape, - std::shared_ptr> + const std::shared_ptr>& argument_space) { auto tabulate_expression_ptr @@ -606,7 +616,8 @@ void declare_objects(nb::module_& m, const std::string& type) coefficients, const std::vector>>& constants, - std::shared_ptr> argument_space) + const std::shared_ptr>& + argument_space) { const ufcx_expression* p = reinterpret_cast(expression); @@ -619,7 +630,7 @@ void declare_objects(nb::module_& m, const std::string& type) } template -void declare_form(nb::module_& m, std::string type) +void declare_form(nb::module_& m, const std::string& type) { using U = typename dolfinx::scalar_value_t; @@ -647,7 +658,7 @@ void declare_form(nb::module_& m, std::string type) const std::map>, nb::ndarray, nb::c_contig>>& entity_maps, - std::shared_ptr> mesh) + const std::shared_ptr>& mesh) { std::map, dolfinx::fem::integral_data> @@ -684,7 +695,8 @@ void declare_form(nb::module_& m, std::string type) nb::arg("entity_maps"), nb::arg("mesh")) .def( "__init__", - [](dolfinx::fem::Form* fp, std::vector forms, + [](dolfinx::fem::Form* fp, + const std::vector& forms, const std::vector< std::shared_ptr>>& spaces, const std::vector>, nb::ndarray, nb::c_contig>>& entity_maps, - std::shared_ptr> mesh) + const std::shared_ptr>& mesh) { std::map> ps; + ps.reserve(forms.size()); for (auto form : forms) ps.push_back(*(reinterpret_cast(form))); new (fp) @@ -805,8 +818,8 @@ void declare_form(nb::module_& m, std::string type) } ufcx_form* p = reinterpret_cast(form); - return dolfinx::fem::create_form_factory({*p}, spaces, coefficients, - constants, sd, {}, mesh); + return dolfinx::fem::create_form_factory( + {*p}, spaces, coefficients, constants, sd, {}, std::move(mesh)); }, nb::arg("form"), nb::arg("spaces"), nb::arg("coefficients"), nb::arg("constants"), nb::arg("subdomains"), nb::arg("mesh"), @@ -849,9 +862,11 @@ void declare_form(nb::module_& m, std::string type) for (auto& [msh, map] : entity_maps) _entity_maps.emplace(msh, std::span(map.data(), map.size())); ufcx_form* p = reinterpret_cast(form); - return dolfinx::fem::create_form( - *p, spaces, coefficients, constants, sd, _entity_maps, mesh); + return dolfinx::fem::create_form(*p, spaces, coefficients, + constants, sd, _entity_maps, + std::move(mesh)); }, + // NOLINTEND(performance-no-int-to-ptr) nb::arg("form"), nb::arg("spaces"), nb::arg("coefficients"), nb::arg("constants"), nb::arg("subdomains"), nb::arg("entity_maps"), nb::arg("mesh"), "Create Form from a pointer to ufcx_form."); @@ -864,7 +879,7 @@ void declare_form(nb::module_& m, std::string type) } template -void declare_cmap(nb::module_& m, std::string type) +void declare_cmap(nb::module_& m, const std::string& type) { std::string pyclass_name = std::string("CoordinateElement_") + type; nb::class_>(m, pyclass_name.c_str(), @@ -894,8 +909,8 @@ void declare_cmap(nb::module_& m, std::string type) .def( "push_forward", [](const dolfinx::fem::CoordinateElement& self, - nb::ndarray, nb::c_contig> X, - nb::ndarray, nb::c_contig> cell_x) + const nb::ndarray, nb::c_contig>& X, + const nb::ndarray, nb::c_contig>& cell_x) { using mdspan2_t = md::mdspan>; using cmdspan2_t @@ -926,8 +941,9 @@ void declare_cmap(nb::module_& m, std::string type) .def( "pull_back", [](const dolfinx::fem::CoordinateElement& self, - nb::ndarray, nb::c_contig> x, - nb::ndarray, nb::c_contig> cell_geometry) + const nb::ndarray, nb::c_contig>& x, + const nb::ndarray, nb::c_contig>& + cell_geometry) { std::size_t num_points = x.shape(0); std::size_t gdim = x.shape(1); @@ -1013,6 +1029,7 @@ void declare_real_functions(nb::module_& m) elements) { std::vector layouts; + layouts.reserve(elements.size()); assert(elements.size() == topology.entity_types(topology.dim()).size()); for (std::size_t i = 0; i < elements.size(); ++i) { @@ -1032,7 +1049,8 @@ void declare_real_functions(nb::module_& m) [](const std::vector< std::shared_ptr>>& V, int dim, - nb::ndarray, nb::c_contig> entities, + const nb::ndarray, nb::c_contig>& + entities, bool remote) { if (V.size() != 2) @@ -1051,7 +1069,8 @@ void declare_real_functions(nb::module_& m) m.def( "locate_dofs_topological", [](const dolfinx::fem::FunctionSpace& V, int dim, - nb::ndarray, nb::c_contig> entities, + const nb::ndarray, nb::c_contig>& + entities, bool remote) { return dolfinx_wrappers::as_nbarray( @@ -1113,7 +1132,7 @@ void declare_real_functions(nb::module_& m) "interpolation_coords", [](const dolfinx::fem::FiniteElement& e, const dolfinx::mesh::Geometry& geometry, - nb::ndarray, nb::c_contig> cells) + const nb::ndarray, nb::c_contig>& cells) { std::vector x = dolfinx::fem::interpolation_coords( e, geometry, std::span(cells.data(), cells.size())); @@ -1126,7 +1145,8 @@ void declare_real_functions(nb::module_& m) [](const dolfinx::mesh::Geometry& geometry0, const dolfinx::fem::FiniteElement& element0, const dolfinx::mesh::Mesh& mesh1, - nb::ndarray, nb::c_contig> cells, + const nb::ndarray, nb::c_contig>& + cells, T padding) { return dolfinx::fem::create_interpolation_data( @@ -1174,7 +1194,8 @@ void fem(nb::module_& m) "Build a dofmap on a mesh."); m.def( "transpose_dofmap", - [](nb::ndarray, nb::c_contig> dofmap, + [](const nb::ndarray, nb::c_contig>& + dofmap, int num_cells) { md::mdspan> _dofmap( @@ -1187,7 +1208,8 @@ void fem(nb::module_& m) "compute_integration_domains", [](dolfinx::fem::IntegralType type, const dolfinx::mesh::Topology& topology, - nb::ndarray, nb::c_contig> entities) + const nb::ndarray, nb::c_contig>& + entities) { return dolfinx_wrappers::as_nbarray( dolfinx::fem::compute_integration_domains( @@ -1224,7 +1246,7 @@ void fem(nb::module_& m) "__init__", [](dolfinx::fem::DofMap* self, const dolfinx::fem::ElementDofLayout& element, - std::shared_ptr index_map, + const std::shared_ptr& index_map, int index_map_bs, const dolfinx::graph::AdjacencyList& dofmap, int bs) { diff --git a/python/dolfinx/wrappers/geometry.cpp b/python/dolfinx/wrappers/geometry.cpp index 2b18e8a219..838956abc7 100644 --- a/python/dolfinx/wrappers/geometry.cpp +++ b/python/dolfinx/wrappers/geometry.cpp @@ -27,7 +27,7 @@ namespace nb = nanobind; namespace { template -void declare_bbtree(nb::module_& m, std::string type) +void declare_bbtree(nb::module_& m, const std::string& type) { // dolfinx::geometry::BoundingBoxTree std::string pyclass_name = "BoundingBoxTree_" + type; @@ -88,7 +88,7 @@ void declare_bbtree(nb::module_& m, std::string type) m.def( "compute_collisions_points", [](const dolfinx::geometry::BoundingBoxTree& tree, - nb::ndarray, nb::c_contig> points) + const nb::ndarray, nb::c_contig>& points) { return dolfinx::geometry::compute_collisions( tree, std::span(points.data(), 3)); @@ -97,7 +97,7 @@ void declare_bbtree(nb::module_& m, std::string type) m.def( "compute_collisions_points", [](const dolfinx::geometry::BoundingBoxTree& tree, - nb::ndarray, nb::c_contig> points) + const nb::ndarray, nb::c_contig>& points) { return dolfinx::geometry::compute_collisions( tree, std::span(points.data(), points.size())); @@ -119,7 +119,7 @@ void declare_bbtree(nb::module_& m, std::string type) [](const dolfinx::geometry::BoundingBoxTree& tree, const dolfinx::geometry::BoundingBoxTree& midpoint_tree, const dolfinx::mesh::Mesh& mesh, - nb::ndarray, nb::c_contig> points) + const nb::ndarray, nb::c_contig>& points) { return dolfinx_wrappers::as_nbarray( dolfinx::geometry::compute_closest_entity( @@ -133,7 +133,7 @@ void declare_bbtree(nb::module_& m, std::string type) [](const dolfinx::geometry::BoundingBoxTree& tree, const dolfinx::geometry::BoundingBoxTree& midpoint_tree, const dolfinx::mesh::Mesh& mesh, - nb::ndarray, nb::c_contig> points) + const nb::ndarray, nb::c_contig>& points) { return dolfinx_wrappers::as_nbarray( dolfinx::geometry::compute_closest_entity( @@ -145,7 +145,8 @@ void declare_bbtree(nb::module_& m, std::string type) m.def( "create_midpoint_tree", [](const dolfinx::mesh::Mesh& mesh, int tdim, - nb::ndarray, nb::c_contig> entities) + const nb::ndarray, nb::c_contig>& + entities) { return dolfinx::geometry::create_midpoint_tree( mesh, tdim, @@ -156,7 +157,7 @@ void declare_bbtree(nb::module_& m, std::string type) "compute_colliding_cells", [](const dolfinx::mesh::Mesh& mesh, const dolfinx::graph::AdjacencyList& candidate_cells, - nb::ndarray, nb::c_contig> points) + const nb::ndarray, nb::c_contig>& points) { return dolfinx::geometry::compute_colliding_cells( mesh, candidate_cells, std::span(points.data(), points.size())); @@ -166,7 +167,7 @@ void declare_bbtree(nb::module_& m, std::string type) "compute_colliding_cells", [](const dolfinx::mesh::Mesh& mesh, const dolfinx::graph::AdjacencyList& candidate_cells, - nb::ndarray, nb::c_contig> points) + const nb::ndarray, nb::c_contig>& points) { return dolfinx::geometry::compute_colliding_cells( mesh, candidate_cells, std::span(points.data(), points.size())); @@ -175,8 +176,8 @@ void declare_bbtree(nb::module_& m, std::string type) m.def( "compute_distance_gjk", - [](nb::ndarray p, - nb::ndarray q) + [](const nb::ndarray& p, + const nb::ndarray& q) { std::size_t p_s0 = p.ndim() == 1 ? 1 : p.shape(0); std::size_t q_s0 = q.ndim() == 1 ? 1 : q.shape(0); @@ -190,8 +191,9 @@ void declare_bbtree(nb::module_& m, std::string type) m.def( "squared_distance", [](const dolfinx::mesh::Mesh& mesh, int dim, - nb::ndarray, nb::c_contig> indices, - nb::ndarray points) + const nb::ndarray, nb::c_contig>& + indices, + const nb::ndarray& points) { std::size_t p_s0 = points.ndim() == 1 ? 1 : points.shape(0); std::span _p(points.data(), 3 * p_s0); @@ -202,7 +204,7 @@ void declare_bbtree(nb::module_& m, std::string type) nb::arg("mesh"), nb::arg("dim"), nb::arg("indices"), nb::arg("points")); m.def("determine_point_ownership", [](const dolfinx::mesh::Mesh& mesh, - nb::ndarray points, const T padding) + const nb::ndarray& points, const T padding) { std::size_t p_s0 = points.ndim() == 1 ? 1 : points.shape(0); std::span _p(points.data(), 3 * p_s0); @@ -216,12 +218,12 @@ void declare_bbtree(nb::module_& m, std::string type) .def( "__init__", [](dolfinx::geometry::PointOwnershipData* self, - nb::ndarray, nb::c_contig> + const nb::ndarray, nb::c_contig>& src_owner, - nb::ndarray, nb::c_contig> + const nb::ndarray, nb::c_contig>& dest_owners, - nb::ndarray, nb::c_contig> dest_points, - nb::ndarray, nb::c_contig> + const nb::ndarray, nb::c_contig>& dest_points, + const nb::ndarray, nb::c_contig>& dest_cells) { new (self) dolfinx::geometry::PointOwnershipData{ diff --git a/python/dolfinx/wrappers/graph.cpp b/python/dolfinx/wrappers/graph.cpp index 9fd231e4a9..97c6d96079 100644 --- a/python/dolfinx/wrappers/graph.cpp +++ b/python/dolfinx/wrappers/graph.cpp @@ -25,7 +25,7 @@ namespace { /// Wrap a C++ graph partitioning function as a Python-ready function template -auto create_partitioner_py(Functor p_cpp) +auto create_partitioner_py(Functor&& p_cpp) { return [p_cpp](dolfinx_wrappers::MPICommWrapper comm, int nparts, const dolfinx::graph::AdjacencyList& local_graph, @@ -38,7 +38,7 @@ namespace dolfinx_wrappers { template -void declare_adjacency_list(nb::module_& m, std::string type) +void declare_adjacency_list(nb::module_& m, const std::string& type) { std::string pyclass_name = std::string("AdjacencyList_") + type; nb::class_>(m, pyclass_name.c_str(), @@ -46,7 +46,7 @@ void declare_adjacency_list(nb::module_& m, std::string type) .def( "__init__", [](dolfinx::graph::AdjacencyList* a, - nb::ndarray, nb::c_contig> adj) + const nb::ndarray, nb::c_contig>& adj) { std::vector data(adj.data(), adj.data() + adj.size()); new (a) dolfinx::graph::AdjacencyList( @@ -56,7 +56,7 @@ void declare_adjacency_list(nb::module_& m, std::string type) .def( "__init__", [](dolfinx::graph::AdjacencyList* a, - nb::ndarray, nb::c_contig> adj) + const nb::ndarray, nb::c_contig>& adj) { std::vector data(adj.data(), adj.data() + adj.size()); new (a) dolfinx::graph::AdjacencyList( @@ -67,8 +67,9 @@ void declare_adjacency_list(nb::module_& m, std::string type) .def( "__init__", [](dolfinx::graph::AdjacencyList* a, - nb::ndarray, nb::c_contig> array, - nb::ndarray, nb::c_contig> displ) + const nb::ndarray, nb::c_contig>& array, + const nb::ndarray, nb::c_contig>& + displ) { std::vector data(array.data(), array.data() + array.size()); std::vector offsets(displ.data(), diff --git a/python/dolfinx/wrappers/io.cpp b/python/dolfinx/wrappers/io.cpp index ccbdb3aa47..c3ffb5f6b5 100644 --- a/python/dolfinx/wrappers/io.cpp +++ b/python/dolfinx/wrappers/io.cpp @@ -51,14 +51,14 @@ void xdmf_real_fn(auto&& m) m.def( "write_mesh", [](dolfinx::io::XDMFFile& self, const dolfinx::mesh::Mesh& mesh, - std::string xpath) { self.write_mesh(mesh, xpath); }, + const std::string& xpath) { self.write_mesh(mesh, xpath); }, nb::arg("mesh"), nb::arg("xpath") = "/Xdmf/Domain"); m.def( "write_meshtags", [](dolfinx::io::XDMFFile& self, const dolfinx::mesh::MeshTags& meshtags, - const dolfinx::mesh::Geometry& x, std::string geometry_xpath, - std::string xpath) + const dolfinx::mesh::Geometry& x, const std::string& geometry_xpath, + const std::string& xpath) { self.write_meshtags(meshtags, x, geometry_xpath, xpath); }, nb::arg("meshtags"), nb::arg("x"), nb::arg("geometry_xpath"), nb::arg("xpath") = "/Xdmf/Domain"); @@ -70,7 +70,7 @@ void xdmf_scalar_fn(auto&& m) m.def( "write_function", [](dolfinx::io::XDMFFile& self, const dolfinx::fem::Function& u, - double t, std::string mesh_xpath) + double t, const std::string& mesh_xpath) { self.write_function(u, t, mesh_xpath); }, nb::arg("u"), nb::arg("t"), nb::arg("mesh_xpath") = "/Xdmf/Domain/Grid[@GridType='Uniform'][1]"); @@ -92,13 +92,14 @@ void vtk_scalar_fn(auto&& m) m.def( "write", [](dolfinx::io::VTKFile& self, - const std::vector>> + const std::vector>>& u_ptr, double t) { std::vector>> u; - for (auto q : u_ptr) + u.reserve(u_ptr.size()); + for (const auto& q : u_ptr) u.push_back(*q); self.write(u, t); @@ -108,7 +109,7 @@ void vtk_scalar_fn(auto&& m) #ifdef HAS_ADIOS2 template -void declare_vtx_writer(nb::module_& m, std::string type) +void declare_vtx_writer(nb::module_& m, const std::string& type) { { std::string pyclass_name = "VTXWriter_" + type; @@ -116,9 +117,9 @@ void declare_vtx_writer(nb::module_& m, std::string type) .def( "__init__", [](dolfinx::io::VTXWriter* self, MPICommWrapper comm, - std::filesystem::path filename, - std::shared_ptr> mesh, - std::string engine) + const std::filesystem::path& filename, + const std::shared_ptr>& mesh, + const std::string& engine) { new (self) dolfinx::io::VTXWriter(comm.get(), filename, mesh, engine); @@ -128,7 +129,7 @@ void declare_vtx_writer(nb::module_& m, std::string type) .def( "__init__", [](dolfinx::io::VTXWriter* self, MPICommWrapper comm, - std::filesystem::path filename, + const std::filesystem::path& filename, const std::vector>, std::shared_ptr>, @@ -136,7 +137,7 @@ void declare_vtx_writer(nb::module_& m, std::string type) const dolfinx::fem::Function, T>>, std::shared_ptr, T>>>>& u, - std::string engine, dolfinx::io::VTXMeshPolicy policy) + const std::string& engine, dolfinx::io::VTXMeshPolicy policy) { new (self) dolfinx::io::VTXWriter(comm.get(), filename, u, engine, policy); @@ -157,15 +158,17 @@ void declare_data_types(nb::module_& m) { m.def( "distribute_entity_data", - [](const dolfinx::mesh::Topology topology, - nb::ndarray, nb::c_contig> + [](const dolfinx::mesh::Topology& topology, + const nb::ndarray, nb::c_contig>& input_global_indices, std::int64_t num_nodes_g, const dolfinx::fem::ElementDofLayout& cmap_dof_layout, - nb::ndarray, nb::c_contig> xdofmap, + const nb::ndarray, nb::c_contig>& + xdofmap, int entity_dim, - nb::ndarray, nb::c_contig> entities, - nb::ndarray, nb::c_contig> values) + const nb::ndarray, nb::c_contig>& + entities, + const nb::ndarray, nb::c_contig>& values) { assert(entities.shape(0) == values.size()); mdspan_t entities_span( @@ -207,7 +210,8 @@ void io(nb::module_& m) m.def( "extract_vtk_connectivity", - [](nb::ndarray, nb::c_contig> dofmap, + [](const nb::ndarray, nb::c_contig>& + dofmap, dolfinx::mesh::CellType cell) { mdspan_t _dofmap(dofmap.data(), dofmap.shape(0), @@ -223,13 +227,13 @@ void io(nb::module_& m) m.def("write_vtkhdf_mesh", &dolfinx::io::VTKHDF::write_mesh) .def("write_vtkhdf_mesh", &dolfinx::io::VTKHDF::write_mesh); m.def("read_vtkhdf_mesh_float64", - [](MPICommWrapper comm, std::string filename, std::size_t gdim) + [](MPICommWrapper comm, const std::string& filename, std::size_t gdim) { return dolfinx::io::VTKHDF::read_mesh(comm.get(), filename, gdim); }); m.def("read_vtkhdf_mesh_float32", - [](MPICommWrapper comm, std::string filename, std::size_t gdim) + [](MPICommWrapper comm, const std::string& filename, std::size_t gdim) { return dolfinx::io::VTKHDF::read_mesh(comm.get(), filename, gdim); @@ -256,7 +260,8 @@ void io(nb::module_& m) .def( "__init__", [](dolfinx::io::XDMFFile* x, MPICommWrapper comm, - std::filesystem::path filename, std::string file_mode, + const std::filesystem::path& filename, + const std::string& file_mode, dolfinx::io::XDMFFile::Encoding encoding) { new (x) dolfinx::io::XDMFFile(comm.get(), filename, file_mode, @@ -270,7 +275,8 @@ void io(nb::module_& m) nb::arg("xpath") = "/Xdmf/Domain") .def( "read_topology_data", - [](dolfinx::io::XDMFFile& self, std::string name, std::string xpath) + [](dolfinx::io::XDMFFile& self, const std::string& name, + const std::string& xpath) { auto [cells, shape] = self.read_topology_data(name, xpath); return as_nbarray(std::move(cells), shape); @@ -278,7 +284,8 @@ void io(nb::module_& m) nb::arg("name") = "mesh", nb::arg("xpath") = "/Xdmf/Domain") .def( "read_geometry_data", - [](dolfinx::io::XDMFFile& self, std::string name, std::string xpath) + [](dolfinx::io::XDMFFile& self, const std::string& name, + const std::string& xpath) { auto [x, shape] = self.read_geometry_data(name, xpath); std::vector& _x = std::get>(x); @@ -313,7 +320,7 @@ void io(nb::module_& m) .def( "__init__", [](dolfinx::io::VTKFile* v, MPICommWrapper comm, - std::filesystem::path filename, std::string mode) + const std::filesystem::path& filename, const std::string& mode) { new (v) dolfinx::io::VTKFile(comm.get(), filename, mode); }, nb::arg("comm"), nb::arg("filename"), nb::arg("mode")) .def("close", &dolfinx::io::VTKFile::close); diff --git a/python/dolfinx/wrappers/la.cpp b/python/dolfinx/wrappers/la.cpp index 97303d818d..1596e5d5d2 100644 --- a/python/dolfinx/wrappers/la.cpp +++ b/python/dolfinx/wrappers/la.cpp @@ -31,7 +31,7 @@ namespace { // InsertMode types -enum class PyInsertMode +enum class PyInsertMode : std::uint8_t { add, insert @@ -188,6 +188,7 @@ void declare_functions(nb::module_& m) [](std::vector*> basis) { std::vector>> _basis; + _basis.reserve(basis.size()); for (std::size_t i = 0; i < basis.size(); ++i) _basis.push_back(*basis[i]); dolfinx::la::orthonormalize(_basis); @@ -200,6 +201,7 @@ void declare_functions(nb::module_& m) { std::vector>> _basis; + _basis.reserve(basis.size()); for (std::size_t i = 0; i < basis.size(); ++i) _basis.push_back(*basis[i]); return dolfinx::la::is_orthonormal(_basis, eps); @@ -240,8 +242,8 @@ void la(nb::module_& m) .def( "__init__", [](dolfinx::la::SparsityPattern* sp, MPICommWrapper comm, - const std::vector> - patterns, + const std::vector< + std::vector>& patterns, const std::array< std::vector, @@ -261,8 +263,10 @@ void la(nb::module_& m) .def( "insert", [](dolfinx::la::SparsityPattern& self, - nb::ndarray, nb::c_contig> rows, - nb::ndarray, nb::c_contig> cols) + const nb::ndarray, nb::c_contig>& + rows, + const nb::ndarray, nb::c_contig>& + cols) { self.insert(std::span(rows.data(), rows.size()), std::span(cols.data(), cols.size())); @@ -275,7 +279,8 @@ void la(nb::module_& m) .def( "insert_diagonal", [](dolfinx::la::SparsityPattern& self, - nb::ndarray, nb::c_contig> rows) + const nb::ndarray, nb::c_contig>& + rows) { self.insert_diagonal(std::span(rows.data(), rows.size())); }, nb::arg("rows")) .def_prop_ro( diff --git a/python/dolfinx/wrappers/log.cpp b/python/dolfinx/wrappers/log.cpp index bb87b8d5d5..b08f7f0f14 100644 --- a/python/dolfinx/wrappers/log.cpp +++ b/python/dolfinx/wrappers/log.cpp @@ -29,7 +29,7 @@ void log(nb::module_& m) m.def( "set_output_file", - [](std::string filename) + [](const std::string& filename) { try { @@ -38,14 +38,14 @@ void log(nb::module_& m) } catch (const spdlog::spdlog_ex& ex) { - std::cout << "Log init failed: " << ex.what() << std::endl; + std::cout << "Log init failed: " << ex.what() << "\n"; } }, nb::arg("filename")); m.def( "set_thread_name", - [](std::string thread_name) + [](const std::string& thread_name) { std::string fmt = "[%Y-%m-%d %H:%M:%S.%e] [" + thread_name + "] [%l] %v"; @@ -59,7 +59,7 @@ void log(nb::module_& m) m.def("get_log_level", []() { return spdlog::get_level(); }); m.def( "log", - [](spdlog::level::level_enum level, std::string s) + [](spdlog::level::level_enum level, const std::string& s) { switch (level) { diff --git a/python/dolfinx/wrappers/mesh.cpp b/python/dolfinx/wrappers/mesh.cpp index a170702868..1a3792470a 100644 --- a/python/dolfinx/wrappers/mesh.cpp +++ b/python/dolfinx/wrappers/mesh.cpp @@ -66,25 +66,26 @@ create_cell_partitioner_cpp(const PythonCellPartitionFunction& p) } // namespace part::impl template -void declare_meshtags(nb::module_& m, std::string type) +void declare_meshtags(nb::module_& m, const std::string& type) { std::string pyclass_name = std::string("MeshTags_") + type; nb::class_>(m, pyclass_name.c_str(), "MeshTags object") - .def( - "__init__", - [](dolfinx::mesh::MeshTags* self, - std::shared_ptr topology, int dim, - nb::ndarray, nb::c_contig> indices, - nb::ndarray, nb::c_contig> values) - { - std::vector indices_vec( - indices.data(), indices.data() + indices.size()); - std::vector values_vec(values.data(), - values.data() + values.size()); - new (self) dolfinx::mesh::MeshTags( - topology, dim, std::move(indices_vec), std::move(values_vec)); - }) + .def("__init__", + [](dolfinx::mesh::MeshTags* self, + const std::shared_ptr& topology, + int dim, + const nb::ndarray, nb::c_contig>& + indices, + const nb::ndarray, nb::c_contig>& values) + { + std::vector indices_vec( + indices.data(), indices.data() + indices.size()); + std::vector values_vec(values.data(), + values.data() + values.size()); + new (self) dolfinx::mesh::MeshTags( + topology, dim, std::move(indices_vec), std::move(values_vec)); + }) .def_prop_ro("dtype", [](const dolfinx::mesh::MeshTags&) { return dolfinx_wrappers::numpy_dtype(); }) .def_rw("name", &dolfinx::mesh::MeshTags::name) @@ -111,9 +112,9 @@ void declare_meshtags(nb::module_& m, std::string type) { return as_nbarray(self.find(value)); }); m.def("create_meshtags", - [](std::shared_ptr topology, int dim, - const dolfinx::graph::AdjacencyList& entities, - nb::ndarray, nb::c_contig> values) + [](const std::shared_ptr& topology, + int dim, const dolfinx::graph::AdjacencyList& entities, + const nb::ndarray, nb::c_contig>& values) { return dolfinx::mesh::create_meshtags( topology, dim, entities, std::span(values.data(), values.size())); @@ -121,7 +122,7 @@ void declare_meshtags(nb::module_& m, std::string type) } template -void declare_mesh(nb::module_& m, std::string type) +void declare_mesh(nb::module_& m, const std::string& type) { std::string pyclass_geometry_name = std::string("Geometry_") + type; nb::class_>(m, pyclass_geometry_name.c_str(), @@ -130,10 +131,11 @@ void declare_mesh(nb::module_& m, std::string type) "__init__", [](dolfinx::mesh::Geometry* self, std::shared_ptr index_map, - nb::ndarray, nb::c_contig> dofmap, + const nb::ndarray, nb::c_contig>& + dofmap, const dolfinx::fem::CoordinateElement& element, - nb::ndarray> x, - nb::ndarray, nb::c_contig> + const nb::ndarray>& x, + const nb::ndarray, nb::c_contig>& input_global_indices) { int shape1 = x.shape(1); @@ -151,7 +153,7 @@ void declare_mesh(nb::module_& m, std::string type) } new (self) dolfinx::mesh::Geometry( - index_map, + std::move(index_map), std::vector>( 1, std::vector( dofmap.data(), dofmap.data() + dofmap.size())), @@ -222,7 +224,8 @@ void declare_mesh(nb::module_& m, std::string type) std::shared_ptr topology, dolfinx::mesh::Geometry& geometry) { - new (mesh) dolfinx::mesh::Mesh(comm.get(), topology, geometry); + new (mesh) dolfinx::mesh::Mesh(comm.get(), std::move(topology), + geometry); }, nb::arg("comm"), nb::arg("topology"), nb::arg("geometry")) .def_prop_ro("geometry", @@ -285,14 +288,14 @@ void declare_mesh(nb::module_& m, std::string type) const std::vector, nb::c_contig>>& cells_nb, const std::vector>& elements, - nb::ndarray x, + const nb::ndarray& x, const part::impl::PythonCellPartitionFunction& p) { std::size_t shape1 = x.ndim() == 1 ? 1 : x.shape(1); std::vector> cells; std::ranges::transform( - cells_nb, std::back_inserter(cells), [](auto c) + cells_nb, std::back_inserter(cells), [](const auto& c) { return std::span(c.data(), c.size()); }); if (p) @@ -325,9 +328,10 @@ void declare_mesh(nb::module_& m, std::string type) m.def( "create_mesh", [](MPICommWrapper comm, - nb::ndarray, nb::c_contig> cells, + const nb::ndarray, nb::c_contig>& + cells, const dolfinx::fem::CoordinateElement& element, - nb::ndarray x, + const nb::ndarray& x, const part::impl::PythonCellPartitionFunction& p) { std::size_t shape1 = x.ndim() == 1 ? 1 : x.shape(1); @@ -367,7 +371,8 @@ void declare_mesh(nb::module_& m, std::string type) m.def( "create_submesh", [](const dolfinx::mesh::Mesh& mesh, int dim, - nb::ndarray, nb::c_contig> entities) + const nb::ndarray, nb::c_contig>& + entities) { std::tuple, std::vector, std::vector, std::vector> @@ -384,7 +389,8 @@ void declare_mesh(nb::module_& m, std::string type) m.def( "cell_normals", [](const dolfinx::mesh::Mesh& mesh, int dim, - nb::ndarray, nb::c_contig> entities) + const nb::ndarray, nb::c_contig>& + entities) { std::vector n = dolfinx::mesh::cell_normals( mesh, dim, std::span(entities.data(), entities.size())); @@ -394,7 +400,8 @@ void declare_mesh(nb::module_& m, std::string type) m.def( "h", [](const dolfinx::mesh::Mesh& mesh, int dim, - nb::ndarray, nb::c_contig> entities) + const nb::ndarray, nb::c_contig>& + entities) { return as_nbarray(dolfinx::mesh::h( mesh, std::span(entities.data(), entities.size()), dim)); @@ -404,7 +411,8 @@ void declare_mesh(nb::module_& m, std::string type) m.def( "compute_midpoints", [](const dolfinx::mesh::Mesh& mesh, int dim, - nb::ndarray, nb::c_contig> entities) + const nb::ndarray, nb::c_contig>& + entities) { std::vector x = dolfinx::mesh::compute_midpoints( mesh, dim, std::span(entities.data(), entities.size())); @@ -479,7 +487,8 @@ void declare_mesh(nb::module_& m, std::string type) m.def( "entities_to_geometry", [](const dolfinx::mesh::Mesh& mesh, int dim, - nb::ndarray, nb::c_contig> entities, + const nb::ndarray, nb::c_contig>& + entities, bool permute) { auto [geom_indices, idx_shape] = dolfinx::mesh::entities_to_geometry( @@ -491,9 +500,11 @@ void declare_mesh(nb::module_& m, std::string type) m.def("create_geometry", [](const dolfinx::mesh::Topology& topology, const std::vector>& elements, - nb::ndarray, nb::c_contig> nodes, - nb::ndarray, nb::c_contig> xdofs, - nb::ndarray, nb::c_contig> x, int dim) + const nb::ndarray, nb::c_contig>& + nodes, + const nb::ndarray, nb::c_contig>& + xdofs, + const nb::ndarray, nb::c_contig>& x, int dim) { return dolfinx::mesh::create_geometry( topology, elements, @@ -514,8 +525,8 @@ void mesh(nb::module_& m) .value("pyramid", dolfinx::mesh::CellType::pyramid) .value("prism", dolfinx::mesh::CellType::prism) .value("hexahedron", dolfinx::mesh::CellType::hexahedron) - .def_prop_ro("name", - [](nb::object obj) { return nb::getattr(obj, "__name__"); }); + .def_prop_ro("name", [](const nb::object& obj) + { return nb::getattr(obj, "__name__"); }); m.def("to_type", &dolfinx::mesh::to_type, nb::arg("cell")); m.def("to_string", &dolfinx::mesh::to_string, nb::arg("type")); @@ -534,7 +545,8 @@ void mesh(nb::module_& m) "extract_topology", [](dolfinx::mesh::CellType cell_type, const dolfinx::fem::ElementDofLayout& layout, - nb::ndarray, nb::c_contig> cells) + const nb::ndarray, nb::c_contig>& + cells) { return dolfinx_wrappers::as_nbarray(dolfinx::mesh::extract_topology( cell_type, layout, std::span(cells.data(), cells.size()))); @@ -594,12 +606,12 @@ void mesh(nb::module_& m) .def( "__init__", [](dolfinx::mesh::Topology* t, dolfinx::mesh::CellType cell_type, - std::shared_ptr vertex_map, - std::shared_ptr cell_map, - std::shared_ptr> cells, - std::optional< - nb::ndarray, nb::c_contig>> - original_index) + const std::shared_ptr& vertex_map, + const std::shared_ptr& cell_map, + const std::shared_ptr>& + cells, + const std::optional, + nb::c_contig>>& original_index) { using U = std::vector>; using V = std::optional; @@ -652,7 +664,7 @@ void mesh(nb::module_& m) idx.front().data(), {idx.front().size()}); }, [](dolfinx::mesh::Topology& self, - nb::ndarray, nb::c_contig> + const nb::ndarray, nb::c_contig>& original_cell_indices) { self.original_cell_index.resize(1); @@ -739,11 +751,10 @@ void mesh(nb::module_& m) "Create default cell partitioner."); m.def( "create_cell_partitioner", - [](std::function( + [](const std::function( MPICommWrapper comm, int nparts, const dolfinx::graph::AdjacencyList& local_graph, - bool ghosting)> - part, + bool ghosting)>& part, dolfinx::mesh::GhostMode mode) -> part::impl::PythonCellPartitionFunction { @@ -765,7 +776,8 @@ void mesh(nb::module_& m) m.def( "compute_incident_entities", [](const dolfinx::mesh::Topology& topology, - nb::ndarray, nb::c_contig> entities, + const nb::ndarray, nb::c_contig>& + entities, int d0, int d1) { return dolfinx_wrappers::as_nbarray( diff --git a/python/dolfinx/wrappers/petsc.cpp b/python/dolfinx/wrappers/petsc.cpp index a9049edf5b..597f4ecaab 100644 --- a/python/dolfinx/wrappers/petsc.cpp +++ b/python/dolfinx/wrappers/petsc.cpp @@ -175,7 +175,8 @@ void petsc_la_module(nb::module_& m) m.def( "create_matrix", [](dolfinx_wrappers::MPICommWrapper comm, - const dolfinx::la::SparsityPattern& p, std::optional type) + const dolfinx::la::SparsityPattern& p, + const std::optional& type) { Mat A = dolfinx::la::petsc::create_matrix(comm.get(), p, type); PyObject* obj = PyPetscMat_New(A); @@ -219,14 +220,14 @@ void petsc_la_module(nb::module_& m) std::shared_ptr, int>>& maps) { std::vector> _x_b; - std::ranges::transform(x_b, std::back_inserter(_x_b), [](auto x) + std::ranges::transform(x_b, std::back_inserter(_x_b), [](const auto& x) { return std::span(x.data(), x.size()); }); using X = std::vector, int>>; X _maps; std::ranges::transform(maps, std::back_inserter(_maps), - [](auto q) -> typename X::value_type + [](const auto& q) -> typename X::value_type { return {*q.first, q.second}; }); dolfinx::la::petsc::scatter_local_vectors(x, _x_b, _maps); }, @@ -271,7 +272,7 @@ void petsc_fem_module(nb::module_& m) std::reference_wrapper, int>>; X _maps; std::ranges::transform(maps, std::back_inserter(_maps), - [](auto q) -> typename X::value_type + [](const auto& q) -> typename X::value_type { return {*q.first, q.second}; }); return dolfinx::fem::petsc::create_vector_block(_maps); }, @@ -286,7 +287,7 @@ void petsc_fem_module(nb::module_& m) std::reference_wrapper, int>>; X _maps; std::ranges::transform(maps, std::back_inserter(_maps), - [](auto m) -> typename X::value_type + [](const auto& m) -> typename X::value_type { return {*m.first, m.second}; }); return dolfinx::fem::petsc::create_vector_nest(_maps); }, @@ -308,12 +309,13 @@ void petsc_fem_module(nb::module_& m) m.def( "assemble_matrix", [](Mat A, const dolfinx::fem::Form& a, - nb::ndarray, nb::c_contig> constants, + const nb::ndarray, nb::c_contig>& + constants, const std::map, nb::ndarray, nb::c_contig>>& coefficients, - std::vector*> - bcs, + const std::vector< + const dolfinx::fem::DirichletBC*>& bcs, bool unrolled) { std::vector& a, - nb::ndarray, nb::c_contig> constants, + const nb::ndarray, nb::c_contig>& + constants, const std::map, nb::ndarray, nb::c_contig>>& coefficients, - nb::ndarray, nb::c_contig> rows0, - nb::ndarray, nb::c_contig> rows1, + const nb::ndarray, nb::c_contig>& rows0, + const nb::ndarray, nb::c_contig>& rows1, bool unrolled) { std::function, @@ -380,8 +383,8 @@ void petsc_fem_module(nb::module_& m) m.def( "insert_diagonal", [](Mat A, const dolfinx::fem::FunctionSpace& V, - std::vector*> - bcs, + const std::vector< + const dolfinx::fem::DirichletBC*>& bcs, PetscScalar diagonal) { std::vector + const std::function& update) // See // https://github.com/wjakob/nanobind/discussions/361 // on why we pass NewtonSolver* rather than @@ -443,8 +447,8 @@ void petsc_nls_module(nb::module_& m) .def( "set_convergence_check", [](dolfinx::nls::petsc::NewtonSolver& self, - std::function( - const dolfinx::nls::petsc::NewtonSolver* solver, const Vec)> + const std::function( + const dolfinx::nls::petsc::NewtonSolver* solver, const Vec)>& convergence_check) // See // https://github.com/wjakob/nanobind/discussions/361 // on why we pass NewtonSolver* rather than diff --git a/python/dolfinx/wrappers/refinement.cpp b/python/dolfinx/wrappers/refinement.cpp index 1e7c73a8e9..2b530e8d95 100644 --- a/python/dolfinx/wrappers/refinement.cpp +++ b/python/dolfinx/wrappers/refinement.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -100,9 +101,11 @@ void refinement(nb::module_& m) m.def( "transfer_facet_meshtag", [](const dolfinx::mesh::MeshTags& parent_meshtag, - std::shared_ptr topology1, - nb::ndarray, nb::c_contig> parent_cell, - nb::ndarray, nb::c_contig> parent_facet) + const std::shared_ptr& topology1, + const nb::ndarray, nb::c_contig>& + parent_cell, + const nb::ndarray, nb::c_contig>& + parent_facet) { int tdim = parent_meshtag.topology()->dim(); if (parent_meshtag.dim() != tdim - 1) @@ -119,8 +122,9 @@ void refinement(nb::module_& m) m.def( "transfer_cell_meshtag", [](const dolfinx::mesh::MeshTags& parent_meshtag, - std::shared_ptr topology1, - nb::ndarray, nb::c_contig> parent_cell) + const std::shared_ptr& topology1, + const nb::ndarray, nb::c_contig>& + parent_cell) { int tdim = parent_meshtag.topology()->dim(); if (parent_meshtag.dim() != tdim) From 8c373eb294574053fe0b2f625da308b9157bfeb2 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Mon, 23 Jun 2025 17:48:57 +0200 Subject: [PATCH 15/15] Remove too new config option --- .clang-tidy | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index c7f809c375..4e4af908e2 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,7 +1,6 @@ WarningsAsErrors: "*" UseColor: true -HeaderFilterRegex: '.*' -ExcludeHeaderFilterRegex: 'MPI_api.h|PETSc_api.h' # Pulled in from python packages and not classified as system headers +HeaderFilterRegex: '^(?!MPI_api.h$|PETSc_api.h$).*' # Pulled in from python packages and not classified as system headers ExtraArgsBefore: - '-Wno-unknown-warning-option' Checks: >