DUNE-FEM (unstable)

hierarchical.hh
1#ifndef DUNE_FEM_SOLVER_COMMUNICATION_HIERARCHICAL_HH
2#define DUNE_FEM_SOLVER_COMMUNICATION_HIERARCHICAL_HH
3
4#include <memory>
5#include <type_traits>
6#include <utility>
7
9
10#include <dune/istl/bvector.hh>
11#include <dune/istl/multitypeblockvector.hh>
12#include <dune/istl/solvercategory.hh>
13
14#include <dune/fem/common/hybrid.hh>
15#include <dune/fem/function/hierarchical/dofvector.hh>
16#include <dune/fem/space/common/commoperations.hh>
17
18namespace Dune
19{
20
21 namespace Fem
22 {
23
24 namespace ISTL
25 {
26
27 // HierarchicalCommunicationVector
28 // -------------------------------
29
30 template< class DiscreteFunctionSpace, class DofContainer >
31 class HierarchicalCommunicationVector
32 {
33 typedef HierarchicalCommunicationVector< DiscreteFunctionSpace, DofContainer > ThisType;
34
35 public:
36 struct DofVector
37 {
38 typedef typename Dune::Fem::Impl::BlockIndicesFor< DofContainer >::Type BlockIndices;
39 static constexpr std::size_t blockSize = Dune::Hybrid::size( BlockIndices() );
40
41 typedef HierarchicalDofBlock< const DofContainer > ConstDofBlockType;
42 typedef HierarchicalDofBlock< DofContainer > DofBlockType;
43
44 explicit DofVector ( DofContainer &data ) : data_( data ) {}
45
46 ConstDofBlockType operator[] ( std::size_t i ) const { return ConstDofBlockType( data_, i ); }
47 DofBlockType operator[] ( std::size_t i ) { return DofBlockType( data_, i ); }
48
49 private:
50 DofContainer &data_;
51 };
52
53 typedef DiscreteFunctionSpace DiscreteFunctionSpaceType;
54
55 typedef typename DiscreteFunctionSpaceType::LocalBlockIndices BlockIndices;
56
57 static constexpr std::size_t blockSize = Hybrid::size( BlockIndices() );
58
59 typedef typename DofContainer::field_type DofType;
60
61 template< class Operation >
62 struct CommDataHandle
63 {
64 typedef typename DiscreteFunctionSpaceType::template CommDataHandle< ThisType, Operation >::Type Type;
65 };
66
67 HierarchicalCommunicationVector ( const DiscreteFunctionSpace &dfSpace, DofContainer &dofContainer )
68 : dfSpace_( dfSpace ), dofVector_( dofContainer )
69 {}
70
71 template< class Operation >
72 typename CommDataHandle< Operation >::Type dataHandle ( const Operation &operation )
73 {
74 return space().createDataHandle( *this, operation );
75 }
76
77 const DofVector &dofVector () const { return dofVector_; }
78 DofVector &dofVector () { return dofVector_; }
79
80 const DiscreteFunctionSpaceType &space () const { return dfSpace_; }
81
82 private:
83 const DiscreteFunctionSpace &dfSpace_;
84 DofVector dofVector_;
85 };
86
87
88
89 // HierarchicalCommunication
90 // -------------------------
91
92 template< class DiscreteFunctionSpace >
93 class HierarchicalCommunication
94 {
95 typedef HierarchicalCommunication< DiscreteFunctionSpace > ThisType;
96
97 typedef typename DiscreteFunctionSpace::AuxiliaryDofsType AuxiliaryDofsType;
98
99 public:
100 typedef DiscreteFunctionSpace DiscreteFunctionSpaceType;
101
102 explicit HierarchicalCommunication ( const DiscreteFunctionSpaceType &dfSpace, Dune::SolverCategory::Category solverCategory = Dune::SolverCategory::sequential )
103 : dfSpace_( dfSpace ), solverCategory_( solverCategory )
104 {}
105
106 const typename DiscreteFunctionSpace::GridPartType::CommunicationType &communicator () const { return dfSpace_.gridPart().comm(); }
107
108 template< class T >
109 void copyOwnerToAll ( const T &x, T &y ) const
110 {
111 y = x;
112 project( y );
113 HierarchicalCommunicationVector< DiscreteFunctionSpaceType, T > z( dfSpace_, y );
114 dfSpace_.communicator().exchange( z, DFCommunicationOperation::Add() );
115 }
116
117 template< class T >
118 void project ( T &x ) const
119 {
120 project( dfSpace_.auxiliaryDofs(), x );
121 }
122
123 template< class T, class F >
124 void dot ( const T &x, const T &y, F &scp ) const
125 {
126 dot( dfSpace_.auxiliaryDofs(), x, y, scp );
127 scp = communicator().sum( scp );
128 }
129
130 template< class T >
131 typename Dune::FieldTraits< typename T::field_type >::real_type norm ( const T &x ) const
132 {
133 using std::sqrt;
134 typename Dune::FieldTraits< typename T::field_type >::real_type norm2( 0 );
135 dot( x, x, norm2 );
136 return sqrt( norm2 );
137 }
138
139 Dune::SolverCategory::Category getSolverCategory () const { return solverCategory_; }
140
141 private:
142 template< class... V >
143 static void project ( const AuxiliaryDofsType &auxiliaryDofs, MultiTypeBlockVector< V... > &x )
144 {
145 Dune::Hybrid::forEach( std::index_sequence_for< V... >(), [ &auxiliaryDofs, &x ] ( auto &&i ) { ThisType::project( auxiliaryDofs, x[ i ] ); } );
146 }
147
148 template< class B, class A >
149 static void project ( const AuxiliaryDofsType &auxiliaryDofs, BlockVector< B, A > &x )
150 {
151 typedef typename B::field_type field_type;
152 for( int i : auxiliaryDofs )
153 x[ i ] = field_type( 0 );
154 }
155
156 template< class... V, class F >
157 static void dot ( const AuxiliaryDofsType &auxiliaryDofs, const MultiTypeBlockVector< V... > &x, const MultiTypeBlockVector< V... > &y, F &scp )
158 {
159 Dune::Hybrid::forEach( std::index_sequence_for< V... >(), [ &auxiliaryDofs, &x, &y, &scp ] ( auto &&i ) { ThisType::dot( auxiliaryDofs, x[ i ], y[ i ], scp ); } );
160 }
161
162 template< class B, class A, class F >
163 static void dot ( const AuxiliaryDofsType &auxiliaryDofs, const BlockVector< B, A > &x, const BlockVector< B, A > &y, F &scp )
164 {
165 const int numAuxiliarys = auxiliaryDofs.size();
166 for( int auxiliary = 0, i = 0; auxiliary < numAuxiliarys; ++auxiliary, ++i )
167 {
168 const int nextAuxiliary = auxiliaryDofs[ auxiliary ];
169 for( ; i < nextAuxiliary; ++i )
170 scp += x[ i ] * y[ i ];
171 }
172 }
173
174 const DiscreteFunctionSpaceType &dfSpace_;
175 Dune::SolverCategory::Category solverCategory_;
176 };
177
178
179
180 // buildCommunication
181 // ------------------
182
183 template< class DiscreteFunctionSpace >
184 void buildCommunication ( const DiscreteFunctionSpace &dfSpace,
185 Dune::SolverCategory::Category solverCategory,
186 std::shared_ptr< HierarchicalCommunication< DiscreteFunctionSpace > > &communication )
187 {
188 communication.reset( new HierarchicalCommunication< DiscreteFunctionSpace >( dfSpace, solverCategory ) );
189 }
190
191
192
193 // SupportsAMG for HierarchicalCommunication
194 // -----------------------------------------
195
196 template< class T >
197 struct SupportsAMG;
198
199 template< class DiscreteFunctionSpace >
200 struct SupportsAMG< HierarchicalCommunication< DiscreteFunctionSpace > >
201 : public std::false_type
202 {};
203
204 } // namespace ISTL
205
206 } // namespace Fem
207
208} // namespace Dune
209
210#endif // #ifndef DUNE_FEM_SOLVER_COMMUNICATION_HIERARCHICAL_HH
This file implements a vector space as a tensor product of a given vector space. The number of compon...
discrete function space
Traits::CommunicationType CommunicationType
Collective communication.
Definition: gridpart.hh:97
Type traits to determine the type of reals (when working with complex numbers)
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 auto size(const T &t)
Size query.
Definition: hybridutilities.hh:73
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:256
Dune namespace.
Definition: alignedallocator.hh:13
Category
Definition: solvercategory.hh:23
@ sequential
Category for sequential solvers.
Definition: solvercategory.hh:25
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 13, 23:29, 2024)