dune-pdelab  2.7-git
callswitch.hh
Go to the documentation of this file.
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 
6 #include <dune/common/concept.hh>
7 #include <dune/common/typetraits.hh>
8 
9 namespace 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>
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
const IG & ig
Definition: constraints.hh:149
For backward compatibility – Do not use this!
Definition: adaptivity.hh:28
Impl::LocalAssemblerCallSwitchHelper< LOP, doIt > LocalAssemblerCallSwitch
Definition: callswitch.hh:407
std::enable_if_t< LOP::isLinear > jacobianApplySkeleton(const LOP &lop, const IG &ig, const LFSU &lfsu_s, const X &z_s, const LFSV &lfsv_s, const LFSU &lfsu_n, const X &z_n, const LFSV &lfsv_n, Y &y_s, Y &y_n)
Definition: jacobianapplyhelper.hh:64
std::enable_if_t< LOP::isLinear > jacobianApplyVolume(const LOP &lop, const EG &eg, const LFSU &lfsu, const X &z, const LFSV &lfsv, Y &y)
Definition: jacobianapplyhelper.hh:23
std::enable_if_t< LOP::isLinear > jacobianApplyBoundary(const LOP &lop, const IG &ig, const LFSU &lfsu_s, const X &z_s, const LFSV &lfsv_s, Y &y_s)
Definition: jacobianapplyhelper.hh:109