DUNE PDELab (git)

vector.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_PDELAB_BACKEND_SIMPLE_VECTOR_HH
4#define DUNE_PDELAB_BACKEND_SIMPLE_VECTOR_HH
5
6#include <algorithm>
7#include <functional>
8#include <memory>
9#include <numeric>
10
13#include <dune/istl/bvector.hh>
14
15#include <dune/pdelab/gridfunctionspace/gridfunctionspace.hh>
16#include <dune/pdelab/gridfunctionspace/lfsindexcache.hh>
18#include <dune/pdelab/backend/interface.hh>
19#include <dune/pdelab/backend/common/uncachedvectorview.hh>
20#include <dune/pdelab/backend/simple/descriptors.hh>
21
22namespace Dune {
23 namespace PDELab {
24
25 namespace Simple {
26
27 namespace {
28
29 // For some reason std::bind cannot directly deduce the correct version
30 // of Dune::fvmeta::abs2, so we package it into a functor to help it along.
31 template<typename K>
32 struct abs2
33 {
34 typename FieldTraits<K>::real_type operator()(const K& k) const
35 {
36 return Dune::fvmeta::abs2(k);
37 }
38 };
39
40 }
41
42 template<typename GFS, typename C>
43 class VectorContainer
44 : public Backend::impl::Wrapper<C>
45 {
46
47 friend Backend::impl::Wrapper<C>;
48
49 public:
50 typedef C Container;
51 typedef typename Container::value_type ElementType;
52 typedef ElementType E;
53
54 // for ISTL solver compatibility
55 typedef ElementType field_type;
56
57 typedef GFS GridFunctionSpace;
58 typedef typename Container::size_type size_type;
59
60 typedef typename GFS::Ordering::Traits::ContainerIndex ContainerIndex;
61
62 typedef typename Container::iterator iterator;
63 typedef typename Container::const_iterator const_iterator;
64
65 template<typename LFSCache>
66 using LocalView = UncachedVectorView<VectorContainer,LFSCache>;
67
68 template<typename LFSCache>
69 using ConstLocalView = ConstUncachedVectorView<const VectorContainer,LFSCache>;
70
71
72 VectorContainer(const VectorContainer& rhs)
73 : _gfs(rhs._gfs)
74 , _container(std::make_shared<Container>(*(rhs._container)))
75 {}
76
77 VectorContainer (const GFS& gfs, Backend::attached_container = Backend::attached_container())
78 : _gfs(gfs)
79 , _container(std::make_shared<Container>(gfs.ordering().blockCount()))
80 {}
81
83 VectorContainer(const GFS& gfs, Backend::unattached_container)
84 : _gfs(gfs)
85 {}
86
92 VectorContainer (const GFS& gfs, Container& container)
93 : _gfs(gfs)
94 , _container(stackobject_to_shared_ptr(container))
95 {
96 _container->resize(gfs.ordering().blockCount());
97 }
98
99 VectorContainer (const GFS& gfs, const E& e)
100 : _gfs(gfs)
101 , _container(std::make_shared<Container>(gfs.ordering().blockCount(),e))
102 {}
103
104 void detach()
105 {
106 _container.reset();
107 }
108
109 void attach(std::shared_ptr<Container> container)
110 {
111 _container = container;
112 }
113
114 bool attached() const
115 {
116 return bool(_container);
117 }
118
119 const std::shared_ptr<Container>& storage() const
120 {
121 return _container;
122 }
123
124 size_type N() const
125 {
126 return _container->size();
127 }
128
129 VectorContainer& operator=(const VectorContainer& r)
130 {
131 if (this == &r)
132 return *this;
133 if (attached())
134 {
135 (*_container) = (*r._container);
136 }
137 else
138 {
139 _container = std::make_shared<Container>(*(r._container));
140 }
141 return *this;
142 }
143
144 VectorContainer& operator=(const E& e)
145 {
146 std::fill(_container->begin(),_container->end(),e);
147 return *this;
148 }
149
150 VectorContainer& operator*=(const E& e)
151 {
152 std::transform(_container->begin(),_container->end(),_container->begin(),
153 std::bind(std::multiplies<E>(),e,std::placeholders::_1));
154 return *this;
155 }
156
157
158 VectorContainer& operator+=(const E& e)
159 {
160 std::transform(_container->begin(),_container->end(),_container->begin(),
161 std::bind(std::plus<E>(),e,std::placeholders::_1));
162 return *this;
163 }
164
165 VectorContainer& operator+=(const VectorContainer& y)
166 {
167 std::transform(_container->begin(),_container->end(),y._container->begin(),
168 _container->begin(),std::plus<E>());
169 return *this;
170 }
171
172 VectorContainer& operator-= (const VectorContainer& y)
173 {
174 std::transform(_container->begin(),_container->end(),y._container->begin(),
175 _container->begin(),std::minus<E>());
176 return *this;
177 }
178
179 E& operator[](const ContainerIndex& ci)
180 {
181 return (*_container)[ci[0]];
182 }
183
184 const E& operator[](const ContainerIndex& ci) const
185 {
186 return (*_container)[ci[0]];
187 }
188
189 typename Dune::template FieldTraits<E>::real_type two_norm() const
190 {
191 using namespace std::placeholders;
192 using std::sqrt;
193 typedef typename Dune::template FieldTraits<E>::real_type Real;
194 return sqrt(std::accumulate(_container->begin(),_container->end(),Real(0),std::bind(std::plus<Real>(),_1,std::bind(abs2<E>(),_2))));
195 }
196
197 typename Dune::template FieldTraits<E>::real_type one_norm() const
198 {
199 typedef typename Dune::template FieldTraits<E>::real_type Real;
200 return std::accumulate(_container->begin(),_container->end(),Real(0),
201 [](const auto& n, const auto& e) {
202 using std::abs;
203 return n + abs(e);
204 });
205 }
206
207 typename Dune::template FieldTraits<E>::real_type infinity_norm() const
208 {
209 if (_container->size() == 0)
210 return 0;
211 using std::abs;
212 return abs(*std::max_element(_container->begin(),_container->end(),
213 [](const auto& a, const auto& b) {
214 using std::abs;
215 return abs(a) < abs(b);
216 }));
217 }
218
219 E operator*(const VectorContainer& y) const
220 {
221 return std::inner_product(_container->begin(),_container->end(),y._container->begin(),E(0));
222 }
223
224 E dot(const VectorContainer& y) const
225 {
226 return std::inner_product(_container->begin(),_container->end(),y._container->begin(),E(0),std::plus<E>(),Dune::dot<E,E>);
227 }
228
229 VectorContainer& axpy(const E& a, const VectorContainer& y)
230 {
231 using namespace std::placeholders;
232 std::transform(_container->begin(),_container->end(),y._container->begin(),
233 _container->begin(),std::bind(std::plus<E>(),_1,std::bind(std::multiplies<E>(),a,_2)));
234 return *this;
235 }
236
237 // for debugging and AMG access
238 Container& base ()
239 {
240 return *_container;
241 }
242
243 const Container& base () const
244 {
245 return *_container;
246 }
247
248 private:
249
250 Container& native ()
251 {
252 return *_container;
253 }
254
255 const Container& native () const
256 {
257 return *_container;
258 }
259
260 public:
261
262 iterator begin()
263 {
264 return _container->begin();
265 }
266
267 const_iterator begin() const
268 {
269 return _container->begin();
270 }
271
272 iterator end()
273 {
274 return _container->end();
275 }
276
277 const_iterator end() const
278 {
279 return _container->end();
280 }
281
282 size_t flatsize() const
283 {
284 return _container->size();
285 }
286
287 const GFS& gridFunctionSpace() const
288 {
289 return _gfs;
290 }
291
292 private:
293 const GFS& _gfs;
294 std::shared_ptr<Container> _container;
295 };
296
297
298 } // namespace Simple
299
300
301#ifndef DOXYGEN
302
303 template<typename GFS, typename E>
304 struct SimpleVectorSelectorHelper
305 {
306
307 using vector_type = typename GFS::Traits::Backend::template vector_type<E>;
308
309 using Type = Simple::VectorContainer<GFS,vector_type>;
310
311 };
312
313 namespace Backend {
314 namespace impl {
315
316 template<template<typename> class Container, typename GFS, typename E>
317 struct BackendVectorSelectorHelper<Simple::VectorBackend<Container>, GFS, E>
318 : public SimpleVectorSelectorHelper<GFS,E>
319 {};
320
321 } // namespace impl
322 } // namespace Backend
323
324#endif // DOXYGEN
325
326 } // namespace PDELab
327} // namespace Dune
328
329#endif // DUNE_PDELAB_BACKEND_SIMPLE_VECTOR_HH
Various tags for influencing backend behavior.
This file implements a vector space as a tensor product of a given vector space. The number of compon...
Implements a vector constructed from a given type representing a field and a compile-time given size.
constexpr index_constant< 1 > _1
Compile time index with value 1.
Definition: indices.hh:55
constexpr index_constant< 2 > _2
Compile time index with value 2.
Definition: indices.hh:58
auto dot(const A &a, const B &b) -> typename std::enable_if< IsNumber< A >::value &&!IsVector< A >::value &&!std::is_same< typename FieldTraits< A >::field_type, typename FieldTraits< A >::real_type > ::value, decltype(conj(a) *b)>::type
computes the dot product for fundamental data types according to Petsc's VectDot function: dot(a,...
Definition: dotproduct.hh:42
constexpr T accumulate(Range &&range, T value, F &&f)
Accumulate values.
Definition: hybridutilities.hh:279
Dune namespace.
Definition: alignedallocator.hh:13
std::shared_ptr< T > stackobject_to_shared_ptr(T &t)
Create a shared_ptr for a stack-allocated object.
Definition: shared_ptr.hh:72
STL namespace.
This file implements several utilities related to std::shared_ptr.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)