DUNE PDELab (git)

callswitch.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_PDELAB_LOCALOPERATOR_CALLSWITCH_HH
4#define DUNE_PDELAB_LOCALOPERATOR_CALLSWITCH_HH
5
8
9namespace Dune {
10 namespace PDELab {
11
12 namespace Impl {
13
14
15#ifndef DOXYGEN
16
17 // ********************************************************************************
18 // concept checks that test whether a local operator provides a given apply method
19 // these are used to emit better error messages for the two variants of
20 // apply methods
21 // ********************************************************************************
22
23 template<typename... Args>
24 struct HasSkipEntity
25 {
26 template<typename LO>
27 auto require(LO&& lo) -> decltype(
28 Concept::requireConvertible<bool>(lo.skip_entity(std::declval<Args>()...))
29 );
30 };
31
32 template<typename... Args>
33 struct HasSkipIntersection
34 {
35 template<typename LO>
36 auto require(LO&& lo) -> decltype(
37 Concept::requireConvertible<bool>(lo.skip_intersection(std::declval<Args>()...))
38 );
39 };
40
41#endif // DOXYGEN
42
43
46 // compile time switching of function call
47 template<typename LOP, bool doIt, bool isLinear = LOP::isLinear>
48 struct LocalAssemblerCallSwitchHelper
49 {
50 //================
51 // Selective assembly methods
52 //================
53 template<typename EG>
54 static bool skip_entity (const LOP& lop, const EG& eg)
55 {
56 return false;
57 }
58
59 template<typename IG>
60 static bool skip_intersection (const LOP& lop, const IG& ig)
61 {
62 return false;
63 }
64
65 //================
66 // Pattern methods
67 //================
68 template<typename LFSU, typename LFSV, typename LocalPattern>
69 static void pattern_volume (const LOP& lop, const LFSU& lfsu, const LFSV& lfsv, LocalPattern& pattern)
70 {
71 }
72 template<typename LFSU, typename LFSV, typename LocalPattern>
73 static void pattern_volume_post_skeleton
74 ( const LOP& lop,
75 const LFSU& lfsu, const LFSV& lfsv,
76 LocalPattern& pattern)
77 {
78 }
79 template<typename LFSU, typename LFSV, typename LocalPattern>
80 static void pattern_skeleton (const LOP& lop, const LFSU& lfsu_s, const LFSV& lfsv_s,
81 const LFSU& lfsu_n, const LFSV& lfsv_n,
82 LocalPattern& pattern_sn,
83 LocalPattern& pattern_ns)
84 {
85 }
86 template<typename LFSU, typename LFSV, typename LocalPattern>
87 static void pattern_boundary(const LOP& lop,
88 const LFSU& lfsu_s, const LFSV& lfsv_s,
89 LocalPattern& pattern_ss)
90 {
91 }
92
93 //==============
94 // Alpha methods
95 //==============
96 template<typename EG, typename LFSU, typename X, typename LFSV, typename R>
97 static void alpha_volume (const LOP& lop, const EG& eg, const LFSU& lfsu, const X& x, const LFSV& lfsv, R& r)
98 {
99 }
100 template<typename EG, typename LFSU, typename X, typename LFSV, typename R>
101 static void alpha_volume_post_skeleton (const LOP& lop, const EG& eg, const LFSU& lfsu, const X& x, const LFSV& lfsv, R& r)
102 {
103 }
104 template<typename IG, typename LFSU, typename X, typename LFSV, typename R>
105 static void alpha_skeleton (const LOP& lop, const IG& ig,
106 const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
107 const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
108 R& r_s, R& r_n)
109 {
110 }
111 template<typename IG, typename LFSU, typename X, typename LFSV, typename R>
112 static void alpha_boundary (const LOP& lop, const IG& ig,
113 const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
114 R& r_s)
115 {
116 }
117
118 //===============
119 // Lambda methods
120 //===============
121 template<typename EG, typename LFSV, typename R>
122 static void lambda_volume (const LOP& lop, const EG& eg, const LFSV& lfsv, R& r)
123 {
124 }
125 template<typename EG, typename LFSV, typename R>
126 static void lambda_volume_post_skeleton (const LOP& lop, const EG& eg, const LFSV& lfsv, R& r)
127 {
128 }
129 template<typename IG, typename LFSV, typename R>
130 static void lambda_skeleton(const LOP& lop, const IG& ig,
131 const LFSV& lfsv_s, const LFSV& lfsv_n,
132 R& r_s, R& r_n)
133 {
134 }
135 template<typename IG, typename LFSV, typename R>
136 static void lambda_boundary (const LOP& lop, const IG& ig, const LFSV& lfsv, R& r)
137 {
138 }
139
140 //=======================
141 // Jacobian apply methods
142 //=======================
143 template<typename EG, typename LFSU, typename X, typename Z, typename LFSV, typename Y>
144 static void jacobian_apply_volume (const LOP& lop, const EG& eg, const LFSU& lfsu, const X& x, const Z& z, const LFSV& lfsv, Y& y)
145 {
146 }
147 template<typename EG, typename LFSU, typename X, typename Z, typename LFSV, typename Y>
148 static void jacobian_apply_volume_post_skeleton (const LOP& lop, const EG& eg, const LFSU& lfsu, const X& x, const Z& z, const LFSV& lfsv, Y& y)
149 {
150 }
151 template<typename IG, typename LFSU, typename X, typename Z, typename LFSV, typename Y>
152 static void jacobian_apply_skeleton (const LOP& lop, const IG& ig,
153 const LFSU& lfsu_s, const X& x_s, const Z& z_s, const LFSV& lfsv_s,
154 const LFSU& lfsu_n, const X& x_n, const Z& z_n, const LFSV& lfsv_n,
155 Y& y_s, Y& y_n)
156 {
157 }
158 template<typename IG, typename LFSU, typename X, typename Z, typename LFSV, typename Y>
159 static void jacobian_apply_boundary (const LOP& lop, const IG& ig,
160 const LFSU& lfsu_s, const X& x_s, const Z& z_s, const LFSV& lfsv_s,
161 Y& y_s)
162 {
163 }
164
165 //=================
166 // Jacobian methods
167 //=================
168 template<typename EG, typename LFSU, typename X, typename LFSV, typename M>
169 static void jacobian_volume (const LOP& lop, const EG& eg, const LFSU& lfsu, const X& x, const LFSV& lfsv, M & mat)
170 {
171 }
172 template<typename EG, typename LFSU, typename X, typename LFSV, typename M>
173 static void jacobian_volume_post_skeleton (const LOP& lop, const EG& eg, const LFSU& lfsu, const X& x, const LFSV& lfsv, M& mat)
174 {
175 }
176 template<typename IG, typename LFSU, typename X, typename LFSV, typename M>
177 static void jacobian_skeleton (const LOP& lop, const IG& ig,
178 const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
179 const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
180 M & mat_ss, M & mat_sn,
181 M & mat_ns, M & mat_nn)
182 {
183 }
184 template<typename IG, typename LFSU, typename X, typename LFSV, typename M>
185 static void jacobian_boundary (const LOP& lop, const IG& ig,
186 const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
187 M & mat_ss)
188 {
189 }
190 };
191
192
193 template<typename LOP>
194 struct LocalAssemblerCallSwitchHelper<LOP,true,true>
195 {
196
197 //================
198 // Selective assembly methods
199 //================
200 template<typename EG>
201 static bool skip_entity (const LOP& lop, const EG& eg)
202 {
203 static_assert(models<Impl::HasSkipEntity<EG>,LOP>());
204 return lop.skip_entity(eg);
205 }
206
207 template<typename IG>
208 static bool skip_intersection (const LOP& lop, const IG& ig)
209 {
210 static_assert(models<Impl::HasSkipIntersection<IG>,LOP>());
211 return lop.skip_intersection(ig);
212 }
213
214 //================
215 // Pattern methods
216 //================
217 template<typename LFSU, typename LFSV, typename LocalPattern>
218 static void pattern_volume (const LOP& lop, const LFSU& lfsu, const LFSV& lfsv, LocalPattern& pattern)
219 {
220 lop.pattern_volume(lfsu,lfsv,pattern);
221 }
222 template<typename LFSU, typename LFSV, typename LocalPattern>
223 static void pattern_volume_post_skeleton
224 ( const LOP& lop,
225 const LFSU& lfsu, const LFSV& lfsv,
226 LocalPattern& pattern)
227 {
228 lop.pattern_volume_post_skeleton(lfsu,lfsv,pattern);
229 }
230 template<typename LFSU, typename LFSV, typename LocalPattern>
231 static void pattern_skeleton (const LOP& lop, const LFSU& lfsu_s, const LFSV& lfsv_s,
232 const LFSU& lfsu_n, const LFSV& lfsv_n,
233 LocalPattern& pattern_sn,
234 LocalPattern& pattern_ns)
235 {
236 lop.pattern_skeleton(lfsu_s,lfsv_s,lfsu_n,lfsv_n,
237 pattern_sn, pattern_ns);
238 }
239 template<typename LFSU, typename LFSV, typename LocalPattern>
240 static void pattern_boundary(const LOP& lop,
241 const LFSU& lfsu_s, const LFSV& lfsv_s,
242 LocalPattern& pattern_ss)
243 {
244 lop.pattern_boundary(lfsu_s,lfsv_s,pattern_ss);
245 }
246
247 //==============
248 // Alpha methods
249 //==============
250 template<typename EG, typename LFSU, typename X, typename LFSV, typename R>
251 static void alpha_volume (const LOP& lop, const EG& eg, const LFSU& lfsu, const X& x, const LFSV& lfsv, R& r)
252 {
253 lop.alpha_volume(eg,lfsu,x,lfsv,r);
254 }
255 template<typename EG, typename LFSU, typename X, typename LFSV, typename R>
256 static void alpha_volume_post_skeleton (const LOP& lop, const EG& eg, const LFSU& lfsu, const X& x, const LFSV& lfsv, R& r)
257 {
258 lop.alpha_volume_post_skeleton(eg,lfsu,x,lfsv,r);
259 }
260 template<typename IG, typename LFSU, typename X, typename LFSV, typename R>
261 static void alpha_skeleton (const LOP& lop, const IG& ig,
262 const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
263 const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
264 R& r_s, R& r_n)
265 {
266 lop.alpha_skeleton(ig,lfsu_s,x_s,lfsv_s,lfsu_n,x_n,lfsv_n,r_s,r_n);
267 }
268 template<typename IG, typename LFSU, typename X, typename LFSV, typename R>
269 static void alpha_boundary (const LOP& lop, const IG& ig,
270 const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
271 R& r_s)
272 {
273 lop.alpha_boundary(ig,lfsu_s,x_s,lfsv_s,r_s);
274 }
275
276 //===============
277 // Lambda methods
278 //===============
279 template<typename EG, typename LFSV, typename R>
280 static void lambda_volume (const LOP& lop, const EG& eg, const LFSV& lfsv, R& r)
281 {
282 lop.lambda_volume(eg,lfsv,r);
283 }
284 template<typename EG, typename LFSV, typename R>
285 static void lambda_volume_post_skeleton (const LOP& lop, const EG& eg, const LFSV& lfsv, R& r)
286 {
287 lop.lambda_volume_post_skeleton(eg,lfsv,r);
288 }
289 template<typename IG, typename LFSV, typename R>
290 static void lambda_skeleton(const LOP& lop, const IG& ig,
291 const LFSV& lfsv_s, const LFSV& lfsv_n,
292 R& r_s, R& r_n)
293 {
294 lop.lambda_skeleton(ig, lfsv_s, lfsv_n, r_s, r_n);
295 }
296 template<typename IG, typename LFSV, typename R>
297 static void lambda_boundary (const LOP& lop, const IG& ig, const LFSV& lfsv, R& r)
298 {
299 lop.lambda_boundary(ig,lfsv,r);
300 }
301
302 //=======================
303 // Jacobian apply methods
304 //=======================
305 template<typename EG, typename LFSU, typename X, typename Z, typename LFSV, typename Y>
306 static auto jacobian_apply_volume (const LOP& lop, const EG& eg, const LFSU& lfsu, const X& x, const Z& z, const LFSV& lfsv, Y& y)
307 {
308 lop.jacobian_apply_volume(eg,lfsu,z,lfsv,y);
309 }
310 template<typename EG, typename LFSU, typename X, typename Z, typename LFSV, typename Y>
311 static void jacobian_apply_volume_post_skeleton (const LOP& lop, const EG& eg, const LFSU& lfsu, const X& x, const Z& z, const LFSV& lfsv, Y& y)
312 {
313 lop.jacobian_apply_volume_post_skeleton(eg,lfsu,z,lfsv,y);
314 }
315 template<typename IG, typename LFSU, typename X, typename Z, typename LFSV, typename Y>
316 static void jacobian_apply_skeleton (const LOP& lop, const IG& ig,
317 const LFSU& lfsu_s, const X& x_s, const Z& z_s, const LFSV& lfsv_s,
318 const LFSU& lfsu_n, const X& x_n, const Z& z_n, const LFSV& lfsv_n,
319 Y& y_s, Y& y_n)
320 {
321 lop.jacobian_apply_skeleton(ig,lfsu_s,z_s,lfsv_s,lfsu_n,z_n,lfsv_n,y_s,y_n);
322 }
323 template<typename IG, typename LFSU, typename X, typename Z, typename LFSV, typename Y>
324 static void jacobian_apply_boundary (const LOP& lop, const IG& ig,
325 const LFSU& lfsu_s, const X& x_s, const Z& z_s, const LFSV& lfsv_s,
326 Y& y_s)
327 {
328 lop.jacobian_apply_boundary(ig,lfsu_s,z_s,lfsv_s,y_s);
329 }
330
331 //=================
332 // Jacobian methods
333 //=================
334 template<typename EG, typename LFSU, typename X, typename LFSV, typename M>
335 static void jacobian_volume (const LOP& lop, const EG& eg, const LFSU& lfsu, const X& x, const LFSV& lfsv, M & mat)
336 {
337 lop.jacobian_volume(eg,lfsu,x,lfsv,mat);
338 }
339 template<typename EG, typename LFSU, typename X, typename LFSV, typename M>
340 static void jacobian_volume_post_skeleton (const LOP& lop, const EG& eg, const LFSU& lfsu, const X& x, const LFSV& lfsv, M & mat)
341 {
342 lop.jacobian_volume_post_skeleton(eg,lfsu,x,lfsv,mat);
343 }
344 template<typename IG, typename LFSU, typename X, typename LFSV, typename M>
345 static void jacobian_skeleton (const LOP& lop, const IG& ig,
346 const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
347 const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
348 M & mat_ss, M & mat_sn,
349 M & mat_ns, M & mat_nn)
350 {
351 lop.jacobian_skeleton(ig,lfsu_s,x_s,lfsv_s,lfsu_n,x_n,lfsv_n,
352 mat_ss, mat_sn, mat_ns, mat_nn);
353 }
354 template<typename IG, typename LFSU, typename X, typename LFSV, typename M>
355 static void jacobian_boundary (const LOP& lop, const IG& ig,
356 const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
357 M & mat_ss)
358 {
359 lop.jacobian_boundary(ig,lfsu_s,x_s,lfsv_s,mat_ss);
360 }
361 };
362
368 template<typename LOP>
369 struct LocalAssemblerCallSwitchHelper<LOP,true,false> :
370 public LocalAssemblerCallSwitchHelper<LOP,true,true>
371 {
372 //=======================
373 // Jacobian apply methods
374 //=======================
375 template<typename EG, typename LFSU, typename X, typename Z, typename LFSV, typename Y>
376 static auto jacobian_apply_volume (const LOP& lop, const EG& eg, const LFSU& lfsu, const X& x, const Z& z, const LFSV& lfsv, Y& y)
377 {
378 lop.jacobian_apply_volume(eg,lfsu,x,z,lfsv,y);
379 }
380 template<typename EG, typename LFSU, typename X, typename Z, typename LFSV, typename Y>
381 static void jacobian_apply_volume_post_skeleton (const LOP& lop, const EG& eg, const LFSU& lfsu, const X& x, const Z& z, const LFSV& lfsv, Y& y)
382 {
383 lop.jacobian_apply_volume_post_skeleton(eg,lfsu,x,z,lfsv,y);
384 }
385 template<typename IG, typename LFSU, typename X, typename Z, typename LFSV, typename Y>
386 static void jacobian_apply_skeleton (const LOP& lop, const IG& ig,
387 const LFSU& lfsu_s, const X& x_s, const Z& z_s, const LFSV& lfsv_s,
388 const LFSU& lfsu_n, const X& x_n, const Z& z_n, const LFSV& lfsv_n,
389 Y& y_s, Y& y_n)
390 {
391 lop.jacobian_apply_skeleton(ig,lfsu_s,x_s,z_s,lfsv_s,lfsu_n,x_n,z_n,lfsv_n,y_s,y_n);
392 }
393 template<typename IG, typename LFSU, typename X, typename Z, typename LFSV, typename Y>
394 static void jacobian_apply_boundary (const LOP& lop, const IG& ig,
395 const LFSU& lfsu_s, const X& x_s, const Z& z_s, const LFSV& lfsv_s,
396 Y& y_s)
397 {
398 lop.jacobian_apply_boundary(ig,lfsu_s,x_s,z_s,lfsv_s,y_s);
399 }
400 };
401
402 } // namespace Impl
403
405 template<typename LOP, bool doIt>
406 using LocalAssemblerCallSwitch =
407 Impl::LocalAssemblerCallSwitchHelper<LOP,doIt>;
408
409 /* we use a nested empty namespace to allow for multiple symbols and avoid issues with the ODR */
410 namespace LocalOperatorApply { namespace {
411
412 auto skipEntity = [](const auto& lop, auto&... args)
413 {
414 using LOP = std::decay_t<decltype(lop)>;
415 return Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doSkipEntity>::
416 skip_entity(lop, args...);
417 };
418
419 auto skipIntersection = [](const auto& lop, auto&... args)
420 {
421 using LOP = std::decay_t<decltype(lop)>;
422 return Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doSkipIntersection>::
423 skip_intersection(lop, args...);
424 };
425
426 auto patternVolume = [](const auto& lop, auto&... args)
427 {
428 using LOP = std::decay_t<decltype(lop)>;
429 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doPatternVolume>::
430 pattern_volume(lop, args...);
431 };
432
433 auto patternVolumePostSkeleton = [](const auto& lop, auto&... args)
434 {
435 using LOP = std::decay_t<decltype(lop)>;
436 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doPatternVolumePostSkeleton>::
437 pattern_volume_post_skeleton(lop, args...);
438 };
439
440 auto patternSkeleton = [](const auto& lop, auto&... args)
441 {
442 using LOP = std::decay_t<decltype(lop)>;
443 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doPatternSkeleton>::
444 pattern_skeleton(lop, args...);
445 };
446
447 auto patternBoundary = [](const auto& lop, auto&... args)
448 {
449 using LOP = std::decay_t<decltype(lop)>;
450 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doPatternBoundary>::
451 pattern_boundary(lop, args...);
452 };
453
455 auto alphaVolume = [](const auto& lop, auto&... args)
456 {
457 using LOP = std::decay_t<decltype(lop)>;
458 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doAlphaVolume>::
459 alpha_volume(lop, args...);
460 };
461
462 auto alphaVolumePostSkeleton = [](const auto& lop, auto&... args)
463 {
464 using LOP = std::decay_t<decltype(lop)>;
465 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doAlphaVolumePostSkeleton>::
466 alpha_volume_post_skeleton(lop, args...);
467 };
468
469 auto alphaSkeleton = [](const auto& lop, auto&... args)
470 {
471 using LOP = std::decay_t<decltype(lop)>;
472 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doAlphaSkeleton>::
473 alpha_skeleton(lop, args...);
474 };
475
476 auto alphaBoundary = [](const auto& lop, auto&... args)
477 {
478 using LOP = std::decay_t<decltype(lop)>;
479 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doAlphaBoundary>::
480 alpha_boundary(lop, args...);
481 };
482
483
485 auto lambdaVolume = [](const auto& lop, auto&... args)
486 {
487 using LOP = std::decay_t<decltype(lop)>;
488 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doLambdaVolume>::
489 lambda_volume(lop, args...);
490 };
491
492 auto lambdaVolumePostSkeleton = [](const auto& lop, auto&... args)
493 {
494 using LOP = std::decay_t<decltype(lop)>;
495 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doLambdaVolumePostSkeleton>::
496 lambda_volume_post_skeleton(lop, args...);
497 };
498
499 auto lambdaSkeleton = [](const auto& lop, auto&... args)
500 {
501 using LOP = std::decay_t<decltype(lop)>;
502 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doLambdaSkeleton>::
503 lambda_skeleton(lop, args...);
504 };
505
506 auto lambdaBoundary = [](const auto& lop, auto&... args)
507 {
508 using LOP = std::decay_t<decltype(lop)>;
509 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doLambdaBoundary>::
510 lambda_boundary(lop, args...);
511 };
512
513
515 auto jacobianVolume = [](const auto& lop, auto&... args)
516 {
517 using LOP = std::decay_t<decltype(lop)>;
518 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doAlphaVolume>::
519 jacobian_volume(lop, args...);
520 };
521
522 auto jacobianVolumePostSkeleton = [](const auto& lop, auto&... args)
523 {
524 using LOP = std::decay_t<decltype(lop)>;
525 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doAlphaVolumePostSkeleton>::
526 jacobian_volume_post_skeleton(lop, args...);
527 };
528
529 auto jacobianSkeleton = [](const auto& lop, auto&... args)
530 {
531 using LOP = std::decay_t<decltype(lop)>;
532 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doAlphaSkeleton>::
533 jacobian_skeleton(lop, args...);
534 };
535
536 auto jacobianBoundary = [](const auto& lop, auto&... args)
537 {
538 using LOP = std::decay_t<decltype(lop)>;
539 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doAlphaBoundary>::
540 jacobian_boundary(lop, args...);
541 };
542
543
545 auto jacobianApplyVolume = [](const auto& lop, auto&... args)
546 {
547 using LOP = std::decay_t<decltype(lop)>;
548 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doAlphaVolume>::
549 jacobian_apply_volume(lop, args...);
550 };
551
552 auto jacobianApplyVolumePostSkeleton = [](const auto& lop, auto&... args)
553 {
554 using LOP = std::decay_t<decltype(lop)>;
555 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doAlphaVolumePostSkeleton>::
556 jacobian_apply_volume_post_skeleton(lop, args...);
557 };
558
559 auto jacobianApplySkeleton = [](const auto& lop, auto&... args)
560 {
561 using LOP = std::decay_t<decltype(lop)>;
562 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doAlphaSkeleton>::
563 jacobian_apply_skeleton(lop, args...);
564 };
565
566 auto jacobianApplyBoundary = [](const auto& lop, auto&... args)
567 {
568 using LOP = std::decay_t<decltype(lop)>;
569 Impl::LocalAssemblerCallSwitchHelper<LOP,LOP::doAlphaBoundary>::
570 jacobian_apply_boundary(lop, args...);
571 };
572
573 } } // namespace LocalOperatorApply
574
575 } // namespace PDELab
576} // namespace Dune
577
578#endif // DUNE_PDELAB_LOCALOPERATOR_CALLSWITCH_HH
Infrastructure for concepts.
Traits for type conversions and type information.
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 23, 23:29, 2024)