Loading...
Searching...
No Matches
stencil_weight.tpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2024 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25#ifndef __BITPIT_STENCIL_WEIGHT_TPP__
26#define __BITPIT_STENCIL_WEIGHT_TPP__
27
28namespace bitpit {
29
36template<typename weight_t>
38 : m_capacity(capacity)
39{
40}
41
49template<typename weight_t>
51{
52 return m_storage.size();
53}
54
63template<typename weight_t>
65{
66 return m_capacity;
67}
68
79template<typename weight_t>
81{
82 m_storage.clear();
83 if (release) {
84 m_storage.shrink_to_fit();
85 }
86}
87
95template<typename weight_t>
97{
98 if (size() == 0) {
99 throw std::runtime_error("Unable to retrieve a weight from the pool: the pool is empty.");
100 }
101
102 weight_t weight = std::move(m_storage.back());
103 m_storage.pop_back();
104
105 return weight;
106}
107
113template<typename weight_t>
115{
116 if (m_capacity == size()) {
117 return;
118 }
119
120 m_storage.emplace_back(std::move(weight));
121}
122
128template<typename weight_t>
129void DiscreteStencilWeightPool<weight_t>::store(std::vector<weight_t> *weights)
130{
131 std::size_t nStorableWeights = std::min(m_capacity - size(), weights->size());
132 if (nStorableWeights == 0) {
133 return;
134 }
135
136 m_storage.insert(m_storage.end(),
137 std::make_move_iterator(weights->begin()),
138 std::make_move_iterator(weights->begin() + nStorableWeights));
139}
140
149template<typename weight_t, typename value_t>
150template<typename W>
151bool DiscreteStencilWeightManager<weight_t, value_t>::isNegligible(const W &weight, const weight_t &zero, double tolerance) const
152{
153 return (std::abs(weight - zero) <= tolerance);
154}
155
164template<typename weight_t, typename value_t>
165template<typename W, typename V, std::size_t D, typename std::enable_if<std::is_same<std::array<V, D>, W>::value>::type *>
166bool DiscreteStencilWeightManager<weight_t, value_t>::isNegligible(const std::array<V, D> &weight, const weight_t &zero, double tolerance) const
167{
168 for (std::size_t k = 0; k < D; ++k) {
169 if (std::abs(weight[k] - zero[k]) > tolerance) {
170 return false;
171 }
172 }
173
174 return true;
175}
176
185template<typename weight_t, typename value_t>
186template<typename W, typename V, typename std::enable_if<std::is_same<std::vector<V>, W>::value>::type *>
187bool DiscreteStencilWeightManager<weight_t, value_t>::isNegligible(const std::vector<V> &weight, const weight_t &zero, double tolerance) const
188{
189 const int nItems = weight.size();
190 for (int k = 0; k < nItems; ++k) {
191 if (std::abs(weight[k] - zero[k]) > tolerance) {
192 return false;
193 }
194 }
195
196 return true;
197}
198
199
208template<typename weight_t, typename value_t>
209template<typename W>
210void DiscreteStencilWeightManager<weight_t, value_t>::sum(const W &weight, double factor, W *target) const
211{
212 *target += factor * weight;
213}
214
223template<typename weight_t, typename value_t>
224template<typename W, typename V, std::size_t D, typename std::enable_if<std::is_same<std::array<V, D>, W>::value>::type *>
225void DiscreteStencilWeightManager<weight_t, value_t>::sum(const std::array<V, D> &weight, double factor, std::array<V, D> *target) const
226{
227 for (std::size_t i = 0; i < D; ++i) {
228 (*target)[i] += factor * weight[i];
229 }
230}
231
244template<typename weight_t, typename value_t>
245template<typename W, typename V, typename std::enable_if<std::is_same<std::vector<V>, W>::value>::type *>
246void DiscreteStencilWeightManager<weight_t, value_t>::sum(const std::vector<V> &weight, double factor, std::vector<V> *target) const
247{
248 std::size_t weightSize = weight.size();
249 std::size_t targetSize = target->size();
250 std::size_t commonSize = std::min(weightSize, targetSize);
251
252 for (std::size_t i = 0; i < commonSize; ++i) {
253 (*target)[i] += factor * weight[i];
254 }
255
256 if (weightSize > targetSize) {
257 target->insert(target->end(), weight.cbegin() + commonSize, weight.cend());
258
259 if (factor != 1.) {
260 auto targetBegin = target->begin();
261 auto targetEnd = target->end();
262 for (auto itr = targetBegin + commonSize; itr != targetEnd; ++itr) {
263 *itr *= factor;
264 }
265 }
266 }
267}
268
275template<typename weight_t, typename value_t>
276template<typename W>
277void DiscreteStencilWeightManager<weight_t, value_t>::copy(const W &weight, W *target) const
278{
279 *target = weight;
280}
281
288template<typename weight_t, typename value_t>
289template<typename W, typename V, std::size_t D, typename std::enable_if<std::is_same<std::array<V, D>, W>::value>::type *>
290void DiscreteStencilWeightManager<weight_t, value_t>::copy(const std::array<V, D> &weight, std::array<V, D> *target) const
291{
292 std::copy_n(weight.data(), D, target->data());
293}
294
303template<typename weight_t, typename value_t>
304template<typename W, typename V, typename std::enable_if<std::is_same<std::vector<V>, W>::value>::type *>
305void DiscreteStencilWeightManager<weight_t, value_t>::copy(const std::vector<V> &weight, std::vector<V> *target) const
306{
307 std::size_t weightSize = weight.size();
308 std::size_t targetSize = target->size();
309 std::size_t commonSize = std::min(weightSize, targetSize);
310
311 std::copy_n(weight.data(), commonSize, target->data());
312
313 if (weightSize < targetSize) {
314 target->resize(weightSize);
315 } else if (weightSize > targetSize) {
316 target->insert(target->end(), weight.begin() + commonSize, weight.end());
317 }
318}
319
326template<typename weight_t, typename value_t>
327template<typename W>
329{
330 *target = std::move(weight);
331}
332
339template<typename weight_t, typename value_t>
340template<typename W>
341value_t & DiscreteStencilWeightManager<weight_t, value_t>::at(const W &weight, std::size_t index)
342{
343 return const_cast<value_t &>(const_cast<const DiscreteStencilWeightManager<weight_t, value_t> *>(this)->at(weight, index));
344}
345
352template<typename weight_t, typename value_t>
353template<typename W>
354const value_t & DiscreteStencilWeightManager<weight_t, value_t>::at(const W &weight, std::size_t index) const
355{
356 BITPIT_UNUSED(index);
357
358 return weight;
359}
360
367template<typename weight_t, typename value_t>
368template<typename W, typename V, std::size_t D, typename std::enable_if<std::is_same<std::array<V, D>, W>::value>::type *>
369value_t & DiscreteStencilWeightManager<weight_t, value_t>::at(const std::array<V, D> &weight, std::size_t index)
370{
371 return const_cast<value_t &>(const_cast<const DiscreteStencilWeightManager<weight_t, value_t> *>(this)->at(weight, index));
372}
373
380template<typename weight_t, typename value_t>
381template<typename W, typename V, std::size_t D, typename std::enable_if<std::is_same<std::array<V, D>, W>::value>::type *>
382const value_t & DiscreteStencilWeightManager<weight_t, value_t>::at(const std::array<V, D> &weight, std::size_t index) const
383{
384 return weight[index];
385}
386
393template<typename weight_t, typename value_t>
394template<typename W, typename V, typename std::enable_if<std::is_same<std::vector<V>, W>::value>::type *>
395value_t & DiscreteStencilWeightManager<weight_t, value_t>::at(const std::vector<V> &weight, std::size_t index)
396{
397 return const_cast<value_t &>(const_cast<const DiscreteStencilWeightManager<weight_t, value_t> *>(this)->at(weight, index));
398}
399
406template<typename weight_t, typename value_t>
407template<typename W, typename V, typename std::enable_if<std::is_same<std::vector<V>, W>::value>::type *>
408const value_t & DiscreteStencilWeightManager<weight_t, value_t>::at(const std::vector<V> &weight, int index) const
409{
410 return weight[index];
411}
412
413}
414
415#endif
bool isNegligible(const W &weight, const weight_t &zero, double tolerance=1e-12) const
void copy(const W &weight, W *target) const
value_t & at(const W &weight, std::size_t index)
void move(W &&weight, W *target) const
void sum(const W &weight, double factor, W *target) const
DiscreteStencilWeightPool(std::size_t capacity=128)
#define BITPIT_UNUSED(variable)
Definition compiler.hpp:63
--- layout: doxygen_footer ---