6#include <range/v3/algorithm/copy.hpp>
7#include <range/v3/algorithm/count_if.hpp>
8#include <range/v3/view/filter.hpp>
9#include <range/v3/view/iota.hpp>
10#include <range/v3/view/transform.hpp>
43template <std::
size_t Dim>
64template <std::
size_t Dim>
67 static_assert(Dim == 1 || Dim == 2);
68 using MatOrVec = std::conditional_t<Dim == 1, GlobalVector, GlobalMatrix>;
74 const int num_threads)
80 void add(std::vector<double>
const& local_data,
81 std::vector<GlobalIndexType>
const& indices)
83 if (local_data.empty())
90 if constexpr (Dim == 2)
92 auto const num_r_c = indices.size();
112 std::vector<GlobalIndexType>
const& indices)
117 std::integral_constant<std::size_t, Dim>{});
122 std::vector<GlobalIndexType>
const& indices,
123 std::integral_constant<std::size_t, 1>)
125 auto const num_r_c = indices.size();
126 auto const*
const __restrict val = values.data();
127 auto const*
const __restrict idx = indices.data();
130 auto const nonzero_count = ranges::count_if(
131 val, val + num_r_c, [](
double v) {
return v != 0.0; });
133 if (nonzero_count == 0)
140 ranges::views::iota(0ul, num_r_c) |
141 ranges::views::filter([val](std::size_t i)
142 {
return val[i] != 0.0; }) |
143 ranges::views::transform(
144 [val, idx](std::size_t i)
147 auto const old_size =
cache_.size();
148 cache_.resize(old_size + nonzero_count);
149 ranges::copy(entries,
cache_.begin() + old_size);
152 stats_.count_nonzero += nonzero_count;
157 std::vector<GlobalIndexType>
const& indices,
158 std::integral_constant<std::size_t, 2>)
160 auto const num_r_c = indices.size();
161 auto const total_entries = num_r_c * num_r_c;
164 auto const* __restrict__
const idx = indices.data();
165 auto const* __restrict__
const val = values.data();
167 auto const old_size =
cache_.size();
168 cache_.resize(old_size + total_entries);
169 auto* __restrict__ dest =
cache_.data() + old_size;
171 for (std::size_t r = 0; r < num_r_c; ++r)
173 auto const r_global = idx[r];
174 for (std::size_t c = 0; c < num_r_c; ++c)
176 dest->indices[0] = r_global;
177 dest->indices[1] = idx[c];
178 dest->value = val[r * num_r_c + c];
183 stats_.count += total_entries;
184 stats_.count_nonzero += total_entries;
190 if (
cache_.size() + space_needed <=
cache_.capacity()) [[likely]]
206 auto const size_initial =
cache_.size();
207 auto const cap_initial =
cache_.capacity();
209 if (size_initial + space_needed <= cap_initial)
218 auto const size_after =
cache_.size();
219 auto const cap_after =
cache_.capacity();
221 if (size_after + space_needed > cap_after)
223 cache_.reserve(size_after + 2 * space_needed);
236 if constexpr (Dim == 2)
238 auto const n_cols =
mat_or_vec_.getNumberOfColumns();
244 for (
auto const [rc, value] :
cache_)
246 auto const [r, c] = rc;
248 auto const c_no_ghost =
258 for (
auto const [r, value] :
cache_)
269 std::vector<MatrixElementCacheEntry<Dim>>
cache_;
275template <
int NumMatrices>
285 :
cache_b_(b, stats.b, num_threads),
290 void add(std::vector<double>
const& local_b_data,
291 std::vector<double>
const& local_Jac_data,
292 std::vector<GlobalIndexType>
const& indices)
294 cache_b_.add(local_b_data, indices);
310 :
cache_M_(M, stats.M, num_threads),
316 void add(std::vector<double>
const& local_M_data,
317 std::vector<double>
const& local_K_data,
318 std::vector<double>
const& local_b_data,
319 std::vector<GlobalIndexType>
const& indices)
321 cache_M_.add(local_M_data, indices);
322 cache_K_.add(local_K_data, indices);
323 cache_b_.add(local_b_data, indices);
MathLib::EigenMatrix GlobalMatrix
MathLib::EigenVector GlobalVector
GlobalMatrix::IndexType GlobalIndexType
void addToCacheImpl(std::vector< double > const &values, std::vector< GlobalIndexType > const &indices, std::integral_constant< std::size_t, 2 >)
static constexpr std::size_t cache_capacity
void addToCacheImpl(std::vector< double > const &values, std::vector< GlobalIndexType > const &indices, std::integral_constant< std::size_t, 1 >)
void addToCache(std::vector< double > const &values, std::vector< GlobalIndexType > const &indices)
void add(std::vector< double > const &local_data, std::vector< GlobalIndexType > const &indices)
OGS_NO_INLINE void ensureEnoughSpaceSlow(std::size_t const space_needed)
std::vector< MatrixElementCacheEntry< Dim > > cache_
void ensureEnoughSpace(std::size_t const space_needed)
MatrixElementCache(MatOrVec &mat_or_vec, Stats &stats, const int num_threads)
std::conditional_t< Dim==1, GlobalVector, GlobalMatrix > MatOrVec
MatrixElementCache< 1 > cache_b_
MatrixElementCache< 2 > cache_Jac_
void add(std::vector< double > const &local_b_data, std::vector< double > const &local_Jac_data, std::vector< GlobalIndexType > const &indices)
MultiMatrixElementCache(GlobalVector &b, GlobalMatrix &Jac, MultiStats< 1 > &stats, const int num_threads)
MultiMatrixElementCache(GlobalMatrix &M, GlobalMatrix &K, GlobalVector &b, MultiStats< 2 > &stats, const int num_threads)
MatrixElementCache< 2 > cache_M_
MatrixElementCache< 1 > cache_b_
MatrixElementCache< 2 > cache_K_
void add(std::vector< double > const &local_M_data, std::vector< double > const &local_K_data, std::vector< double > const &local_b_data, std::vector< GlobalIndexType > const &indices)
Eigen::Map< const Matrix > toMatrix(std::vector< double > const &data, Eigen::MatrixXd::Index rows, Eigen::MatrixXd::Index cols)
GlobalIndexType transformToNonGhostIndex(GlobalIndexType const i, GlobalIndexType const n)
MatrixElementCacheEntry & operator=(MatrixElementCacheEntry const &)=default
MatrixElementCacheEntry(MatrixElementCacheEntry &&)=default
std::array< GlobalIndexType, Dim > indices
MatrixElementCacheEntry()=default
MatrixElementCacheEntry & operator=(MatrixElementCacheEntry &&)=default
MatrixElementCacheEntry(std::array< GlobalIndexType, Dim > const &indices, double value)
MatrixElementCacheEntry(MatrixElementCacheEntry const &)=default