From 830a9e9c0e48815919dcfc3f7e6384feb1b93fae Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Mon, 15 Jul 2024 11:27:01 +0200 Subject: [PATCH] Replace `std::transform` with `std::ranges::transform` (#3297) * Use std::for_each over std::transform for in place operations * Fix missing ranges * Fix plaza * Switch to std::ranges::transform instead of for_each * Switch to const version of array * std::transform -> std::ranges::transform * Apply suggestions from code review Co-authored-by: Garth N. Wells * Apply suggestion Co-authored-by: Garth N. Wells --------- Co-authored-by: Garth N. Wells --- cpp/demo/interpolation-io/main.cpp | 3 +- cpp/demo/poisson_matrix_free/main.cpp | 5 +- cpp/dolfinx/common/IndexMap.cpp | 111 +++++++++++------------ cpp/dolfinx/common/MPI.h | 9 +- cpp/dolfinx/common/Scatterer.h | 14 ++- cpp/dolfinx/common/utils.h | 4 +- cpp/dolfinx/fem/CoordinateElement.cpp | 4 +- cpp/dolfinx/fem/DirichletBC.cpp | 24 ++--- cpp/dolfinx/fem/DirichletBC.h | 8 +- cpp/dolfinx/fem/DofMap.cpp | 5 +- cpp/dolfinx/fem/Form.h | 9 +- cpp/dolfinx/fem/assembler.h | 11 ++- cpp/dolfinx/fem/discreteoperators.h | 7 +- cpp/dolfinx/fem/dofmapbuilder.cpp | 12 +-- cpp/dolfinx/geometry/BoundingBoxTree.h | 3 +- cpp/dolfinx/geometry/utils.h | 5 +- cpp/dolfinx/graph/ordering.cpp | 12 +-- cpp/dolfinx/graph/partition.cpp | 70 +++++++------- cpp/dolfinx/io/ADIOS2Writers.h | 16 ++-- cpp/dolfinx/io/VTKFile.cpp | 6 +- cpp/dolfinx/io/xdmf_function.cpp | 8 +- cpp/dolfinx/io/xdmf_utils.cpp | 13 ++- cpp/dolfinx/la/MatrixCSR.h | 18 ++-- cpp/dolfinx/la/Vector.h | 11 +-- cpp/dolfinx/mesh/Geometry.h | 8 +- cpp/dolfinx/mesh/Topology.cpp | 52 +++++------ cpp/dolfinx/mesh/graphbuild.cpp | 9 +- cpp/dolfinx/mesh/topologycomputation.cpp | 50 +++++----- cpp/dolfinx/mesh/utils.h | 78 ++++++++-------- cpp/dolfinx/refinement/plaza.h | 30 +++--- cpp/test/io.cpp | 2 +- python/dolfinx/wrappers/assemble.cpp | 15 ++- python/dolfinx/wrappers/mesh.cpp | 43 +++++---- python/dolfinx/wrappers/pycoeff.h | 17 ++-- 34 files changed, 321 insertions(+), 371 deletions(-) diff --git a/cpp/demo/interpolation-io/main.cpp b/cpp/demo/interpolation-io/main.cpp index d6c2cf7c6ce..b365b51251d 100644 --- a/cpp/demo/interpolation-io/main.cpp +++ b/cpp/demo/interpolation-io/main.cpp @@ -149,8 +149,7 @@ void interpolate_nedelec(std::shared_ptr> mesh, { std::vector f(2 * x.extent(1), 0.0); std::copy_n(x.data_handle(), f.size(), f.begin()); - std::transform(f.cbegin(), f.cend(), f.begin(), - [](auto x) { return x + T(1); }); + std::ranges::transform(f, f.begin(), [](auto x) { return x + T(1); }); return {f, {2, x.extent(1)}}; }, cells1); diff --git a/cpp/demo/poisson_matrix_free/main.cpp b/cpp/demo/poisson_matrix_free/main.cpp index f3b2f0cb298..f6df536d440 100644 --- a/cpp/demo/poisson_matrix_free/main.cpp +++ b/cpp/demo/poisson_matrix_free/main.cpp @@ -63,9 +63,8 @@ namespace linalg /// @param[in] y void axpy(auto&& r, auto alpha, auto&& x, auto&& y) { - std::transform(x.array().begin(), x.array().end(), y.array().begin(), - r.mutable_array().begin(), - [alpha](auto x, auto y) { return alpha * x + y; }); + std::ranges::transform(x.array(), y.array(), r.mutable_array().begin(), + [alpha](auto x, auto y) { return alpha * x + y; }); } /// @brief Solve problem A.x = b using the conjugate gradient (CG) diff --git a/cpp/dolfinx/common/IndexMap.cpp b/cpp/dolfinx/common/IndexMap.cpp index 5f924d93790..034ab3ef634 100644 --- a/cpp/dolfinx/common/IndexMap.cpp +++ b/cpp/dolfinx/common/IndexMap.cpp @@ -112,9 +112,8 @@ communicate_ghosts_to_owners(MPI_Comm comm, std::span src, } // Count number of ghosts per dest - std::transform(send_data.begin(), send_data.end(), - std::back_inserter(send_sizes), - [](auto& d) { return d.size(); }); + std::ranges::transform(send_data, std::back_inserter(send_sizes), + [](auto& d) { return d.size(); }); // Send how many indices I ghost to each owner, and receive how many // of my indices other ranks ghost @@ -560,14 +559,13 @@ common::compute_owned_indices(std::span indices, std::vector owned; owned.reserve(num_ghost_indices + recv_buffer.size()); std::copy(indices.begin(), it_owned_end, std::back_inserter(owned)); - std::transform(recv_buffer.begin(), recv_buffer.end(), - std::back_inserter(owned), - [range = map.local_range()](auto idx) - { - assert(idx >= range[0]); - assert(idx < range[1]); - return idx - range[0]; - }); + std::ranges::transform(recv_buffer, std::back_inserter(owned), + [range = map.local_range()](auto idx) + { + assert(idx >= range[0]); + assert(idx < range[1]); + return idx - range[0]; + }); std::ranges::sort(owned); owned.erase(std::unique(owned.begin(), owned.end()), owned.end()); @@ -590,9 +588,8 @@ common::stack_index_maps( // Get local offset (into new map) for each index map std::vector local_sizes; - std::transform(maps.begin(), maps.end(), std::back_inserter(local_sizes), - [](auto map) - { return map.second * map.first.get().size_local(); }); + std::ranges::transform(maps, std::back_inserter(local_sizes), [](auto& map) + { return map.second * map.first.get().size_local(); }); std::vector local_offset(local_sizes.size() + 1, 0); std::partial_sum(local_sizes.begin(), local_sizes.end(), std::next(local_offset.begin())); @@ -657,9 +654,8 @@ common::stack_index_maps( } // Count number of ghosts per dest - std::transform(ghost_by_rank.begin(), ghost_by_rank.end(), - std::back_inserter(send_sizes), - [](auto& g) { return g.size(); }); + std::ranges::transform(ghost_by_rank, std::back_inserter(send_sizes), + [](auto& g) { return g.size(); }); // Send buffer and ghost position to send buffer position for (auto& g : ghost_by_rank) @@ -880,8 +876,8 @@ void IndexMap::local_to_global(std::span local, { assert(local.size() <= global.size()); const std::int32_t local_size = _local_range[1] - _local_range[0]; - std::transform( - local.begin(), local.end(), global.begin(), + std::ranges::transform( + local, global.begin(), [local_size, local_range = _local_range[0], &ghosts = _ghosts](auto local) { if (local < local_size) @@ -904,22 +900,23 @@ void IndexMap::global_to_local(std::span global, global_to_local[i] = {_ghosts[i], i + local_size}; std::ranges::sort(global_to_local); - std::transform(global.begin(), global.end(), local.begin(), - [range = _local_range, - &global_to_local](std::int64_t index) -> std::int32_t - { - if (index >= range[0] and index < range[1]) - return index - range[0]; - else - { - auto it = std::ranges::lower_bound( - global_to_local, index, std::ranges::less(), - [](auto& e) { return e.first; }); - return (it != global_to_local.end() and it->first == index) - ? it->second - : -1; - } - }); + std::ranges::transform( + global, local.begin(), + [range = _local_range, + &global_to_local](std::int64_t index) -> std::int32_t + { + if (index >= range[0] and index < range[1]) + return index - range[0]; + else + { + auto it = std::ranges::lower_bound(global_to_local, index, + std::ranges::less(), + [](auto e) { return e.first; }); + return (it != global_to_local.end() and it->first == index) + ? it->second + : -1; + } + }); } //----------------------------------------------------------------------------- std::vector IndexMap::global_indices() const @@ -957,19 +954,17 @@ graph::AdjacencyList IndexMap::index_to_dest_ranks() const { // Build list of (owner rank, index) pairs for each ghost index, and sort std::vector> owner_to_ghost; - std::transform(_ghosts.begin(), _ghosts.end(), _owners.begin(), - std::back_inserter(owner_to_ghost), - [](auto idx, auto r) -> std::pair - { return {r, idx}; }); + std::ranges::transform(_ghosts, _owners, std::back_inserter(owner_to_ghost), + [](auto idx, auto r) -> std::pair + { return {r, idx}; }); std::ranges::sort(owner_to_ghost); // Build send buffer (the second component of each pair in // owner_to_ghost) to send to rank that owns the index std::vector send_buffer; send_buffer.reserve(owner_to_ghost.size()); - std::transform(owner_to_ghost.begin(), owner_to_ghost.end(), - std::back_inserter(send_buffer), - [](auto x) { return x.second; }); + std::ranges::transform(owner_to_ghost, std::back_inserter(send_buffer), + [](auto x) { return x.second; }); // Compute send sizes and displacements std::vector send_sizes, send_disp{0}; @@ -1023,8 +1018,8 @@ graph::AdjacencyList IndexMap::index_to_dest_ranks() const // Build adjacency list data for (owned index) -> (ghosting ranks) data.reserve(idx_to_rank.size()); - std::transform(idx_to_rank.begin(), idx_to_rank.end(), - std::back_inserter(data), [](auto x) { return x.second; }); + std::ranges::transform(idx_to_rank, std::back_inserter(data), + [](auto x) { return x.second; }); offsets.reserve(this->size_local() + this->num_ghosts() + 1); { auto it = idx_to_rank.begin(); @@ -1074,9 +1069,8 @@ graph::AdjacencyList IndexMap::index_to_dest_ranks() const } // Count number of ghosts per destination and build send buffer - std::transform(dest_idx_to_rank.begin(), dest_idx_to_rank.end(), - std::back_inserter(send_sizes), - [](auto& x) { return x.size(); }); + std::ranges::transform(dest_idx_to_rank, std::back_inserter(send_sizes), + [](auto& x) { return x.size(); }); for (auto& d : dest_idx_to_rank) send_buffer.insert(send_buffer.end(), d.begin(), d.end()); @@ -1138,8 +1132,8 @@ graph::AdjacencyList IndexMap::index_to_dest_ranks() const // Add processed received data to adjacency list data array, and // extend offset array - std::transform(idxpos_to_rank.begin(), idxpos_to_rank.end(), - std::back_inserter(data), [](auto x) { return x.second; }); + std::ranges::transform(idxpos_to_rank, std::back_inserter(data), + [](auto x) { return x.second; }); auto it = idxpos_to_rank.begin(); for (std::size_t i = 0; i < _ghosts.size(); ++i) { @@ -1153,8 +1147,8 @@ graph::AdjacencyList IndexMap::index_to_dest_ranks() const } // Convert ranks for owned indices from neighbour to global ranks - std::transform(idx_to_rank.begin(), idx_to_rank.end(), data.begin(), - [&dest](auto x) { return dest[x.second]; }); + std::ranges::transform(idx_to_rank, data.begin(), + [&dest](auto x) { return dest[x.second]; }); return graph::AdjacencyList(std::move(data), std::move(offsets)); } @@ -1214,14 +1208,13 @@ std::vector IndexMap::shared_indices() const std::vector shared; shared.reserve(recv_buffer.size()); - std::transform(recv_buffer.begin(), recv_buffer.end(), - std::back_inserter(shared), - [range = _local_range](auto idx) - { - assert(idx >= range[0]); - assert(idx < range[1]); - return idx - range[0]; - }); + std::ranges::transform(recv_buffer, std::back_inserter(shared), + [range = _local_range](auto idx) + { + assert(idx >= range[0]); + assert(idx < range[1]); + return idx - range[0]; + }); // Sort and remove duplicates std::ranges::sort(shared); diff --git a/cpp/dolfinx/common/MPI.h b/cpp/dolfinx/common/MPI.h index 0b59f5521e0..0c32ba144a3 100644 --- a/cpp/dolfinx/common/MPI.h +++ b/cpp/dolfinx/common/MPI.h @@ -450,8 +450,8 @@ distribute_to_postoffice(MPI_Comm comm, const U& x, // Convert to local indices const std::int64_t r0 = MPI::local_range(rank, shape[0], size)[0]; std::vector index_local(recv_buffer_index.size()); - std::transform(recv_buffer_index.cbegin(), recv_buffer_index.cend(), - index_local.begin(), [r0](auto idx) { return idx - r0; }); + std::ranges::transform(recv_buffer_index, index_local.begin(), + [r0](auto idx) { return idx - r0; }); return {index_local, recv_buffer_data}; } @@ -549,9 +549,8 @@ distribute_from_postoffice(MPI_Comm comm, std::span indices, // post offices assert(send_disp.back() == (int)src_to_index.size()); std::vector send_buffer_index(src_to_index.size()); - std::transform(src_to_index.cbegin(), src_to_index.cend(), - send_buffer_index.begin(), - [](auto& x) { return std::get<1>(x); }); + std::ranges::transform(src_to_index, send_buffer_index.begin(), + [](auto x) { return std::get<1>(x); }); // Prepare the receive buffer std::vector recv_buffer_index(recv_disp.back()); diff --git a/cpp/dolfinx/common/Scatterer.h b/cpp/dolfinx/common/Scatterer.h index 47f900caf4c..85717f60f3b 100644 --- a/cpp/dolfinx/common/Scatterer.h +++ b/cpp/dolfinx/common/Scatterer.h @@ -86,10 +86,10 @@ class Scatterer std::span ghosts = map.ghosts(); std::vector owners_sorted(owners.size()); std::vector ghosts_sorted(owners.size()); - std::transform(perm.begin(), perm.end(), owners_sorted.begin(), - [&owners](auto idx) { return owners[idx]; }); - std::transform(perm.begin(), perm.end(), ghosts_sorted.begin(), - [&ghosts](auto idx) { return ghosts[idx]; }); + std::ranges::transform(perm, owners_sorted.begin(), + [&owners](auto idx) { return owners[idx]; }); + std::ranges::transform(perm, ghosts_sorted.begin(), + [&ghosts](auto idx) { return ghosts[idx]; }); // For data associated with ghost indices, packed by owning // (neighbourhood) rank, compute sizes and displacements. I.e., @@ -145,10 +145,8 @@ class Scatterer // Scale sizes and displacements by block size { - auto rescale = [](auto& x, int bs) - { - std::transform(x.begin(), x.end(), x.begin(), - [bs](auto e) { return e *= bs; }); + auto rescale = [](auto& x, int bs) { + std::ranges::transform(x, x.begin(), [bs](auto e) { return e *= bs; }); }; rescale(_sizes_local, bs); rescale(_displs_local, bs); diff --git a/cpp/dolfinx/common/utils.h b/cpp/dolfinx/common/utils.h index 3c7876de66e..6a5c8dc2000 100644 --- a/cpp/dolfinx/common/utils.h +++ b/cpp/dolfinx/common/utils.h @@ -34,8 +34,8 @@ sort_unique(const U& indices, const V& values) using T = typename std::pair; std::vector data(indices.size()); - std::transform(indices.begin(), indices.end(), values.begin(), data.begin(), - [](auto& idx, auto& v) -> T { return {idx, v}; }); + std::ranges::transform(indices, values, data.begin(), + [](auto& idx, auto& v) -> T { return {idx, v}; }); // Sort make unique std::ranges::sort(data); diff --git a/cpp/dolfinx/fem/CoordinateElement.cpp b/cpp/dolfinx/fem/CoordinateElement.cpp index f464e7cb915..fc3122b486a 100644 --- a/cpp/dolfinx/fem/CoordinateElement.cpp +++ b/cpp/dolfinx/fem/CoordinateElement.cpp @@ -148,8 +148,8 @@ void CoordinateElement::pull_back_nonaffine(mdspan2_t X, dX[i] += K(i, j) * (x(p, j) - xk[j]); // Compute Xk += dX - std::transform(dX.begin(), dX.end(), Xk_b.begin(), Xk_b.begin(), - [](auto a, auto b) { return a + b; }); + std::ranges::transform(dX, Xk_b, Xk_b.begin(), + [](auto a, auto b) { return a + b; }); // Compute norm(dX) if (auto dX_squared diff --git a/cpp/dolfinx/fem/DirichletBC.cpp b/cpp/dolfinx/fem/DirichletBC.cpp index 9c862323bb0..5d2f3d6e694 100644 --- a/cpp/dolfinx/fem/DirichletBC.cpp +++ b/cpp/dolfinx/fem/DirichletBC.cpp @@ -115,18 +115,17 @@ get_remote_dofs(MPI_Comm comm, const common::IndexMap& map, int bs_map, // Convert dofs indices to 'block' map indices std::vector dofs_local_m; dofs_local_m.reserve(dofs_local.size()); - std::transform(dofs_local.begin(), dofs_local.end(), - std::back_inserter(dofs_local_m), - [bs_map](auto dof) { return dof / bs_map; }); + std::ranges::transform(dofs_local, std::back_inserter(dofs_local_m), + [bs_map](auto dof) { return dof / bs_map; }); // Compute global index of each block map.local_to_global(dofs_local_m, dofs_global); // Add offset - std::transform(dofs_global.begin(), dofs_global.end(), dofs_local.begin(), - dofs_global.begin(), - [bs_map](auto global_block, auto local_dof) - { return bs_map * global_block + (local_dof % bs_map); }); + std::ranges::transform( + dofs_global, dofs_local, dofs_global.begin(), + [bs_map](auto global_block, auto local_dof) + { return bs_map * global_block + (local_dof % bs_map); }); } MPI_Wait(&request, MPI_STATUS_IGNORE); @@ -360,8 +359,9 @@ std::array, 2> fem::locate_dofs_topological( std::array, 2> sorted_bc_dofs = bc_dofs; for (std::size_t b = 0; b < 2; ++b) { - std::transform(perm.cbegin(), perm.cend(), sorted_bc_dofs[b].begin(), - [&bc_dofs = bc_dofs[b]](auto p) { return bc_dofs[p]; }); + std::ranges::transform(perm, sorted_bc_dofs[b].begin(), + [&bc_dofs = bc_dofs[b]](auto p) + { return bc_dofs[p]; }); sorted_bc_dofs[b].erase( std::unique(sorted_bc_dofs[b].begin(), sorted_bc_dofs[b].end()), sorted_bc_dofs[b].end()); @@ -414,9 +414,9 @@ std::array, 2> fem::locate_dofs_topological( std::array, 2> out_dofs = sorted_bc_dofs; for (std::size_t b = 0; b < 2; ++b) { - std::transform(perm.cbegin(), perm.cend(), out_dofs[b].begin(), - [&sorted_dofs = sorted_bc_dofs[b]](auto p) - { return sorted_dofs[p]; }); + std::ranges::transform(perm, out_dofs[b].begin(), + [&sorted_dofs = sorted_bc_dofs[b]](auto p) + { return sorted_dofs[p]; }); out_dofs[b].erase(std::unique(out_dofs[b].begin(), out_dofs[b].end()), out_dofs[b].end()); } diff --git a/cpp/dolfinx/fem/DirichletBC.h b/cpp/dolfinx/fem/DirichletBC.h index da8600e1585..d49ad1fd9f0 100644 --- a/cpp/dolfinx/fem/DirichletBC.h +++ b/cpp/dolfinx/fem/DirichletBC.h @@ -236,10 +236,10 @@ std::array, 2> locate_dofs_geometrical( // Copy to separate array std::array dofs = {std::vector(bc_dofs.size()), std::vector(bc_dofs.size())}; - std::transform(bc_dofs.cbegin(), bc_dofs.cend(), dofs[0].begin(), - [](auto dof) { return dof[0]; }); - std::transform(bc_dofs.cbegin(), bc_dofs.cend(), dofs[1].begin(), - [](auto dof) { return dof[1]; }); + std::ranges::transform(bc_dofs, dofs[0].begin(), + [](auto dof) { return dof[0]; }); + std::ranges::transform(bc_dofs, dofs[1].begin(), + [](auto dof) { return dof[1]; }); return dofs; } diff --git a/cpp/dolfinx/fem/DofMap.cpp b/cpp/dolfinx/fem/DofMap.cpp index 460c017c60c..b3d1e6ce5ef 100644 --- a/cpp/dolfinx/fem/DofMap.cpp +++ b/cpp/dolfinx/fem/DofMap.cpp @@ -69,9 +69,8 @@ fem::DofMap build_collapsed_dofmap(const DofMap& dofmap_view, { std::vector indices; indices.reserve(dofs_view.size()); - std::transform(dofs_view.begin(), dofs_view.end(), - std::back_inserter(indices), - [bs_view](auto idx) { return idx / bs_view; }); + std::ranges::transform(dofs_view, std::back_inserter(indices), + [bs_view](auto idx) { return idx / bs_view; }); auto [_index_map, _sub_imap_to_imap] = common::create_sub_index_map( *dofmap_view.index_map, indices, common::IndexMapOrder::preserve); index_map = std::make_shared(std::move(_index_map)); diff --git a/cpp/dolfinx/fem/Form.h b/cpp/dolfinx/fem/Form.h index 96c436b4d08..8a68932f808 100644 --- a/cpp/dolfinx/fem/Form.h +++ b/cpp/dolfinx/fem/Form.h @@ -325,8 +325,8 @@ class Form { std::vector ids; const auto& integrals = _integrals[static_cast(type)]; - std::transform(integrals.begin(), integrals.end(), std::back_inserter(ids), - [](auto& integral) { return integral.id; }); + std::ranges::transform(integrals, std::back_inserter(ids), + [](auto& integral) { return integral.id; }); return ids; } @@ -385,9 +385,8 @@ class Form { case IntegralType::cell: { - std::transform(entities.begin(), entities.end(), - std::back_inserter(mapped_entities), - [&entity_map](auto e) { return entity_map[e]; }); + std::ranges::transform(entities, std::back_inserter(mapped_entities), + [&entity_map](auto e) { return entity_map[e]; }); break; } case IntegralType::exterior_facet: diff --git a/cpp/dolfinx/fem/assembler.h b/cpp/dolfinx/fem/assembler.h index 7e6fcb82154..e50cb1b30e8 100644 --- a/cpp/dolfinx/fem/assembler.h +++ b/cpp/dolfinx/fem/assembler.h @@ -37,9 +37,10 @@ make_coefficients_span(const std::map, { using Key = typename std::remove_reference_t::key_type; std::map, int>> c; - std::transform(coeffs.cbegin(), coeffs.cend(), std::inserter(c, c.end()), - [](auto& e) -> typename decltype(c)::value_type - { return {e.first, {e.second.first, e.second.second}}; }); + std::ranges::transform(coeffs, std::inserter(c, c.end()), + [](auto& e) -> typename decltype(c)::value_type { + return {e.first, {e.second.first, e.second.second}}; + }); return c; } @@ -231,8 +232,8 @@ void apply_lifting( std::vector, std::pair, int>>> _coeffs; - std::transform(coeffs.cbegin(), coeffs.cend(), std::back_inserter(_coeffs), - [](auto& c) { return make_coefficients_span(c); }); + std::ranges::transform(coeffs, std::back_inserter(_coeffs), + [](auto& c) { return make_coefficients_span(c); }); apply_lifting(b, a, _constants, _coeffs, bcs1, x0, scale); } diff --git a/cpp/dolfinx/fem/discreteoperators.h b/cpp/dolfinx/fem/discreteoperators.h index 754b218993b..3989e77e9e0 100644 --- a/cpp/dolfinx/fem/discreteoperators.h +++ b/cpp/dolfinx/fem/discreteoperators.h @@ -231,10 +231,9 @@ void interpolation_matrix(const FunctionSpace& V0, e0->tabulate(basis_derivatives_reference0_b, X, Xshape, 0); // Clamp values - std::transform(basis_derivatives_reference0_b.begin(), - basis_derivatives_reference0_b.end(), - basis_derivatives_reference0_b.begin(), [atol = 1e-14](auto x) - { return std::abs(x) < atol ? 0.0 : x; }); + std::ranges::transform( + basis_derivatives_reference0_b, basis_derivatives_reference0_b.begin(), + [atol = 1e-14](auto x) { return std::abs(x) < atol ? 0.0 : x; }); // Create working arrays std::vector basis_reference0_b(Xshape[0] * dim0 * value_size_ref0); diff --git a/cpp/dolfinx/fem/dofmapbuilder.cpp b/cpp/dolfinx/fem/dofmapbuilder.cpp index 9e201e67b27..303ab41aced 100644 --- a/cpp/dolfinx/fem/dofmapbuilder.cpp +++ b/cpp/dolfinx/fem/dofmapbuilder.cpp @@ -390,8 +390,8 @@ std::pair, std::int32_t> compute_reordering_map( // Get mesh entity ownership offset for each IndexMap std::vector offset(index_maps.size(), -1); - std::transform(index_maps.begin(), index_maps.end(), offset.begin(), - [](auto map) { return map->size_local(); }); + std::ranges::transform(index_maps, offset.begin(), + [](auto& map) { return map->size_local(); }); // Compute the number of dofs 'owned' by this process const std::int32_t owned_size = std::accumulate( @@ -441,10 +441,10 @@ std::pair, std::int32_t> compute_reordering_map( // Apply graph reordering to owned dofs const std::vector node_remap = reorder_owned( dofmaps, owned_size, original_to_contiguous, reorder_fn); - std::transform(original_to_contiguous.begin(), original_to_contiguous.end(), - original_to_contiguous.begin(), - [&node_remap, owned_size](auto index) - { return index < owned_size ? node_remap[index] : index; }); + std::ranges::transform( + original_to_contiguous, original_to_contiguous.begin(), + [&node_remap, owned_size](auto index) + { return index < owned_size ? node_remap[index] : index; }); } return {std::move(original_to_contiguous), owned_size}; diff --git a/cpp/dolfinx/geometry/BoundingBoxTree.h b/cpp/dolfinx/geometry/BoundingBoxTree.h index 743350ae17e..64ede45a057 100644 --- a/cpp/dolfinx/geometry/BoundingBoxTree.h +++ b/cpp/dolfinx/geometry/BoundingBoxTree.h @@ -170,8 +170,7 @@ _build_from_point(std::span, std::int32_t>> points, // Sort bounding boxes along longest axis std::array b_diff; - std::transform(b1.begin(), b1.end(), b0.begin(), b_diff.begin(), - std::minus()); + std::ranges::transform(b1, b0, b_diff.begin(), std::minus()); const std::size_t axis = std::distance(b_diff.begin(), std::ranges::max_element(b_diff)); diff --git a/cpp/dolfinx/geometry/utils.h b/cpp/dolfinx/geometry/utils.h index 76eefdd0cbd..1bc36e8687b 100644 --- a/cpp/dolfinx/geometry/utils.h +++ b/cpp/dolfinx/geometry/utils.h @@ -814,10 +814,7 @@ PointOwnershipData determine_point_ownership(const mesh::Mesh& mesh, // but divide by three { auto rescale = [](auto& x) - { - std::transform(x.cbegin(), x.cend(), x.begin(), - [](auto e) { return (e / 3); }); - }; + { std::ranges::transform(x, x.begin(), [](auto e) { return (e / 3); }); }; rescale(recv_sizes); rescale(recv_offsets); rescale(send_sizes); diff --git a/cpp/dolfinx/graph/ordering.cpp b/cpp/dolfinx/graph/ordering.cpp index 7162e4d5acb..df41220546b 100644 --- a/cpp/dolfinx/graph/ordering.cpp +++ b/cpp/dolfinx/graph/ordering.cpp @@ -241,8 +241,8 @@ gps_reorder_unlabelled(const graph::AdjacencyList& graph, std::vector wn(k), wh(k), wl(k); for (const std::vector& r : rgc) { - std::transform(ls.begin(), ls.end(), wn.begin(), - [](const std::vector& vec) { return vec.size(); }); + std::ranges::transform(ls, wn.begin(), [](const std::vector& vec) + { return vec.size(); }); std::ranges::copy(wn, wh.begin()); std::ranges::copy(wn, wl.begin()); for (int w : r) @@ -251,10 +251,10 @@ gps_reorder_unlabelled(const graph::AdjacencyList& graph, ++wl[lvp[w][1]]; } // Zero any entries which did not increase - std::transform(wh.begin(), wh.end(), wn.begin(), wh.begin(), - [](int vh, int vn) { return (vh > vn) ? vh : 0; }); - std::transform(wl.begin(), wl.end(), wn.begin(), wl.begin(), - [](int vl, int vn) { return (vl > vn) ? vl : 0; }); + std::ranges::transform(wh, wn, wh.begin(), + [](int vh, int vn) { return (vh > vn) ? vh : 0; }); + std::ranges::transform(wl, wn, wl.begin(), + [](int vl, int vn) { return (vl > vn) ? vl : 0; }); // Find maximum of those that did increase int h0 = *std::ranges::max_element(wh); diff --git a/cpp/dolfinx/graph/partition.cpp b/cpp/dolfinx/graph/partition.cpp index 0b7d58f8679..e6ad5dbb61c 100644 --- a/cpp/dolfinx/graph/partition.cpp +++ b/cpp/dolfinx/graph/partition.cpp @@ -206,8 +206,8 @@ graph::build::distribute(MPI_Comm comm, } } - std::transform(offsets1.begin(), offsets1.end(), offsets1.begin(), - [off = offsets0.back()](auto x) { return x + off; }); + std::ranges::transform(offsets1, offsets1.begin(), + [off = offsets0.back()](auto x) { return x + off; }); data0.insert(data0.end(), data1.begin(), data1.end()); offsets0.insert(offsets0.end(), std::next(offsets1.begin()), offsets1.end()); src_ranks0.insert(src_ranks0.end(), src_ranks1.begin(), src_ranks1.end()); @@ -495,15 +495,15 @@ graph::build::compute_ghost_indices(MPI_Comm comm, std::ranges::sort(old_to_new); // Replace values in recv_data with new_index and send back - std::transform(recv_data.begin(), recv_data.end(), recv_data.begin(), - [&old_to_new](auto r) - { - auto it = std::ranges::lower_bound( - old_to_new, r, std::ranges::less(), - [](auto& e) { return e[0]; }); - assert(it != old_to_new.end() and (*it)[0] == r); - return (*it)[1]; - }); + std::ranges::transform(recv_data, recv_data.begin(), + [&old_to_new](auto r) + { + auto it = std::ranges::lower_bound( + old_to_new, r, std::ranges::less(), + [](auto e) { return e[0]; }); + assert(it != old_to_new.end() and (*it)[0] == r); + return (*it)[1]; + }); std::vector new_recv(send_data.size()); MPI_Neighbor_alltoallv(recv_data.data(), recv_sizes.data(), @@ -515,24 +515,22 @@ graph::build::compute_ghost_indices(MPI_Comm comm, // Build (old id, new id) pairs std::vector> old_to_new1(send_data.size()); - std::transform(send_data.begin(), send_data.end(), new_recv.begin(), - old_to_new1.begin(), - [](auto idx_old, auto idx_new) -> - typename decltype(old_to_new1)::value_type - { return {idx_old, idx_new}; }); + std::ranges::transform(send_data, new_recv, old_to_new1.begin(), + [](auto idx_old, auto idx_new) -> + typename decltype(old_to_new1)::value_type + { return {idx_old, idx_new}; }); std::ranges::sort(old_to_new1); std::vector ghost_global_indices(ghost_indices.size()); - std::transform(ghost_indices.begin(), ghost_indices.end(), - ghost_global_indices.begin(), - [&old_to_new1](auto q) - { - auto it = std::ranges::lower_bound( - old_to_new1, std::array{q, 0}, - [](auto& a, auto& b) { return a[0] < b[0]; }); - assert(it != old_to_new1.end() and (*it)[0] == q); - return (*it)[1]; - }); + std::ranges::transform(ghost_indices, ghost_global_indices.begin(), + [&old_to_new1](auto q) + { + auto it = std::ranges::lower_bound( + old_to_new1, std::array{q, 0}, + [](auto a, auto b) { return a[0] < b[0]; }); + assert(it != old_to_new1.end() and (*it)[0] == q); + return (*it)[1]; + }); return ghost_global_indices; } @@ -577,16 +575,16 @@ std::vector graph::build::compute_local_to_local( // Compute inverse map for local0_to_local1 std::vector local0_to_local1; local0_to_local1.reserve(local0_to_global.size()); - std::transform(local0_to_global.begin(), local0_to_global.end(), - std::back_inserter(local0_to_local1), - [&global_to_local1](auto l2g) - { - auto it = std::ranges::lower_bound( - global_to_local1, l2g, std::ranges::less(), - [](auto& e) { return e.first; }); - assert(it != global_to_local1.end() and it->first == l2g); - return it->second; - }); + std::ranges::transform( + local0_to_global, std::back_inserter(local0_to_local1), + [&global_to_local1](auto l2g) + { + auto it = std::ranges::lower_bound(global_to_local1, l2g, + std::ranges::less(), + [](auto e) { return e.first; }); + assert(it != global_to_local1.end() and it->first == l2g); + return it->second; + }); return local0_to_local1; } diff --git a/cpp/dolfinx/io/ADIOS2Writers.h b/cpp/dolfinx/io/ADIOS2Writers.h index ce5f4091b96..ab4030c1885 100644 --- a/cpp/dolfinx/io/ADIOS2Writers.h +++ b/cpp/dolfinx/io/ADIOS2Writers.h @@ -202,8 +202,8 @@ void initialize_function_attributes(adios2::IO& io, !assc) { std::vector u_type; - std::transform(u_data.cbegin(), u_data.cend(), std::back_inserter(u_type), - [](auto& f) { return f[1]; }); + std::ranges::transform(u_data, std::back_inserter(u_type), + [](auto f) { return f[1]; }); io.DefineAttribute("Fides_Variable_Associations", u_type.data(), u_type.size()); } @@ -214,8 +214,8 @@ void initialize_function_attributes(adios2::IO& io, !fields) { std::vector names; - std::transform(u_data.cbegin(), u_data.cend(), std::back_inserter(names), - [](auto& f) { return f[0]; }); + std::ranges::transform(u_data, std::back_inserter(names), + [](auto f) { return f[0]; }); io.DefineAttribute("Fides_Variable_List", names.data(), names.size()); } @@ -364,15 +364,15 @@ void write_data(adios2::IO& io, adios2::Engine& engine, adios2::Variable local_output_r = impl_adios2::define_variable( io, u.name + impl_adios2::field_ext[0], {}, {}, {num_vertices, num_components}); - std::transform(data.begin(), data.end(), data_real.begin(), - [](auto x) -> X { return std::real(x); }); + std::ranges::transform(data, data_real.begin(), + [](auto x) -> X { return std::real(x); }); engine.Put(local_output_r, data_real.data()); adios2::Variable local_output_c = impl_adios2::define_variable( io, u.name + impl_adios2::field_ext[1], {}, {}, {num_vertices, num_components}); - std::transform(data.begin(), data.end(), data_imag.begin(), - [](auto x) -> X { return std::imag(x); }); + std::ranges::transform(data, data_imag.begin(), + [](auto x) -> X { return std::imag(x); }); engine.Put(local_output_c, data_imag.data()); engine.PerformPuts(); } diff --git a/cpp/dolfinx/io/VTKFile.cpp b/cpp/dolfinx/io/VTKFile.cpp index 541323a3f59..0f9b7d59b14 100644 --- a/cpp/dolfinx/io/VTKFile.cpp +++ b/cpp/dolfinx/io/VTKFile.cpp @@ -155,12 +155,10 @@ void add_data(const std::string& name, { using U = typename T::value_type; std::vector v(values.size()); - std::transform(values.begin(), values.end(), v.begin(), - [](auto x) { return x.real(); }); + std::ranges::transform(values, v.begin(), [](auto x) { return x.real(); }); add_data_float(name + field_ext[0], num_components, std::span(v), node); - std::transform(values.begin(), values.end(), v.begin(), - [](auto x) { return x.imag(); }); + std::ranges::transform(values, v.begin(), [](auto x) { return x.imag(); }); add_data_float(name + field_ext[1], num_components, std::span(v), node); } diff --git a/cpp/dolfinx/io/xdmf_function.cpp b/cpp/dolfinx/io/xdmf_function.cpp index b213f3d648f..47ce57ddd6e 100644 --- a/cpp/dolfinx/io/xdmf_function.cpp +++ b/cpp/dolfinx/io/xdmf_function.cpp @@ -191,13 +191,13 @@ void xdmf_function::add_function(MPI_Comm comm, const fem::Function& u, _data.resize(data_values.size()); if (component == "real_") { - std::transform(data_values.begin(), data_values.end(), _data.begin(), - [](auto x) { return x.real(); }); + std::ranges::transform(data_values, _data.begin(), + [](auto x) { return x.real(); }); } else if (component == "imag_") { - std::transform(data_values.begin(), data_values.end(), _data.begin(), - [](auto x) { return x.imag(); }); + std::ranges::transform(data_values, _data.begin(), + [](auto x) { return x.imag(); }); } u = std::span>(_data); } diff --git a/cpp/dolfinx/io/xdmf_utils.cpp b/cpp/dolfinx/io/xdmf_utils.cpp index 01b061398b3..5a6fd0554a6 100644 --- a/cpp/dolfinx/io/xdmf_utils.cpp +++ b/cpp/dolfinx/io/xdmf_utils.cpp @@ -61,8 +61,8 @@ xdmf_utils::get_cell_type(const pugi::xml_node& topology_node) // Convert XDMF cell type string to DOLFINx cell type string std::string cell_type = type_attr.as_string(); - std::transform(cell_type.begin(), cell_type.end(), cell_type.begin(), - [](unsigned char c) { return std::tolower(c); }); + std::ranges::transform(cell_type, cell_type.begin(), + [](auto c) { return std::tolower(c); }); auto it = xdmf_to_dolfin.find(cell_type); if (it == xdmf_to_dolfin.end()) { @@ -400,8 +400,8 @@ xdmf_utils::distribute_entity_data( { int size = dolfinx::MPI::size(comm); std::vector> dest_to_index; - std::transform( - indices.begin(), indices.end(), std::back_inserter(dest_to_index), + std::ranges::transform( + indices, std::back_inserter(dest_to_index), [size, num_nodes](auto n) { return std::pair(dolfinx::MPI::index_owner(size, n, num_nodes), n); }); @@ -458,9 +458,8 @@ xdmf_utils::distribute_entity_data( // Prepare send buffer std::vector send_buffer; send_buffer.reserve(indices.size()); - std::transform(dest_to_index.begin(), dest_to_index.end(), - std::back_inserter(send_buffer), - [](auto x) { return x.second; }); + std::ranges::transform(dest_to_index, std::back_inserter(send_buffer), + [](auto x) { return x.second; }); std::vector recv_buffer(recv_disp.back()); err = MPI_Neighbor_alltoallv(send_buffer.data(), num_items_send.data(), diff --git a/cpp/dolfinx/la/MatrixCSR.h b/cpp/dolfinx/la/MatrixCSR.h index 891a8024cd4..2f46304f83a 100644 --- a/cpp/dolfinx/la/MatrixCSR.h +++ b/cpp/dolfinx/la/MatrixCSR.h @@ -475,8 +475,9 @@ MatrixCSR::MatrixCSR(const SparsityPattern& p, BlockMode mode) // Compute off-diagonal offset for each row (compact) std::span num_diag_nnz = p.off_diagonal_offsets(); _off_diagonal_offset.reserve(num_diag_nnz.size()); - std::transform(num_diag_nnz.begin(), num_diag_nnz.end(), _row_ptr.begin(), - std::back_inserter(_off_diagonal_offset), std::plus{}); + std::ranges::transform(num_diag_nnz, _row_ptr, + std::back_inserter(_off_diagonal_offset), + std::plus{}); } // Some short-hand @@ -553,9 +554,8 @@ MatrixCSR::MatrixCSR(const SparsityPattern& p, BlockMode mode) std::vector recv_disp; { std::vector send_sizes; - std::transform(data_per_proc.begin(), data_per_proc.end(), - std::back_inserter(send_sizes), - [](auto x) { return 2 * x; }); + std::ranges::transform(data_per_proc, std::back_inserter(send_sizes), + [](auto x) { return 2 * x; }); std::vector recv_sizes(dest_ranks.size()); send_sizes.reserve(1); @@ -582,10 +582,10 @@ MatrixCSR::MatrixCSR(const SparsityPattern& p, BlockMode mode) // data values _val_recv_disp.resize(recv_disp.size()); const int bs2 = _bs[0] * _bs[1]; - std::transform(recv_disp.begin(), recv_disp.end(), _val_recv_disp.begin(), - [&bs2](auto d) { return bs2 * d / 2; }); - std::transform(_val_send_disp.begin(), _val_send_disp.end(), - _val_send_disp.begin(), [&bs2](auto d) { return d * bs2; }); + std::ranges::transform(recv_disp, _val_recv_disp.begin(), + [&bs2](auto d) { return bs2 * d / 2; }); + std::ranges::transform(_val_send_disp, _val_send_disp.begin(), + [&bs2](auto d) { return d * bs2; }); // Global-to-local map for ghost columns std::vector> global_to_local; diff --git a/cpp/dolfinx/la/Vector.h b/cpp/dolfinx/la/Vector.h index a4d32511f6c..9b69e4670fb 100644 --- a/cpp/dolfinx/la/Vector.h +++ b/cpp/dolfinx/la/Vector.h @@ -325,9 +325,9 @@ void orthonormalize(std::vector> basis) // basis_i <- basis_i - dot_ij basis_j auto dot_ij = inner_product(bi, bj); - std::transform(bj.array().begin(), bj.array().end(), bi.array().begin(), - bi.mutable_array().begin(), - [dot_ij](auto xj, auto xi) { return xi - dot_ij * xj; }); + std::ranges::transform(bj.array(), bi.array(), bi.mutable_array().begin(), + [dot_ij](auto xj, auto xi) + { return xi - dot_ij * xj; }); } // Normalise basis function @@ -337,9 +337,8 @@ void orthonormalize(std::vector> basis) throw std::runtime_error( "Linear dependency detected. Cannot orthogonalize."); } - std::transform(bi.array().begin(), bi.array().end(), - bi.mutable_array().begin(), - [norm](auto x) { return x / norm; }); + std::ranges::transform(bi.array(), bi.mutable_array().begin(), + [norm](auto x) { return x / norm; }); } } diff --git a/cpp/dolfinx/mesh/Geometry.h b/cpp/dolfinx/mesh/Geometry.h index 6870cf63b3f..70eb6aa8fc0 100644 --- a/cpp/dolfinx/mesh/Geometry.h +++ b/cpp/dolfinx/mesh/Geometry.h @@ -334,8 +334,8 @@ create_geometry( // Allocate space for input global indices and copy data std::vector igi(nodes.size()); - std::transform(l2l.cbegin(), l2l.cend(), igi.begin(), - [&nodes](auto index) { return nodes[index]; }); + std::ranges::transform(l2l, igi.begin(), + [&nodes](auto index) { return nodes[index]; }); // Build coordinate dof array, copying coordinates to correct position assert(x.size() % dim == 0); @@ -426,8 +426,8 @@ create_geometry( // Allocate space for input global indices and copy data std::vector igi(nodes.size()); - std::transform(l2l.cbegin(), l2l.cend(), igi.begin(), - [&nodes](auto index) { return nodes[index]; }); + std::ranges::transform(l2l, igi.begin(), + [&nodes](auto index) { return nodes[index]; }); // Build coordinate dof array, copying coordinates to correct position assert(x.size() % dim == 0); diff --git a/cpp/dolfinx/mesh/Topology.cpp b/cpp/dolfinx/mesh/Topology.cpp index 80b20a5842a..f7d7af3caee 100644 --- a/cpp/dolfinx/mesh/Topology.cpp +++ b/cpp/dolfinx/mesh/Topology.cpp @@ -435,9 +435,8 @@ exchange_indexing(MPI_Comm comm, std::span indices, // Prepare send sizes and send displacements std::vector send_sizes; send_sizes.reserve(dest.size()); - std::transform(send_buffer.begin(), send_buffer.end(), - std::back_inserter(send_sizes), - [](auto& x) { return x.size(); }); + std::ranges::transform(send_buffer, std::back_inserter(send_sizes), + [](auto& x) { return x.size(); }); std::vector send_disp(dest.size() + 1, 0); std::partial_sum(send_sizes.begin(), send_sizes.end(), std::next(send_disp.begin())); @@ -534,19 +533,18 @@ std::vector> exchange_ghost_indexing( // Build list of (owner rank, index) pairs for each ghost index, and // sort std::vector> owner_to_ghost; - std::transform(map0.ghosts().begin(), map0.ghosts().end(), - map0.owners().begin(), std::back_inserter(owner_to_ghost), - [](auto idx, auto r) -> std::pair - { return {r, idx}; }); + std::ranges::transform(map0.ghosts(), map0.owners(), + std::back_inserter(owner_to_ghost), + [](auto idx, auto r) -> std::pair + { return {r, idx}; }); std::ranges::sort(owner_to_ghost); // Build send buffer (the second component of each pair in // owner_to_ghost) to send to rank that owns the index std::vector send_buffer; send_buffer.reserve(owner_to_ghost.size()); - std::transform(owner_to_ghost.begin(), owner_to_ghost.end(), - std::back_inserter(send_buffer), - [](auto x) { return x.second; }); + std::ranges::transform(owner_to_ghost, std::back_inserter(send_buffer), + [](auto x) { return x.second; }); // Compute send sizes and displacements std::vector send_sizes, send_disp{0}; @@ -606,8 +604,8 @@ std::vector> exchange_ghost_indexing( // Compute send sizes and offsets std::vector send_sizes(dest.size()); - std::transform(shared_vertices_fwd.begin(), shared_vertices_fwd.end(), - send_sizes.begin(), [](auto& x) { return 3 * x.size(); }); + std::ranges::transform(shared_vertices_fwd, send_sizes.begin(), + [](auto& x) { return 3 * x.size(); }); std::vector send_disp(dest.size() + 1); std::partial_sum(send_sizes.begin(), send_sizes.end(), std::next(send_disp.begin())); @@ -1169,18 +1167,14 @@ Topology mesh::create_topology( global_to_local_vertices; global_to_local_vertices.reserve(owned_vertices.size() + unowned_vertices.size()); - std::transform(owned_vertices.begin(), owned_vertices.end(), - local_vertex_indices.begin(), - std::back_inserter(global_to_local_vertices), - [](auto idx0, auto idx1) { - return std::pair(idx0, idx1); - }); - std::transform(unowned_vertices.begin(), unowned_vertices.end(), - local_vertex_indices_unowned.begin(), - std::back_inserter(global_to_local_vertices), - [](auto idx0, auto idx1) { - return std::pair(idx0, idx1); - }); + std::ranges::transform( + owned_vertices, local_vertex_indices, + std::back_inserter(global_to_local_vertices), [](auto idx0, auto idx1) + { return std::pair(idx0, idx1); }); + std::ranges::transform( + unowned_vertices, local_vertex_indices_unowned, + std::back_inserter(global_to_local_vertices), [](auto idx0, auto idx1) + { return std::pair(idx0, idx1); }); std::ranges::sort(global_to_local_vertices); // Send (from the ghost cell owner) and receive global indices for @@ -1227,15 +1221,13 @@ Topology mesh::create_topology( std::vector> global_to_local_vertices; global_to_local_vertices.reserve(owned_vertices.size() + unowned_vertices.size()); - std::transform( - owned_vertices.begin(), owned_vertices.end(), - local_vertex_indices.begin(), + std::ranges::transform( + owned_vertices, local_vertex_indices, std::back_inserter(global_to_local_vertices), [](auto idx0, auto idx1) -> std::pair { return {idx0, idx1}; }); - std::transform( - unowned_vertices.begin(), unowned_vertices.end(), - local_vertex_indices_unowned.begin(), + std::ranges::transform( + unowned_vertices, local_vertex_indices_unowned, std::back_inserter(global_to_local_vertices), [](auto idx0, auto idx1) -> std::pair { return {idx0, idx1}; }); diff --git a/cpp/dolfinx/mesh/graphbuild.cpp b/cpp/dolfinx/mesh/graphbuild.cpp index 4d521af22e3..9229c686eb5 100644 --- a/cpp/dolfinx/mesh/graphbuild.cpp +++ b/cpp/dolfinx/mesh/graphbuild.cpp @@ -328,8 +328,8 @@ graph::AdjacencyList compute_nonlocal_dual_graph( { auto e = local_graph.links(i); disp[i] += e.size(); - std::transform(e.begin(), e.end(), std::next(data.begin(), offsets[i]), - [cell_offset](auto x) { return x + cell_offset; }); + std::ranges::transform(e, std::next(data.begin(), offsets[i]), + [cell_offset](auto x) { return x + cell_offset; }); } // Add non-local data @@ -421,9 +421,8 @@ mesh::build_local_dual_graph( for (int f = 0; f < cell_facets.num_nodes(); ++f) { auto facet_vertices = cell_facets.links(f); - std::transform(facet_vertices.begin(), facet_vertices.end(), - std::back_inserter(facets), - [v](auto idx) { return v[idx]; }); + std::ranges::transform(facet_vertices, std::back_inserter(facets), + [v](auto idx) { return v[idx]; }); std::sort(std::prev(facets.end(), facet_vertices.size()), facets.end()); facets.insert(facets.end(), max_vertices_per_facet - facet_vertices.size(), -1); diff --git a/cpp/dolfinx/mesh/topologycomputation.cpp b/cpp/dolfinx/mesh/topologycomputation.cpp index 01b81510272..1f69d89057a 100644 --- a/cpp/dolfinx/mesh/topologycomputation.cpp +++ b/cpp/dolfinx/mesh/topologycomputation.cpp @@ -44,8 +44,8 @@ graph::AdjacencyList create_adj_list(U& data, std::int32_t size) std::vector array; array.reserve(data.size()); - std::transform(data.begin(), data.end(), std::back_inserter(array), - [](auto x) { return x.second; }); + std::ranges::transform(data, std::back_inserter(array), + [](auto x) { return x.second; }); std::vector offsets{0}; offsets.reserve(size + 1); @@ -307,9 +307,8 @@ get_local_indexing(MPI_Comm comm, const common::IndexMap& vertex_map, shared_entities_data.push_back({idx, ranks[r]}); shared_entities_data.push_back({idx, mpi_rank}); recv_index.push_back(idx); - std::transform( - entity.begin(), entity.end(), - std::back_inserter(shared_entity_to_global_vertices_data), + std::ranges::transform( + entity, std::back_inserter(shared_entity_to_global_vertices_data), [idx](auto v) -> std::pair { return {idx, v}; }); } @@ -364,15 +363,13 @@ get_local_indexing(MPI_Comm comm, const common::IndexMap& vertex_map, } num_local = c; - std::transform(local_index.cbegin(), local_index.cend(), - local_index.begin(), - [&c](auto index) { return index == -1 ? c++ : index; }); + std::ranges::transform(local_index, local_index.begin(), [&c](auto index) + { return index == -1 ? c++ : index; }); assert(c == entity_count); // Convert interprocess entities to local_index - std::transform(interprocess_entities.cbegin(), interprocess_entities.cend(), - interprocess_entities.begin(), - [&local_index](std::int32_t i) { return local_index[i]; }); + std::ranges::transform(interprocess_entities, interprocess_entities.begin(), + [&local_index](auto i) { return local_index[i]; }); } //--------- @@ -390,25 +387,20 @@ get_local_indexing(MPI_Comm comm, const common::IndexMap& vertex_map, std::vector send_global_index_data; for (const auto& indices : send_index) { - std::transform(indices.cbegin(), indices.cend(), - std::back_inserter(send_global_index_data), - [&local_index, size = num_local, - offset = local_offset](auto idx) -> std::int64_t - { - // If not in our local range, send -1. - return local_index[idx] < size - ? offset + local_index[idx] - : -1; - }); + std::ranges::transform( + indices, std::back_inserter(send_global_index_data), + [&local_index, size = num_local, + offset = local_offset](auto idx) -> std::int64_t + { + // If not in our local range, send -1. + return local_index[idx] < size ? offset + local_index[idx] : -1; + }); } // Transform send/receive sizes and displacements for scalar send for (auto x : {&send_sizes, &send_disp, &recv_sizes, &recv_disp}) - { - std::transform(x->begin(), x->end(), x->begin(), - [num_vertices_per_e](auto a) - { return a / num_vertices_per_e; }); - } + std::ranges::transform(*x, x->begin(), [num_vertices_per_e](auto a) + { return a / num_vertices_per_e; }); recv_data.resize(recv_disp.back()); MPI_Neighbor_alltoallv(send_global_index_data.data(), send_sizes.data(), @@ -441,9 +433,9 @@ get_local_indexing(MPI_Comm comm, const common::IndexMap& vertex_map, // Create map from initial numbering to new local indices std::vector new_entity_index(entity_index.size()); - std::transform(entity_index.begin(), entity_index.end(), - new_entity_index.begin(), - [&local_index](auto index) { return local_index[index]; }); + std::ranges::transform(entity_index, new_entity_index.begin(), + [&local_index](auto index) + { return local_index[index]; }); return {std::move(new_entity_index), std::move(index_map), std::move(interprocess_entities)}; diff --git a/cpp/dolfinx/mesh/utils.h b/cpp/dolfinx/mesh/utils.h index a555d130afa..669a61fec74 100644 --- a/cpp/dolfinx/mesh/utils.h +++ b/cpp/dolfinx/mesh/utils.h @@ -295,8 +295,8 @@ std::vector cell_normals(const Mesh& mesh, int dim, // Define normal by rotating tangent counter-clockwise std::array t; - std::transform(p[1].begin(), p[1].end(), p[0].begin(), t.begin(), - [](auto x, auto y) { return x - y; }); + std::ranges::transform(p[1], p[0], t.begin(), + [](auto x, auto y) { return x - y; }); T norm = std::sqrt(t[0] * t[0] + t[1] * t[1]); std::span ni(n.data() + 3 * i, 3); @@ -320,16 +320,16 @@ std::vector cell_normals(const Mesh& mesh, int dim, // Compute (p1 - p0) and (p2 - p0) std::array dp1, dp2; - std::transform(p[1].begin(), p[1].end(), p[0].begin(), dp1.begin(), - [](auto x, auto y) { return x - y; }); - std::transform(p[2].begin(), p[2].end(), p[0].begin(), dp2.begin(), - [](auto x, auto y) { return x - y; }); + std::ranges::transform(p[1], p[0], dp1.begin(), + [](auto x, auto y) { return x - y; }); + std::ranges::transform(p[2], p[0], dp2.begin(), + [](auto x, auto y) { return x - y; }); // Define cell normal via cross product of first two edges std::array ni = math::cross(dp1, dp2); T norm = std::sqrt(ni[0] * ni[0] + ni[1] * ni[1] + ni[2] * ni[2]); - std::transform(ni.begin(), ni.end(), std::next(n.begin(), 3 * i), - [norm](auto x) { return x / norm; }); + std::ranges::transform(ni, std::next(n.begin(), 3 * i), + [norm](auto x) { return x / norm; }); } return n; @@ -349,16 +349,16 @@ std::vector cell_normals(const Mesh& mesh, int dim, // Compute (p1 - p0) and (p2 - p0) std::array dp1, dp2; - std::transform(p[1].begin(), p[1].end(), p[0].begin(), dp1.begin(), - [](auto x, auto y) { return x - y; }); - std::transform(p[2].begin(), p[2].end(), p[0].begin(), dp2.begin(), - [](auto x, auto y) { return x - y; }); + std::ranges::transform(p[1], p[0], dp1.begin(), + [](auto x, auto y) { return x - y; }); + std::ranges::transform(p[2], p[0], dp2.begin(), + [](auto x, auto y) { return x - y; }); // Define cell normal via cross product of first two edges std::array ni = math::cross(dp1, dp2); T norm = std::sqrt(ni[0] * ni[0] + ni[1] * ni[1] + ni[2] * ni[2]); - std::transform(ni.begin(), ni.end(), std::next(n.begin(), 3 * i), - [norm](auto x) { return x / norm; }); + std::ranges::transform(ni, std::next(n.begin(), 3 * i), + [norm](auto x) { return x / norm; }); } return n; @@ -395,9 +395,9 @@ std::vector compute_midpoints(const Mesh& mesh, int dim, for (auto row : rows) { std::span xg(x.data() + 3 * row, 3); - std::transform(p.begin(), p.end(), xg.begin(), p.begin(), - [size = rows.size()](auto x, auto y) - { return x + y / size; }); + std::ranges::transform(p, xg, p.begin(), + [size = rows.size()](auto x, auto y) + { return x + y / size; }); } } @@ -953,13 +953,11 @@ Mesh> create_mesh( assert(cells.size() == elements.size()); std::int32_t num_cell_types = cells.size(); std::vector celltypes; - std::transform(elements.cbegin(), elements.cend(), - std::back_inserter(celltypes), - [](auto e) { return e.cell_shape(); }); + std::ranges::transform(elements, std::back_inserter(celltypes), + [](auto e) { return e.cell_shape(); }); std::vector doflayouts; - std::transform(elements.cbegin(), elements.cend(), - std::back_inserter(doflayouts), - [](auto e) { return e.create_dof_layout(); }); + std::ranges::transform(elements, std::back_inserter(doflayouts), + [](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 @@ -1090,17 +1088,14 @@ Mesh> create_mesh( // Create Topology std::vector> cells1_v_span; - std::transform(cells1_v.cbegin(), cells1_v.cend(), - std::back_inserter(cells1_v_span), - [](auto& c) { return std::span(c); }); + std::ranges::transform(cells1_v, std::back_inserter(cells1_v_span), + [](auto& c) { return std::span(c); }); std::vector> original_idx1_span; - std::transform(original_idx1.cbegin(), original_idx1.cend(), - std::back_inserter(original_idx1_span), - [](auto& c) { return std::span(c); }); + std::ranges::transform(original_idx1, std::back_inserter(original_idx1_span), + [](auto& c) { return std::span(c); }); std::vector> ghost_owners_span; - std::transform(ghost_owners.cbegin(), ghost_owners.cend(), - std::back_inserter(ghost_owners_span), - [](auto& c) { return std::span(c); }); + std::ranges::transform(ghost_owners, std::back_inserter(ghost_owners_span), + [](auto& c) { return std::span(c); }); Topology topology = create_topology(comm, celltypes, cells1_v_span, original_idx1_span, @@ -1234,13 +1229,12 @@ create_subgeometry(const Mesh& mesh, int dim, // Create sub-geometry dofmap std::vector sub_x_dofmap; sub_x_dofmap.reserve(x_indices.size()); - std::transform(x_indices.cbegin(), x_indices.cend(), - std::back_inserter(sub_x_dofmap), - [&x_to_subx_dof_map](auto x_dof) - { - assert(x_to_subx_dof_map[x_dof] != -1); - return x_to_subx_dof_map[x_dof]; - }); + std::ranges::transform(x_indices, std::back_inserter(sub_x_dofmap), + [&x_to_subx_dof_map](auto x_dof) + { + assert(x_to_subx_dof_map[x_dof] != -1); + return x_to_subx_dof_map[x_dof]; + }); // Create sub-geometry coordinate element CellType sub_coord_cell @@ -1252,9 +1246,9 @@ create_subgeometry(const Mesh& mesh, int dim, const std::vector& igi = geometry.input_global_indices(); std::vector sub_igi; sub_igi.reserve(subx_to_x_dofmap.size()); - std::transform(subx_to_x_dofmap.begin(), subx_to_x_dofmap.end(), - std::back_inserter(sub_igi), - [&igi](std::int32_t sub_x_dof) { return igi[sub_x_dof]; }); + std::ranges::transform(subx_to_x_dofmap, std::back_inserter(sub_igi), + [&igi](auto sub_x_dof) + { return igi[sub_x_dof]; }); // Create geometry return {Geometry(sub_x_dof_index_map, std::move(sub_x_dofmap), {sub_cmap}, diff --git a/cpp/dolfinx/refinement/plaza.h b/cpp/dolfinx/refinement/plaza.h index 379bed09c88..a3223d6c39e 100644 --- a/cpp/dolfinx/refinement/plaza.h +++ b/cpp/dolfinx/refinement/plaza.h @@ -585,14 +585,13 @@ compute_refinement_data(const mesh::Mesh& mesh, Option option) ranks.erase(std::unique(ranks.begin(), ranks.end()), ranks.end()); // Convert edge_ranks from global rank to to neighbourhood ranks - std::transform(edge_ranks.array().begin(), edge_ranks.array().end(), - edge_ranks.array().begin(), - [&ranks](auto r) - { - auto it = std::ranges::lower_bound(ranks, r); - assert(it != ranks.end() and *it == r); - return std::distance(ranks.begin(), it); - }); + std::ranges::transform(edge_ranks.array(), edge_ranks.array().begin(), + [&ranks](auto r) + { + auto it = std::ranges::lower_bound(ranks, r); + assert(it != ranks.end() and *it == r); + return std::distance(ranks.begin(), it); + }); MPI_Comm comm; MPI_Dist_graph_create_adjacent(mesh.comm(), ranks.size(), ranks.data(), @@ -652,14 +651,13 @@ compute_refinement_data(const mesh::Mesh& mesh, ranks.erase(std::unique(ranks.begin(), ranks.end()), ranks.end()); // Convert edge_ranks from global rank to to neighbourhood ranks - std::transform(edge_ranks.array().begin(), edge_ranks.array().end(), - edge_ranks.array().begin(), - [&ranks](auto r) - { - auto it = std::ranges::lower_bound(ranks, r); - assert(it != ranks.end() and *it == r); - return std::distance(ranks.begin(), it); - }); + std::ranges::transform(edge_ranks.array(), edge_ranks.array().begin(), + [&ranks](auto r) + { + auto it = std::ranges::lower_bound(ranks, r); + assert(it != ranks.end() and *it == r); + return std::distance(ranks.begin(), it); + }); // Get number of neighbors std::vector marked_edges( diff --git a/cpp/test/io.cpp b/cpp/test/io.cpp index 58fa1da92b0..655e2258d55 100644 --- a/cpp/test/io.cpp +++ b/cpp/test/io.cpp @@ -36,7 +36,7 @@ void test_fides_mesh() auto x = mesh->geometry().x(); // Move all coordinates of the mesh geometry - std::transform(x.begin(), x.end(), x.begin(), [](auto x) { return x + 1; }); + std::ranges::transform(x, x.begin(), [](auto x) { return x + 1; }); writer.write(0.2); // Only move x coordinate diff --git a/python/dolfinx/wrappers/assemble.cpp b/python/dolfinx/wrappers/assemble.cpp index 7dc07803e07..d216039d083 100644 --- a/python/dolfinx/wrappers/assemble.cpp +++ b/python/dolfinx/wrappers/assemble.cpp @@ -172,8 +172,8 @@ void declare_assembly_functions(nb::module_& m) // Move into NumPy data structures std::map> c; - std::transform( - coeffs.begin(), coeffs.end(), std::inserter(c, c.end()), + std::ranges::transform( + coeffs, std::inserter(c, c.end()), [](auto& e) -> typename decltype(c)::value_type { std::size_t num_ents @@ -396,16 +396,15 @@ void declare_assembly_functions(nb::module_& m) _x0.emplace_back(x.data(), x.size()); std::vector> _constants; - std::transform(constants.begin(), constants.end(), - std::back_inserter(_constants), [](auto& c) - { return std::span(c.data(), c.size()); }); + std::ranges::transform( + constants, std::back_inserter(_constants), + [](auto& c) { return std::span(c.data(), c.size()); }); std::vector, std::pair, int>>> _coeffs; - std::transform(coeffs.begin(), coeffs.end(), - std::back_inserter(_coeffs), - [](auto& c) { return py_to_cpp_coeffs(c); }); + std::ranges::transform(coeffs, std::back_inserter(_coeffs), + [](auto& c) { return py_to_cpp_coeffs(c); }); dolfinx::fem::apply_lifting(std::span(b.data(), b.size()), a, _constants, _coeffs, bcs1, _x0, scale); diff --git a/python/dolfinx/wrappers/mesh.cpp b/python/dolfinx/wrappers/mesh.cpp index a68cdc5f7a6..45299d926b5 100644 --- a/python/dolfinx/wrappers/mesh.cpp +++ b/python/dolfinx/wrappers/mesh.cpp @@ -60,10 +60,9 @@ auto create_cell_partitioner_py(Functor p) std::vector> cells_nb) { std::vector> cells; - std::transform(cells_nb.begin(), cells_nb.end(), std::back_inserter(cells), - [](auto c) { - return std::span(c.data(), c.size()); - }); + std::ranges::transform( + cells_nb, std::back_inserter(cells), [](auto c) + { return std::span(c.data(), c.size()); }); return p(comm.get(), n, cell_types, cells); }; } @@ -90,12 +89,13 @@ create_cell_partitioner_cpp(const PythonCellPartitionFunction& p) const std::vector>& cells) { std::vector> cells_nb; - std::transform(cells.begin(), cells.end(), std::back_inserter(cells_nb), - [](auto c) - { - return nb::ndarray( - c.data(), {c.size()}, nb::handle()); - }); + std::ranges::transform( + cells, std::back_inserter(cells_nb), + [](auto c) + { + return nb::ndarray( + c.data(), {c.size()}, nb::handle()); + }); return p(dolfinx_wrappers::MPICommWrapper(comm), n, cell_types, cells_nb); }; @@ -291,9 +291,8 @@ void declare_mesh(nb::module_& m, std::string type) std::size_t shape1 = x.ndim() == 1 ? 1 : x.shape(1); std::vector> cells; - std::transform( - cells_nb.begin(), cells_nb.end(), std::back_inserter(cells), - [](auto c) + std::ranges::transform( + cells_nb, std::back_inserter(cells), [](auto c) { return std::span(c.data(), c.size()); }); if (p) @@ -304,8 +303,8 @@ void declare_mesh(nb::module_& m, std::string type) const std::vector>& cells) { std::vector> cells_nb; - std::transform( - cells.begin(), cells.end(), std::back_inserter(cells_nb), + std::ranges::transform( + cells, std::back_inserter(cells_nb), [](auto c) { return nb::ndarray( @@ -340,13 +339,13 @@ void declare_mesh(nb::module_& m, std::string type) const std::vector>& cells) { std::vector> cells_nb; - std::transform(cells.begin(), cells.end(), - std::back_inserter(cells_nb), - [](auto c) - { - return nb::ndarray( - c.data(), {c.size()}, nb::handle()); - }); + std::ranges::transform( + cells, std::back_inserter(cells_nb), + [](auto c) + { + return nb::ndarray( + c.data(), {c.size()}, nb::handle()); + }); return p(MPICommWrapper(comm), n, cell_types, cells_nb); }; return dolfinx::mesh::create_mesh( diff --git a/python/dolfinx/wrappers/pycoeff.h b/python/dolfinx/wrappers/pycoeff.h index 0bcf0409a55..a056bd51400 100644 --- a/python/dolfinx/wrappers/pycoeff.h +++ b/python/dolfinx/wrappers/pycoeff.h @@ -19,13 +19,14 @@ py_to_cpp_coeffs( { using Key_t = typename std::remove_reference_t::key_type; std::map, int>> c; - std::transform(coeffs.begin(), coeffs.end(), std::inserter(c, c.end()), - [](auto& e) -> typename decltype(c)::value_type - { - return {e.first, - {std::span(static_cast(e.second.data()), - e.second.shape(0)), - e.second.shape(1)}}; - }); + std::ranges::transform( + coeffs, std::inserter(c, c.end()), + [](auto& e) -> typename decltype(c)::value_type + { + return {e.first, + {std::span(static_cast(e.second.data()), + e.second.shape(0)), + e.second.shape(1)}}; + }); return c; }