DUNE-FEM (unstable)

localcontribution.hh
1#ifndef DUNE_FEM_OPERATOR_COMMON_LOCALCONTRIBUTION_HH
2#define DUNE_FEM_OPERATOR_COMMON_LOCALCONTRIBUTION_HH
3
4#include <algorithm>
5#include <type_traits>
6#include <vector>
7#include <utility>
8
11
12#include <dune/fem/common/utility.hh>
13#include <dune/fem/function/common/localcontribution.hh>
14#include <dune/fem/operator/common/operator.hh>
15#include <dune/fem/operator/common/temporarylocalmatrix.hh>
16#include <dune/fem/storage/rowreferencevector.hh>
17#include <dune/fem/storage/subvector.hh>
18
19namespace Dune
20{
21
22 namespace Fem
23 {
24
25 namespace Assembly
26 {
27
28 namespace Global
29 {
30
31 // AddBase
32 // -------
33
34 template< class AssembledOperator >
35 struct AddBase< AssembledOperator, std::enable_if_t< Fem::IsAssembledOperator< AssembledOperator >::value > >
36 {
37 template <class DF, class RF>
38 static void begin ( Dune::Fem::AssembledOperator< DF, RF > &op ) {}
39 template <class DF, class RF>
40 static void end ( Dune::Fem::AssembledOperator< DF, RF > &op ) { op.flushAssembly(); }
41 };
42
43
44
45 // SetBase
46 // -------
47
48 template< class AssembledOperator >
49 struct SetBase< AssembledOperator, std::enable_if_t< Fem::IsAssembledOperator< AssembledOperator >::value > >
50 {
51 template <class DF, class RF>
52 static void begin ( Dune::Fem::AssembledOperator< DF, RF > &op ) {}
53 template <class DF, class RF>
54 static void end ( Dune::Fem::AssembledOperator< DF, RF > &op ) { op.flushAssembly(); }
55 };
56
57 } // namespace Global
58
59
60
61
62 namespace Impl
63 {
64
65 template< class LocalMatrix >
66 struct LocalMatrixGetter
67 {
68 typedef typename LocalMatrix::value_type value_type;
69
70 explicit LocalMatrixGetter ( const LocalMatrix &localMatrix ) : localMatrix_( localMatrix ) {}
71
72 decltype( auto ) operator[] ( int row ) const { return localMatrix_[ row ]; }
73
74 value_type get ( int row, int col ) const { return localMatrix_[ row ][ col ]; }
75
76 const LocalMatrix & localMatrix() const { return localMatrix_; }
77
78 private:
79 const LocalMatrix &localMatrix_;
80 };
81
82 } // namespace Impl
83
84
85
86 // AddBase
87 // -------
88
89 template< class AssembledOperator >
90 struct AddBase< AssembledOperator, std::enable_if_t< Fem::IsAssembledOperator< AssembledOperator >::value > >
91 {
92 typedef typename AssembledOperator::RangeFieldType value_type;
93
94 typedef Global::Add< AssembledOperator > GlobalOperationType;
95
96 template< class DomainEntity, class RangeEntity, class LocalMatrix >
97 void begin ( const DomainEntity &domainEntity, const RangeEntity &rangeEntity, const AssembledOperator &op, LocalMatrix &localMatrix ) const
98 {
99 localMatrix.clear();
100 }
101
102 template< class DomainEntity, class RangeEntity, class LocalMatrix >
103 void end ( const DomainEntity &domainEntity, const RangeEntity &rangeEntity, LocalMatrix &localMatrix, AssembledOperator &op ) const
104 {
105 op.addLocalMatrix( domainEntity, rangeEntity, Impl::LocalMatrixGetter< LocalMatrix >( localMatrix ) );
106 }
107 };
108
109
110
111 // AddScaledBase
112 // -------------
113
114 template< class AssembledOperator >
115 struct AddScaledBase< AssembledOperator, std::enable_if_t< Fem::IsAssembledOperator< AssembledOperator >::value > >
116 : public AddBase< AssembledOperator >
117 {
118 typedef typename AssembledOperator::RangeFieldType value_type;
119
120 AddScaledBase ( value_type factor ) : factor_( std::move( factor ) ) {}
121
122 template< class DomainEntity, class RangeEntity, class LocalMatrix >
123 void end ( const DomainEntity &domainEntity, const RangeEntity &rangeEntity, LocalMatrix &localMatrix, AssembledOperator &op ) const
124 {
125 op.addScaledLocalMatrix( domainEntity, rangeEntity, Impl::LocalMatrixGetter< LocalMatrix >( localMatrix ), factor_ );
126 }
127
128 private:
129 value_type factor_;
130 };
131
132
133
134 // SetAndSelectBaseImpl
135 // ---------------------
136
137 template< class AssembledOperator, const bool getAndSet >
138 struct SetAndSelectBaseImpl
139 {
140 typedef typename AssembledOperator::RangeFieldType value_type;
141
142 typedef Global::Set< AssembledOperator > GlobalOperationType;
143
144 template< class DomainEntity, class RangeEntity, class LocalMatrix >
145 void begin ( const DomainEntity &domainEntity, const RangeEntity &rangeEntity, const AssembledOperator &op, LocalMatrix &localMatrix ) const
146 {
147 if constexpr ( getAndSet )
148 {
149 // get values first for modification
150 op.getLocalMatrix( domainEntity, rangeEntity, localMatrix );
151 }
152 else // set only
153 {
154 localMatrix.clear();
155 }
156 }
157
158 template< class DomainEntity, class RangeEntity, class LocalMatrix >
159 void end ( const DomainEntity &domainEntity, const RangeEntity &rangeEntity, LocalMatrix &localMatrix, AssembledOperator &op ) const
160 {
161 op.setLocalMatrix( domainEntity, rangeEntity, Impl::LocalMatrixGetter< LocalMatrix >( localMatrix ) );
162 }
163 };
164
165 // SetBase
166 // -------
167 template< class AssembledOperator >
168 struct SetBase< AssembledOperator, std::enable_if_t< Fem::IsAssembledOperator< AssembledOperator >::value > >
169 : public SetAndSelectBaseImpl< AssembledOperator, false > // set only
170 {
171 };
172
173 // SetSelectedBase
174 // ---------------
175
176 template< class AssembledOperator >
177 struct SetSelectedBase< AssembledOperator, std::enable_if_t< Fem::IsAssembledOperator< AssembledOperator >::value > >
178 : public SetAndSelectBaseImpl< AssembledOperator, true > // get and set
179 {
180 };
181
182 } // namespace Assembly
183
184 } // namespace Fem
185
186
187 namespace Fem
188 {
189
190 // LocalContribution for Assembled Operators
191 // -----------------------------------------
192
193 template< class AssembledOperator, template< class > class AssemblyOperation >
194 class LocalContribution< AssembledOperator, AssemblyOperation, std::enable_if_t< Fem::IsAssembledOperator< AssembledOperator >::value > >
195 : public TemporaryLocalMatrix< typename AssembledOperator::DomainFunctionType::DiscreteFunctionSpaceType,
196 typename AssembledOperator::RangeFunctionType::DiscreteFunctionSpaceType
197 >
198 {
199 public:
200 typedef AssembledOperator AssembledOperatorType;
201 typedef AssemblyOperation< AssembledOperator > AssemblyOperationType;
202
203 typedef typename AssembledOperatorType::DomainFunctionType::DiscreteFunctionSpaceType DomainSpaceType;
204 typedef typename AssembledOperatorType::RangeFunctionType::DiscreteFunctionSpaceType RangeSpaceType;
205
206 private:
207 typedef LocalContribution< AssembledOperator, AssemblyOperation > ThisType;
208 typedef TemporaryLocalMatrix< DomainSpaceType, RangeSpaceType > BaseType;
209
210 public:
211 typedef typename DomainSpaceType::BasisFunctionSetType DomainBasisFunctionSetType;
212 typedef typename RangeSpaceType::BasisFunctionSetType RangeBasisFunctionSetType;
213
214 typedef typename DomainBasisFunctionSetType::EntityType DomainEntityType;
215 typedef typename RangeBasisFunctionSetType::EntityType RangeEntityType;
216
217 typedef typename AssembledOperatorType::RangeFieldType value_type;
218
219 typedef typename BaseType :: MatrixEntriesType LocalMatrixEntriesType;
220 typedef typename LocalMatrixEntriesType::size_type SizeType;
221
222 typedef RowReferenceVector< value_type > row_reference;
223 typedef RowReferenceVector< const value_type > const_row_reference;
224
225 private:
226 template< class T, class... U >
227 struct InTypeRange
228 : public std::integral_constant< bool, Std::Or( std::is_same< T, U >::value... ) >
229 {};
230
231 template< class T >
232 struct IsRangeValue
233 : public InTypeRange< T, typename RangeBasisFunctionSetType::RangeType,
234 typename RangeBasisFunctionSetType::JacobianRangeType,
235 typename RangeBasisFunctionSetType::HessianRangeType >
236 {};
237
238 struct ColIndexMapper
239 {
240 ColIndexMapper ( SizeType j, SizeType cols ) : j_( j ), cols_( cols ) {}
241
242 SizeType operator[] ( SizeType i ) const { return (i*cols_ + j_); }
243
244 private:
245 SizeType j_, cols_;
246 };
247
248 protected:
249 using BaseType::mat_cols;
250
251 public:
252 using BaseType::domainBasisFunctionSet;
253 using BaseType::rangeBasisFunctionSet;
254
255 template< class... Args >
256 explicit LocalContribution ( AssembledOperator &assembledOperator, Args &&... args )
257 : BaseType( assembledOperator.domainSpace(), assembledOperator.rangeSpace() ),
258 assembledOperator_( assembledOperator ),
259 assemblyOperation_( std::forward< Args >( args )... )
260 {
261 assembledOperator.template beginAssemble< typename AssemblyOperationType::GlobalOperationType >();
262 }
263
264 LocalContribution ( const ThisType & ) = delete;
265 LocalContribution ( ThisType && ) = delete;
266
267 ~LocalContribution () { assembledOperator().template endAssemble< typename AssemblyOperationType::GlobalOperationType >(); }
268
269 ThisType &operator= ( const ThisType & ) = delete;
270 ThisType &operator= ( ThisType && ) = delete;
271
272 const AssembledOperatorType &assembledOperator () const { return assembledOperator_; }
273 AssembledOperatorType &assembledOperator () { return assembledOperator_; }
274
275 SubVector< LocalMatrixEntriesType, ColIndexMapper > column ( SizeType j )
276 {
277 return SubVector< LocalMatrixEntriesType, ColIndexMapper >( localMatrixEntries(), ColIndexMapper( j, mat_cols() ) );
278 }
279
280 SubVector< const LocalMatrixEntriesType, ColIndexMapper > column ( SizeType j ) const
281 {
282 return SubVector< const LocalMatrixEntriesType, ColIndexMapper >( localMatrixEntries(), ColIndexMapper( j, mat_cols() ) );
283 }
284
285 // this method behaves different to column
286 typename BaseType::MatrixColumnType matrixColumn( SizeType j )
287 {
288 return BaseType::column( j );
289 }
290
291 // inherited from DenseMatrix
292 using BaseType :: axpy;
293
294 template< class Point, class... Factors >
295 auto axpy ( const Point &x, const Factors &... factors )
296 -> std::enable_if_t< Std::And( (IsRangeValue< std::decay_t< decltype( std::declval< Factors & >()[ 0 ] ) > >::value)... ) >
297 {
298 const SizeType matCols = mat_cols();
299 for( SizeType j = 0; j < matCols; ++j )
300 {
301 auto col = column( j );
302 rangeBasisFunctionSet().axpy( x, factors[ j ]..., col );
303 }
304 }
305
317 int order () const { return domainBasisFunctionSet().order() + rangeBasisFunctionSet().order(); }
318
320 void bind ( const DomainEntityType &domainEntity, const RangeEntityType &rangeEntity )
321 {
322 BaseType::bind( domainEntity, rangeEntity );
323 assemblyOperation_.begin( domainEntity, rangeEntity, assembledOperator(), *this );
324 }
325
327 void unbind ()
328 {
329 assemblyOperation_.end( domainBasisFunctionSet().entity(), rangeBasisFunctionSet().entity(), *this, assembledOperator() );
330 BaseType::unbind();
331 }
332
334 const LocalMatrixEntriesType &localMatrixEntries () const { return fields_; }
336 LocalMatrixEntriesType &localMatrixEntries () { return fields_; }
337
338 protected:
339 using BaseType::fields_;
340 AssembledOperatorType &assembledOperator_;
341 AssemblyOperationType assemblyOperation_;
342 };
343
344 } // namespace Fem
345
346} // namespace Dune
347
348#endif // #ifndef DUNE_FEM_OPERATOR_COMMON_LOCALCONTRIBUTION_HH
abstract matrix operator
Definition: operator.hh:133
virtual void flushAssembly()
commit intermediate states of linear operator assembly
Definition: operator.hh:136
Implements a matrix constructed from a given type representing a field and a compile-time given numbe...
This file implements a dense vector with a dynamic size.
Dune namespace.
Definition: alignedallocator.hh:13
constexpr auto get(std::integer_sequence< T, II... >, std::integral_constant< std::size_t, pos >={})
Return the entry at position pos of the given sequence.
Definition: integersequence.hh:22
STL namespace.
RangeFunction::RangeFieldType RangeFieldType
field type of the operator's range
Definition: operator.hh:43
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)