DUNE-FEM (unstable)

localcontribution.hh
1#ifndef DUNE_FEM_FUNCTION_COMMON_LOCALCONTRIBUTION_HH
2#define DUNE_FEM_FUNCTION_COMMON_LOCALCONTRIBUTION_HH
3
4#include <algorithm>
5#include <type_traits>
6#include <utility>
7#include <vector>
8
11
12#include <dune/fem/common/hybrid.hh>
13#include <dune/fem/common/localcontribution.hh>
14#include <dune/fem/space/common/commoperations.hh>
15#include <dune/fem/function/localfunction/temporary.hh>
16
17namespace Dune
18{
19
20 namespace Fem
21 {
22
23 // External Forward Declarations
24 // -----------------------------
25
26 template< class >
27 struct DiscreteFunctionTraits;
28
29 class IsDiscreteFunction;
30
31
32
33 namespace Assembly
34 {
35
36 namespace Global
37 {
38
39 // AddBase
40 // -------
41
42 template< class DiscreteFunction >
43 struct AddBase< DiscreteFunction, std::enable_if_t< std::is_base_of< Fem::IsDiscreteFunction, DiscreteFunction >::value > >
44 {
45 typedef typename DiscreteFunction::DofType DofType;
46
47 static void begin ( DiscreteFunction &df )
48 {
49 typedef typename DiscreteFunction::DiscreteFunctionSpaceType::LocalBlockIndices LocalBlockIndices;
50
51 // clear auxiliary DoFs
52 auto &dofVector = df.dofVector();
53 for( const auto &auxiliaryDof : df.space().auxiliaryDofs() )
54 Hybrid::forEach( LocalBlockIndices(), [ &dofVector, &auxiliaryDof ] ( auto &&j ) { dofVector[ auxiliaryDof ][ j ] = DofType( 0 ); } );
55 }
56
57 static void end ( DiscreteFunction &df, const bool communicate )
58 {
59 if ( communicate )
60 {
61 df.space().communicate( df, DFCommunicationOperation::Add() );
62 }
63 }
64 };
65
66
67
68 // SetBase
69 // -------
70
71 template< class DiscreteFunction >
72 struct SetBase< DiscreteFunction, std::enable_if_t< std::is_base_of< Fem::IsDiscreteFunction, DiscreteFunction >::value > >
73 {
74 static void begin ( DiscreteFunction &df ) {}
75 static void end ( DiscreteFunction &df, const bool communicate )
76 {
77 if ( communicate )
78 {
79 df.space().communicate( df, DFCommunicationOperation::Copy() );
80 }
81 }
82 };
83
84 } // namespace Global
85
86
87
88 // AddBase
89 // -------
90
91 template< class DiscreteFunction >
92 struct AddBase< DiscreteFunction, std::enable_if_t< std::is_base_of< Fem::IsDiscreteFunction, DiscreteFunction >::value > >
93 {
94 typedef typename DiscreteFunction::DofType DofType;
95
96 typedef Global::Add< DiscreteFunction > GlobalOperationType;
97
98 template< class Entity, class LocalDofVector >
99 void begin ( const Entity &entity, const DiscreteFunction &df, LocalDofVector &localDofVector ) const
100 {
101 std::fill( localDofVector.begin(), localDofVector.end(), DofType( 0 ) );
102 }
103
104 template< class Entity, class LocalDofVector >
105 void end ( const Entity &entity, LocalDofVector &localDofVector, DiscreteFunction &df ) const
106 {
107 df.addLocalDofs( entity, localDofVector );
108 }
109 };
110
111
112
113 // AddScaledBase
114 // -------------
115
116 template< class DiscreteFunction >
117 struct AddScaledBase< DiscreteFunction, std::enable_if_t< std::is_base_of< Fem::IsDiscreteFunction, DiscreteFunction >::value > >
118 : public AddBase< DiscreteFunction >
119 {
120 AddScaledBase ( typename DiscreteFunction::DofType factor ) : factor_( std::move( factor ) ) {}
121
122 template< class Entity, class LocalDofVector >
123 void end ( const Entity &entity, LocalDofVector &localDofVector, DiscreteFunction &df ) const
124 {
125 df.addScaledLocalDofs( entity, factor_, localDofVector );
126 }
127
128 private:
129 typename DiscreteFunction::DofType factor_;
130 };
131
132
133 namespace detail
134 {
135
136 template< class DiscreteFunction, const bool getAndSet >
137 struct SetAndSelectDFImpl
138 {
139 typedef typename DiscreteFunction::DofType DofType;
140
141 typedef Global::Set< DiscreteFunction > GlobalOperationType;
142
143 template< class Entity, class LocalDofVector >
144 void begin ( const Entity &entity, const DiscreteFunction &df, LocalDofVector &localDofVector ) const
145 {
146 if constexpr ( getAndSet )
147 {
148 // obtain local dofs
149 df.getLocalDofs ( entity, localDofVector );
150 }
151 else
152 {
153 // reset all dofs
154 std::fill( localDofVector.begin(), localDofVector.end(), DofType( 0 ) );
155 }
156 }
157
158 template< class Entity, class LocalDofVector >
159 void end ( const Entity &entity, LocalDofVector &localDofVector, DiscreteFunction &df ) const
160 {
161 df.setLocalDofs( entity, localDofVector );
162 }
163 };
164 }
165
166
167 // SetBase
168 // -------
169
170 template< class DiscreteFunction >
171 struct SetBase< DiscreteFunction, std::enable_if_t< std::is_base_of< Fem::IsDiscreteFunction, DiscreteFunction >::value > >
172 : public detail::SetAndSelectDFImpl< DiscreteFunction, false >
173 {};
174
175 // SetSelectedBase
176 // ---------------
177
178 template< class DiscreteFunction >
179 struct SetSelectedBase< DiscreteFunction, std::enable_if_t< std::is_base_of< Fem::IsDiscreteFunction, DiscreteFunction >::value > >
180 : public detail::SetAndSelectDFImpl< DiscreteFunction, true >
181 {};
182
183 } // namespace Assembly
184 }
185
186 // consistency with Dune::DenseVector and DenseMatrix
187 template< class DiscreteFunction, template< class > class AssemblyOperation >
188 struct FieldTraits< Fem::LocalContribution< DiscreteFunction, AssemblyOperation, std::enable_if_t< std::is_base_of< Fem::IsDiscreteFunction, DiscreteFunction >::value > > >
189 : public FieldTraits< typename DiscreteFunction::DofType >
190 {
191 };
192
193
194 namespace Fem
195 {
196
197 // LocalContribution for Discrete Functions
198 // ----------------------------------------
199
200 template< class DiscreteFunction, template< class > class AssemblyOperation >
201 class LocalContribution< DiscreteFunction, AssemblyOperation, std::enable_if_t< std::is_base_of< Fem::IsDiscreteFunction, DiscreteFunction >::value > >
202 : public TemporaryLocalFunction< typename DiscreteFunction::DiscreteFunctionSpaceType >
203 {
204 typedef typename DiscreteFunction::DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
205 typedef LocalContribution< DiscreteFunction, AssemblyOperation > ThisType;
207
208 public:
209 typedef DiscreteFunction DiscreteFunctionType;
210 typedef AssemblyOperation< typename DiscreteFunctionTraits< DiscreteFunctionType >::DiscreteFunctionType > AssemblyOperationType;
211
212 typedef typename DiscreteFunctionType::DiscreteFunctionSpaceType::BasisFunctionSetType BasisFunctionSetType;
213 typedef typename DiscreteFunctionType::DofType DofType;
214
215 typedef typename DiscreteFunctionType::RangeType RangeType;
216 typedef typename RangeType::field_type RangeFieldType;
217 typedef typename DiscreteFunctionType::JacobianRangeType JacobianRangeType;
218
219 typedef typename BaseType :: LocalDofVectorType LocalDofVectorType;
220 typedef typename LocalDofVectorType::size_type SizeType;
221
222 typedef typename BasisFunctionSetType::EntityType EntityType;
223
224 using BaseType::entity;
225 using BaseType::localDofVector;
226 using BaseType::axpy;
227
228 template< class... Args >
229 explicit LocalContribution ( DiscreteFunctionType &discreteFunction, const bool communicate, Args &&... args )
230 : BaseType( discreteFunction.space() ),
231 discreteFunction_( discreteFunction ),
232 assemblyOperation_( std::forward< Args >( args )... ),
233 communicate_( communicate ),
234 bound_( false )
235 {
236 discreteFunction.template beginAssemble< typename AssemblyOperationType::GlobalOperationType >();
237 }
238
239 template< class... Args >
240 explicit LocalContribution ( DiscreteFunctionType &discreteFunction, Args &&... args )
241 : LocalContribution( discreteFunction, /* communicate */ true, args... )
242 {}
243
244 LocalContribution ( const ThisType & ) = delete;
245 LocalContribution ( ThisType && ) = delete;
246
247 ~LocalContribution () { discreteFunction().template endAssemble< typename AssemblyOperationType::GlobalOperationType >( communicate_ ); }
248
249 ThisType &operator= ( const ThisType & ) = delete;
250 ThisType &operator= ( ThisType && ) = delete;
251
252 const DiscreteFunctionType& discreteFunction () const { return discreteFunction_; }
253 DiscreteFunctionType& discreteFunction () { return discreteFunction_; }
254
255 void bind ( const EntityType &entity )
256 {
257 BaseType::bind( entity );
258 bound_ = true;
259 assemblyOperation_.begin( entity, discreteFunction(), localDofVector() );
260 }
261
262 void unbind ()
263 {
264 if (bound_)
265 {
266 // write back dofs to discrete function
267 assemblyOperation_.end( entity(), localDofVector(), discreteFunction() );
268 // unbind local contribution
269 BaseType::unbind();
270 }
271 }
272
273 protected:
274 // LocalContribution is not a LocalFunction,
275 // thus disable evaluate,jacobian and hessian methods
276 using BaseType::evaluate;
277 using BaseType::evaluateQuadrature;
278 using BaseType::jacobian;
279 using BaseType::hessian;
280
281 protected:
282 DiscreteFunctionType& discreteFunction_;
283 AssemblyOperationType assemblyOperation_;
284 const bool communicate_;
285 bool bound_;
286 };
287
288 } // namespace Fem
289
290} // namespace Dune
291
292#endif // #ifndef DUNE_FEM_FUNCTION_COMMON_LOCALCONTRIBUTION_HH
DiscreteFunctionSpaceType::RangeType RangeType
type of range vector
Definition: discretefunction.hh:614
DiscreteFunctionSpaceType::JacobianRangeType JacobianRangeType
type of jacobian
Definition: discretefunction.hh:616
forward declaration
Definition: discretefunction.hh:51
Implements the dense vector interface, with an exchangeable storage class.
Type traits to determine the type of reals (when working with complex numbers)
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:256
Dune namespace.
Definition: alignedallocator.hh:13
STL namespace.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 13, 23:29, 2024)