AMDiS  0.1
The Adaptive Multi-Dimensional Simulation Toolbox
VectorFacade.hpp
1 #pragma once
2 
3 #include <string>
4 #include <type_traits>
5 #include <utility>
6 
7 #include <dune/common/classname.hh>
8 #include <dune/common/deprecated.hh>
9 #include <dune/common/hybridutilities.hh>
10 #include <dune/common/rangeutilities.hh>
11 #include <dune/common/shared_ptr.hh>
12 #include <dune/common/std/type_traits.hh>
13 #include <dune/functions/functionspacebases/concepts.hh>
14 #include <dune/functions/functionspacebases/sizeinfo.hh>
15 
16 #include <amdis/Output.hpp>
17 #include <amdis/common/Concepts.hpp>
18 #include <amdis/common/ConceptsBase.hpp>
19 #include <amdis/common/FakeContainer.hpp>
20 #include <amdis/common/TypeTraits.hpp>
21 #include <amdis/functions/NodeIndices.hpp>
22 #include <amdis/operations/Assigner.hpp>
23 #include <amdis/typetree/MultiIndex.hpp>
24 
25 namespace AMDiS
26 {
28 
35  template <class T, template <class> class VectorImpl>
36  class VectorFacade
37  {
38  using Self = VectorFacade;
39  using Impl = VectorImpl<T>;
40 
41  private:
42  // States the vector can be in. Is changed on various insertion or gathering methods.
43  enum class VectorState
44  {
45  unknown = 0,
46  synchronized = 1,
47  insert_values = 2,
48  add_values = 3
49  };
50 
51  template <class A>
52  using VectorStateOf_t = std::conditional_t<std::is_same_v<A,Assigner::plus_assign>,
53  std::integral_constant<VectorState, VectorState::add_values>,
54  std::integral_constant<VectorState, VectorState::insert_values>>;
55 
56  public:
57  using size_type = typename Impl::size_type;
58  using value_type = typename Impl::value_type;
59 
62  template <class GlobalBasis,
63  class = std::void_t<decltype(std::declval<GlobalBasis>().dimension())> >
64  VectorFacade(GlobalBasis const& basis)
65  : impl_(basis)
66  {
67  resizeZero(sizeInfo(basis));
68  }
69 
71  Impl const& impl() const { return impl_; }
72  Impl& impl() { return impl_; }
73 
74 
75  template <class V>
76  using HasLocalSize = decltype(std::declval<V>().localSize());
77 
78  template <class V>
79  using HasGlobalSize = decltype(std::declval<V>().globalSize());
80 
82  std::size_t localSize() const
83  {
84  if constexpr (Dune::Std::is_detected<HasLocalSize,Impl>::value)
85  return impl_.localSize();
86  else
87  return impl_.size();
88  }
89 
91  std::size_t globalSize() const
92  {
93  if constexpr (Dune::Std::is_detected<HasGlobalSize,Impl>::value)
94  return impl_.globalSize();
95  else
96  return impl_.size();
97  }
98 
100  template <class SizeInfo>
101  void resize(SizeInfo const& sizeInfo)
102  {
103  init(sizeInfo, false);
104  }
105 
107  template <class SizeInfo>
108  void resizeZero(SizeInfo const& sizeInfo)
109  {
110  init(sizeInfo, true);
111  }
112 
115  template <class SizeInfo>
116  void init(SizeInfo const& sizeInfo, bool clear)
117  {
118  impl_.init(sizeInfo, clear);
119  state_ = clear ? VectorState::synchronized : VectorState::unknown;
120  }
121 
123  void finish()
124  {
125  impl_.finish();
126  state_ = VectorState::unknown;
127  }
128 
130  template <class Index,
131  REQUIRES(Concepts::MultiIndex<Index>)>
132  typename Impl::value_type at(Index const& idx) const
133  {
134  const_cast<Self*>(this)->synchronize();
135  return impl_.at(idx);
136  }
137 
139 
149  template <class Index, class Assign = Assigner::plus_assign,
150  REQUIRES(Concepts::MultiIndex<Index>)>
151  void insert(Index const& idx, typename Impl::value_type const& value, Assign assign = {})
152  {
153  test_exit_dbg(state_ == VectorStateOf_t<Assign>::value ||
154  state_ == VectorState::unknown ||
155  state_ == VectorState::synchronized,
156  "Vector in invalid state {} for insertion by {}.", to_string(state_), Dune::className<Assign>());
157 
158  impl_.insert(idx, value, assign);
159 
160  // set the state to insert_values or add_values
161  state_ = VectorStateOf_t<Assign>::value;
162  }
163 
165  template <class Index,
166  REQUIRES(Concepts::MultiIndex<Index>)>
167  void set(Index const& idx, typename Impl::value_type const& value)
168  {
169  insert(idx, value, Assigner::assign{});
170  }
171 
173  template <class Index,
174  REQUIRES(Concepts::MultiIndex<Index>)>
175  void add(Index const& idx, typename Impl::value_type const& value)
176  {
177  insert(idx, value, Assigner::plus_assign{});
178  }
179 
180 
183 
195  template <class LocalView, class Node, class Buffer,
196  REQUIRES(Concepts::LocalView<LocalView>),
197  REQUIRES(Concepts::BasisNode<Node>)>
198  void gather(LocalView const& localView, Node const& node, Buffer& buffer) const
199  {
200  test_exit(state_ == VectorState::unknown ||
201  state_ == VectorState::synchronized,
202  "Vector in invalid state {} for gather operations.", to_string(state_));
203 
204  const_cast<Self*>(this)->synchronize();
205 
206  buffer.resize(node.size());
207  impl_.gather(nodeIndices(localView, node), buffer.begin());
208  }
209 
210  // [[expects: localView is bound to an element]]
211  template <class LocalView, class Buffer,
212  REQUIRES(Concepts::LocalView<LocalView>)>
213  void gather(LocalView const& localView, Buffer& buffer) const
214  {
215  gather(localView, localView.tree(), buffer);
216  }
217 
219 
238  template <class LocalView, class Node, class NodeVector, class MaskRange, class Assign,
239  REQUIRES(Concepts::LocalView<LocalView>),
240  REQUIRES(Concepts::BasisNode<Node>)>
241  void scatter(LocalView const& localView, Node const& node, NodeVector const& localVector,
242  MaskRange const& mask, Assign assign)
243  {
244  test_exit(state_ == VectorStateOf_t<Assign>::value ||
245  state_ == VectorState::unknown ||
246  state_ == VectorState::synchronized,
247  "Vector in invalid state {} for insertion by {}.", to_string(state_), Dune::className<Assign>());
248 
249  assert(localVector.size() == node.size());
250 
251  // create a range of DOF indices on the node
252  impl_.scatter(nodeIndices(localView, node), localVector, mask, assign);
253 
254  // set the state to insert_values or add_values
255  state_ = VectorStateOf_t<Assign>::value;
256  }
257 
259  // [[expects: localView is bound to an element]]
260  // [[expects: node is in localView.tree()]]
261  template <class LocalView, class Node, class NodeVector, class Assign,
262  REQUIRES(Concepts::LocalView<LocalView>),
263  REQUIRES(Concepts::BasisNode<Node>)>
264  void scatter(LocalView const& localView, Node const& node, NodeVector const& localVector, Assign assign)
265  {
266  scatter(localView, node, localVector, FakeContainer<bool,true>{}, assign);
267  }
268 
270  // [[expects: localView is bound to an element]]
271  template <class LocalView, class LocalVector, class Assign,
272  REQUIRES(Concepts::LocalView<LocalView>)>
273  void scatter(LocalView const& localView, LocalVector const& localVector, Assign assign)
274  {
275  scatter(localView, localView.tree(), localVector, assign);
276  }
277 
279 
285  template <class LocalInd, class Func>
286  void forEach(LocalInd const& localInd, Func&& func)
287  {
288  synchronize();
289  impl_.forEach(localInd, FWD(func));
290  }
291 
293  template <class Func>
294  void forEach(Func&& func)
295  {
296  synchronize();
297  impl_.forEach(FWD(func));
298  }
299 
301 
307  template <class LocalInd, class Func>
308  void forEach(LocalInd const& localInd, Func&& func) const
309  {
310  const_cast<Self*>(this)->synchronize();
311  impl_.forEach(localInd, FWD(func));
312  }
313 
315  template <class Func>
316  void forEach(Func&& func) const
317  {
318  const_cast<Self*>(this)->synchronize();
319  impl_.forEach(FWD(func));
320  }
321 
322 
323  private:
324  // synchronizes ghost values. Does not touch owned values
325  void synchronize()
326  {
327  if (state_ != VectorState::synchronized)
328  impl_.synchronize();
329 
330  state_ = VectorState::synchronized;
331  }
332 
333  // print the vector state to string for debugging purposes
334  static std::string to_string(VectorState state)
335  {
336  switch (state) {
337  case VectorState::synchronized: return "synchronized";
338  case VectorState::insert_values: return "insert_values";
339  case VectorState::add_values: return "add_values";
340  default: return "unknown";
341  }
342  }
343 
344  private:
346  Impl impl_;
347 
350  VectorState state_ = VectorState::unknown;
351  };
352 
353 
354  namespace Impl
355  {
356  template <class T, class Facade>
357  struct VectorTypeImpl;
358 
359  template <class T, class S, template <class> class Impl>
360  struct VectorTypeImpl<T,VectorFacade<S,Impl>>
361  {
362  using type = VectorFacade<T,Impl>;
363  };
364 
365  } // end namespace Impl
366 
368  template <class T, class Facade>
369  using VectorType_t = typename Impl::VectorTypeImpl<T,Facade>::type;
370 
371 } // end namespace AMDiS
std::size_t localSize() const
Return the number of entries in the local part of the vector.
Definition: VectorFacade.hpp:82
void gather(LocalView const &localView, Node const &node, Buffer &buffer) const
Extract values from the vector referring to the given local indices and store it into a buffer...
Definition: VectorFacade.hpp:198
void finish()
Finish the insertion of values, see init()
Definition: VectorFacade.hpp:123
The basic container that stores a base vector and a corresponding basis.
Definition: LinearSolverInterface.hpp:23
void forEach(Func &&func) const
Call forEach for all entries in the vector.
Definition: VectorFacade.hpp:316
std::size_t globalSize() const
Return the number of entries in the global vector.
Definition: VectorFacade.hpp:91
Definition: Assigner.hpp:16
Impl::value_type at(Index const &idx) const
Return the value of the vector at the local index idx.
Definition: VectorFacade.hpp:132
void test_exit_dbg(bool condition, Args &&... args)
call assert_msg, in debug mode only
Definition: Output.hpp:205
Global basis defined on a pre-basis.
Definition: GlobalBasis.hpp:53
void scatter(LocalView const &localView, Node const &node, NodeVector const &localVector, MaskRange const &mask, Assign assign)
Insert a block of values into the vector (add or overwrite to existing values)
Definition: VectorFacade.hpp:241
void forEach(LocalInd const &localInd, Func &&func)
Apply func to each value at given indices localInd.
Definition: VectorFacade.hpp:286
VectorFacade(GlobalBasis const &basis)
Definition: VectorFacade.hpp:64
Contains all classes needed for solving linear and non linear equation systems.
Definition: AdaptBase.hpp:6
constexpr bool LocalView
A Dune::Functions::LocalView type.
Definition: Concepts.hpp:182
Tree const & tree() const
Return the local ansatz tree associated to the bound entity.
Definition: LocalView.hpp:107
void add(Index const &idx, typename Impl::value_type const &value)
See insert for assignment operation Assigner::plus_assign.
Definition: VectorFacade.hpp:175
void forEach(LocalInd const &localInd, Func &&func) const
Apply func to each value at given indices localInd.
Definition: VectorFacade.hpp:308
void resize(SizeInfo const &sizeInfo)
Resize the vector to the size of the basis.
Definition: VectorFacade.hpp:101
typename Impl::VectorTypeImpl< T, Facade >::type VectorType_t
Type transformation changing the value type of the vector.
Definition: VectorFacade.hpp:369
A container-like data-structure not storing anything and with empty implementations in many container...
Definition: FakeContainer.hpp:34
void init(SizeInfo const &sizeInfo, bool clear)
Definition: VectorFacade.hpp:116
void insert(Index const &idx, typename Impl::value_type const &value, Assign assign={})
Insert a single value into the matrix (add or overwrite to existing value)
Definition: VectorFacade.hpp:151
void resizeZero(SizeInfo const &sizeInfo)
Resize the vector to the size of the basis and set to zero.
Definition: VectorFacade.hpp:108
Impl const & impl() const
Return the underlying linear algebra backend.
Definition: VectorFacade.hpp:71
void scatter(LocalView const &localView, Node const &node, NodeVector const &localVector, Assign assign)
Call scatter with MaskRange set to FakeContainer.
Definition: VectorFacade.hpp:264
constexpr bool GlobalBasis
A Dune::Functions::GlobalBasis type.
Definition: Concepts.hpp:190
void scatter(LocalView const &localView, LocalVector const &localVector, Assign assign)
Call scatter with Node given by the tree of the localView.
Definition: VectorFacade.hpp:273
void forEach(Func &&func)
Call forEach for all entries in the vector.
Definition: VectorFacade.hpp:294
void test_exit(bool condition, std::string const &str, Args &&... args)
test for condition and in case of failure print message and exit
Definition: Output.hpp:163
auto nodeIndices(LocalView const &localView, Node const &node)
Returns a range over (flat) DOF indices on a node, given by the localView.
Definition: NodeIndices.hpp:13
Definition: Assigner.hpp:7