25#ifndef __BITPIT_STENCIL_TPP__
26#define __BITPIT_STENCIL_TPP__
33template<
typename weight_t,
typename value_t>
41template<
typename weight_t,
typename value_t>
44 return m_weightManager;
54template<
typename weight_t,
typename value_t>
57 buffer << stencil.m_zero;
59 std::size_t nItems = stencil.
size();
63 const weight_t *weightData = stencil.
weightData();
64 for (std::size_t n = 0; n < nItems; ++n) {
65 buffer << patternData[n];
66 buffer << weightData[n];
69 buffer << stencil.m_constant;
81template<
typename weight_t,
typename value_t>
82IBinaryStream& operator>>(IBinaryStream &buffer, DiscreteStencil<weight_t, value_t> &stencil)
84 buffer >> stencil.m_zero;
89 stencil.resize(nItems);
90 long *patternData = stencil.patternData();
91 weight_t *weightData = stencil.weightData();
92 for (std::size_t n = 0; n < nItems; ++n) {
93 buffer >> patternData[n];
94 buffer >> weightData[n];
97 buffer >> stencil.m_constant;
107template<
typename weight_t,
typename value_t>
119template<
typename weight_t,
typename value_t>
122 m_pattern(size, -1), m_weights(size, m_zero),
134template<
typename weight_t,
typename value_t>
137 m_pattern(pattern, pattern + size), m_weights(size, m_zero),
150template<
typename weight_t,
typename value_t>
153 m_pattern(pattern, pattern + size), m_weights(weights, weights + size),
164template<
typename weight_t,
typename value_t>
167 m_weightManager.copy(zero, &m_zero);
169 std::size_t previousSize = this->size();
170 std::size_t commonSize = std::min(previousSize, size);
171 for (std::size_t n = 0; n < commonSize; ++n) {
173 m_weightManager.copy(m_zero, m_weights.data() + n);
175 if (previousSize != size) {
189template<
typename weight_t,
typename value_t>
192 m_weightManager.copy(zero, &m_zero);
194 std::size_t previousSize = this->size();
195 std::size_t commonSize = std::min(previousSize, size);
196 for (std::size_t n = 0; n < commonSize; ++n) {
197 m_pattern[n] = pattern[n];
198 m_weightManager.copy(m_zero, m_weights.data() + n);
200 if (previousSize != size) {
202 for (std::size_t n = previousSize; n < size; ++n) {
203 m_pattern[n] = pattern[n];
218template<
typename weight_t,
typename value_t>
221 m_weightManager.copy(zero, &m_zero);
223 std::size_t previousSize = this->size();
224 std::size_t commonSize = std::min(previousSize, size);
225 for (std::size_t n = 0; n < commonSize; ++n) {
226 m_pattern[n] = pattern[n];
227 m_weightManager.copy(weights[n], m_weights.data() + n);
229 if (size > previousSize) {
231 for (std::size_t n = previousSize; n < size; ++n) {
232 appendItem(pattern[n], weights[n]);
234 }
else if (size < previousSize) {
247template<
typename weight_t,
typename value_t>
250 initialize(other.
size(), other.m_pattern.data(), other.m_weights.data(), other.m_zero);
258template<
typename weight_t,
typename value_t>
261 return m_pattern.size();
269template<
typename weight_t,
typename value_t>
272 m_pattern.resize(size, -1);
273 m_weights.resize(size, m_zero);
284template<
typename weight_t,
typename value_t>
287 m_pattern.reserve(capacity);
288 m_weights.reserve(capacity);
297template<
typename weight_t,
typename value_t>
300 return m_pattern[pos];
309template<
typename weight_t,
typename value_t>
312 return m_pattern[pos];
320template<
typename weight_t,
typename value_t>
323 return m_pattern.data();
332template<
typename weight_t,
typename value_t>
335 return m_pattern.data();
344template<
typename weight_t,
typename value_t>
356template<
typename weight_t,
typename value_t>
359 return m_weights[pos];
368template<
typename weight_t,
typename value_t>
371 return m_weights[pos];
379template<
typename weight_t,
typename value_t>
382 return m_weights.data();
390template<
typename weight_t,
typename value_t>
393 return m_weights.data();
402template<
typename weight_t,
typename value_t>
405 m_weights[pos] = weight;
414template<
typename weight_t,
typename value_t>
417 m_weights[pos] = std::move(weight);
427template<
typename weight_t,
typename value_t>
430 m_weightManager.sum(weight, factor, m_weights.data() + pos);
438template<
typename weight_t,
typename value_t>
441 m_weightManager.copy(m_zero, m_weights.data() + pos);
451template<
typename weight_t,
typename value_t>
455 setWeight(pos, weight);
465template<
typename weight_t,
typename value_t>
469 setWeight(pos, std::move(weight));
482template<
typename weight_t,
typename value_t>
485 weight_t *target = findWeight(
id);
487 m_weightManager.sum(weight, factor, target);
489 appendItem(
id, weight);
491 m_weights.back() *= factor;
505template<
typename weight_t,
typename value_t>
508 m_pattern.push_back(
id);
509 appendWeight(weight);
521template<
typename weight_t,
typename value_t>
524 m_pattern.push_back(
id);
525 appendWeight(std::move(weight));
533template<
typename weight_t,
typename value_t>
544template<
typename weight_t,
typename value_t>
555template<
typename weight_t,
typename value_t>
558 m_weightManager.copy(constant, &m_constant);
566template<
typename weight_t,
typename value_t>
569 m_weightManager.move(std::move(constant), &m_constant);
578template<
typename weight_t,
typename value_t>
581 m_weightManager.sum(constant, factor, &m_constant);
587template<
typename weight_t,
typename value_t>
590 m_weightManager.copy(m_zero, &m_constant);
603template<
typename weight_t,
typename value_t>
608 m_pattern.shrink_to_fit();
611 clearWeights(release);
622template<
typename weight_t,
typename value_t>
625 const std::size_t other_nItems = other.
size();
626 for (std::size_t n = 0; n < other_nItems; ++n) {
627 sumItem(other.m_pattern[n], other.m_weights[n], factor);
630 sumConstant(other.m_constant, factor);
638template<
typename weight_t,
typename value_t>
641 std::size_t nItems = size();
642 for (std::size_t n = 0; n < nItems; ++n) {
643 if (m_weightManager.isNegligible(m_weights[n], m_zero, tolerance)) {
644 m_pattern.erase(m_pattern.begin() + n);
645 m_weights.erase(m_weights.begin() + n);
657template<
typename weight_t,
typename value_t>
660 renumber([&map] (
long id) ->
long {
return map.at(
id); });
669template<
typename weight_t,
typename value_t>
670template<
typename Mapper>
673 for (
long &
id : m_pattern) {
683template<
typename weight_t,
typename value_t>
686 const std::size_t nItems = size();
691 weight_t complement = m_zero;
692 for (
const weight_t &weight : m_weights) {
693 m_weightManager.sum(weight, -1., &complement);
696 appendItem(
id, complement);
702template<
typename weight_t,
typename value_t>
705 for (weight_t &weight : m_weights) {
706 m_weightManager.copy(m_zero, &weight);
719template<
typename weight_t,
typename value_t>
722 auto patternBegin = m_pattern.cbegin();
723 auto patternEnd = m_pattern.cend();
724 for (
auto itr = patternBegin; itr != patternEnd; ++itr) {
726 return (m_weights.data() + std::distance(patternBegin, itr));
740template<
typename weight_t,
typename value_t>
741const weight_t * DiscreteStencil<weight_t, value_t>::findWeight(
long id)
const
743 auto patternBegin = m_pattern.cbegin();
744 auto patternEnd = m_pattern.cend();
745 for (
auto itr = patternBegin; itr != patternEnd; ++itr) {
747 return (m_weights.data() + std::distance(patternBegin, itr));
759template<
typename weight_t,
typename value_t>
762 m_weights.push_back(std::move(weight));
770template<
typename weight_t,
typename value_t>
773 m_weights.push_back(weight);
786template<
typename weight_t,
typename value_t>
791 m_weights.shrink_to_fit();
801template<
typename weight_t,
typename value_t>
804 const std::size_t nItems = size();
806 weight_t
sum = m_zero;
807 for (std::size_t n = 0; n < nItems; ++n) {
808 long id = m_pattern[n];
809 weight_t weight = factor * m_weights[n];
810 out <<
" id: " <<
id <<
" weight: " << weight << std::endl;
811 m_weightManager.sum(weight, 1., &
sum);
814 out <<
" constant : " << (factor * m_constant) << std::endl;
815 out <<
" sum : " <<
sum << std::endl;
823template<
typename weight_t,
typename value_t>
826 std::size_t nItems = size();
828 return (
sizeof(m_zero) + nItems * (
sizeof(
long) +
sizeof(weight_t)) +
sizeof(m_constant));
842template<
typename weight_t,
typename value_t>
859template<
typename weight_t,
typename value_t>
862 const weight_t *weight = findWeight(
id);
867 throw(
"The stencil doens't contain an item with the specified id");
881template<
typename weight_t,
typename value_t>
884 weight_t *weight = findWeight(
id);
889 appendItem(
id, m_zero);
891 return m_weights.back();
900template<
typename weight_t,
typename value_t>
903 for (weight_t &weight : m_weights) {
906 m_constant *= factor;
917template<
typename weight_t,
typename value_t>
920 for (weight_t &weight : m_weights) {
923 m_constant /= factor;
934template<
typename weight_t,
typename value_t>
948template<
typename weight_t,
typename value_t>
961template<
typename weight_t,
typename value_t>
964 m_weightPool(nullptr)
974template<
typename weight_t,
typename value_t>
977 m_weightPool(nullptr)
988template<
typename weight_t,
typename value_t>
991 m_weightPool(nullptr)
1003template<
typename weight_t,
typename value_t>
1006 m_weightPool(nullptr)
1016template<
typename weight_t,
typename value_t>
1019 m_weightPool = pool;
1027template<
typename weight_t,
typename value_t>
1030 if (m_weightPool && m_weightPool->size() > 0) {
1031 this->m_weights.emplace_back(m_weightPool->retrieve());
1032 this->m_weights.back() = weight;
1048template<
typename weight_t,
typename value_t>
1052 m_weightPool->store(&(this->m_weights));
1067template<
typename weight_t,
typename value_t>
1070 return (factor * stencil);
1080template<
typename weight_t,
typename value_t>
1084 stencil_result *= factor;
1086 return stencil_result;
1096template<
typename weight_t,
typename value_t>
1100 stencil_result /= factor;
1102 return stencil_result;
1112template<
typename weight_t,
typename value_t>
1116 stencil_result += stencil_B;
1118 return stencil_result;
1128template<
typename weight_t,
typename value_t>
1132 stencil_result -= stencil_B;
1134 return stencil_result;
1144template <
typename V>
1147 return (vector * stencil);
1157template <
typename V>
1160 const std::size_t nItems = stencil.
size();
1162 stencil_B.
resize(nItems);
1163 for (std::size_t n = 0; n < nItems; ++n) {
1179template <
typename V>
1183 dotProduct(stencil, vector, &stencil_dotProduct);
1185 return stencil_dotProduct;
1195template <
typename V>
1198 const std::size_t nItems = stencil.
size();
1199 stencil_dotProduct->
resize(nItems);
1202 const bitpit::StencilVector::weight_type *weightData = stencil.
weightData();
1203 long *patternData_dotProduct = stencil_dotProduct->
patternData();
1204 typename bitpit::DiscreteStencil<V>::weight_type *weightData_dotProduct = stencil_dotProduct->
weightData();
1205 for (std::size_t n = 0; n < nItems; ++n) {
1206 patternData_dotProduct[n] = patternData[n];
1207 weightData_dotProduct[n] = ::dotProduct(weightData[n], vector);
1220template <
typename V>
1224 project(stencil, direction, &stencil_projection);
1226 return stencil_projection;
1236template <
typename V>
1239 stencil_projection->initialize(stencil);
1240 const std::size_t nItems = stencil_projection->size();
1243 for (std::size_t n = 0; n < nItems; ++n) {
1245 weight = ::dotProduct(weight, direction) * direction;
1248 stencil_projection->
setConstant(::dotProduct(stencil_projection->getConstant(), direction) * direction);
Metafunction for generating a discretization stencil.
void sumWeight(std::size_t pos, const weight_t &weight, double factor=1.)
void sumConstant(const weight_t &constant, double factor=1.)
static const weight_manager_type m_weightManager
long & getPattern(std::size_t pos)
void addComplementToZero(long id)
void setWeight(std::size_t pos, const weight_t &weight)
void reserve(std::size_t nItems)
virtual void clearWeights(bool release)
void resize(std::size_t nItems)
void optimize(double tolerance=1.e-12)
void clear(bool release=false)
DiscreteStencil< weight_t, value_t > & operator-=(const DiscreteStencil< weight_t, value_t > &other)
weight_t & getWeight(std::size_t pos)
DiscreteStencil(const weight_t &zero=weight_t())
void setItem(std::size_t pos, long id, const weight_t &weight)
void zeroWeight(std::size_t pos)
DiscreteStencil< weight_t, value_t > & operator+=(const DiscreteStencil< weight_t, value_t > &other)
void renumber(const std::unordered_map< long, long > &map)
void display(std::ostream &out, double factor=1.) const
size_t getBinarySize() const
void appendItem(long id, const weight_t &weight)
DiscreteStencil< weight_t, value_t > & operator/=(double factor)
virtual void appendWeight(weight_t &&weight)
void setConstant(const weight_t &constant)
DiscreteStencil< weight_t, value_t > & operator*=(double factor)
void sum(const DiscreteStencil< weight_t, value_t > &other, double factor)
void setPattern(std::size_t pos, long id)
static const weight_manager_type & getWeightManager()
void sumItem(long id, const weight_t &weight, double factor=1.)
void initialize(std::size_t nItems, const weight_t &zero=weight_t())
weight_t & operator[](long id)
void appendWeight(const weight_t &weight) override
void clearWeights(bool release) override
void setWeightPool(weight_pool_type *pool)
MPDiscreteStencil(const weight_t &zero=weight_t())
void sum(const std::array< T, d > &x, T1 &s)
T dotProduct(const std::array< T, d > &x, const std::array< T, d > &y)
std::vector< T > operator+(const std::vector< T > &, const std::vector< T > &)