DUNE PDELab (git)

assembler.hh
1// -*- tab-width: 2; indent-tabs-mode: nil -*-
2// vi: set et ts=2 sw=2 sts=2:
3#ifndef DUNE_PDELAB_GRIDOPERATOR_FASTDG_ASSEMBLER_HH
4#define DUNE_PDELAB_GRIDOPERATOR_FASTDG_ASSEMBLER_HH
5
7#include <dune/pdelab/gridoperator/common/assemblerutilities.hh>
8#include <dune/pdelab/gridfunctionspace/localfunctionspace.hh>
9#include <dune/pdelab/gridfunctionspace/lfsindexcache.hh>
10#include <dune/pdelab/common/geometrywrapper.hh>
11#include <dune/pdelab/common/intersectiontype.hh>
12
13namespace Dune{
14 namespace PDELab{
15
24 template<typename GFSU, typename GFSV, typename CU, typename CV, bool nonoverlapping_mode=false>
26 public:
27
30 using EntitySet = typename GFSU::Traits::EntitySet;
31 using Element = typename EntitySet::Element;
32 using Intersection = typename EntitySet::Intersection;
34
38 typedef GFSV TestGridFunctionSpace;
40
42 typedef typename GFSU::Traits::SizeType SizeType;
43
45 static const bool isGalerkinMethod = std::is_same<GFSU,GFSV>::value;
46
47 FastDGAssembler (const GFSU& gfsu_, const GFSV& gfsv_, const CU& cu_, const CV& cv_)
48 : gfsu(gfsu_)
49 , gfsv(gfsv_)
50 , cu(cu_)
51 , cv(cv_)
52 , lfsu(gfsu_)
53 , lfsv(gfsv_)
54 , lfsun(gfsu_)
55 , lfsvn(gfsv_)
56 { }
57
58 FastDGAssembler (const GFSU& gfsu_, const GFSV& gfsv_)
59 : gfsu(gfsu_)
60 , gfsv(gfsv_)
61 , cu()
62 , cv()
63 , lfsu(gfsu_)
64 , lfsv(gfsv_)
65 , lfsun(gfsu_)
66 , lfsvn(gfsv_)
67 { }
68
70 const GFSU& trialGridFunctionSpace() const
71 {
72 return gfsu;
73 }
74
76 const GFSV& testGridFunctionSpace() const
77 {
78 return gfsv;
79 }
80
81 // Assembler (const GFSU& gfsu_, const GFSV& gfsv_)
82 // : gfsu(gfsu_), gfsv(gfsv_), lfsu(gfsu_), lfsv(gfsv_),
83 // lfsun(gfsu_), lfsvn(gfsv_),
84 // sub_triangulation(ST(gfsu_.gridview(),Dune::PDELab::NoSubTriangulationImp()))
85 // { }
86
87 template<class LocalAssemblerEngine>
88 void assemble(LocalAssemblerEngine & assembler_engine) const
89 {
90 const bool fast = true;
91 typedef LFSIndexCache<LFSU,CU,fast> LFSUCache;
92
93 typedef LFSIndexCache<LFSV,CV,fast> LFSVCache;
94
95 const bool needs_constraints_caching = assembler_engine.needsConstraintsCaching(cu,cv);
96
97 LFSUCache lfsu_cache(lfsu,cu,needs_constraints_caching);
98 LFSVCache lfsv_cache(lfsv,cv,needs_constraints_caching);
99 LFSUCache lfsun_cache(lfsun,cu,needs_constraints_caching);
100 LFSVCache lfsvn_cache(lfsvn,cv,needs_constraints_caching);
101
102 // Notify assembler engine about oncoming assembly
103 assembler_engine.preAssembly();
104
105 // Extract integration requirements from the local assembler
106 const bool require_uv_skeleton = assembler_engine.requireUVSkeleton();
107 const bool require_v_skeleton = assembler_engine.requireVSkeleton();
108 const bool require_uv_boundary = assembler_engine.requireUVBoundary();
109 const bool require_v_boundary = assembler_engine.requireVBoundary();
110 const bool require_uv_processor = assembler_engine.requireUVBoundary();
111 const bool require_v_processor = assembler_engine.requireVBoundary();
112 const bool require_uv_post_skeleton = assembler_engine.requireUVVolumePostSkeleton();
113 const bool require_v_post_skeleton = assembler_engine.requireVVolumePostSkeleton();
114 const bool require_skeleton_two_sided = assembler_engine.requireSkeletonTwoSided();
115
116 auto entity_set = gfsu.entitySet();
117 auto& index_set = entity_set.indexSet();
118
119 // Traverse grid view
120 for (const auto& element : elements(entity_set,assembler_engine.partition()))
121 {
122 // Compute unique id
123 auto ids = index_set.uniqueIndex(element);
124
125 ElementGeometry<Element> eg(element);
126
127 if(assembler_engine.skipEntity(eg))
128 continue;
129
130 // Bind local test function space to element
131 lfsv.bind(element,std::integral_constant<bool,fast>{});
132 lfsv_cache.update();
133
134 // Notify assembler engine about bind
135 assembler_engine.onBindLFSV(eg,lfsv_cache);
136
137 // Volume integration
138 assembler_engine.assembleVVolume(eg,lfsv_cache);
139
140 // Bind local trial function space to element
141 lfsu.bind(element,std::integral_constant<bool,fast>{});
142 lfsu_cache.update();
143
144 // Notify assembler engine about bind
145 assembler_engine.onBindLFSUV(eg,lfsu_cache,lfsv_cache);
146
147 // Load coefficients of local functions
148 assembler_engine.loadCoefficientsLFSUInside(lfsu_cache);
149
150 // Volume integration
151 assembler_engine.assembleUVVolume(eg,lfsu_cache,lfsv_cache);
152
153 // Skip if no intersection iterator is needed
154 if (require_uv_skeleton || require_v_skeleton ||
155 require_uv_boundary || require_v_boundary ||
156 require_uv_processor || require_v_processor)
157 {
158 // Traverse intersections
159 unsigned int intersection_index = 0;
160 for(const auto& intersection : intersections(entity_set,element))
161 {
162
163 IntersectionGeometry<Intersection> ig(intersection,intersection_index);
164
165 if(assembler_engine.skipIntersection(ig))
166 continue;
167
168 auto intersection_data = classifyIntersection(entity_set,intersection);
169 auto intersection_type = std::get<0>(intersection_data);
170 auto& outside_element = std::get<1>(intersection_data);
171
172 switch (intersection_type)
173 {
174 case IntersectionType::skeleton:
175 // the specific ordering of the if-statements in the old code caused periodic
176 // boundary intersection to be handled the same as skeleton intersections
177 case IntersectionType::periodic:
178 if (require_uv_skeleton || require_v_skeleton)
179 {
180 // compute unique id for neighbor
181
182 auto idn = index_set.uniqueIndex(outside_element);
183
184 // Visit face if id is bigger
185 bool visit_face = ids > idn
186 or require_skeleton_two_sided
187 or (assembler_engine.partition() == Partitions::interiorBorder
188 and outside_element.partitionType() != InteriorEntity);
189
190 // unique vist of intersection
191 if (visit_face)
192 {
193 // Bind local test space to neighbor element
194 lfsvn.bind(outside_element,std::integral_constant<bool,fast>{});
195 lfsvn_cache.update();
196
197 // Notify assembler engine about binds
198 assembler_engine.onBindLFSVOutside(ig,lfsv_cache,lfsvn_cache);
199
200 // Skeleton integration
201 assembler_engine.assembleVSkeleton(ig,lfsv_cache,lfsvn_cache);
202
203 if(require_uv_skeleton){
204
205 // Bind local trial space to neighbor element
206 lfsun.bind(outside_element,std::integral_constant<bool,fast>{});
207 lfsun_cache.update();
208
209 // Notify assembler engine about binds
210 assembler_engine.onBindLFSUVOutside(ig,
211 lfsu_cache,lfsv_cache,
212 lfsun_cache,lfsvn_cache);
213
214 // Load coefficients of local functions
215 assembler_engine.loadCoefficientsLFSUOutside(lfsun_cache);
216
217 // Skeleton integration
218 assembler_engine.assembleUVSkeleton(ig,lfsu_cache,lfsv_cache,lfsun_cache,lfsvn_cache);
219
220 // Notify assembler engine about unbinds
221 assembler_engine.onUnbindLFSUVOutside(ig,
222 lfsu_cache,lfsv_cache,
223 lfsun_cache,lfsvn_cache);
224 }
225
226 // Notify assembler engine about unbinds
227 assembler_engine.onUnbindLFSVOutside(ig,lfsv_cache,lfsvn_cache);
228 }
229 }
230 break;
231
232 case IntersectionType::boundary:
233 if(require_uv_boundary || require_v_boundary )
234 {
235
236 // Boundary integration
237 assembler_engine.assembleVBoundary(ig,lfsv_cache);
238
239 if(require_uv_boundary){
240 // Boundary integration
241 assembler_engine.assembleUVBoundary(ig,lfsu_cache,lfsv_cache);
242 }
243 }
244 break;
245
246 case IntersectionType::processor:
247 if(require_uv_processor || require_v_processor )
248 {
249
250 // Processor integration
251 assembler_engine.assembleVProcessor(ig,lfsv_cache);
252
253 if(require_uv_processor){
254 // Processor integration
255 assembler_engine.assembleUVProcessor(ig,lfsu_cache,lfsv_cache);
256 }
257 }
258 break;
259 } // switch
260
261 ++intersection_index;
262 } // iit
263 } // do skeleton
264
265 if(require_uv_post_skeleton || require_v_post_skeleton){
266 // Volume integration
267 assembler_engine.assembleVVolumePostSkeleton(eg,lfsv_cache);
268
269 if(require_uv_post_skeleton){
270 // Volume integration
271 assembler_engine.assembleUVVolumePostSkeleton(eg,lfsu_cache,lfsv_cache);
272 }
273 }
274
275 // Notify assembler engine about unbinds
276 assembler_engine.onUnbindLFSUV(eg,lfsu_cache,lfsv_cache);
277
278 // Notify assembler engine about unbinds
279 assembler_engine.onUnbindLFSV(eg,lfsv_cache);
280
281 } // it
282
283 // Notify assembler engine that assembly is finished
284 assembler_engine.postAssembly(gfsu,gfsv);
285
286 }
287
288 private:
289
290 /* global function spaces */
291 const GFSU& gfsu;
292 const GFSV& gfsv;
293
294 typename std::conditional<
295 std::is_same<CU,EmptyTransformation>::value,
296 const CU,
297 const CU&
298 >::type cu;
299 typename std::conditional<
300 std::is_same<CV,EmptyTransformation>::value,
301 const CV,
302 const CV&
303 >::type cv;
304
305 /* local function spaces */
306 typedef LocalFunctionSpace<GFSU, TrialSpaceTag> LFSU;
307 typedef LocalFunctionSpace<GFSV, TestSpaceTag> LFSV;
308 // local function spaces in local cell
309 mutable LFSU lfsu;
310 mutable LFSV lfsv;
311 // local function spaces in neighbor
312 mutable LFSU lfsun;
313 mutable LFSV lfsvn;
314
315 }; // end class FastDGAssembler
316 } // end namespace PDELab
317} // end namespace Dune
318#endif
Wrap element.
Definition: geometrywrapper.hh:16
The fast DG assembler for standard DUNE grid.
Definition: assembler.hh:25
GFSU::Traits::SizeType SizeType
Size type as used in grid function space.
Definition: assembler.hh:42
typename GFSU::Traits::EntitySet EntitySet
Definition: assembler.hh:30
const GFSV & testGridFunctionSpace() const
Get the test grid function space.
Definition: assembler.hh:76
const GFSU & trialGridFunctionSpace() const
Get the trial grid function space.
Definition: assembler.hh:70
GFSU TrialGridFunctionSpace
Definition: assembler.hh:37
static const bool isGalerkinMethod
Static check on whether this is a Galerkin method.
Definition: assembler.hh:45
The local assembler engine which handles the integration parts as provided by the global assemblers.
Definition: assembler.hh:34
void assembleUVVolume(const EG &eg, const LFSU &lfsu, const LFSV &lfsv)
void assembleVSkeleton(const IG &ig, const LFSV_S &lfsv_s, const LFSV_N &lfsv_n)
void assembleUVProcessor(const IG &ig, const LFSU_S &lfsu_s, const LFSV_S &lfsv_s)
bool skipIntersection(const IG &ig)
void assembleUVSkeleton(const IG &ig, const LFSU_S &lfsu_s, const LFSV_S &lfsv_s, const LFSU_N &lfsu_n, const LFSV_N &lfsv_n)
void assembleVProcessor(const IG &ig, const LFSV_S &lfsv_s)
void preAssembly()
Called directly before assembling.
void assembleVVolumePostSkeleton(const EG &eg, const LFSV &lfsv)
void assembleUVVolumePostSkeleton(const EG &eg, const LFSU &lfsu, const LFSV &lfsv)
void assembleVBoundary(const IG &ig, const LFSV_S &lfsv_s)
void assembleVVolume(const EG &eg, const LFSV &lfsv)
void postAssembly()
Called last thing after assembling.
void assembleUVBoundary(const IG &ig, const LFSU_S &lfsu_s, const LFSV_S &lfsv_s)
Traits for type conversions and type information.
@ InteriorEntity
all interior entities
Definition: gridenums.hh:31
constexpr InteriorBorder interiorBorder
PartitionSet for the interior and border partitions.
Definition: partitionset.hh:286
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)