19#include <boost/version.hpp>
20#include <boost/fusion/algorithm.hpp>
21#include <boost/fusion/sequence.hpp>
31 template <
class>
class VariableSet;
33 namespace LinearSpace_Detail
36 template <
class Space0,
class Space2,
int id>
struct Copy;
38 template <
class Space,
int id,
class VSDescriptions>
43 boost::fusion::at_c<id>(to.data) = boost::fusion::at_c<id>(from.
data).coefficients();
48 template <
class Space,
class VSDescriptions>
53 boost::fusion::at_c<0>(to.data) = boost::fusion::at_c<0>(from.
data).coefficients();
75 template <
class Scalar_,
class Seq>
88 template <
typename>
struct ReadBlock;
89 template <
typename>
struct WriteBlock;
104 using Component = std::remove_reference_t<typename boost::fusion::result_of::at_c<Sequence const,m>::type>;
123 template <
class VSDescriptions>
139 template <
typename... Args>
142 applyUnaryOp(Assign(0));
156 return boost::fusion::accumulate(
data,0,[](
auto dim,
auto const& v) {
return dim+v.dim(); });
168 template <
class VSDescriptions>
172 static_assert(result_of::size<Sequence>::type::value == VSDescriptions::noOfVariables,
"Numbers of variables do not match.");
174 result_of::size<typename VSDescriptions::RepresentationData>::type::value-1>::apply(y,*
this);
179 template <
class OtherSeq>
183 static_assert(result_of::size<Sequence>::type::value == result_of::size<OtherSeq>::type::value,
"Numbers of variables do not match.");
189 template <
class FunctionSpace,
int m>
199 return applyUnaryOp(Assign(a));
203 template <
class First,
class Last>
206 static_assert(boost::fusion::result_of::size<Sequence>::type::value == boost::fusion::result_of::distance<First,Last>::type::value,
207 "Numbers of variables do not match.");
220 template <
class SequenceY>
223 return applyBinaryOp(Add(),y);
229 return applyBinaryOp(Sub(),y);
235 return applyBinaryOp(Axpy(a),y);
244 template <
class InIterator>
245 void read(InIterator i) [[deprecated]]
254 template <
class InIterator>
255 void read(
int rbegin,
int rend, InIterator i) { boost::fusion::for_each(
data,ReadBlock<InIterator>(rbegin,rend,i)); }
263 template <
class OutIterator>
264 void write(OutIterator i)
const [[deprecated]]
273 template <
class DataOutIter>
274 void write(
int rbegin,
int rend, DataOutIter i)
const
276 boost::fusion::for_each(
data,WriteBlock<DataOutIter>(rbegin,rend,i));
295 zip_view<vector<Sequence const&,Sequence const&> > zipped(vector<Sequence const&,Sequence const&>(
data,y.
data));
297 for_each(zipped,[&](
auto const& p) { s += at_c<0>(p) * at_c<1>(p); });
312 return (*
this)*(*this);
333 template <
class BinaryOp>
336 PairOp(BinaryOp
const& op_): op(op_) {}
338 template <
class Pair>
void operator()(Pair p)
const {
339 op(boost::fusion::at_c<0>(p),boost::fusion::at_c<1>(p));
346 template <
class UnaryOp>
347 Self& applyUnaryOp(UnaryOp
const& op) {
348 boost::fusion::for_each(
data,op);
352 template <
class BinaryOp,
class SpaceY>
353 Self& applyBinaryOp(BinaryOp
const& op, SpaceY
const& y) {
355 typedef typename SpaceY::Sequence SequenceY;
356 zip_view<vector<Sequence&,SequenceY const&> > zipped(vector<Sequence&,SequenceY const&>(
data,y.data));
357 for_each(zipped,PairOp<BinaryOp>(op));
361 struct Add {
template <
class T,
class S>
void operator()(T& a, S
const& b)
const { a += b; } };
362 struct Sub {
template <
class T>
void operator()(T& a, T
const& b)
const { a -= b; } };
364 Assign(
Scalar s_): s(s_) {}
365 template <
class T>
void operator()(T& a)
const { a = s; }
371 ScalarMult(
Scalar s_): s(s_) {}
372 template <
class Element>
void operator()(Element& e)
const { e *= s; }
379 template <
class T>
void operator()(T& a, T
const& b)
const {
393 template <
class DataOutIter>
396 WriteBlock(
int& rbegin_,
int& rend_, DataOutIter& out_): rbegin(rbegin_), rend(rend_), out(out_) {}
397 template <
class VectorBlock>
void operator()(VectorBlock
const& v)
const
399 if (rbegin<=0 && rend>0)
411 template <
class DataInIter>
414 ReadBlock(
int& rbegin_,
int& rend_, DataInIter& in_): rbegin(rbegin_), rend(rend_), in(in_) {}
416 template <
class VectorBlock>
void operator()(VectorBlock& v)
const
418 if (rbegin<=0 && rend>0)
456 template <
int m,
class Scalar,
class Sequence>
459 return boost::fusion::at_c<m>(x.
data);
462 template <
int m,
class Scalar,
class Sequence>
465 return boost::fusion::at_c<m>(x.
data);
477 template <
class X0,
class ...Xs>
480 using Sequence = boost::fusion::vector<X0,Xs...>;
492 template <
class Scalar,
class Seq,
class OutIter>
495 boost::fusion::for_each(v.
data,[&](
auto& x) { i = vectorToSequence(x,i); });
504 template <
class Scalar,
class Seq,
class InIter>
507 boost::fusion::for_each(v.
data,[&](
auto& x) { i = vectorFromSequence(x,i); });
A class for representing finite element functions.
StorageType const & coefficients() const
Provides read-only access to the coefficients of the finite element basis functions.
Self & axpy(Scalar a, Self const &y)
this <- this + a*y
LinearProductSpace(S const &init)
Constructor with explicit data.
void read(int rbegin, int rend, InIterator i)
Reads the coefficients of the subrange [rbegin,rend[ sequentially from an input iterator....
LinearProductSpace(LinearProductSpace< Scalar, Sequence > &&y)
Move constructor.
Self & operator+=(LinearProductSpace< Scalar, SequenceY > const &y)
In place addition.
Self & operator=(boost::fusion::iterator_range< First, Last > range)
Assignment from a (hopefully compatible) boost::fusion iterator range.
void read(InIterator i)
DEPRECATED use vectorFromSequence instead.
Self & operator=(VariableSet< VSDescriptions > const &y)
Assignment from a different (hopefully compatible) type.
LinearProductSpace(boost::fusion::transform_view< Args... > const &data_)
Self & operator*=(Scalar a)
Scaling.
size_t dim() const
Number of scalar degrees of freedom. This computes the total number of degrees of freedom,...
LinearProductSpace(LinearProductSpace< Scalar, Sequence > const &y)
Copy constructor.
Self & operator=(FunctionSpaceElement< FunctionSpace, m > const &fse)
Assignment from a (hopefully compatible) FunctionSpaceElement.
field_type operator*(Self const &y) const
Scalar product.
Self & operator=(LinearProductSpace< Scalar, OtherSeq > const &y)
Assignment from a different (hopefully compatible) type.
Scalar_ Scalar
scalar type
LinearProductSpace()=delete
Self & operator=(Scalar a)
Assignment to constant scalar.
void write(int rbegin, int rend, DataOutIter i) const
Writes the coefficients of the subrange [rbegin,rend[ sequentially to an output iterator....
field_type dot(Self const &y) const
Scalar product.
Self & operator-=(Self const &y)
In place subtraction.
double two_norm2() const
squared euclidean norm
LinearProductSpace(const VariableSet< VSDescriptions > &y)
Copy from VariableSet.
std::remove_reference_t< typename boost::fusion::result_of::at_c< Sequence const, m >::type > Component
The type of the m-th component.
void write(OutIterator i) const
DEPRECATED use vectorToSequence instead.
Seq Sequence
boost::fusion::vector of element vectors.
double two_norm() const
euclidean norm
Self & operator=(Self const &y)
Assignment from the same type.
A class for storing a heterogeneous collection of FunctionSpaceElement s.
FEFunctionSpace and FunctionSpaceElement and the like.
OutIter vectorToSequence(LinearProductSpace< Scalar, Seq > const &v, OutIter i)
writes the coefficients of a vector to a flat scalar sequence <Scalar,Seq>
auto const & component(LinearProductSpace< Scalar, Sequence > const &x)
Provides access to the m-th component of a product space.
InIter vectorFromSequence(LinearProductSpace< Scalar, Seq > &v, InIter i)
reads the coefficients of a vector from a flat scalar sequence <Scalar,Seq>
auto cartesianProduct(X0 const &x0, Xs const &... xs)
Creates a cartesian product of the given vectors, i.e. a LinearProductSpace object.
auto & component(LinearProductSpace< Scalar, Sequence > &x)
static void apply(const VariableSet< VSDescriptions > &from, Space &to)
static void apply(const VariableSet< VSDescriptions > &from, Space &to)