Loading...
Searching...
No Matches
stencil.tpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 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_TPP__
26#define __BITPIT_STENCIL_TPP__
27
28namespace bitpit {
29
33template<typename weight_t, typename value_t>
34const typename DiscreteStencil<weight_t, value_t>::weight_manager_type DiscreteStencil<weight_t, value_t>::m_weightManager = typename DiscreteStencil<weight_t>::weight_manager_type();
35
41template<typename weight_t, typename value_t>
46
54template<typename weight_t, typename value_t>
55OBinaryStream& operator<<(OBinaryStream &buffer, const DiscreteStencil<weight_t, value_t> &stencil)
56{
57 buffer << stencil.m_zero;
58
59 std::size_t nItems = stencil.size();
60 buffer << nItems;
61
62 const long *patternData = stencil.patternData();
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];
67 }
68
69 buffer << stencil.m_constant;
70
71 return buffer;
72}
73
81template<typename weight_t, typename value_t>
82IBinaryStream& operator>>(IBinaryStream &buffer, DiscreteStencil<weight_t, value_t> &stencil)
83{
84 buffer >> stencil.m_zero;
86 std::size_t nItems;
87 buffer >> nItems;
88
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];
95 }
97 buffer >> stencil.m_constant;
99 return buffer;
107template<typename weight_t, typename value_t>
119template<typename weight_t, typename value_t>
120DiscreteStencil<weight_t, value_t>::DiscreteStencil(std::size_t size, const weight_t &zero)
121 : m_zero(zero),
122 m_pattern(size, -1), m_weights(size, m_zero),
123 m_constant(m_zero)
134template<typename weight_t, typename value_t>
135DiscreteStencil<weight_t, value_t>::DiscreteStencil(std::size_t size, const long *pattern, const weight_t &zero)
136 : m_zero(zero),
137 m_pattern(pattern, pattern + size), m_weights(size, m_zero),
138 m_constant(m_zero)
139{
141
150template<typename weight_t, typename value_t>
151DiscreteStencil<weight_t, value_t>::DiscreteStencil(std::size_t size, const long *pattern, const weight_t *weights, const weight_t &zero)
152 : m_zero(zero),
153 m_pattern(pattern, pattern + size), m_weights(weights, weights + size),
154 m_constant(m_zero)
155{
156}
157
164template<typename weight_t, typename value_t>
165void DiscreteStencil<weight_t, value_t>::initialize(std::size_t size, const weight_t &zero)
166{
167 m_weightManager.copy(zero, &m_zero);
168
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) {
172 m_pattern[n] = -1;
173 m_weightManager.copy(m_zero, m_weights.data() + n);
174 }
175 if (previousSize != size) {
176 resize(size);
177 }
178
179 zeroConstant();
180}
181
189template<typename weight_t, typename value_t>
190void DiscreteStencil<weight_t, value_t>::initialize(std::size_t size, const long *pattern, const weight_t &zero)
191{
192 m_weightManager.copy(zero, &m_zero);
193
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);
199 }
200 if (previousSize != size) {
201 resize(size);
202 for (std::size_t n = previousSize; n < size; ++n) {
203 m_pattern[n] = pattern[n];
204 }
205 }
206
207 zeroConstant();
208}
209
218template<typename weight_t, typename value_t>
219void DiscreteStencil<weight_t, value_t>::initialize(std::size_t size, const long *pattern, const weight_t *weights, const weight_t &zero)
220{
221 m_weightManager.copy(zero, &m_zero);
222
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);
228 }
229 if (size > previousSize) {
230 reserve(size);
231 for (std::size_t n = previousSize; n < size; ++n) {
232 appendItem(pattern[n], weights[n]);
233 }
234 } else if (size < previousSize) {
235 resize(size);
236 }
237
238 zeroConstant();
239}
240
247template<typename weight_t, typename value_t>
249{
250 initialize(other.size(), other.m_pattern.data(), other.m_weights.data(), other.m_zero);
251}
252
258template<typename weight_t, typename value_t>
260{
261 return m_pattern.size();
262}
263
269template<typename weight_t, typename value_t>
271{
272 m_pattern.resize(size, -1);
273 m_weights.resize(size, m_zero);
274}
275
284template<typename weight_t, typename value_t>
286{
287 m_pattern.reserve(capacity);
288 m_weights.reserve(capacity);
289}
290
297template<typename weight_t, typename value_t>
299{
300 return m_pattern[pos];
301}
302
309template<typename weight_t, typename value_t>
310const long & DiscreteStencil<weight_t, value_t>::getPattern(std::size_t pos) const
311{
312 return m_pattern[pos];
313}
314
320template<typename weight_t, typename value_t>
322{
323 return m_pattern.data();
324}
325
332template<typename weight_t, typename value_t>
334{
335 return m_pattern.data();
336}
337
344template<typename weight_t, typename value_t>
346{
347 m_pattern[pos] = id;
348}
349
356template<typename weight_t, typename value_t>
358{
359 return m_weights[pos];
360}
361
368template<typename weight_t, typename value_t>
369const weight_t & DiscreteStencil<weight_t, value_t>::getWeight(std::size_t pos) const
370{
371 return m_weights[pos];
372}
373
379template<typename weight_t, typename value_t>
381{
382 return m_weights.data();
383}
384
390template<typename weight_t, typename value_t>
392{
393 return m_weights.data();
394}
395
402template<typename weight_t, typename value_t>
403void DiscreteStencil<weight_t, value_t>::setWeight(std::size_t pos, const weight_t &weight)
404{
405 m_weights[pos] = weight;
406}
407
414template<typename weight_t, typename value_t>
415void DiscreteStencil<weight_t, value_t>::setWeight(std::size_t pos, weight_t &&weight)
416{
417 m_weights[pos] = std::move(weight);
418}
419
427template<typename weight_t, typename value_t>
428void DiscreteStencil<weight_t, value_t>::sumWeight(std::size_t pos, const weight_t &weight, double factor)
429{
430 m_weightManager.sum(weight, factor, m_weights.data() + pos);
431}
432
438template<typename weight_t, typename value_t>
440{
441 m_weightManager.copy(m_zero, m_weights.data() + pos);
442}
443
451template<typename weight_t, typename value_t>
452void DiscreteStencil<weight_t, value_t>::setItem(std::size_t pos, long id, const weight_t &weight)
453{
454 setPattern(pos, id);
455 setWeight(pos, weight);
456}
457
465template<typename weight_t, typename value_t>
466void DiscreteStencil<weight_t, value_t>::setItem(std::size_t pos, long id, weight_t &&weight)
467{
468 setPattern(pos, id);
469 setWeight(pos, std::move(weight));
470}
471
482template<typename weight_t, typename value_t>
483void DiscreteStencil<weight_t, value_t>::sumItem(long id, const weight_t &weight, double factor)
484{
485 weight_t *target = findWeight(id);
486 if (target) {
487 m_weightManager.sum(weight, factor, target);
488 } else {
489 appendItem(id, weight);
490 if (factor != 1.) {
491 m_weights.back() *= factor;
492 }
493 }
494}
495
505template<typename weight_t, typename value_t>
506void DiscreteStencil<weight_t, value_t>::appendItem(long id, const weight_t &weight)
507{
508 m_pattern.push_back(id);
509 appendWeight(weight);
510}
511
521template<typename weight_t, typename value_t>
523{
524 m_pattern.push_back(id);
525 appendWeight(std::move(weight));
526}
527
533template<typename weight_t, typename value_t>
535{
536 return m_constant;
537}
538
544template<typename weight_t, typename value_t>
546{
547 return m_constant;
548}
549
555template<typename weight_t, typename value_t>
557{
558 m_weightManager.copy(constant, &m_constant);
559}
560
566template<typename weight_t, typename value_t>
568{
569 m_weightManager.move(std::move(constant), &m_constant);
570}
571
578template<typename weight_t, typename value_t>
579void DiscreteStencil<weight_t, value_t>::sumConstant(const weight_t &constant, double factor)
580{
581 m_weightManager.sum(constant, factor, &m_constant);
582}
583
587template<typename weight_t, typename value_t>
589{
590 m_weightManager.copy(m_zero, &m_constant);
591}
592
603template<typename weight_t, typename value_t>
605{
606 m_pattern.clear();
607 if (release) {
608 m_pattern.shrink_to_fit();
609 }
610
611 clearWeights(release);
612
613 zeroConstant();
614}
615
622template<typename weight_t, typename value_t>
624{
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);
628 }
629
630 sumConstant(other.m_constant, factor);
631}
632
638template<typename weight_t, typename value_t>
640{
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);
646 --n;
647 --nItems;
648 }
649 }
650}
651
657template<typename weight_t, typename value_t>
658void DiscreteStencil<weight_t, value_t>::renumber(const std::unordered_map<long, long> &map)
659{
660 renumber([&map] (long id) -> long { return map.at(id); });
661}
662
669template<typename weight_t, typename value_t>
670template<typename Mapper>
672{
673 for (long &id : m_pattern) {
674 id = map(id);
675 }
676}
677
683template<typename weight_t, typename value_t>
685{
686 const std::size_t nItems = size();
687 if (nItems == 0) {
688 return;
689 }
690
691 weight_t complement = m_zero;
692 for (const weight_t &weight : m_weights) {
693 m_weightManager.sum(weight, -1., &complement);
694 }
695
696 appendItem(id, complement);
697}
698
702template<typename weight_t, typename value_t>
704{
705 for (weight_t &weight : m_weights) {
706 m_weightManager.copy(m_zero, &weight);
707 }
708
709 setConstant(m_zero);
710}
711
719template<typename weight_t, typename value_t>
721{
722 auto patternBegin = m_pattern.cbegin();
723 auto patternEnd = m_pattern.cend();
724 for (auto itr = patternBegin; itr != patternEnd; ++itr) {
725 if (*itr == id) {
726 return (m_weights.data() + std::distance(patternBegin, itr));
727 }
728 }
729
730 return nullptr;
731}
732
740template<typename weight_t, typename value_t>
741const weight_t * DiscreteStencil<weight_t, value_t>::findWeight(long id) const
742{
743 auto patternBegin = m_pattern.cbegin();
744 auto patternEnd = m_pattern.cend();
745 for (auto itr = patternBegin; itr != patternEnd; ++itr) {
746 if (*itr == id) {
747 return (m_weights.data() + std::distance(patternBegin, itr));
748 }
749 }
750
751 return nullptr;
752}
753
759template<typename weight_t, typename value_t>
761{
762 m_weights.push_back(std::move(weight));
763}
764
770template<typename weight_t, typename value_t>
772{
773 m_weights.push_back(weight);
774}
775
786template<typename weight_t, typename value_t>
788{
789 m_weights.clear();
790 if (release) {
791 m_weights.shrink_to_fit();
792 }
793}
794
801template<typename weight_t, typename value_t>
802void DiscreteStencil<weight_t, value_t>::display(std::ostream &out, double factor) const
803{
804 const std::size_t nItems = size();
805
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);
812 }
813
814 out << " constant : " << (factor * m_constant) << std::endl;
815 out << " sum : " << sum << std::endl;
816}
817
823template<typename weight_t, typename value_t>
825{
826 std::size_t nItems = size();
827
828 return (sizeof(m_zero) + nItems * (sizeof(long) + sizeof(weight_t)) + sizeof(m_constant));
829}
830
842template<typename weight_t, typename value_t>
844{
845 return const_cast<weight_t &>(static_cast<const DiscreteStencil<weight_t, value_t> &>(*this).at(id));
846}
847
859template<typename weight_t, typename value_t>
860const weight_t & DiscreteStencil<weight_t, value_t>::at(long id) const
861{
862 const weight_t *weight = findWeight(id);
863 if (weight) {
864 return *weight;
865 }
866
867 throw("The stencil doens't contain an item with the specified id");
868}
869
881template<typename weight_t, typename value_t>
883{
884 weight_t *weight = findWeight(id);
885 if (weight) {
886 return *weight;
887 }
888
889 appendItem(id, m_zero);
890
891 return m_weights.back();
892}
893
900template<typename weight_t, typename value_t>
902{
903 for (weight_t &weight : m_weights) {
904 weight *= factor;
905 }
906 m_constant *= factor;
907
908 return *this;
909}
910
917template<typename weight_t, typename value_t>
919{
920 for (weight_t &weight : m_weights) {
921 weight /= factor;
922 }
923 m_constant /= factor;
924
925 return *this;
926}
927
934template<typename weight_t, typename value_t>
941
948template<typename weight_t, typename value_t>
955
961template<typename weight_t, typename value_t>
963 : DiscreteStencil<weight_t, value_t>(zero),
964 m_weightPool(nullptr)
965{
966}
967
974template<typename weight_t, typename value_t>
975MPDiscreteStencil<weight_t, value_t>::MPDiscreteStencil(std::size_t size, const weight_t &zero)
976 : DiscreteStencil<weight_t, value_t>(size, zero),
977 m_weightPool(nullptr)
978{
979}
980
988template<typename weight_t, typename value_t>
989MPDiscreteStencil<weight_t, value_t>::MPDiscreteStencil(std::size_t size, const long *pattern, const weight_t &zero)
990 : DiscreteStencil<weight_t, value_t>(size, pattern, zero),
991 m_weightPool(nullptr)
992{
993}
994
1003template<typename weight_t, typename value_t>
1004MPDiscreteStencil<weight_t, value_t>::MPDiscreteStencil(std::size_t size, const long *pattern, const weight_t *weights, const weight_t &zero)
1005 : DiscreteStencil<weight_t, value_t>(size, pattern, weights, zero),
1006 m_weightPool(nullptr)
1007
1008{
1009}
1010
1016template<typename weight_t, typename value_t>
1021
1027template<typename weight_t, typename value_t>
1029{
1030 if (m_weightPool && m_weightPool->size() > 0) {
1031 this->m_weights.emplace_back(m_weightPool->retrieve());
1032 this->m_weights.back() = weight;
1033 } else {
1035 }
1036}
1037
1048template<typename weight_t, typename value_t>
1050{
1051 if (m_weightPool) {
1052 m_weightPool->store(&(this->m_weights));
1053 }
1054
1056}
1057
1058}
1059
1067template<typename weight_t, typename value_t>
1069{
1070 return (factor * stencil);
1071}
1072
1080template<typename weight_t, typename value_t>
1082{
1083 bitpit::DiscreteStencil<weight_t, value_t> stencil_result(stencil);
1084 stencil_result *= factor;
1085
1086 return stencil_result;
1087}
1088
1096template<typename weight_t, typename value_t>
1098{
1099 bitpit::DiscreteStencil<weight_t, value_t> stencil_result(stencil);
1100 stencil_result /= factor;
1101
1102 return stencil_result;
1103}
1104
1112template<typename weight_t, typename value_t>
1114{
1115 bitpit::DiscreteStencil<weight_t, value_t> stencil_result(stencil_A);
1116 stencil_result += stencil_B;
1117
1118 return stencil_result;
1119}
1120
1128template<typename weight_t, typename value_t>
1130{
1131 bitpit::DiscreteStencil<weight_t, value_t> stencil_result(stencil_A);
1132 stencil_result -= stencil_B;
1133
1134 return stencil_result;
1135}
1136
1144template <typename V>
1145typename bitpit::DiscreteStencil<std::array<V, 3>> operator*(const typename bitpit::DiscreteStencil<V> &stencil, const std::array<V, 3> &vector)
1146{
1147 return (vector * stencil);
1148}
1149
1157template <typename V>
1158typename bitpit::DiscreteStencil<std::array<V, 3>> operator*(const std::array<V, 3> &vector, const typename bitpit::DiscreteStencil<V> &stencil)
1159{
1160 const std::size_t nItems = stencil.size();
1161 bitpit::StencilVector stencil_B;
1162 stencil_B.resize(nItems);
1163 for (std::size_t n = 0; n < nItems; ++n) {
1164 stencil_B.setPattern(n, stencil.getPattern(n));
1165 stencil_B.setWeight(n, ::operator*(stencil.getWeight(n), vector));
1166 }
1167 stencil_B.setConstant(::operator*(stencil.getConstant(), vector));
1168
1169 return stencil_B;
1170}
1171
1179template <typename V>
1180typename bitpit::DiscreteStencil<V> dotProduct(const typename bitpit::DiscreteStencil<std::array<V, 3>> &stencil, const typename bitpit::DiscreteStencil<std::array<V, 3>>::weight_type &vector)
1181{
1182 typename bitpit::DiscreteStencil<V> stencil_dotProduct;
1183 dotProduct(stencil, vector, &stencil_dotProduct);
1184
1185 return stencil_dotProduct;
1186}
1187
1195template <typename V>
1196void dotProduct(const typename bitpit::DiscreteStencil<std::array<V, 3>> &stencil, const typename bitpit::DiscreteStencil<std::array<V, 3>>::weight_type &vector, typename bitpit::DiscreteStencil<V> *stencil_dotProduct)
1197{
1198 const std::size_t nItems = stencil.size();
1199 stencil_dotProduct->resize(nItems);
1200
1201 const long *patternData = stencil.patternData();
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);
1208 }
1209
1210 stencil_dotProduct->setConstant(::dotProduct(stencil.getConstant(), vector));
1211}
1212
1220template <typename V>
1221typename bitpit::DiscreteStencil<std::array<V, 3>> project(const typename bitpit::DiscreteStencil<std::array<V, 3>> &stencil, const std::array<V, 3> &direction)
1222{
1223 typename bitpit::DiscreteStencil<std::array<V, 3>> stencil_projection;
1224 project(stencil, direction, &stencil_projection);
1225
1226 return stencil_projection;
1227}
1228
1236template <typename V>
1237void project(const typename bitpit::DiscreteStencil<std::array<V, 3>> &stencil, const std::array<V, 3> &direction, typename bitpit::DiscreteStencil<std::array<V, 3>> *stencil_projection)
1238{
1239 stencil_projection->initialize(stencil);
1240 const std::size_t nItems = stencil_projection->size();
1241
1242 typename bitpit::DiscreteStencil<std::array<V, 3>>::weight_type *weightData_projection = stencil_projection->weightData();
1243 for (std::size_t n = 0; n < nItems; ++n) {
1244 typename bitpit::DiscreteStencil<std::array<V, 3>>::weight_type &weight = weightData_projection[n];
1245 weight = ::dotProduct(weight, direction) * direction;
1246 }
1247
1248 stencil_projection->setConstant(::dotProduct(stencil_projection->getConstant(), direction) * direction);
1249}
1250
1251#endif
Metafunction for generating a discretization stencil.
Definition stencil.hpp:59
void sumWeight(std::size_t pos, const weight_t &weight, double factor=1.)
Definition stencil.tpp:428
void sumConstant(const weight_t &constant, double factor=1.)
Definition stencil.tpp:579
weight_t * weightData()
Definition stencil.tpp:380
static const weight_manager_type m_weightManager
Definition stencil.hpp:155
long & getPattern(std::size_t pos)
Definition stencil.tpp:298
void addComplementToZero(long id)
Definition stencil.tpp:684
void setWeight(std::size_t pos, const weight_t &weight)
Definition stencil.tpp:403
void reserve(std::size_t nItems)
Definition stencil.tpp:285
virtual void clearWeights(bool release)
Definition stencil.tpp:787
void resize(std::size_t nItems)
Definition stencil.tpp:270
void optimize(double tolerance=1.e-12)
Definition stencil.tpp:639
weight_t & at(long id)
Definition stencil.tpp:843
void clear(bool release=false)
Definition stencil.tpp:604
DiscreteStencil< weight_t, value_t > & operator-=(const DiscreteStencil< weight_t, value_t > &other)
Definition stencil.tpp:949
weight_t & getWeight(std::size_t pos)
Definition stencil.tpp:357
DiscreteStencil(const weight_t &zero=weight_t())
Definition stencil.tpp:108
void setItem(std::size_t pos, long id, const weight_t &weight)
Definition stencil.tpp:452
weight_t & getConstant()
Definition stencil.tpp:545
void zeroWeight(std::size_t pos)
Definition stencil.tpp:439
std::size_t size() const
Definition stencil.tpp:259
DiscreteStencil< weight_t, value_t > & operator+=(const DiscreteStencil< weight_t, value_t > &other)
Definition stencil.tpp:935
void renumber(const std::unordered_map< long, long > &map)
Definition stencil.tpp:658
void display(std::ostream &out, double factor=1.) const
Definition stencil.tpp:802
size_t getBinarySize() const
Definition stencil.tpp:824
void appendItem(long id, const weight_t &weight)
Definition stencil.tpp:506
DiscreteStencil< weight_t, value_t > & operator/=(double factor)
Definition stencil.tpp:918
virtual void appendWeight(weight_t &&weight)
Definition stencil.tpp:760
void setConstant(const weight_t &constant)
Definition stencil.tpp:556
DiscreteStencil< weight_t, value_t > & operator*=(double factor)
Definition stencil.tpp:901
void sum(const DiscreteStencil< weight_t, value_t > &other, double factor)
Definition stencil.tpp:623
void setPattern(std::size_t pos, long id)
Definition stencil.tpp:345
static const weight_manager_type & getWeightManager()
Definition stencil.tpp:42
void sumItem(long id, const weight_t &weight, double factor=1.)
Definition stencil.tpp:483
void initialize(std::size_t nItems, const weight_t &zero=weight_t())
Definition stencil.tpp:165
weight_t & operator[](long id)
Definition stencil.tpp:882
void appendWeight(const weight_t &weight) override
Definition stencil.tpp:1028
void clearWeights(bool release) override
Definition stencil.tpp:1049
void setWeightPool(weight_pool_type *pool)
Definition stencil.tpp:1017
MPDiscreteStencil(const weight_t &zero=weight_t())
Definition stencil.tpp:962
Output binary stream.
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 > &)
--- layout: doxygen_footer ---